Skip to content

Commit

Permalink
feat: Basic boilerplate for GOSS API endpoint (#3893)
Browse files Browse the repository at this point in the history
  • Loading branch information
DafyddLlyr authored Nov 20, 2024
1 parent 7c5a73a commit d37679c
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 0 deletions.
20 changes: 20 additions & 0 deletions api.planx.uk/modules/send/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/SessionPayload"
/goss/{localAuthority}:
post:
summary: Submits an application to GOSS case management
description: |
<b>Test only endpoint - not live</b>
<br/><br/>
Submits an application to GOSS case management
tags:
- send
parameters:
- $ref: "#/components/parameters/localAuthority"
security:
- hasuraAuth: []
requestBody:
description: This endpoint is only called via Hasura's scheduled event webhook, so body is wrapped in a `payload` key
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/SessionPayload"
/uniform/{localAuthority}:
post:
summary: Submits an application to Uniform
Expand Down
39 changes: 39 additions & 0 deletions api.planx.uk/modules/send/goss/controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ServerError } from "../../../errors/serverError.js";
import type { SendIntegrationController } from "../types.js";
import { checkGOSSAuditTable, isTeamUsingGOSS, sendToGOSS } from "./service.js";

export const sendToGOSSController: SendIntegrationController = async (
_req,
res,
next,
) => {
const {
payload: { sessionId },
} = res.locals.parsedReq.body;
const localAuthority = res.locals.parsedReq.params.localAuthority;

if (!isTeamUsingGOSS(localAuthority)) {
return next(
new ServerError({
message: `Cannot submit to GOSS. Team "${localAuthority}" does not support this integration.`,
status: 400,
}),
);
}

const previouslySubmittedApplication = await checkGOSSAuditTable(sessionId);
if (previouslySubmittedApplication) {
return res.status(200).send({
sessionId,
gossId: previouslySubmittedApplication.id,
message: "Skipping send, already successfully submitted",
});
}

const application = await sendToGOSS(sessionId);

return res.status(200).send({
message: "Successfully submitted GOSS application",
application,
});
};
38 changes: 38 additions & 0 deletions api.planx.uk/modules/send/goss/goss.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import supertest from "supertest";
import app from "../../../server.js";

it("requires auth", async () => {
await supertest(app)
.post("/goss/west-berkshire")
.send({ payload: { sessionId: "37e3649b-4854-4249-a5c3-7937c1b952b9" } })
.expect(401);
});

it("throws an error if payload is missing", async () => {
await supertest(app)
.post("/goss/west-berkshire")
.set({ Authorization: process.env.HASURA_PLANX_API_KEY! })
.send({ payload: null })
.expect(400)
.then((res) => {
expect(res.body).toHaveProperty("issues");
expect(res.body).toHaveProperty("name", "ZodError");
});
});

it("throws an error if team is unsupported", async () => {
await supertest(app)
.post("/goss/unsupported-team")
.set({ Authorization: process.env.HASURA_PLANX_API_KEY! })
.send({ payload: { sessionId: "37e3649b-4854-4249-a5c3-7937c1b952b9" } })
.expect(400)
.then((res) => {
expect(res.body.error).toMatch(
/Cannot submit to GOSS. Team "unsupported-team" does not support this integration./,
);
});
});

it.todo("does not re-send an application which has already been submitted");
it.todo("creates an audit record after submitting");
it.todo("returns a success upon completion");
28 changes: 28 additions & 0 deletions api.planx.uk/modules/send/goss/service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { markSessionAsSubmitted } from "../../saveAndReturn/service/utils.js";

export const isTeamUsingGOSS = (team: string) => {
// TODO: Query db for this
const GOSS_TEAMS = ["west-berkshire"];
return GOSS_TEAMS.includes(team);
};

export const createGOSSApplicationAuditRecord = async () => {
console.log("TODO: Create audit record");
};

export const checkGOSSAuditTable = async (sessionId: string) => {
console.log("TODO: Check GOSS audit table");
return {
id: "abc123",
};
};

export const sendToGOSS = async (sessionId: string) => {
const applicationData = {};
// TODO: Post payload to GOSS

await createGOSSApplicationAuditRecord();
await markSessionAsSubmitted(sessionId);

return applicationData;
};
7 changes: 7 additions & 0 deletions api.planx.uk/modules/send/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { downloadApplicationFiles } from "./downloadApplicationFiles/index.js";
import { sendToS3 } from "./s3/index.js";
import { sendToIdoxNexus } from "./idox/nexus.js";
import { sendIntegrationSchema } from "./types.js";
import { sendToGOSSController } from "./goss/controller.js";

const router = Router();

Expand Down Expand Up @@ -48,6 +49,12 @@ router.post(
validate(sendIntegrationSchema),
sendToS3,
);
router.post(
"/goss/:localAuthority",
useHasuraAuth,
validate(sendIntegrationSchema),
sendToGOSSController,
);

router.get("/download-application-files/:sessionId", downloadApplicationFiles);

Expand Down

0 comments on commit d37679c

Please sign in to comment.