Skip to content

Commit 542fd28

Browse files
Add route to get submission record by reference
1 parent 1940cdb commit 542fd28

4 files changed

Lines changed: 95 additions & 1 deletion

File tree

src/api/types.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@
5959
* @typedef {{ Params: { formId: string }}} GenerateFeedbackSubmissionsFile
6060
*/
6161

62+
/**
63+
* @typedef {{ Params: { referenceNumber: string }}} GetSubmissionByReference
64+
*/
65+
6266
/**
6367
* @typedef {object} UploadPayload
6468
* @property {('initiated'|'pending'|'ready')} uploadStatus - Have all scans completed, can be initiated, pending or ready

src/models/form.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { formAdapterSubmissionMessagePayloadSchema } from '@defra/forms-engine-plugin/engine/types/schema.js'
12
import Joi from 'joi'
23

34
export const magicLinkSchema = Joi.string().uuid().required()
@@ -38,6 +39,7 @@ export const validateSavedLinkResponseSchema = Joi.object({
3839
export const generateFormSubmissionsFileResponseSchema = Joi.object({
3940
message: Joi.string().required()
4041
}).label('generateFormSubmissionsFileResponse')
42+
4143
export const generateFeedbackSubmissionsFileResponseSchema = Joi.object({
4244
message: Joi.string().required()
4345
}).label('generateFeedbackSubmissionsFileResponse')
@@ -46,3 +48,19 @@ export const resetSaveAndExitLinkResponseSchema = Joi.object({
4648
recordFound: Joi.boolean().required(),
4749
recordUpdated: Joi.boolean().required()
4850
}).label('resetSaveAndExitLinkResponseSchema')
51+
52+
/**
53+
* @type {Joi.ObjectSchema<FormSubmissionDocument>}
54+
*/
55+
export const getSubmissionByReferenceResponseSchema = Joi.object()
56+
.keys({
57+
_id: Joi.string().hex().required(),
58+
recordCreatedAt: Joi.string().isoDate().required(),
59+
expireAt: Joi.string().isoDate().required()
60+
})
61+
.concat(formAdapterSubmissionMessagePayloadSchema)
62+
.label('getSubmissionByReferenceResponseSchema')
63+
64+
/**
65+
* @import { FormSubmissionDocument } from '~/src/api/types.js'
66+
*/

src/repositories/submission-repository.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,35 @@ export async function createSubmissionRecord(document, session) {
6565
}
6666
}
6767

68+
/**
69+
* Gets a submission record based on reference number
70+
* @param {string} referenceNumber - the reference number
71+
* @returns { Promise<WithId<FormSubmissionDocument> | null> }
72+
*/
73+
export async function getSubmissionRecordByReference(referenceNumber) {
74+
logger.info('Reading submission record')
75+
76+
const coll = /** @type {Collection<FormSubmissionDocument>} */ (
77+
db.collection(SUBMISSIONS_COLLECTION_NAME)
78+
)
79+
80+
try {
81+
const result = await coll.findOne({
82+
'meta.referenceNumber': referenceNumber
83+
})
84+
85+
logger.info('Read submission record')
86+
87+
return result
88+
} catch (err) {
89+
logger.error(
90+
err,
91+
`Failed to read submission record - ${getErrorMessage(err)}`
92+
)
93+
throw err
94+
}
95+
}
96+
6897
/**
6998
* @import { ClientSession, ObjectId, WithId, Collection, FindCursor } from 'mongodb'
7099
* @import { FormSubmissionDocument } from '~/src/api/types.js'

src/routes/admin.js

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { Scopes, idSchema } from '@defra/forms-model'
2+
import Boom from '@hapi/boom'
23
import Joi from 'joi'
34

45
import {
56
generateFeedbackSubmissionsFileResponseSchema,
67
generateFormSubmissionsFileResponseSchema,
8+
getSubmissionByReferenceResponseSchema,
79
magicLinkSchema,
810
resetSaveAndExitLinkResponseSchema
911
} from '~/src/models/form.js'
12+
import { getSubmissionRecordByReference } from '~/src/repositories/submission-repository.js'
1013
import { resetSaveAndExitLink } from '~/src/services/save-and-exit-service.js'
1114
import {
1215
generateFeedbackSubmissionsFileForAll,
@@ -125,10 +128,50 @@ export default [
125128
}
126129
}
127130
}
131+
}),
132+
133+
/**
134+
* @satisfies {ServerRoute<GetSubmissionByReference>}
135+
*/
136+
({
137+
method: 'GET',
138+
path: '/submission/{referenceNumber}',
139+
async handler(request) {
140+
const { params } = request
141+
const { referenceNumber } = params
142+
143+
const record = await getSubmissionRecordByReference(referenceNumber)
144+
145+
if (!record) {
146+
return Boom.notFound(
147+
`Submission record with reference ${referenceNumber} was not found`
148+
)
149+
}
150+
151+
return record
152+
},
153+
options: {
154+
tags: ['api'],
155+
auth: {
156+
scope: [`+${Scopes.FormRead}`]
157+
},
158+
validate: {
159+
params: Joi.object()
160+
.keys({
161+
referenceNumber: Joi.string().required()
162+
})
163+
.label('getSubmissionByReferenceParams')
164+
},
165+
response: {
166+
status: {
167+
200: getSubmissionByReferenceResponseSchema
168+
}
169+
}
170+
}
128171
})
129172
]
130173

131174
/**
132175
* @import { ServerRoute } from '@hapi/hapi'
133-
* @import { GenerateFeedbackSubmissionsFile, GenerateFormSubmissionsFile, ResetSaveAndExit } from '~/src/api/types.js'
176+
* @import { GenerateFeedbackSubmissionsFile, GenerateFormSubmissionsFile, GetSubmissionByReference, ResetSaveAndExit } from '~/src/api/types.js'
134177
*/

0 commit comments

Comments
 (0)