# Queue Migration Notes This project no longer supports Redis as a runtime dependency. Queue publishing and consumption are SQS-only, while transient auth/runtime state is stored in MySQL. ## Current Flow 1. API writes business data to MySQL. 2. If `QUEUE_OUTBOX_ENABLED=true`, email jobs are persisted to `email_outbox_messages`. 3. Worker polls the outbox and publishes serialized messages to SQS. 4. Worker consumes SQS messages with long polling and sends email through Amazon SES v2. 5. Successful processing deletes the SQS message. 6. Failed processing leaves the message unacked so SQS visibility timeout and DLQ redrive policy handle retries. ## What Changed - Removed Redis producer, consumer, and Redis-backed idempotency paths. - Removed Redis token store used for: - refresh/session bookkeeping - SSO state - TOTP/WebAuthn challenges - security PIN lock/cooldown state - Added MySQL-backed transient stores: - `auth_runtime_tokens` - `queue_idempotency_records` - Simplified bootstrap: - API uses MySQL + optional direct SQS publisher when outbox is disabled. - Worker uses MySQL + SQS only. ## Required Environment Queue and worker settings: ```bash EMAIL_PROVIDER=mock EMAIL_MOCK_DIR=.local/emails QUEUE_MESSAGE_SCHEMA_VERSION=v2 QUEUE_ENABLE_LEGACY_PAYLOAD_FALLBACK=true QUEUE_IDEMPOTENCY_KEY_PREFIX=queue:idempotency:email: QUEUE_IDEMPOTENCY_TTL=24h QUEUE_PROCESSING_TTL=15m QUEUE_WORKER_CONCURRENCY=4 QUEUE_WORKER_MAX_BATCH_SIZE=10 QUEUE_WORKER_PROCESS_TIMEOUT=30s QUEUE_WORKER_SHUTDOWN_TIMEOUT=30s QUEUE_WORKER_BACKOFF_MIN=1s QUEUE_WORKER_BACKOFF_MAX=5m QUEUE_WORKER_PERMANENT_FAILURE_DELAY=30s QUEUE_WORKER_MONITOR_ADDR=127.0.0.1:9090 QUEUE_WORKER_HEALTH_ERROR_THRESHOLD=3 QUEUE_WORKER_DEPTH_POLL_INTERVAL=30s QUEUE_OUTBOX_ENABLED=true QUEUE_OUTBOX_POLL_INTERVAL=1s QUEUE_OUTBOX_BATCH_SIZE=10 QUEUE_OUTBOX_DISPATCH_TIMEOUT=10s QUEUE_OUTBOX_LOCK_TTL=1m QUEUE_OUTBOX_MAX_ATTEMPTS=20 ``` SES settings: ```bash AWS_REGION=ap-southeast-1 SES_REGION= SES_FROM=no-reply@example.com SES_CONFIGURATION_SET= SES_SEND_TIMEOUT=10s SES_ENDPOINT= SES_ALLOW_INSECURE_ENDPOINT=false ``` Local/dev recommendation when you do not have AWS SES: - set `EMAIL_PROVIDER=mock` - keep SQS on LocalStack if needed - inspect delivered mock emails in `EMAIL_MOCK_DIR` AWS / SQS settings: ```bash AWS_REGION=ap-southeast-1 SQS_ENDPOINT= SQS_ALLOW_INSECURE_ENDPOINT=false SQS_QUEUE_URL=https://sqs.ap-southeast-1.amazonaws.com/123456789012/wucher-email SQS_QUEUE_TYPE=standard SQS_MESSAGE_GROUP_ID=email SQS_MAX_MESSAGES=10 SQS_WAIT_TIME_SECONDS=20 SQS_VISIBILITY_TIMEOUT=60s ``` ## SQS Expectations Configure the queue outside the application with: - long polling enabled - sensible visibility timeout - DLQ redrive policy - `maxReceiveCount` aligned with retry tolerance Recommended baseline: - `ReceiveMessageWaitTimeSeconds=20` - `VisibilityTimeout=60` - `maxReceiveCount=5` ## IAM API needs `sqs:SendMessage` only when `QUEUE_OUTBOX_ENABLED=false`. Worker needs: - `sqs:SendMessage` to the main queue when dispatching outbox messages - `sqs:ReceiveMessage` - `sqs:DeleteMessageBatch` - `sqs:ChangeMessageVisibility` - `sqs:GetQueueAttributes` - `ses:SendEmail` If SES event tracking is enabled, provision it separately with: - SES configuration set event destinations - SNS topic publish permissions - a dedicated SQS event queue and consumer policy ## Breaking Changes - Remove these Redis env vars from deployment: - `REDIS_ADDR` - `REDIS_PASSWORD` - `REDIS_DB` - `QUEUE_PRIMARY_BACKEND` - `QUEUE_SECONDARY_BACKEND` - `QUEUE_SECONDARY_REQUIRED` - `QUEUE_CONSUMER_BACKEND` - `QUEUE_IDEMPOTENCY_BACKEND` - `QUEUE_PRODUCER_MODE` - `QUEUE_REDIS_DLQ_KEY` - `AUTH_EMAIL_QUEUE_KEY` - `SQS_DLQ_URL` - Worker now requires MySQL even when it is only consuming SQS, because idempotency state is persisted in MySQL. - Old Redis backlog is not consumed by this version. Drain or discard legacy Redis queues before deploy. ## Deployment Checklist 1. Ensure MySQL migration/AutoMigrate runs and creates `auth_runtime_tokens` and `queue_idempotency_records`. 2. Create or verify the SQS queue and DLQ redrive policy. 3. Verify the SES identity/domain and optional configuration set. 4. Remove Redis and SMTP config from runtime manifests and secrets. 5. Deploy API and worker. 6. Verify: - worker `/health` - worker `/metrics` - SQS queue depth - outbox rows are progressing from `pending` to `published` - SES send acceptance/message IDs in worker logs 7. Manually delete Redis infrastructure after confirming there is no remaining backlog you still need.