Skip to content

Commit ceb4bce

Browse files
authored
Merge pull request #181 from UKForeignOffice/add-api-spec
Add API specification
2 parents 987d5e6 + dda163e commit ceb4bce

1 file changed

Lines changed: 317 additions & 0 deletions

File tree

api/API_SPECIFICATION.md

Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
# API Endpoints
2+
3+
## Overview
4+
This document describes the public API routes in the API workspace.
5+
6+
Base path roots used by the server:
7+
- `GET /health-check` — simple health-check.
8+
- `POST /forms` — submit a form payload.
9+
- `POST /forms/emails/ses` — used by SES_PROCESS job to prepare/send case email.
10+
- `POST /forms/emails/notify` — used by NOTIFY_PROCESS job to prepare/send user email.
11+
12+
---
13+
14+
## GET /health-check
15+
- Description: Basic health endpoint used by uptime/monitoring checks.
16+
- Request: No body required.
17+
- Response: 200 OK
18+
Example:
19+
```json
20+
{
21+
"uptime": 123.456,
22+
"message": "OK",
23+
"timestamp": 1580500000000
24+
}
25+
26+
# Forms API
27+
28+
## POST `/forms`
29+
30+
**Description**
31+
Main form submission endpoint. Used to submit a form payload received from the front-end (or webhook). On success it enqueues two jobs (`SES_PROCESS` and `NOTIFY_PROCESS`) and returns a reference that identifies the submission (GOV.UK Pay reference or a generated reference).
32+
33+
**Middleware**
34+
- `validationHandler` — validates the overall webhook/form shape (see **Validation** section).
35+
36+
### Request Body
37+
38+
The API expects a **“webhook output” style** payload with the following structure.
39+
40+
#### Required Top-Level Keys
41+
42+
- `name`: `string`
43+
- `questions`: `array` of question objects
44+
- `metadata`: `object` containing `type`, optional `pay`, etc.
45+
46+
#### Question Object
47+
48+
- `question`: `string`
49+
- `fields`: `array` of `FormField` objects
50+
51+
#### FormField Object
52+
53+
- `key`: `string`
54+
- `type`: `string`
55+
- `title`: `string`
56+
- `answer`: `string[] | string | boolean | null`
57+
58+
#### Metadata (partial)
59+
60+
- `type`: one of:
61+
- `affirmation`
62+
- `cni`
63+
- `exchange`
64+
- `certifyCopy`
65+
- `requestDocument`
66+
- `consularLetter`
67+
- Optional `pay` object (see `FormDataBody` type in code)
68+
- Optional `paymentSkipped`, `postal` flags
69+
70+
**Example request (simplified)**
71+
```
72+
{
73+
"name": "example form",
74+
"questions":
75+
[
76+
{
77+
"question": "Applicant name",
78+
"fields":
79+
[
80+
{
81+
"key": "applicantName",
82+
"title": "Name",
83+
"type": "text",
84+
"answer": "Jane Doe"
85+
}
86+
]
87+
}
88+
],
89+
"metadata":
90+
{
91+
"type": "affirmation",
92+
"paymentSkipped": false,
93+
"pay":
94+
{
95+
"payId": "pay-123",
96+
"reference": "PAYREF-0001",
97+
"state":
98+
{
99+
"status": "submitted",
100+
"finished": true
101+
}
102+
}
103+
}
104+
}
105+
```
106+
### Success Response
107+
108+
- **200 OK**
109+
110+
**Example**
111+
```
112+
{
113+
"reference": "PAYREF-0001"
114+
}
115+
```
116+
117+
### Error Responses
118+
119+
- **400 Bad Request** — returned by `validationHandler` when the body fails validation, with a message describing invalid fields.
120+
- **Other 4xx/5xx** — returned by error middleware when `submitService` fails.
121+
122+
### Notes
123+
124+
- Validation is implemented in `api/src/middlewares/validate.ts` using Joi.
125+
- Ensures:
126+
- `questions` array exists
127+
- `question.fields` objects are present
128+
- `metadata.type` is one of the allowed types
129+
- The handler calls `submitService.submitForm(req.body)` and returns the `reference` value from the service.
130+
131+
---
132+
133+
## POST `/forms/emails/ses`
134+
135+
**Path**
136+
`/forms/emails/ses`
137+
138+
**Description**
139+
Prepares case email to be sent to FCDO via SES. Called by the `SES_PROCESS` job (worker).
140+
141+
**Middleware**
142+
- `caseEmailHandlers.validate` — validates the SES/email-case shape.
143+
144+
### Request Body Shape
145+
146+
Validated by Joi in `handlers/forms/emails/case/index.ts`.
147+
148+
- `fields`: **required** array of objects with:
149+
- `key`: `string` (required)
150+
- `type`: `string` (required)
151+
- `title`: `string` (optional)
152+
- `answer`: `any` (optional)
153+
- `metadata` object must include:
154+
- `reference`: `string` (required)
155+
- `type`: optional; if present must be one of the allowed form types
156+
- Optional `payment` object
157+
158+
**Example request (simplified)**
159+
```
160+
{
161+
"fields":
162+
[
163+
{
164+
"key": "applicantName",
165+
"type": "text",
166+
"title": "Applicant name",
167+
"answer": "Jane Doe"
168+
}
169+
],
170+
"metadata":
171+
{
172+
"reference": "PAYREF-0001",
173+
"type": "affirmation",
174+
"payment":
175+
{
176+
"amount": 30
177+
}
178+
}
179+
}
180+
```
181+
182+
### Success Response
183+
184+
- **200 OK**
185+
186+
**Example**
187+
```
188+
{
189+
"jobId": "pgboss-job-uuid"
190+
}
191+
```
192+
193+
### Error Responses
194+
195+
- **400 Bad Request** — validation failed
196+
Wrapped in `ApplicationError("SES","PROCESS_VALIDATION",400, ...)`
197+
- **5xx** — returned when `caseService.sendEmail` throws
198+
199+
### Notes
200+
201+
- After validation, the handler:
202+
1. Determines the case service via `getCaseServiceName(formType)`
203+
2. Fetches it from `res.app.services[caseServiceName]`
204+
3. Calls `sendEmail(req.body)`
205+
206+
---
207+
208+
## POST `/forms/emails/notify`
209+
210+
**Path**
211+
`/forms/emails/notify`
212+
213+
**Description**
214+
Prepares and sends a confirmation email to the user (Notify). Called by the `NOTIFY_PROCESS` job (worker).
215+
216+
**Middleware**
217+
- `userEmailHandlers.validate` — validates the body before processing.
218+
219+
### Request Body Shape
220+
221+
Validated in `handlers/forms/emails/user/index.ts`.
222+
223+
- `answers`: `object` (required)
224+
- `metadata` object must include:
225+
- `reference`: `string` (required)
226+
- `type`: one of the allowed form types (required)
227+
- Optional `payment` object
228+
```
229+
{
230+
"answers":
231+
{
232+
"applicantName": "Jane Doe",
233+
"email": "jane@example.com"
234+
},
235+
"metadata":
236+
{
237+
"reference": "PAYREF-0001",
238+
"type": "affirmation"
239+
}
240+
}
241+
```
242+
243+
### Success Response
244+
245+
- **200 OK**
246+
247+
**Example**
248+
```
249+
{
250+
"jobId": "pgboss-job-uuid"
251+
}
252+
```
253+
254+
### Error Responses
255+
256+
- **400 Bad Request** — validation failed
257+
Wrapped in `ApplicationError("NOTIFY","PROCESS_VALIDATION",400, ...)`
258+
- **5xx** — returned when `userService.sendEmailToUser` throws
259+
260+
### Notes
261+
262+
- The handler calls `res.app.services.userService.sendEmailToUser(req.body)`
263+
- Returns the created job ID
264+
265+
---
266+
267+
## Validation Summary
268+
269+
### `/forms`
270+
271+
Implemented in `api/src/middlewares/validate.ts`.
272+
273+
Key checks:
274+
275+
- `name`: required string
276+
- `questions`: required array
277+
- Each question must have:
278+
- `question`: string
279+
- `fields`: array
280+
- Field items must have:
281+
- `key`: string
282+
- `type`: string
283+
- `metadata.type` must be one of the allowed form types
284+
285+
On failure, throws:
286+
`ApplicationError("WEBHOOK","VALIDATION",400, ...)`
287+
288+
### `/forms/emails/ses`
289+
290+
- Implemented in `handlers/forms/emails/case/index.ts`
291+
- Expects:
292+
- `fields` array
293+
- `metadata.reference`
294+
- Optional `metadata.type` from allowed list
295+
296+
On failure, throws:
297+
`ApplicationError("SES","PROCESS_VALIDATION",400, ...)`
298+
299+
### `/forms/emails/notify`
300+
301+
- Implemented in `handlers/forms/emails/user/index.ts`
302+
- Expects:
303+
- `answers` object
304+
- `metadata.reference`
305+
- `metadata.type` (required)
306+
307+
On failure, throws:
308+
`ApplicationError("NOTIFY","PROCESS_VALIDATION",400, ...)`
309+
310+
---
311+
312+
## Common Response / Error Format
313+
314+
- Success responses return **HTTP 200** with JSON containing the expected keys (e.g. `reference`, `jobId`).
315+
- Validation and application errors are thrown or forwarded as `ApplicationError` instances.
316+
- See `api/src/middlewares/error-handlers.ts` for the exact error response format.
317+

0 commit comments

Comments
 (0)