Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
/apps/web/src/server/static/scripts/*
/apps/web/src/server/static/styles/*
/apps/functions/migration/database/db-client/*
/apps/api/src/database/client/*
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,6 @@ build
**/.terraform/*
**/.terraform
**/.terragrunt-cache

# Prisma
apps/api/src/database/client
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ coverage
apps/e2e/cypress/fixtures/*
.vscode
.build
apps/api/src/database/client
1 change: 1 addition & 0 deletions apps/api/jsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"paths": {
"#app-test": ["./src/server/app-test.js"],
"#api-constants": ["./src/server/applications/constants.js"],
"#database-client": ["./src/database/client/client.js"],
"#config/*": ["./src/server/config/*"],
"#infrastructure/*": ["./src/server/infrastructure/*"],
"#middleware/*": ["./src/server/middleware/*"],
Expand Down
13 changes: 6 additions & 7 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@
"engines": {
"node": ">=20.0.0 <21.0.0"
},
"prisma": {
"schema": "src/database/schema.prisma",
"seed": "node src/database/seed/seed-development.js"
},
"type": "module",
"scripts": {
"test": "npm run prisma-generate && cross-env NODE_ENV=test NODE_OPTIONS=\"--experimental-vm-modules --max-old-space-size=8192\" npx jest --forceExit --coverage",
Expand All @@ -32,7 +28,7 @@
"db:seed:prod": "npm run prisma-generate && cross-env NODE_ENV=production node src/database/seed/seed-production.js",
"db:create:gs51": "npm run prisma-generate && node src/database/seed/seed-gs51.js",
"prisma:format": "npx prisma format",
"prisma-generate": "npx prisma generate",
"prisma-generate": "npx prisma generate && tsc --project src/database/client-tsconfig.json",
"tscheck": "npx tsc -p jsconfig.json --maxNodeModuleJsDepth 0"
},
"dependencies": {
Expand All @@ -49,6 +45,7 @@
"@pins/examination-timetable-utils": "*",
"@pins/platform": "*",
"@prisma/instrumentation": "*",
"@prisma/adapter-mssql": "*",
"@prisma/client": "*",
"@supercharge/promise-pool": "*",
"ajv": "*",
Expand Down Expand Up @@ -89,12 +86,14 @@
"rimraf": "*",
"supertest": "*",
"swagger-autogen": "*",
"swagger-typescript-api": "*"
"swagger-typescript-api": "*",
"typescript": "*"
},
"imports": {
"#app-test": "./src/server/app-test.js",
"#api-constants": "./src/server/applications/constants.js",
"#config/*": "./src/server/config/*",
"#database-client": "./src/database/client/client.js",
"#config/*": "./src/server/config/*",
"#infrastructure/*": "./src/server/infrastructure/*",
"#middleware/*": "./src/server/middleware/*",
"#repositories/*": "./src/server/repositories/*",
Expand Down
17 changes: 17 additions & 0 deletions apps/api/prisma.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { defineConfig } from 'prisma/config';
import path from 'node:path';
import dotenv from 'dotenv';

// load configuration from .env file into process.env
dotenv.config();

export default defineConfig({
schema: path.join('src', 'database', 'schema.prisma'),
migrations: {
path: path.join('src', 'database', 'migrations'),
seed: 'node src/database/seed/seed-development.js'
},
datasource: {
url: process.env.DATABASE_URL || ''
}
});
23 changes: 16 additions & 7 deletions apps/api/setup-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -397,22 +397,31 @@ class MockPrismaClient {
return Array.isArray(results) ? results : [];
}
});

// see https://www.prisma.io/docs/orm/reference/prisma-client-reference#extends
// return the prisma client instance
$extends = jest.fn().mockImplementation(() => this);
}

const mockPrismaUse = jest.fn().mockResolvedValue();

MockPrismaClient.prototype.$executeRawUnsafe = mockExecuteRawUnsafe;
MockPrismaClient.prototype.$use = mockPrismaUse;

class MockPrisma {}
class MockPrisma {
// see https://www.prisma.io/docs/orm/prisma-client/client-extensions
static defineExtension(func) {
func(new MockPrismaClient());
}
}

jest.unstable_mockModule('@prisma/client', () => ({
jest.unstable_mockModule('#database-client', () => ({
PrismaClient: MockPrismaClient,
Prisma: MockPrisma,
default: {
// PrismaClient: MockPrismaClient,
// Prisma: MockPrisma
}
Prisma: MockPrisma
}));

jest.unstable_mockModule('@prisma/adapter-mssql', () => ({
PrismaMssql: jest.fn()
}));

const mockSendEvents = jest.fn().mockImplementation(sendEvents);
Expand Down
12 changes: 12 additions & 0 deletions apps/api/src/database/client-tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"include": ["./client/client.ts"],
"compilerOptions": {
"baseUrl": "./client",
"esModuleInterop": true,
"moduleResolution": "nodenext",
"checkJs": false,
"target": "esnext",
"module": "NodeNext",
"skipLibCheck": true
}
}
5 changes: 3 additions & 2 deletions apps/api/src/database/schema.prisma
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
generator client {
provider = "prisma-client-js"
provider = "prisma-client"
output = "./client"
importFileExtension = "js"
}

datasource db {
provider = "sqlserver"
url = env("DATABASE_URL")
}

/// Case model
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/database/seed/data-gs51.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createRepresentation } from './data-test.js';

/**
*
* @param {import('@prisma/client').PrismaClient} databaseConnector
* @param {import('#database-client').PrismaClient} databaseConnector
*/
export const createGeneralS51Application = async (databaseConnector) => {
try {
Expand Down
10 changes: 5 additions & 5 deletions apps/api/src/database/seed/data-static.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

/**
*
* @typedef {import('@prisma/client').Prisma.SectorCreateInput} SectorCreateInput
* @typedef {import('@prisma/client').Prisma.RegionCreateInput} RegionCreateInput
* @typedef {import('@prisma/client').Prisma.ZoomLevelCreateInput} ZoomLevelCreateInput
* @typedef {import('@prisma/client').Prisma.ExaminationTimetableTypeCreateInput} ExaminationTimetableTypeCreateInput
* @typedef {import('#database-client').Prisma.SectorCreateInput} SectorCreateInput
* @typedef {import('#database-client').Prisma.RegionCreateInput} RegionCreateInput
* @typedef {import('#database-client').Prisma.ZoomLevelCreateInput} ZoomLevelCreateInput
* @typedef {import('#database-client').Prisma.ExaminationTimetableTypeCreateInput} ExaminationTimetableTypeCreateInput
*
* @typedef {{ abbreviation: string, name: string, displayNameEn: string, displayNameCy: string}} SubSectorPartial
* @typedef {{ sectorName: string, subSector: SubSectorPartial}} SubSectorPartialWithSectorName
Expand Down Expand Up @@ -490,7 +490,7 @@ export const examinationTimetableTypes = [
/**
* seed static data into the database. Does not disconnect from the database or handle errors.
*
* @param {import('@prisma/client').PrismaClient} databaseConnector
* @param {import('#database-client').PrismaClient} databaseConnector
*/
export async function seedStaticData(databaseConnector) {
for (const sector of sectors) {
Expand Down
12 changes: 6 additions & 6 deletions apps/api/src/database/seed/data-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export function createRepresentation(caseReference, index, isValidStatus = false
/**
*
* @param {number} caseId
* @returns {import('@prisma/client').Prisma.ProjectUpdateCreateManyInput}
* @returns {import('#database-client').Prisma.ProjectUpdateCreateManyInput}
*/
function generateProjectUpdate(caseId) {
const statuses = ['draft', 'published', 'unpublished', 'archived'];
Expand All @@ -98,7 +98,7 @@ function generateProjectUpdate(caseId) {
];
const dates = oneDatePerMonth();
/**
* @type {import('@prisma/client').Prisma.ProjectUpdateCreateManyInput}
* @type {import('#database-client').Prisma.ProjectUpdateCreateManyInput}
*/
const projectUpdate = {
caseId,
Expand All @@ -114,9 +114,9 @@ function generateProjectUpdate(caseId) {
}

/**
* @param {import('@prisma/client').PrismaClient} databaseConnector
* @param {import('#database-client').PrismaClient} databaseConnector
* @param {number} caseId
* @returns {Promise<import('@prisma/client').Prisma.BatchPayload>}
* @returns {Promise<import('#database-client').Prisma.BatchPayload>}
*/
function createProjectUpdates(databaseConnector, caseId) {
const numUpdates = pseudoRandomInt(0, 28);
Expand All @@ -131,7 +131,7 @@ function createProjectUpdates(databaseConnector, caseId) {

/**
*
* @param {import('@prisma/client').PrismaClient} databaseConnector
* @param {import('#database-client').PrismaClient} databaseConnector
* @param {{name: string, abbreviation: string, displayNameEn: string}} subSector
* @param {number} index
*/
Expand Down Expand Up @@ -214,7 +214,7 @@ const createApplication = async (databaseConnector, subSector, index) => {
};

/**
* @param {import('@prisma/client').PrismaClient} databaseConnector
* @param {import('#database-client').PrismaClient} databaseConnector
*/
export async function seedTestData(databaseConnector) {
// now create some sample applications
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/database/seed/seed-clear.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { truncateTable } from '../prisma.truncate.js';
/**
* Seeding function to clear down a database, deletes all cases, documents, records, reference tables, etc
*
* @param {import('@prisma/client').PrismaClient} databaseConnector
* @param {import('#database-client').PrismaClient} databaseConnector
*/
export async function deleteAllRecords(databaseConnector) {
const deleteCases = databaseConnector.case.deleteMany();
Expand Down
14 changes: 11 additions & 3 deletions apps/api/src/database/seed/seed-development.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Set NODE_ENV before importing any modules that depend on it
process.env.NODE_ENV = 'seeding';

import { databaseConnector } from '#utils/database-connector.js';
import { seedStaticData } from './data-static.js';
import { seedTestData } from './data-test.js';
Expand All @@ -11,14 +14,19 @@ import { deleteAllRecords } from './seed-clear.js';
* @returns {Promise<void>}
*/
const seedDevelopment = async () => {
process.env.NODE_ENV = 'seeding';
try {
await deleteAllRecords(databaseConnector);
// Check if database is empty first
const caseCount = await databaseConnector.case.count();

if (caseCount > 0) {
await deleteAllRecords(databaseConnector);
}

await seedStaticData(databaseConnector);
await seedTestData(databaseConnector);
await createGeneralS51Application(databaseConnector);
} catch (error) {
console.error(error);
console.error('Error during seeding:', error);
throw error;
} finally {
await databaseConnector.$disconnect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ import {
import { validateDocumentVersionMetadataBody } from './document.validators.js';

/**
* @typedef {import('@prisma/client').Document} Document
* @typedef {import('@prisma/client').DocumentVersion} DocumentVersion
* @typedef {import('#database-client').Document} Document
* @typedef {import('#database-client').DocumentVersion} DocumentVersion
* @typedef {import('@pins/applications.api').Schema.DocumentDetails} DocumentDetails
* @typedef {import('@pins/applications.api').Schema.DocumentVersionWithDocument} DocumentVersionWithDocument
* @typedef {import('@pins/applications.api').Api.DocumentToSave} DocumentToSave
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ import { getApplicationDocumentsFolderName } from '#utils/mapping/map-document-f
import { handleCreationOfDocumentActivityLogs } from '../../../migration/migrators/nsip-document-migrator.js';

/**
* @typedef {import('@prisma/client').DocumentVersion} DocumentVersion
* @typedef {import('@prisma/client').Document} Document
* @typedef {import('@prisma/client').Document & {documentName: string}} DocumentWithDocumentName
* @typedef {import('@prisma/client').Prisma.DocumentVersionGetPayload<{include: {Document: {include: {folder: {include: {case: {include: {CaseStatus: true}}}}}}}}> } DocumentVersionWithDocumentAndFolder
* @typedef {import('#database-client').DocumentVersion} DocumentVersion
* @typedef {import('#database-client').Document} Document
* @typedef {import('#database-client').Document & {documentName: string}} DocumentWithDocumentName
* @typedef {import('#database-client').Prisma.DocumentVersionGetPayload<{include: {Document: {include: {folder: {include: {case: {include: {CaseStatus: true}}}}}}}}> } DocumentVersionWithDocumentAndFolder
* @typedef {import('@pins/applications.api').Schema.DocumentDetails} DocumentDetails
* @typedef {import('@pins/applications.api').Schema.DocumentVersionWithDocument} DocumentVersionWithDocument
* @typedef {import('@pins/applications.api').Api.DocumentAndBlobInfoManyResponse} DocumentAndBlobInfoManyResponse
Expand Down Expand Up @@ -359,7 +359,7 @@ export const createDocuments = async (documentsToUpload, caseId, isS51, tx) => {
tx
);

/** @type {Promise<import('@prisma/client').DocumentActivityLog>[]} */
/** @type {Promise<import('#database-client').DocumentActivityLog>[]} */
// TODO: refactor to use createMany instead?
const documentActivityLogs = requestToGetDocumentStorageProperties.map((document) =>
documentActivityLogRepository.create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import { featureFlagClient } from '#utils/feature-flags.js';
/** @typedef {{ guid: string}} documentGuid */

/**
* @typedef {import('@prisma/client').DocumentVersion} DocumentVersion
* @typedef {import('@prisma/client').Document} Document
* @typedef {import('#database-client').DocumentVersion} DocumentVersion
* @typedef {import('#database-client').Document} Document
* @typedef {import('@pins/applications.api').Api.DocumentVersionUpsertRequestBody} DocumentVersionUpsertRequestBody
* @typedef {import('@pins/applications.api').Schema.DocumentVersionUpsertInput} DocumentVersionUpsertInput
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { mockApplicationGet } from '#utils/application-factory-for-tests.js';

/**
* @param {Date} now
* @returns {(caseId: number) => import('@prisma/client').ProjectUpdate}
* @returns {(caseId: number) => import('#database-client').ProjectUpdate}
*/
const makeDummyProjectUpdate = (now) => (caseId) => ({
id: 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe('notification-logs', () => {
describe('get', () => {
/**
* @param {number} projectUpdateId
* @returns {import('@prisma/client').ProjectUpdateNotificationLog}
* @returns {import('#database-client').ProjectUpdateNotificationLog}
*/
const dummyLog = (projectUpdateId) => {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
addAttachmentRepresentation,
deleteAttachmentRepresentation
} from './attachment.service.js';
import { Prisma } from '@prisma/client';
import { Prisma } from '#database-client';

const prismaUniqueConstraintFailedCode = 'P2002';
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import { verifyNotTraining } from '../application/application.validators.js';
* @typedef {import('@planning-inspectorate/data-model').Schemas.Event} NSIPExamTimetableItem
* @typedef {import('@planning-inspectorate/data-model').Schemas.ExaminationTimetable} NSIPExamTimetable
* @typedef {import('@pins/applications.api').Schema.Folder} Folder
* @typedef {import('@prisma/client').Prisma.ExaminationTimetableItemGetPayload<{include: {ExaminationTimetableType: true} }>} ExaminationTimetableItemWithType
* @typedef {import('#database-client').Prisma.ExaminationTimetableItemGetPayload<{include: {ExaminationTimetableType: true} }>} ExaminationTimetableItemWithType
*/

/**
* Grabs the description and event line items from the examinationTimetableItem and parses them into a description string and
* NSIPExamTimetableItemDescriptionLineItem array when the categoryType is Deadline
*
* @param {import('@prisma/client').ExaminationTimetableItem} examinationTimetableItem
* @param {import('#database-client').ExaminationTimetableItem} examinationTimetableItem
* @returns { { description: string, descriptionWelsh: string, eventLineItems: { description: string, descriptionWelsh: string }[] | string } }
*/
function extractDescriptionAndLineItems(examinationTimetableItem) {
Expand Down Expand Up @@ -315,7 +315,7 @@ export const deleteDeadlineSubFolders = async (caseId, parentFolderId) => {

/**
*
* @param {import('@prisma/client').ExaminationTimetableItem} timetableItem
* @param {import('#database-client').ExaminationTimetableItem} timetableItem
* @param {number} caseId
* @returns {Promise<boolean>}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
* @typedef {import('@pins/applications').S51AdviceDetails} S51AdviceDetails
* @typedef {import('@pins/applications.api').Schema.S51Advice} S51Advice
* @typedef {import('@pins/applications.api').Schema.S51AdviceDocument} S51AdviceDocument
* @typedef {import('@prisma/client').Prisma.S51AdviceGetPayload<{include: {S51AdviceDocument: true}}>} S51AdviceWithS51AdviceDocuments
* @typedef {import('#database-client').Prisma.S51AdviceGetPayload<{include: {S51AdviceDocument: true}}>} S51AdviceWithS51AdviceDocuments
* @typedef {import('@pins/applications.api').Api.DocumentAndBlobInfoManyResponse} DocumentAndBlobInfoManyResponse
* @typedef {{ page: number, pageDefaultSize: number, pageCount: number, itemCount: number, items: S51AdviceDetails[]}} S51AdvicePaginatedDetails
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ describe('subscriptions', () => {
describe('get (list)', () => {
/**
*
* @returns {import('@prisma/client').Subscription}
* @returns {import('#database-client').Subscription}
*/
const dummySubscription = () => {
return {
Expand Down Expand Up @@ -665,7 +665,7 @@ describe('subscriptions', () => {
* @typedef {Object} Test
* @property {string} name
* @property {*} request
* @property {import('@prisma/client').Prisma.SubscriptionCreateInput} want
* @property {import('#database-client').Prisma.SubscriptionCreateInput} want
*/
/** @type {Test[]} */
const tests = [
Expand Down
Loading
Loading