Skip to content

fix(#485-#488): sync API_SPEC error codes/events, add email DLQ, validate templates at startup#613

Merged
hman38705 merged 1 commit intosolutions-plug:mainfrom
Haroldwonder:fix/485-488-api-spec-email-queue-dlq-template-validation
Apr 27, 2026
Merged

fix(#485-#488): sync API_SPEC error codes/events, add email DLQ, validate templates at startup#613
hman38705 merged 1 commit intosolutions-plug:mainfrom
Haroldwonder:fix/485-488-api-spec-email-queue-dlq-template-validation

Conversation

@Haroldwonder
Copy link
Copy Markdown
Contributor

@Haroldwonder Haroldwonder commented Apr 27, 2026

Summary

#485 — Refresh API_SPEC to match current contract and error enums

  • Error codes: corrected all values to match the on-chain #[repr(u32)] enum (100–148). The spec previously used sequential 1–50 values that did not match the contract.
  • Events table: added 7 missing events (ref_dist, mkt_prune, upg_init, upg_vote, upg_exec, upg_rej, mkt_state); corrected topic layouts for mon_reset, rep_set, dep_set; fixed OracleResultSet data payload to include oracle_id (multi-oracle support added in Emit accurate oracle source metadata in oracle result events #405).
  • Bumped spec version to 1.1.0.

#486 — Email retry backoff with exponential delay

Exponential backoff was already implemented in mark_failed (2^attempt × 60s). No code change needed; confirmed and documented.

#487 — Email queue dead-letter handling

  • Added EMAIL_DEAD_LETTER_KEY = "email:dead_letter" Redis sorted set.
  • mark_failed now pushes permanently-failed jobs (max attempts reached) to the DLQ with a failed_at score for time-ordered inspection.
  • New EmailQueue methods: list_dead_letter(), requeue_dead_letter(job_id).
  • QueueStats gains a dead_letter field (visible in existing GET /api/v1/email/queue/stats).
  • Two new admin-only routes (API key + IP whitelist protected, audit-logged):
    • GET /api/v1/email/queue/dead-letter — list all DLQ job IDs
    • POST /api/v1/email/queue/dead-letter/:job_id/requeue — move a job back to the main queue

#488 — Email template validation on startup

  • EmailTemplateEngine::new() now calls validate_all_templates() before returning.
  • Each of the 4 templates is rendered with representative fixture data.
  • With strict_mode enabled, any missing variable or syntax error causes the server to refuse to start with a clear error message, rather than failing silently at send time.

Files changed

File Change
API_SPEC.md Error codes corrected (100–148), events table expanded and corrected
services/api/src/email/queue.rs DLQ constant, DLQ push in mark_failed, list_dead_letter, requeue_dead_letter, QueueStats.dead_letter
services/api/src/email/templates.rs validate_all_templates() called in new()
services/api/src/handlers.rs email_dead_letter_list, email_dead_letter_requeue handlers
services/api/src/main.rs Two new admin routes registered
services/api/src/audit_middleware.rs Audit entries for new DLQ routes

Closes #485, closes #486, closes #487, closes #488

…DLQ, validate templates at startup

solutions-plug#485: Correct error code values in API_SPEC.md to match #[repr(u32)] enum
(100-148). Expand events table with 7 missing events (ref_dist, mkt_prune,
upg_init, upg_vote, upg_exec, upg_rej, mkt_state), fix OracleResultSet data
payload to include oracle_id, correct topic layouts for mon_reset/rep_set/
dep_set. Bump spec version to 1.1.0.

solutions-plug#486: Exponential backoff already present in mark_failed (2^n * 60s).

solutions-plug#487: Add EMAIL_DEAD_LETTER_KEY Redis sorted set. mark_failed now pushes
permanently-failed jobs to the DLQ. Add list_dead_letter() and
requeue_dead_letter() methods. Expose via admin API:
  GET  /api/v1/email/queue/dead-letter
  POST /api/v1/email/queue/dead-letter/:job_id/requeue
QueueStats gains dead_letter field. Audit middleware covers new routes.

solutions-plug#488: EmailTemplateEngine::new() calls validate_all_templates() which renders
all 4 templates with representative fixture data. Invalid syntax or missing
variables now cause a startup error instead of a runtime send failure.
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented Apr 27, 2026

@Haroldwonder Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@hman38705 hman38705 merged commit e1cdec4 into solutions-plug:main Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants