mass_mail_engine/docs/openapi.yaml
warrenchen e9712fb1f7 feat: Implement SendEngine database context and migrations
- Added SendEngineDbContext for managing database interactions.
- Created SendEngineDbContextFactory for design-time database context creation.
- Established dependency injection for the infrastructure layer.
- Defined entity configurations for Tenant, MailingList, Subscriber, ListMember, EventInbox, Campaign, SendJob, SendBatch, DeliverySummary, AuthClient, AuthClientKey, and WebhookNonce.
- Generated initial database migration snapshot.
- Implemented installer program for database migration commands.
2026-02-10 17:56:29 +09:00

465 lines
11 KiB
YAML

openapi: 3.1.0
info:
title: Send Engine API
version: 0.1.0
description: |
Send Engine external API and webhooks.
servers:
- url: https://send-engine.example.com
security:
- bearerAuth: []
paths:
/api/send-jobs:
post:
summary: Create send job
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSendJobRequest'
responses:
'200':
description: Created
content:
application/json:
schema:
$ref: '#/components/schemas/CreateSendJobResponse'
'409':
description: Conflict
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/send-jobs/{id}:
get:
summary: Get send job
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/SendJob'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/send-jobs/{id}/cancel:
post:
summary: Cancel send job
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/SendJobStatusResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'404':
description: Not found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/webhooks/subscriptions:
post:
summary: Member Center subscription events
security:
- webhookSignature: []
webhookTimestamp: []
webhookNonce: []
webhookClientId: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriptionEvent'
responses:
'200':
description: Accepted
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'409':
description: Duplicate event
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/webhooks/lists/full-sync:
post:
summary: Member Center full list sync
security:
- webhookSignature: []
webhookTimestamp: []
webhookNonce: []
webhookClientId: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/FullSyncBatch'
responses:
'200':
description: Accepted
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'409':
description: Duplicate batch
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'422':
description: Validation error
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/webhooks/ses:
post:
summary: SES/SNS events
security:
- sesSignature: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SesEvent'
responses:
'200':
description: OK
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
webhookSignature:
type: apiKey
in: header
name: X-Signature
webhookTimestamp:
type: apiKey
in: header
name: X-Timestamp
webhookNonce:
type: apiKey
in: header
name: X-Nonce
webhookClientId:
type: apiKey
in: header
name: X-Client-Id
sesSignature:
type: apiKey
in: header
name: X-Amz-Sns-Signature
schemas:
CreateSendJobRequest:
type: object
required: [list_id, subject]
properties:
tenant_id:
type: string
format: uuid
list_id:
type: string
format: uuid
name:
type: string
subject:
type: string
minLength: 1
body_html:
type: string
body_text:
type: string
template:
type: object
additionalProperties: true
scheduled_at:
type: string
format: date-time
window_start:
type: string
format: date-time
window_end:
type: string
format: date-time
tracking:
$ref: '#/components/schemas/TrackingOptions'
oneOf:
- required: [body_html]
- required: [body_text]
- required: [template]
CreateSendJobResponse:
type: object
required: [send_job_id, status]
properties:
send_job_id:
type: string
format: uuid
status:
type: string
enum: [pending, running, completed, failed, cancelled]
SendJob:
type: object
required: [id, tenant_id, list_id, campaign_id, status]
properties:
id:
type: string
format: uuid
tenant_id:
type: string
format: uuid
list_id:
type: string
format: uuid
campaign_id:
type: string
format: uuid
status:
type: string
enum: [pending, running, completed, failed, cancelled]
scheduled_at:
type: string
format: date-time
window_start:
type: string
format: date-time
window_end:
type: string
format: date-time
SendJobStatusResponse:
type: object
required: [id, status]
properties:
id:
type: string
format: uuid
status:
type: string
enum: [pending, running, completed, failed, cancelled]
TrackingOptions:
type: object
properties:
open:
type: boolean
click:
type: boolean
SubscriptionEvent:
type: object
required: [event_id, event_type, tenant_id, list_id, subscriber, occurred_at]
properties:
event_id:
type: string
format: uuid
event_type:
type: string
enum: [subscription.activated, subscription.unsubscribed, preferences.updated]
tenant_id:
type: string
format: uuid
list_id:
type: string
format: uuid
subscriber:
$ref: '#/components/schemas/SubscriberPayload'
occurred_at:
type: string
format: date-time
SubscriberPayload:
type: object
required: [id, email, status]
properties:
id:
type: string
format: uuid
email:
type: string
format: email
status:
type: string
enum: [active, unsubscribed, bounced, complaint]
preferences:
type: object
additionalProperties: true
FullSyncBatch:
type: object
required: [sync_id, batch_no, batch_total, tenant_id, list_id, subscribers, occurred_at]
properties:
sync_id:
type: string
format: uuid
batch_no:
type: integer
minimum: 1
batch_total:
type: integer
minimum: 1
tenant_id:
type: string
format: uuid
list_id:
type: string
format: uuid
subscribers:
type: array
items:
$ref: '#/components/schemas/SubscriberPayload'
occurred_at:
type: string
format: date-time
SesEvent:
type: object
required: [event_type, message_id, tenant_id, email, occurred_at]
properties:
event_type:
type: string
enum: [bounce, complaint, delivery, open, click]
message_id:
type: string
tenant_id:
type: string
format: uuid
email:
type: string
format: email
bounce_type:
type: string
enum: [hard, soft]
occurred_at:
type: string
format: date-time
ErrorResponse:
type: object
required: [error, message, request_id]
properties:
error:
type: string
message:
type: string
request_id:
type: string