From 93cf90e99b54ea18ff1106e093aab8abbfbe7a97 Mon Sep 17 00:00:00 2001 From: Jessica McInchak Date: Thu, 19 Oct 2023 08:31:10 +0100 Subject: [PATCH] feat: add an admin endpoint for the Digital Planning Application format (#2322) --- .../admin/session/digitalPlanningData.test.ts | 53 + .../admin/session/digitalPlanningData.ts | 35 + api.planx.uk/server.ts | 5 + .../tests/mocks/digitalPlanningDataMocks.ts | 1713 +++++++++++++++++ editor.planx.uk/pnpm-lock.yaml | 116 +- 5 files changed, 1836 insertions(+), 86 deletions(-) create mode 100644 api.planx.uk/admin/session/digitalPlanningData.test.ts create mode 100644 api.planx.uk/admin/session/digitalPlanningData.ts create mode 100644 api.planx.uk/tests/mocks/digitalPlanningDataMocks.ts diff --git a/api.planx.uk/admin/session/digitalPlanningData.test.ts b/api.planx.uk/admin/session/digitalPlanningData.test.ts new file mode 100644 index 0000000000..254a0ab8c8 --- /dev/null +++ b/api.planx.uk/admin/session/digitalPlanningData.test.ts @@ -0,0 +1,53 @@ +import supertest from "supertest"; +import app from "../../server"; +import { authHeader } from "../../tests/mockJWT"; +import { expectedPlanningPermissionPayload } from "../../tests/mocks/digitalPlanningDataMocks"; + +const endpoint = (strings: TemplateStringsArray) => + `/admin/session/${strings[0]}/digital-planning-application`; + +const mockGenerateDigitalPlanningApplicationPayload = jest + .fn() + .mockResolvedValue(expectedPlanningPermissionPayload); + +jest.mock("@opensystemslab/planx-core", () => { + return { + CoreDomainClient: jest.fn().mockImplementation(() => ({ + export: { + digitalPlanningDataPayload: () => + mockGenerateDigitalPlanningApplicationPayload(), + }, + })), + }; +}); + +describe("Digital Planning Application payload admin endpoint", () => { + it("requires a user to be logged in", async () => { + await supertest(app) + .get(endpoint`123`) + .expect(401) + .then((res) => + expect(res.body).toEqual({ + error: "No authorization token was found", + }), + ); + }); + + it("requires a user to have the 'platformAdmin' role", async () => { + await supertest(app) + .get(endpoint`123`) + .set(authHeader({ role: "teamEditor" })) + .expect(403); + }); + + it("returns a valid JSON payload", async () => { + await supertest(app) + .get(endpoint`123`) + .set(authHeader({ role: "platformAdmin" })) + .expect(200) + .expect("content-type", "application/json; charset=utf-8") + .then((res) => + expect(res.body).toEqual(expectedPlanningPermissionPayload), + ); + }); +}); diff --git a/api.planx.uk/admin/session/digitalPlanningData.ts b/api.planx.uk/admin/session/digitalPlanningData.ts new file mode 100644 index 0000000000..76929647ba --- /dev/null +++ b/api.planx.uk/admin/session/digitalPlanningData.ts @@ -0,0 +1,35 @@ +import { NextFunction, Request, Response } from "express"; +import { $api } from "../../client"; + +/** + * @swagger + * /admin/session/{sessionId}/digital-planning-application: + * get: + * summary: Generates a Digital Planning Application payload + * description: Generates a Digital Planning Application payload and validates it against the Digital Planning Data JSON Schema + * tags: + * - admin + * parameters: + * - $ref: '#/components/parameters/sessionId' + * security: + * - bearerAuth: [] + */ +export const getDigitalPlanningApplicationPayload = async ( + req: Request, + res: Response, + next: NextFunction, +) => { + try { + const data = await $api.export.digitalPlanningDataPayload( + req.params.sessionId, + ); + res.set("content-type", "application/json"); + return res.send(data); + } catch (error) { + return next({ + message: + "Failed to make Digital Planning Application payload: " + + (error as Error).message, + }); + } +}; diff --git a/api.planx.uk/server.ts b/api.planx.uk/server.ts index 6264fdf11b..afbc99655a 100644 --- a/api.planx.uk/server.ts +++ b/api.planx.uk/server.ts @@ -72,6 +72,7 @@ import webhookRoutes from "./modules/webhooks/routes"; import analyticsRoutes from "./modules/analytics/routes"; import { useSwaggerDocs } from "./docs"; import { Role } from "@opensystemslab/planx-core/types"; +import { getDigitalPlanningApplicationPayload } from "./admin/session/digitalPlanningData"; import { $public } from "./client"; const router = express.Router(); @@ -213,6 +214,10 @@ app.get("/admin/session/:sessionId/html", getHTMLExport); app.get("/admin/session/:sessionId/html-redacted", getRedactedHTMLExport); app.get("/admin/session/:sessionId/zip", generateZip); app.get("/admin/session/:sessionId/summary", getSessionSummary); +app.get( + "/admin/session/:sessionId/digital-planning-application", + getDigitalPlanningApplicationPayload, +); app.post("/flows/:flowId/copy", useTeamEditorAuth, copyFlow); diff --git a/api.planx.uk/tests/mocks/digitalPlanningDataMocks.ts b/api.planx.uk/tests/mocks/digitalPlanningDataMocks.ts new file mode 100644 index 0000000000..6265025838 --- /dev/null +++ b/api.planx.uk/tests/mocks/digitalPlanningDataMocks.ts @@ -0,0 +1,1713 @@ +export const expectedPlanningPermissionPayload = { + data: { + application: { + type: { + value: "pp.full.householder", + description: "Planning Permission - Full householder", + }, + fee: { + calculated: 206, + payable: 206, + exemption: { + disability: true, + resubmission: true, + }, + reduction: { + sports: true, + parishCouncil: true, + alternative: true, + }, + reference: { + govPay: "sandbox-ref-456", + }, + }, + declaration: { + accurate: true, + connection: { + value: "none", + }, + }, + }, + user: { + role: "proxy", + }, + applicant: { + type: "individual", + contact: { + name: { + first: "David", + last: "Bowie", + }, + email: "ziggy@example.com", + phone: { + primary: "Not provided by agent", + }, + company: {}, + }, + address: { + sameAsSiteAddress: true, + }, + siteContact: { + role: "proxy", + }, + interest: "owner.sole", + ownership: { + certificate: "a", + }, + agent: { + contact: { + name: { + first: "Ziggy", + last: "Stardust", + }, + email: "ziggy@example.com", + phone: { + primary: "01100 0110 0011", + }, + company: {}, + }, + address: { + line1: "40 Stansfield Road", + line2: "Brixton", + town: "London", + county: "Greater London", + postcode: "SW9 9RZ", + country: "UK", + }, + }, + }, + property: { + address: { + latitude: 51.4656522, + longitude: -0.1185926, + x: 530787, + y: 175754, + title: "40, STANSFIELD ROAD, LONDON", + singleLine: "40, STANSFIELD ROAD, LONDON, SW9 9RZ", + source: "Ordnance Survey", + uprn: "100021892955", + usrn: "21901294", + pao: "40", + street: "STANSFIELD ROAD", + town: "LONDON", + postcode: "SW9 9RZ", + }, + boundary: { + site: { + type: "Feature", + geometry: { + type: "Polygon", + coordinates: [ + [ + [-0.1186569035053321, 51.465703531871384], + [-0.1185938715934822, 51.465724418998775], + [-0.1184195280075143, 51.46552473766957], + [-0.11848390102387167, 51.4655038504508], + [-0.1186569035053321, 51.465703531871384], + ], + ], + }, + properties: null, + }, + area: { + hectares: 0.012592, + squareMetres: 125.92, + }, + }, + constraints: { + planning: [ + { + value: "tpo", + description: "Tree Preservation Order (TPO) or zone", + overlaps: false, + }, + { + value: "listed", + description: "Listed Building", + overlaps: false, + }, + { + value: "article4", + description: "Article 4 Direction area", + overlaps: false, + }, + { + value: "monument", + description: "Site of a Scheduled Monument", + overlaps: false, + }, + { + value: "designated", + description: "Designated land", + overlaps: false, + }, + { + value: "nature.SAC", + description: "Special Area of Conservation (SAC)", + overlaps: false, + }, + { + value: "nature.ASNW", + description: "Ancient Semi-Natural Woodland (ASNW)", + overlaps: false, + }, + { + value: "nature.SSSI", + description: "Site of Special Scientific Interest (SSSI)", + overlaps: false, + }, + { + value: "locallyListed", + description: "Locally Listed Building", + overlaps: false, + }, + { + value: "designated.SPA", + description: "Special Protection Area (SPA)", + overlaps: false, + }, + { + value: "designated.WHS", + description: "UNESCO World Heritage Site or buffer zone", + overlaps: false, + }, + { + value: "registeredPark", + description: "Historic Park or Garden", + overlaps: false, + }, + { + value: "designated.AONB", + description: "Area of Outstanding Natural Beauty (AONB)", + overlaps: false, + }, + { + value: "article4.caz", + description: "Central Activities Zone (CAZ)", + overlaps: false, + }, + { + value: "designated.nationalPark", + description: "National Park", + overlaps: false, + }, + { + value: "designated.conservationArea", + description: "Conservation Area", + overlaps: false, + }, + { + value: "designated.nationalPark.broads", + description: "National Park - Broads", + overlaps: false, + }, + { + value: "road.classified", + description: "Classified Road", + overlaps: false, + }, + ], + }, + localAuthorityDistrict: ["Lambeth"], + region: "London", + type: { + value: "residential.dwelling.house.terrace", + description: "Terrace", + }, + }, + proposal: { + projectType: [ + { + value: "extend.roof.dormer", + description: "Add a roof dormer", + }, + ], + description: + "Roof extension to the rear of the property, incorporating starship launchpad.", + boundary: { + site: { + type: "Feature", + geometry: { + type: "Polygon", + coordinates: [ + [ + [-0.1186569035053321, 51.465703531871384], + [-0.1185938715934822, 51.465724418998775], + [-0.1184195280075143, 51.46552473766957], + [-0.11848390102387167, 51.4655038504508], + [-0.1186569035053321, 51.465703531871384], + ], + ], + }, + properties: null, + }, + area: { + hectares: 0.012592, + squareMetres: 125.92, + }, + }, + date: { + start: "2024-05-01", + completion: "2024-05-02", + }, + details: { + extend: { + area: { + squareMetres: 45, + }, + }, + vehicleParking: { + type: [ + { + value: "cars.offStreet.residents", + description: "Off-street parking for residents only", + }, + { + value: "bicycles.offStreet", + description: "Off-street parking for bicycles", + }, + ], + cars: { + count: { + existing: 1, + proposed: 1, + }, + offStreet: { + count: { + existing: 0, + proposed: 0, + }, + club: { + count: { + existing: 0, + proposed: 0, + }, + }, + disabled: { + count: { + existing: 0, + proposed: 0, + }, + }, + other: { + count: { + existing: 0, + proposed: 0, + }, + }, + residents: { + count: { + existing: 1, + proposed: 1, + }, + }, + }, + onStreet: { + count: { + existing: 0, + proposed: 0, + }, + club: { + count: { + existing: 0, + proposed: 0, + }, + }, + disabled: { + count: { + existing: 0, + proposed: 0, + }, + }, + other: { + count: { + existing: 0, + proposed: 0, + }, + }, + residents: { + count: { + existing: 0, + proposed: 0, + }, + }, + }, + }, + vans: { + count: { + existing: 0, + proposed: 0, + }, + offStreet: { + count: { + existing: 0, + proposed: 0, + }, + }, + onStreet: { + count: { + existing: 0, + proposed: 0, + }, + }, + }, + motorcycles: { + count: { + existing: 0, + proposed: 0, + }, + offStreet: { + count: { + existing: 0, + proposed: 0, + }, + }, + onStreet: { + count: { + existing: 0, + proposed: 0, + }, + }, + }, + bicycles: { + count: { + existing: 2, + proposed: 2, + }, + offStreet: { + count: { + existing: 2, + proposed: 2, + }, + }, + onStreet: { + count: { + existing: 0, + proposed: 0, + }, + }, + }, + buses: { + count: { + existing: 0, + proposed: 0, + }, + offStreet: { + count: { + existing: 0, + proposed: 0, + }, + }, + onStreet: { + count: { + existing: 0, + proposed: 0, + }, + }, + }, + }, + }, + }, + }, + result: [], + responses: [ + { + question: "Is the property in Lambeth?", + responses: [ + { + value: "Yes", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "The property", + }, + }, + { + question: "What type of property is it?", + responses: [ + { + value: "House", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "The property", + }, + }, + { + question: "What type of house it is?", + responses: [ + { + value: "Terrace", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "The property", + }, + }, + { + question: "Is the property in a flood zone?", + responses: [ + { + value: "No", + }, + ], + metadata: { + sectionName: "The property", + }, + }, + { + question: "What type of property is it?", + responses: [ + { + value: "House", + metadata: { + flags: ["Listed building consent / Not required"], + }, + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About the project", + }, + }, + { + question: "List the changes involved in the project", + responses: [ + { + value: "Add a roof extension", + metadata: { + flags: ["Listed building consent / Not required"], + }, + }, + ], + metadata: { + sectionName: "About the project", + }, + }, + { + question: "Have works already started?", + responses: [ + { + value: "No", + }, + ], + metadata: { + sectionName: "About the project", + }, + }, + { + question: "Is the property in a flood zone?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About the project", + }, + }, + { + question: "What type of changes does the project involve?", + responses: [ + { + value: "Extension", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About the project", + }, + }, + { + question: "Is the project to add an outbuilding?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About the project", + }, + }, + { + question: "How much new floor area is being added to the house?", + responses: [ + { + value: "Less than 100m²", + }, + ], + metadata: { + sectionName: "About the project", + }, + }, + { + question: + "How much exactly is the internal floor area of the property increasing by?", + responses: [ + { + value: "45", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: + "Does the project involve creating any new bedrooms or bathrooms?", + responses: [ + { + value: "No", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Describe the wall materials of the existing house", + responses: [ + { + value: "London stock brick", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Describe the wall materials of the new extension", + responses: [ + { + value: "Metallic cladding, reflective. Multiple colours.", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Describe the material of the roof of the existing house", + responses: [ + { + value: "Grey slate", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Describe the material for the new roof of the extension", + responses: [ + { + value: "Zinc panels", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Describe the window materials of the existing house", + responses: [ + { + value: "Wooden sash windows, painted white", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Describe the window materials of the extension", + responses: [ + { + value: "Brushed steel.", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Describe the door materials of the existing house", + responses: [ + { + value: "Wood, painted.", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Describe the door materials of the extension", + responses: [ + { + value: "No door present", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: + "Are there any trees that could fall within the property or the areas affected by the project (the previously drawn outline)?", + responses: [ + { + value: "No", + }, + ], + metadata: { + sectionName: "About the project", + }, + }, + { + question: "Does the project involve any of these?", + responses: [ + { + value: "No, none of these", + }, + ], + metadata: { + sectionName: "About the project", + }, + }, + { + question: "Is the property in Greater London?", + responses: [ + { + value: "Yes", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About the project", + }, + }, + { + question: "Does the site include more than one property?", + responses: [ + { + value: "No", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Do you know the title number of the property?", + responses: [ + { + value: "No", + }, + ], + metadata: { + sectionName: "About the project", + }, + }, + { + question: + "Does the property have an Energy Performance Certificate (EPC)?", + responses: [ + { + value: "No", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "What type of application is this?", + responses: [ + { + value: "Planning permission for a home", + }, + ], + metadata: { + autoAnswered: true, + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "When will the works start?", + responses: [ + { + value: "2024-05-01", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "When will the works be completed?", + responses: [ + { + value: "2024-05-02", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Does the site include parking spaces for any of these?", + responses: [ + { + value: "Cars", + }, + { + value: "Bicycles", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Total number of car parking spaces before", + responses: [ + { + value: "1", + }, + ], + metadata: { + sectionName: "About the project", + }, + }, + { + question: "Total number of car parking spaces after", + responses: [ + { + value: "1", + }, + ], + metadata: { + sectionName: "About the project", + }, + }, + { + question: "What types of car parking space are present?", + responses: [ + { + value: "Off-street parking for residents only", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Off-street, residents-only car spaces before", + responses: [ + { + value: "1", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Off-street, residents-only car spaces after", + responses: [ + { + value: "1", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "What type of bicycle parking is there?", + responses: [ + { + value: "Off-street cycle parking", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Off-street bicycle spaces before", + responses: [ + { + value: "2", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Off-street bicycle spaces after", + responses: [ + { + value: "2", + }, + ], + metadata: { + policyRefs: [ + { + text: "Greater London Authority Act 1999", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Is the property on designated land?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About the project", + }, + }, + { + question: "Does the property include any of these?", + responses: [ + { + value: "None of these", + }, + ], + metadata: { + autoAnswered: true, + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) 2015 (as amended)", + }, + ], + sectionName: "About the project", + }, + }, + { + question: "Heritage Statement needed?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About the project", + }, + }, + { + question: "Is the property in a flood zone?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About the project", + }, + }, + { + question: "What type of application is it?", + responses: [ + { + value: "Apply for planning permission", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About you", + }, + }, + { + question: "Your contact details", + responses: [ + { + value: "Mx Ziggy Stardust 01100 0110 0011 ziggy@example.com", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: "Is this a test?", + responses: [ + { + value: "No", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: "Are you applying on behalf of someone else?", + responses: [ + { + value: "Yes", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: "Which of these best describes you?", + responses: [ + { + value: "Friend or relative", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: "Your contact address", + responses: [ + { + value: + "40 Stansfield Road, Brixton, London, Greater London, SW9 9RZ, UK", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: "Which of these best describes the applicant?", + responses: [ + { + value: "Private individual", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: "Applicant's title", + responses: [ + { + value: "Mr", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: "Do you want to provide an email address for the applicant?", + responses: [ + { + value: "No", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: "Do you want to provide a telephone number for the applicant?", + responses: [ + { + value: "No", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: + "Is the applicant's contact address the same as the property address?", + responses: [ + { + value: "Yes", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: "Which of these best describes you?", + responses: [ + { + value: "Friend or relative", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About you", + }, + }, + { + question: + "We may need to visit your site to assess your application. If we do, who should we contact to arrange the visit?", + responses: [ + { + value: "Me", + }, + ], + metadata: { + sectionName: "About you", + }, + }, + { + question: "Which of these best describes you?", + responses: [ + { + value: "Friend or relative acting on the applicant's behalf", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About you", + }, + }, + { + question: + "Which of these best describes the applicant's interest in the land?", + responses: [ + { + value: "Sole owner", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Development Management Procedure) (England) Order 2015", + }, + ], + sectionName: "About you", + }, + }, + { + question: + "Did you get any pre-application advice from the council before making this application?", + responses: [ + { + value: "No", + }, + ], + metadata: { + sectionName: "About this application", + }, + }, + { + question: "What type of planning application are you making?", + responses: [ + { + value: "Full planning permission", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "Is the property a home?", + responses: [ + { + value: "Yes", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "What types of changes does the application relate to?", + responses: [ + { + value: "Extension", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "What type of extension is it?", + responses: [ + { + value: "Roof extension", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "List the changes involved in the roof extension", + responses: [ + { + value: "Add dormer", + }, + ], + metadata: { + sectionName: "About this application", + }, + }, + { + question: + "Is the purpose of the project to support the needs of a disabled resident?", + responses: [ + { + value: "No", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Fees for Applications, Deemed Applications, Requests and Site Visits) (England) Regulations 2012, Regulation 14UK Statutory Instruments 2012 No. 2920 Regulation 4, Equalities Act 2010, Section 6 Children Act 1989, Part 3", + }, + ], + sectionName: "About this application", + }, + }, + { + question: "Is it a prior approval application?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "Is the property a home?", + responses: [ + { + value: "Yes", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "What works does the project involve?", + responses: [ + { + value: "Extension", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "Is this application a resubmission?", + responses: [ + { + value: "No", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Fees for Applications, Deemed Applications, Requests and Site Visits) (England) Regulations 2012, Regulation 9", + }, + ], + sectionName: "About this application", + }, + }, + { + question: "Does the application qualify for a disability exemption?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "Does the application qualify for a resubmission exemption?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "Is the site a sports field?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + policyRefs: [ + { + text: "The Town and Country Planning (Fees for Applications, Deemed Applications, Requests and Site Visits) (England) Regulations 2012 Chapter 2, Paragraph 3", + }, + ], + sectionName: "About this application", + }, + }, + { + question: + "Is the application being made by (or on behalf of) a parish or community council?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + policyRefs: [ + { + text: "The Town and Country Planning (Fees for Applications, Deemed Applications, Requests and Site Visits) (England) Regulations 2012 - Regulation 11", + }, + ], + sectionName: "About this application", + }, + }, + { + question: + "Are you also submitting another proposal for the same site today?", + responses: [ + { + value: "No", + }, + ], + metadata: { + policyRefs: [ + { + text: "The Town and Country Planning (Fees for Applications, Deemed Applications, Requests and Site Visits) (England) Regulations 2012 Chapter 2, Paragraph 10", + }, + ], + sectionName: "About this application", + }, + }, + { + question: + "Does the application qualify for the sports club fee reduction?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: + "Does the application qualify for the parish council reduction?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + policyRefs: [ + { + text: "The Town and Country Planning (Fees for Applications, Deemed Applications, Requests and Site Visits) (England) Regulations 2012 - Regulation 11", + }, + ], + sectionName: "About this application", + }, + }, + { + question: + "Does the application qualify for the alternative application reduction?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + policyRefs: [ + { + text: "The Town and Country Planning (Fees for Applications, Deemed Applications, Requests and Site Visits) (England) Regulations 2012 Chapter 2, Paragraph 10", + }, + ], + sectionName: "About this application", + }, + }, + { + question: "What type of application is it?", + responses: [ + { + value: "Full planning permission", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "What does the project involve?", + responses: [ + { + value: "Extension", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "About this application", + }, + }, + { + question: "How much new floor area is being created?", + responses: [ + { + value: "Less than 100m²", + metadata: { + flags: ["Community infrastructure levy / Not liable"], + }, + }, + ], + metadata: { + autoAnswered: true, + policyRefs: [ + { + text: "The Community Infrastructure Levy Regulations 2010, Regulation 42", + }, + ], + sectionName: "About this application", + }, + }, + { + question: "Is this a householder planning application?", + responses: [ + { + value: "Yes", + metadata: { + flags: ["Community infrastructure levy / Not liable"], + }, + }, + ], + metadata: { + autoAnswered: true, + policyRefs: [ + { + text: "The Community Infrastructure Levy Regulations 2010, Regulation 42", + }, + ], + sectionName: "About this application", + }, + }, + { + question: "Have the works already started?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "Upload drawings", + }, + }, + { + question: "What changes does the project involve?", + responses: [ + { + value: "Extension", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "Upload drawings", + }, + }, + { + question: "Is the project to add an outbuilding?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "Upload drawings", + }, + }, + { + question: "Which Local Planning authority is it?", + responses: [ + { + value: "Lambeth", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "Check", + }, + }, + { + question: "Connections with London Borough of Lambeth", + responses: [ + { + value: "None of the above apply to me", + }, + ], + metadata: { + sectionName: "Check", + }, + }, + { + question: "I confirm that:", + responses: [ + { + value: + "The information contained in this application is truthful, accurate and complete, to the best of my knowledge", + }, + ], + metadata: { + sectionName: "Check", + }, + }, + { + question: "Does the application qualify for a disability exemption?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "Pay and send", + }, + }, + { + question: "Does the application qualify for a resubmission exemption?", + responses: [ + { + value: "No", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "Pay and send", + }, + }, + { + question: "Which Local Planning authority is it?", + responses: [ + { + value: "Lambeth", + }, + ], + metadata: { + autoAnswered: true, + sectionName: "Pay and send", + }, + }, + ], + files: [ + { + name: "https://api.editor.planx.dev/file/private/vg0av01p/RoofPlan.pdf", + type: [ + { + value: "property.drawing.roofPlan", + description: "Roof plan - existing", + }, + { + value: "proposal.drawing.roofPlan", + description: "Roof plan - proposed", + }, + ], + }, + { + name: "https://api.editor.planx.dev/file/private/ka97yl2c/Site%20plan.pdf", + type: [ + { + value: "property.drawing.sitePlan", + description: "Site plan - existing", + }, + { + value: "proposal.drawing.sitePlan", + description: "Site plan - proposed", + }, + ], + }, + { + name: "https://api.editor.planx.dev/file/private/osprppqo/Elevations.pdf", + type: [ + { + value: "property.drawing.elevation", + description: "Elevation plan - existing", + }, + { + value: "proposal.drawing.elevation", + description: "Elevation plan - proposed", + }, + ], + }, + { + name: "https://api.editor.planx.dev/file/private/cri3ziaj/Plan.pdf", + type: [ + { + value: "property.drawing.floorPlan", + description: "Floor plan - existing", + }, + { + value: "proposal.drawing.floorPlan", + description: "Floor plan - proposed", + }, + ], + }, + ], + metadata: { + service: { + flowId: "01e38c5d-e701-4e44-acdc-4d6b5cc3b854", + name: "Apply for planning permission", + owner: "Lambeth", + url: "https://www.editor.planx.dev/lambeth/apply-for-planning-permission/preview", + }, + session: { + source: "PlanX", + id: "81bcaa0f-baf5-4573-ba0a-ea868c573faf", + createdAt: "2023-10-01 00:00:00", + submittedAt: "2023-10-02 00:00:00", + }, + schema: { + url: "https://theopensystemslab.github.io/digital-planning-data-schemas/v0.0.1/schema.json", + }, + }, +}; diff --git a/editor.planx.uk/pnpm-lock.yaml b/editor.planx.uk/pnpm-lock.yaml index df6573388b..c5e7b2aaca 100644 --- a/editor.planx.uk/pnpm-lock.yaml +++ b/editor.planx.uk/pnpm-lock.yaml @@ -3351,6 +3351,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 + dev: true /@babel/runtime@7.22.6: resolution: {integrity: sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==} @@ -3866,7 +3867,7 @@ packages: resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} dependencies: '@babel/helper-module-imports': 7.22.5 - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 '@emotion/hash': 0.9.1 '@emotion/memoize': 0.8.1 '@emotion/serialize': 1.1.2 @@ -3902,7 +3903,7 @@ packages: peerDependencies: react: '>=16.3.0' dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 '@emotion/cache': 10.0.29 '@emotion/css': 10.0.27 '@emotion/serialize': 0.11.16 @@ -5260,10 +5261,10 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 '@emotion/is-prop-valid': 1.2.1 - '@mui/types': 7.2.4(@types/react@18.2.20) - '@mui/utils': 5.14.11(@types/react@18.2.20)(react@18.2.0) + '@mui/types': 7.2.6(@types/react@18.2.20) + '@mui/utils': 5.14.13(@types/react@18.2.20)(react@18.2.0) '@popperjs/core': 2.11.8 '@types/react': 18.2.20 clsx: 2.0.0 @@ -5393,23 +5394,6 @@ packages: react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) dev: false - /@mui/private-theming@5.14.11(@types/react@18.2.20)(react@18.2.0): - resolution: {integrity: sha512-MSnNNzTu9pfKLCKs1ZAKwOTgE4bz+fQA0fNr8Jm7NDmuWmw0CaN9Vq2/MHsatE7+S0A25IAKby46Uv1u53rKVQ==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.23.2 - '@mui/utils': 5.14.13(@types/react@18.2.20)(react@18.2.0) - '@types/react': 18.2.20 - prop-types: 15.8.1 - react: 18.2.0 - dev: false - /@mui/private-theming@5.14.13(@types/react@18.2.20)(react@18.2.0): resolution: {integrity: sha512-5EFqk4tqiSwPguj4NW/6bUf4u1qoUWXy9lrKfNh9H6oAohM+Ijv/7qSxFjnxPGBctj469/Sc5aKAR35ILBKZLQ==} engines: {node: '>=12.0.0'} @@ -5436,32 +5420,10 @@ packages: peerDependenciesMeta: '@types/react': optional: true - dependencies: - '@babel/runtime': 7.22.15 - '@mui/utils': 5.14.11(@types/react@18.2.20)(react@18.2.0) - '@types/react': 18.2.20 - prop-types: 15.8.1 - react: 18.2.0 - dev: false - - /@mui/styled-engine@5.14.11(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0): - resolution: {integrity: sha512-jdUlqRgTYQ8RMtPX4MbRZqar6W2OiIb6J5KEFbIu4FqvPrk44Each4ppg/LAqp1qNlBYq5i+7Q10MYLMpDxX9A==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@emotion/react': ^11.4.1 - '@emotion/styled': ^11.3.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@emotion/react': - optional: true - '@emotion/styled': - optional: true dependencies: '@babel/runtime': 7.23.2 - '@emotion/cache': 11.11.0 - '@emotion/react': 11.11.1(@types/react@18.2.20)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.20)(react@18.2.0) - csstype: 3.1.2 + '@mui/utils': 5.14.13(@types/react@18.2.20)(react@18.2.0) + '@types/react': 18.2.20 prop-types: 15.8.1 react: 18.2.0 dev: false @@ -5565,13 +5527,13 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 '@emotion/react': 11.11.1(@types/react@18.2.20)(react@18.2.0) '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.20)(react@18.2.0) - '@mui/private-theming': 5.14.11(@types/react@18.2.20)(react@18.2.0) - '@mui/styled-engine': 5.14.11(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0) - '@mui/types': 7.2.4(@types/react@18.2.20) - '@mui/utils': 5.14.11(@types/react@18.2.20)(react@18.2.0) + '@mui/private-theming': 5.14.13(@types/react@18.2.20)(react@18.2.0) + '@mui/styled-engine': 5.14.13(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0) + '@mui/types': 7.2.6(@types/react@18.2.20) + '@mui/utils': 5.14.13(@types/react@18.2.20)(react@18.2.0) '@types/react': 18.2.20 clsx: 2.0.0 csstype: 3.1.2 @@ -5601,24 +5563,6 @@ packages: '@types/react': 18.2.20 dev: false - /@mui/utils@5.14.11(@types/react@18.2.20)(react@18.2.0): - resolution: {integrity: sha512-fmkIiCPKyDssYrJ5qk+dime1nlO3dmWfCtaPY/uVBqCRMBZ11JhddB9m8sjI2mgqQQwRJG5bq3biaosNdU/s4Q==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.23.2 - '@types/prop-types': 15.7.8 - '@types/react': 18.2.20 - prop-types: 15.8.1 - react: 18.2.0 - react-is: 18.2.0 - dev: false - /@mui/utils@5.14.13(@types/react@18.2.20)(react@18.2.0): resolution: {integrity: sha512-2AFpyXWw7uDCIqRu7eU2i/EplZtks5LAMzQvIhC79sPV9IhOZU2qwOWVnPtdctRXiQJOAaXulg+A37pfhEueQw==} engines: {node: '>=12.0.0'} @@ -9436,7 +9380,7 @@ packages: '@babel/preset-env': 7.22.7(@babel/core@7.22.9) '@babel/preset-react': 7.22.5(@babel/core@7.22.9) '@babel/preset-typescript': 7.23.0(@babel/core@7.22.9) - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 babel-plugin-macros: 3.1.0 babel-plugin-transform-react-remove-prop-types: 0.4.24 transitivePeerDependencies: @@ -12995,7 +12939,7 @@ packages: /history@4.10.1: resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 loose-envify: 1.4.0 resolve-pathname: 3.0.0 tiny-invariant: 1.3.1 @@ -14620,7 +14564,7 @@ packages: /jspdf@2.5.1: resolution: {integrity: sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 atob: 2.1.2 btoa: 1.2.1 fflate: 0.4.8 @@ -14634,53 +14578,53 @@ packages: /jss-plugin-camel-case@10.10.0: resolution: {integrity: sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 hyphenate-style-name: 1.0.4 jss: 10.10.0 /jss-plugin-default-unit@10.10.0: resolution: {integrity: sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 jss: 10.10.0 /jss-plugin-global@10.10.0: resolution: {integrity: sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 jss: 10.10.0 /jss-plugin-nested@10.10.0: resolution: {integrity: sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 jss: 10.10.0 tiny-warning: 1.0.3 /jss-plugin-props-sort@10.10.0: resolution: {integrity: sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 jss: 10.10.0 /jss-plugin-rule-value-function@10.10.0: resolution: {integrity: sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 jss: 10.10.0 tiny-warning: 1.0.3 /jss-plugin-vendor-prefixer@10.10.0: resolution: {integrity: sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 css-vendor: 2.0.8 jss: 10.10.0 /jss@10.10.0: resolution: {integrity: sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 csstype: 3.1.2 is-in-browser: 1.1.3 tiny-warning: 1.0.3 @@ -17248,7 +17192,7 @@ packages: prosemirror-state: ^1.4.2 prosemirror-view: ^1.30.2 dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 '@remirror/core-constants': 2.0.1 '@remirror/core-helpers': 2.0.3 escape-string-regexp: 4.0.0 @@ -17590,7 +17534,7 @@ packages: dependencies: '@babel/core': 7.22.9 '@babel/generator': 7.22.9 - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 ast-types: 0.14.2 commander: 2.20.3 doctrine: 3.0.0 @@ -17672,7 +17616,7 @@ packages: react: ^16.6.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.6.0 || ^17.0.0 || ^18.0.0 dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 invariant: 2.2.4 prop-types: 15.8.1 react: 18.2.0 @@ -17792,7 +17736,7 @@ packages: react-native: optional: true dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 '@types/react-redux': 7.1.25 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 @@ -18099,7 +18043,7 @@ packages: /redux@4.2.1: resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 dev: false /regenerate-unicode-properties@10.1.0: @@ -18124,7 +18068,7 @@ packages: /regenerator-transform@0.15.1: resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} dependencies: - '@babel/runtime': 7.22.15 + '@babel/runtime': 7.23.2 /regex-not@1.0.2: resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==}