Appearance
Newsletter Subscription Backend
The public newsletter flow creates a contact, then sends the newsletter welcome message. This page documents orchestration and business behavior. See the Newsletter Subscribe API for the complete request, response, validation, status, and rate-limit contract.
Architecture
text
Request -> VineJS -> SubscriptionsController -> BrevoService -> ResendService -> Response1
| Component | Responsibility |
|---|---|
start/routes.ts | Registers the public throttled route |
validators/subscription.ts | Validates the email input |
subscriptions_controller.ts | Orders provider calls and maps failures to HTTP |
brevo_service.ts | Creates the contact in the configured list |
resend_service.ts | Renders and sends the newsletter welcome message |
emails/welcome.edge | Owns newsletter welcome content |
Provider transport and credential configuration is documented in Email Infrastructure.
Orchestration
SubscriptionsController.subscribe() performs the flow synchronously:
- Validate
emailwithsubscribeValidator. - Call
BrevoService.addSubscriber(email, listId). - If contact creation succeeds, await
ResendService.sendWelcomeEmail(email). - Return
201only after both calls finish.
typescript
const { email } = await request.validateUsing(subscribeValidator)
await BrevoService.addSubscriber(email, listId)
await ResendService.sendWelcomeEmail(email)
response.status(201)
return renderSuccessResponsePayload({
message: 'Successfully subscribed to the newsletter.',
})1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
Contact creation intentionally runs first. A duplicate or other contact failure therefore does not send a welcome message.
Failure Behavior
- VineJS rejects missing or malformed email input before a provider call.
DuplicateSubscriberErrormaps to409 Conflict.- Other contact-provider errors map to
500 Internal Server Errorand skip welcome delivery. - Welcome-delivery errors map to
500 Internal Server Errorafter the contact has been created. - The controller records failures with request-scoped key
newsletter:subscribe. - There is no queue, background retry, fallback provider, or compensating contact deletion.
The exact public error bodies belong to the API contract.
Welcome Template
apps/server/resources/views/emails/welcome.edge is specific to newsletter signup. Account registration does not render this template. ResendService passes the subscriber address to Adonis Mail and awaits delivery.
Tests
bash
node ace test --files tests/unit/validators/subscription_validator.spec.ts
node ace test --files tests/functional/subscriptions.spec.ts1
2
2
The functional tests stub Brevo and Resend at the external-service boundary. They cover success, required and malformed email input, duplicate contacts, and unexpected contact-provider failure. Routine tests must not create live contacts or send live mail.
Current Boundaries
- The endpoint creates one contact and sends one welcome template.
- The application does not send newsletter campaigns or store delivery analytics.
- Subscriber lifecycle operations outside signup are handled through approved provider operations.