Objective
Harden PostKit for production use by adding provider abstraction, secure configuration, delivery observability, retry/idempotency strategy, tenant-safe logging, and operational controls around email sending.
Context
PostKit will be shared by multiple PoCs/tenants. A delivery failure or security mistake must not leak data across tenants or make the platform difficult to operate.
This epic focuses on production behavior around the core API, not template authoring.
Required technology / platform
- Azure Functions / Node.js / TypeScript
- Azure-native configuration and secret management patterns
- Prefer Managed Identity where supported
- Application Insights / Azure Monitor or the observability pattern already used by
poc-plattform-kit
- provider interface owned by PostKit, not provider-specific DTOs leaking into consumers
Provider abstraction
Define a stable interface such as:
interface EmailProvider {
send(message: RenderedEmail, context: SendContext): Promise<DeliveryResult>;
}
The consumer API must remain provider-agnostic.
Provider implementation should support at minimum:
- recipient(s)
- subject
- HTML body
- reply-to where required
- sender/from configuration
- provider message ID
- failure classification
Do not expose provider credentials or provider-specific internals through the public API.
Tenant configuration
Support tenant-scoped configuration for values such as:
- verified sender/from address
- reply-to defaults
- display name
- provider/account configuration where necessary
- branding defaults
Tenant configuration must not be mutable by arbitrary send requests.
Reliability
Define and document behavior for:
- transient provider failures
- permanent provider failures
- duplicate requests
- retries
- timeouts
- function restarts
Before adding automatic retries to sends, implement or explicitly define an idempotency model so retries cannot accidentally send duplicate emails.
Potential contract:
Idempotency-Key: <consumer-generated-key>
The exact persistence mechanism can be selected during implementation, but the design must account for Azure Functions being stateless.
Observability
Every send attempt should be traceable using:
- PostKit request/correlation ID
- authenticated tenant ID
- template key
- environment
- delivery outcome
- provider message ID when available
- duration/latency
- stable error/failure category
Do not log:
- full email bodies by default
- credentials/secrets
- sensitive variable payloads
- authentication tokens
Recipient logging should follow a documented privacy-safe approach.
Metrics / operational signals
Expose or log enough structured data to answer:
- sends per tenant/template
- success/failure rate
- provider failures
- template-not-found failures
- validation failures
- latency
- retry/duplicate behavior
Security
- Keep providers and tenant credentials in secure configuration/secret storage.
- Ensure tenant resolution is authoritative and server-side.
- Prevent cross-tenant storage access.
- Validate template keys and storage paths.
- Enforce request size limits.
- Rate-limit or otherwise protect abusive consumers where appropriate.
- Do not allow arbitrary caller-supplied HTML in the normal template-send endpoint.
- Define CORS narrowly; public browsers should not call the privileged send endpoint directly.
Work
Agent implementation notes
Inspect the latest logging, correlation ID, Azure configuration, Key Vault/Managed Identity, and deployment conventions in singleton-sd/poc-plattform-kit before implementation.
Do not invent a distributed system unnecessarily. Prefer Azure-native capabilities and small abstractions. If durable queues or persistence become necessary for delivery guarantees, document the reason and architecture decision before introducing them.
Keep this epic compatible with the core API contract in Epic #2 and the runtime template model in Epic #3.
Acceptance criteria
- Email provider can be replaced without changing consumer SDK contracts.
- Secrets are not committed to source or exposed in responses/logs.
- A send can be traced from PostKit correlation ID to provider outcome.
- Cross-tenant configuration/template access is tested and blocked.
- Transient/permanent failures are classified consistently.
- Retry behavior cannot casually create duplicate sends.
- Operational documentation explains how to diagnose failed sends and provider issues.
Objective
Harden PostKit for production use by adding provider abstraction, secure configuration, delivery observability, retry/idempotency strategy, tenant-safe logging, and operational controls around email sending.
Context
PostKit will be shared by multiple PoCs/tenants. A delivery failure or security mistake must not leak data across tenants or make the platform difficult to operate.
This epic focuses on production behavior around the core API, not template authoring.
Required technology / platform
poc-plattform-kitProvider abstraction
Define a stable interface such as:
The consumer API must remain provider-agnostic.
Provider implementation should support at minimum:
Do not expose provider credentials or provider-specific internals through the public API.
Tenant configuration
Support tenant-scoped configuration for values such as:
Tenant configuration must not be mutable by arbitrary send requests.
Reliability
Define and document behavior for:
Before adding automatic retries to sends, implement or explicitly define an idempotency model so retries cannot accidentally send duplicate emails.
Potential contract:
The exact persistence mechanism can be selected during implementation, but the design must account for Azure Functions being stateless.
Observability
Every send attempt should be traceable using:
Do not log:
Recipient logging should follow a documented privacy-safe approach.
Metrics / operational signals
Expose or log enough structured data to answer:
Security
Work
EmailProviderabstraction.Agent implementation notes
Inspect the latest logging, correlation ID, Azure configuration, Key Vault/Managed Identity, and deployment conventions in
singleton-sd/poc-plattform-kitbefore implementation.Do not invent a distributed system unnecessarily. Prefer Azure-native capabilities and small abstractions. If durable queues or persistence become necessary for delivery guarantees, document the reason and architecture decision before introducing them.
Keep this epic compatible with the core API contract in Epic #2 and the runtime template model in Epic #3.
Acceptance criteria