Skip to content

Commit de684cb

Browse files
authored
Merge pull request #506 from bcgov/feature/bf-refactor
refactor: bring forward handling
2 parents 8ddcbb1 + edf7448 commit de684cb

13 files changed

Lines changed: 421 additions & 280 deletions

File tree

.github/workflows/unit-tests.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,14 @@ jobs:
8888
env:
8989
CI: true
9090
- name: Save Coverage Results
91-
if: matrix.node-version == '22.x'
91+
if: matrix.node-version == '24.x'
9292
uses: actions/upload-artifact@v7
9393
with:
9494
name: coverage-app
9595
path: ${{ github.workspace }}/app/coverage
9696
retention-days: 1
9797
- name: Monitor Coverage
98-
if: "matrix.node-version == '22.x' && github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork"
98+
if: "matrix.node-version == '24.x' && github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork"
9999
uses: slavcodev/coverage-monitor-action@398c4cbbb710e549a8407fdef96ae8b9454d0463 # 1.10.0
100100
with:
101101
comment_mode: update
@@ -153,14 +153,14 @@ jobs:
153153
env:
154154
CI: true
155155
- name: Save Coverage Results
156-
if: matrix.node-version == '22.x'
156+
if: matrix.node-version == '24.x'
157157
uses: actions/upload-artifact@v7
158158
with:
159159
name: coverage-frontend
160160
path: ${{ github.workspace }}/frontend/coverage
161161
retention-days: 1
162162
- name: Monitor Coverage
163-
if: "matrix.node-version == '22.x' && github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork"
163+
if: "matrix.node-version == '24.x' && github.event_name == 'pull_request' && ! github.event.pull_request.head.repo.fork"
164164
uses: slavcodev/coverage-monitor-action@398c4cbbb710e549a8407fdef96ae8b9454d0463 # 1.10.0
165165
with:
166166
comment_mode: update

app/src/controllers/noteHistory.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
updateNoteHistoryService
77
} from '../services/noteHistory.ts';
88

9-
import { Resource } from '../utils/enums/application.ts';
9+
import { Initiative, Resource } from '../utils/enums/application.ts';
1010
import { BringForwardType } from '../utils/enums/projectCommon.ts';
1111

1212
import type { Request, Response } from 'express';
@@ -30,7 +30,11 @@ export const listBringForwardsController = async (
3030
req: Request<never, never, never, { bringForwardState?: BringForwardType }>,
3131
res: Response<BringForward[], LocalContext>
3232
) => {
33-
const response = await listBringForwardsService(res.locals.currentContext.initiative, req.query.bringForwardState);
33+
const initiativeCode = res.locals.currentContext.initiative;
34+
const response = await listBringForwardsService(
35+
initiativeCode !== Initiative.PCNS ? initiativeCode : undefined,
36+
req.query.bringForwardState
37+
);
3438
res.status(200).json(response);
3539
};
3640

@@ -50,7 +54,7 @@ export const updateNoteHistoryController = async (
5054
const response = await updateNoteHistoryService(
5155
res.locals.currentAuthorization,
5256
res.locals.currentContext,
53-
history,
57+
{ ...history, noteHistoryId: req.params.noteHistoryId },
5458
note,
5559
resource
5660
);
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,83 @@
11
import { WritableRepository } from './writable.ts';
2+
import { Initiative } from '../utils/enums/application.ts';
3+
import { BringForwardType } from '../utils/enums/projectCommon.ts';
24

35
import type { PrismaTransactionClient } from '../db/database.ts';
46

57
export class NoteHistoryRepository extends WritableRepository<PrismaTransactionClient['note_history']> {
68
constructor(tx: PrismaTransactionClient, principal: string) {
79
super(tx.note_history, principal, true);
810
}
11+
12+
public async listBringForwards(
13+
initiativeCode: Exclude<Initiative, Initiative.PCNS> | undefined,
14+
state: BringForwardType
15+
) {
16+
return await this.findMany({
17+
where: {
18+
bringForwardState: state,
19+
activity: {
20+
initiative: {
21+
code: initiativeCode
22+
}
23+
}
24+
},
25+
orderBy: {
26+
createdAt: 'desc'
27+
},
28+
select: {
29+
noteHistoryId: true,
30+
activityId: true,
31+
createdBy: true,
32+
bringForwardDate: true,
33+
bringForwardState: true,
34+
escalateToSupervisor: true,
35+
escalateToDirector: true,
36+
title: true,
37+
activity: {
38+
select: {
39+
enquiry: {
40+
select: {
41+
activityId: true,
42+
enquiryId: true
43+
}
44+
},
45+
electrificationProject: {
46+
select: {
47+
projectId: true,
48+
projectName: true
49+
}
50+
},
51+
generalProject: {
52+
select: {
53+
projectId: true,
54+
projectName: true
55+
}
56+
},
57+
housingProject: {
58+
select: {
59+
projectId: true,
60+
projectName: true
61+
}
62+
}
63+
}
64+
},
65+
note: { orderBy: { createdAt: 'desc' } }
66+
}
67+
});
68+
}
69+
70+
public async listNoteHistories(activityId: string) {
71+
return await this.findMany({
72+
where: {
73+
activityId
74+
},
75+
orderBy: {
76+
createdAt: 'desc'
77+
},
78+
include: {
79+
note: { orderBy: { createdAt: 'desc' } }
80+
}
81+
});
82+
}
983
}

app/src/services/noteHistory.ts

Lines changed: 25 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@ import { v4 as uuidv4 } from 'uuid';
22

33
import { unitOfWork } from '../db/unitOfWork.ts';
44
import { emailBringForwardNotification } from '../domains/noteHistory.ts';
5-
import { SYSTEM_ID } from '../utils/constants/application.ts';
65
import { BringForwardType } from '../utils/enums/projectCommon.ts';
76
import { GroupName, Initiative, Resource } from '../utils/enums/application.ts';
87

98
import type {
109
BringForward,
1110
CurrentAuthorization,
1211
CurrentContext,
13-
Enquiry,
1412
NoteHistory,
1513
NoteHistoryBase
1614
} from '../types/index.ts';
@@ -55,112 +53,46 @@ export const deleteNoteHistoryService = async (noteHistoryId: string): Promise<v
5553

5654
/**
5755
* Retrieve a list of bring forward type note histories by the given state
58-
* @param initiative The initiative for which the note history belongs to
56+
* @param initiativeCode The initiative for which the note history belongs to
5957
* @param state The state to search for
6058
* @returns A Promise that resolves to the note histories for the given parameters
6159
*/
6260
export const listBringForwardsService = async (
63-
initiative: Initiative,
61+
initiativeCode: Exclude<Initiative, Initiative.PCNS> | undefined,
6462
state: BringForwardType = BringForwardType.UNRESOLVED
6563
): Promise<BringForward[]> => {
66-
return await unitOfWork.execute(
67-
async ({ electrificationProject, enquiry, generalProject, housingProject, noteHistory, user }) => {
68-
const history = await noteHistory.findMany({
69-
where: {
70-
bringForwardState: state,
71-
activity: {
72-
initiative: {
73-
code: initiative
74-
}
75-
}
76-
},
77-
orderBy: {
78-
createdAt: 'desc'
79-
},
80-
include: {
81-
note: { orderBy: { createdAt: 'desc' } }
82-
}
64+
return await unitOfWork.execute(async ({ noteHistory, user }) => {
65+
const history = await noteHistory.listBringForwards(initiativeCode, state);
66+
67+
if (history.length) {
68+
const users = await user.search({
69+
userId: history
70+
.map((x) => x.createdBy)
71+
.filter((x) => !!x)
72+
.map((x) => x!)
8373
});
8474

85-
if (history.length) {
86-
const [elecProj, generalProj, housingProj] = await Promise.all([
87-
electrificationProject.search({
88-
activityId: history.map((x) => x.activityId)
89-
}),
90-
generalProject.search({
91-
activityId: history.map((x) => x.activityId)
92-
}),
93-
housingProject.search({
94-
activityId: history.map((x) => x.activityId)
95-
})
96-
]);
97-
98-
const users = await user.findMany({
99-
where: {
100-
AND: [
101-
{
102-
userId: {
103-
in: history
104-
.map((x) => x.createdBy)
105-
.filter((x) => !!x)
106-
.map((x) => x!)
107-
}
108-
}
109-
],
110-
NOT: [
111-
{
112-
userId: SYSTEM_ID
113-
}
114-
]
115-
}
116-
});
75+
return history.map((h) => {
76+
const project = h.activity.housingProject ?? h.activity.generalProject ?? h.activity.electrificationProject;
11777

118-
const enquiries: Enquiry[] = (
119-
await Promise.all([
120-
enquiry.search(
121-
{
122-
activityId: history.map((x) => x.activityId)
123-
},
124-
Initiative.ELECTRIFICATION
125-
),
126-
enquiry.search(
127-
{
128-
activityId: history.map((x) => x.activityId)
129-
},
130-
Initiative.GENERAL
131-
),
132-
enquiry.search(
133-
{
134-
activityId: history.map((x) => x.activityId)
135-
},
136-
Initiative.HOUSING
137-
)
138-
])
139-
).flat();
140-
141-
return history.map((h) => ({
78+
return {
14279
activityId: h.activityId,
143-
noteId: h.noteHistoryId,
144-
electrificationProjectId: elecProj.find((s) => s.activityId === h.activityId)?.electrificationProjectId,
145-
generalProjectId: generalProj.find((s) => s.activityId === h.activityId)?.generalProjectId,
146-
housingProjectId: housingProj.find((s) => s.activityId === h.activityId)?.housingProjectId,
147-
enquiryId: enquiries.find((s) => s.activityId === h.activityId)?.enquiryId,
80+
noteHistoryId: h.noteHistoryId,
81+
projectId: project?.projectId,
82+
enquiryId: h.activity.enquiry?.find((e) => e.activityId === h.activityId)?.enquiryId,
83+
initiative: initiativeCode,
14884
title: h.title,
149-
projectName:
150-
elecProj.find((s) => s.activityId === h.activityId)?.projectName ??
151-
generalProj.find((s) => s.activityId === h.activityId)?.projectName ??
152-
housingProj.find((s) => s.activityId === h.activityId)?.projectName ??
153-
null,
85+
projectName: project?.projectName ?? null,
15486
createdByFullName: users.find((u) => u?.userId === h.createdBy)?.fullName ?? null,
15587
bringForwardDate: h.bringForwardDate?.toISOString(),
15688
escalateToSupervisor: h.escalateToSupervisor,
15789
escalateToDirector: h.escalateToDirector
158-
}));
159-
} else {
160-
return [];
161-
}
90+
} satisfies BringForward;
91+
});
92+
} else {
93+
return [];
16294
}
163-
);
95+
});
16496
};
16597

16698
/**
@@ -174,17 +106,7 @@ export const listNoteHistoriesService = async (
174106
activityId: string
175107
): Promise<NoteHistory[]> => {
176108
return await unitOfWork.execute(async ({ noteHistory }) => {
177-
const result = await noteHistory.findMany({
178-
where: {
179-
activityId: activityId
180-
},
181-
orderBy: {
182-
createdAt: 'desc'
183-
},
184-
include: {
185-
note: { orderBy: { createdAt: 'desc' } }
186-
}
187-
});
109+
const result = await noteHistory.listNoteHistories(activityId);
188110

189111
if (currentAuthorization?.attributes.includes('scope:self')) {
190112
return result.filter((x) => x.shownToProponent);

app/src/types/stuff.d.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,16 @@ export interface AtsUserSearchParameters extends ParsedQs {
6868

6969
export interface BringForward {
7070
activityId: string;
71-
noteId: string;
72-
electrificationProjectId?: string;
73-
housingProjectId?: string;
71+
noteHistoryId: string;
72+
projectId?: string;
7473
enquiryId?: string;
74+
initiative?: Initiative;
7575
title: string;
7676
projectName: string | null;
7777
bringForwardDate?: string;
7878
createdByFullName: string | null;
79+
escalateToSupervisor: boolean;
80+
escalateToDirector: boolean;
7981
}
8082

8183
export interface ContactSearchParameters {

app/tests/unit/controllers/noteHistory.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ describe('updateNoteHistoryController', () => {
138138
expect(updateSpy).toHaveBeenCalledWith(
139139
TEST_CURRENT_AUTH_CONTEXT_NAVIGATOR,
140140
TEST_CURRENT_CONTEXT,
141-
expect.objectContaining({ noteHistoryId: TEST_NOTE_HISTORY_1.noteHistoryId }),
141+
expect.objectContaining({ noteHistoryId: 'nh-123' }),
142142
'updated note',
143143
Resource.ENQUIRY
144144
);

0 commit comments

Comments
 (0)