feat: use postgres

This commit is contained in:
Ilia Denisov
2026-04-26 20:34:39 +02:00
committed by GitHub
parent 48b0056b49
commit fe829285a6
365 changed files with 29223 additions and 24049 deletions
+21 -20
View File
@@ -6,22 +6,22 @@
sequenceDiagram
participant Auth as Auth / Session Service
participant Mail as Mail Service
participant Redis
participant Postgres
participant Scheduler
participant SMTP as Provider
Auth->>Mail: POST /api/v1/internal/login-code-deliveries + Idempotency-Key
Mail->>Mail: validate request and idempotency scope
alt MAIL_SMTP_MODE = stub
Mail->>Redis: persist delivery as suppressed
Mail->>Postgres: persist delivery as suppressed
Mail-->>Auth: 200 {outcome=suppressed}
else MAIL_SMTP_MODE = smtp
Mail->>Redis: persist delivery as queued + attempt #1 scheduled
Mail->>Postgres: persist delivery as queued + attempt #1 scheduled
Mail-->>Auth: 200 {outcome=sent}
Scheduler->>Redis: claim due attempt
Scheduler->>Postgres: claim due attempt (FOR UPDATE SKIP LOCKED)
Scheduler->>SMTP: send rendered auth mail
SMTP-->>Scheduler: accepted or classified failure
Scheduler->>Redis: commit sent / retry / failed / dead_letter
Scheduler->>Postgres: commit sent / retry / failed / dead_letter
end
```
@@ -36,16 +36,17 @@ sequenceDiagram
participant Stream as Redis Stream mail:delivery_commands
participant Consumer as Command consumer
participant Mail as Mail Service
participant Postgres
participant Redis
Notify->>Stream: XADD generic command
Consumer->>Stream: XREAD from last stored offset
Consumer->>Mail: decode and validate command
alt malformed or conflicting command
Mail->>Redis: record malformed command entry
Mail->>Postgres: record malformed command entry
Consumer->>Redis: save stream offset
else valid command
Mail->>Redis: persist delivery + first attempt + optional payload bundle
Mail->>Postgres: persist delivery + first attempt + optional payload bundle
Consumer->>Redis: save stream offset
end
```
@@ -55,29 +56,29 @@ sequenceDiagram
```mermaid
sequenceDiagram
participant Scheduler
participant Redis
participant Postgres
participant Worker as Attempt worker
participant SMTP as Provider
Scheduler->>Redis: find next due delivery
Scheduler->>Redis: load work item
Scheduler->>Postgres: find next due delivery (next_attempt_at <= now)
Scheduler->>Postgres: load work item (delivery + active attempt)
alt template delivery not yet rendered
Scheduler->>Redis: render and store materialized content
Scheduler->>Postgres: render and store materialized content
end
Scheduler->>Redis: claim scheduled attempt
Scheduler->>Postgres: claim scheduled attempt (FOR UPDATE SKIP LOCKED)
Scheduler->>Worker: enqueue claimed work
Worker->>SMTP: send materialized message
SMTP-->>Worker: accepted / suppressed / transient_failure / permanent_failure
alt accepted
Worker->>Redis: commit sent + provider_accepted
Worker->>Postgres: commit sent + provider_accepted
else suppressed
Worker->>Redis: commit suppressed + provider_rejected
Worker->>Postgres: commit suppressed + provider_rejected
else transient failure before retry budget ends
Worker->>Redis: commit transport_failed|timed_out + next scheduled attempt
Worker->>Postgres: commit transport_failed|timed_out + next scheduled attempt
else retry budget exhausted
Worker->>Redis: commit dead_letter + dead-letter entry
Worker->>Postgres: commit dead_letter + dead-letter entry
else permanent failure
Worker->>Redis: commit failed + provider_rejected
Worker->>Postgres: commit failed + provider_rejected
end
```
@@ -87,12 +88,12 @@ sequenceDiagram
sequenceDiagram
participant Ops as Trusted operator
participant Mail as Mail Service
participant Redis
participant Postgres
Ops->>Mail: POST /api/v1/internal/deliveries/{delivery_id}/resend
Mail->>Redis: load original delivery and optional payload bundle
Mail->>Postgres: load original delivery and optional payload bundle
Mail->>Mail: verify original status is terminal
Mail->>Redis: create clone delivery with source=operator_resend
Mail->>Postgres: create clone delivery with source=operator_resend
Mail-->>Ops: 200 {delivery_id=<clone>}
```