Skip to content

Commit 5c94a6e

Browse files
committed
Final fixes
1 parent 1425d6e commit 5c94a6e

29 files changed

+460
-249
lines changed
-292 Bytes
Binary file not shown.

back/package-lock.json

+213-82
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

back/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"passport-local": "^1.0.0",
6565
"passport-oauth2-client-password": "^0.1.2",
6666
"pdf-lib": "^1.12.0",
67+
"postgres-migrations": "^5.1.0",
6768
"rate-limit-redis": "^2.0.0",
6869
"request": "^2.88.2",
6970
"winston": "^3.2.1",

back/prisma/migrate.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const dbConfig = {
66
user: process.env.POSTGRES_USER,
77
password: process.env.POSTGRES_PASSWORD,
88
host: process.env.POSTGRES_HOST,
9-
port: process.env.POSTGRES_PORT
9+
port: parseInt(process.env.POSTGRES_PORT, 10)
1010
};
1111

1212
migrate(dbConfig, path.join(__dirname, "migrations"))

back/prisma/migrations/03_migration.relations.sql

+33-1
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,36 @@ ALTER TABLE "default$default"."StatusLog" RENAME COLUMN "user" to "userId";
5757
ALTER TABLE "default$default"."TransportSegment" RENAME COLUMN "form" to "formId";
5858

5959
-- Form.isAccepted default to false
60-
ALTER TABLE "default$default"."Form" ALTER COLUMN "isAccepted" SET DEFAULT FALSE;
60+
ALTER TABLE "default$default"."Form" ALTER COLUMN "isAccepted" SET DEFAULT FALSE;
61+
62+
-- Application admins: Migrate from N-N to 1-N
63+
ALTER TABLE "default$default"."User" ADD COLUMN "applicationId" character varying(30);
64+
65+
UPDATE "default$default"."User"
66+
SET "applicationId" = t."A"
67+
FROM (
68+
SELECT *
69+
FROM "default$default"."_ApplicationToUser"
70+
) t
71+
WHERE t."B" = "default$default"."User"."id";
72+
73+
DROP TABLE "default$default"."_ApplicationToUser";
74+
75+
-- Appendix2 forms: Migrate from N-N to 1-N
76+
ALTER TABLE "default$default"."Form" ADD COLUMN "appendix2RootFormId" character varying(30);
77+
78+
UPDATE "default$default"."Form"
79+
SET "appendix2RootFormId" = t."A"
80+
FROM (
81+
SELECT *
82+
FROM "default$default"."_FormToForm"
83+
) t
84+
WHERE t."B" = "default$default"."Form"."id";
85+
86+
DROP TABLE "default$default"."_FormToForm";
87+
88+
-- Some fields were added in the Prisma1 schema while migrating
89+
-- They might be missing in some environments.
90+
ALTER TABLE "default$default"."Form" ADD COLUMN IF NOT EXISTS "signedBy" character varying(30);
91+
ALTER TABLE "default$default"."TemporaryStorageDetail" ADD COLUMN IF NOT EXISTS "tempStorerSignedBy" character varying(30);
92+
ALTER TABLE "default$default"."Form" ADD COLUMN IF NOT EXISTS "wasteDetailsPop" BOOLEAN SET DEFAULT FALSE NOT NULL;

back/prisma/schema.prisma

+34
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ enum Status {
6565
SEALED
6666
SENT
6767
RECEIVED
68+
ACCEPTED
6869
PROCESSED
6970
AWAITING_GROUP
7071
GROUPED
@@ -73,6 +74,7 @@ enum Status {
7374
7475
// Temporary storage status
7576
TEMP_STORED
77+
TEMP_STORER_ACCEPTED
7678
RESEALED
7779
RESENT
7880
}
@@ -128,6 +130,8 @@ model Application {
128130
logoUrl String?
129131
redirectUris String[]
130132
admins User[]
133+
AccessToken AccessToken[]
134+
Grant Grant[]
131135
}
132136

133137
model Company {
@@ -150,6 +154,25 @@ model Company {
150154
traderReceipt TraderReceipt? @relation(fields: [traderReceiptId], references: [id])
151155
transporterReceiptId String?
152156
transporterReceipt TransporterReceipt? @relation(fields: [transporterReceiptId], references: [id])
157+
CompanyAssociation CompanyAssociation[]
158+
MembershipRequest MembershipRequest[]
159+
}
160+
161+
// Companies with restricted diffusion of SIRENE information (police, army, etc)
162+
163+
// "Certaines entreprises demandent à ne pas figurer sur les listes de diffusion publique
164+
// en vertu de l'article A123-96 du code du commerce. On parle d‘entreprise non diffusable.
165+
// Dans ce cas les API SIRENE ne diffusent pas les informations de cette entreprise dans
166+
// les résultats de recherche. Pour des raisons de sécurité, certaines associations et les
167+
// organismes relevant du Ministère de la Défense ne sont pas diffusibles non plus."
168+
model AnonymousCompany {
169+
id String @id @default(cuid())
170+
siret String @unique
171+
name String
172+
address String
173+
codeNaf String
174+
libelleNaf String
175+
codeCommune String
153176
}
154177

155178
model CompanyAssociation {
@@ -218,6 +241,7 @@ model Form {
218241
wasteDetailsNumberOfPackages Int?
219242
wasteDetailsQuantity Float?
220243
wasteDetailsQuantityType QuantityType?
244+
wasteDetailsPop Boolean @default(false)
221245
readableId String @unique
222246
status Status @default(DRAFT)
223247
sentAt DateTime?
@@ -278,6 +302,7 @@ model Form {
278302
appendix2RootForm Form? @relation("FormToForm", fields: [appendix2RootFormId], references: [id])
279303
ownerId String
280304
owner User @relation(fields: [ownerId], references: [id])
305+
StatusLog StatusLog[]
281306
}
282307

283308
model Grant {
@@ -396,20 +421,23 @@ model TemporaryStorageDetail {
396421
signedByTransporter Boolean?
397422
signedBy String?
398423
signedAt DateTime?
424+
Form Form[]
399425
}
400426

401427
model TraderReceipt {
402428
id String @id @default(cuid())
403429
receiptNumber String
404430
validityLimit DateTime
405431
department String
432+
Company Company[]
406433
}
407434

408435
model TransporterReceipt {
409436
id String @id @default(cuid())
410437
receiptNumber String
411438
validityLimit DateTime
412439
department String
440+
Company Company[]
413441
}
414442

415443
model TransportSegment {
@@ -449,6 +477,12 @@ model User {
449477
applicationId String?
450478
application Application? @relation(fields: [applicationId], references: [id])
451479
companyAssociations CompanyAssociation[]
480+
AccessToken AccessToken[]
481+
Form Form[]
482+
Grant Grant[]
483+
MembershipRequest MembershipRequest[]
484+
StatusLog StatusLog[]
485+
UserActivationHash UserActivationHash[]
452486
}
453487

454488
model UserAccountHash {

back/prisma/scripts/load-anonymous-companies.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as fs from "fs";
22
import { Updater, registerUpdater } from "./helper/helper";
3-
import { prisma } from "../../src/generated/prisma-client";
3+
import prisma from "src/prisma";
44

55
@registerUpdater(
66
"Load anonymous companies",
@@ -20,7 +20,7 @@ export class LoadAnonymousCompaniesUpdater implements Updater {
2020
const data = JSON.parse(fs.readFileSync(fixturePath, "utf8"));
2121

2222
for (const companyInput of data) {
23-
await prisma.createAnonymousCompany(companyInput);
23+
await prisma.anonymousCompany.create({ data: companyInput });
2424
}
2525
} catch (err) {
2626
console.error("☠ Something went wrong during the update", err);
+18-18
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
import { Updater, registerUpdater } from "./helper/helper";
2-
import { prisma } from "../../src/generated/prisma-client";
2+
import prisma from "src/prisma";
33

44
@registerUpdater(
5-
"Migrate the forms to received forms to the new accepted status",
6-
"Replace RECEIVED with ACCEPTED, and TEMP_STORED to TEMP_STORER_ACCEPTED",
7-
true
5+
"Migrate the forms to received forms to the new accepted status",
6+
"Replace RECEIVED with ACCEPTED, and TEMP_STORED to TEMP_STORER_ACCEPTED",
7+
true
88
)
99
export class MigrateAcceptedForms implements Updater {
10-
async run() {
11-
await prisma.updateManyForms({
12-
where: {
13-
status: "RECEIVED"
14-
},
15-
data: { status: "ACCEPTED" }
16-
})
10+
async run() {
11+
await prisma.forms.updateMany({
12+
where: {
13+
status: "RECEIVED"
14+
},
15+
data: { status: "ACCEPTED" }
16+
});
1717

18-
await prisma.updateManyForms({
19-
where: {
20-
status: "TEMP_STORED"
21-
},
22-
data: { status: "TEMP_STORER_ACCEPTED" }
23-
})
24-
}
18+
await prisma.forms.updateMany({
19+
where: {
20+
status: "TEMP_STORED"
21+
},
22+
data: { status: "TEMP_STORER_ACCEPTED" }
23+
});
24+
}
2525
}

back/prisma/scripts/set-contacts.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import axios from "axios";
2-
import { addContact } from "src/common/mails.helper";
2+
import { addContact } from "src/mailer/mailing";
33
import prisma from "src/prisma";
44
import { Updater, registerUpdater } from "./helper/helper";
55

back/src/commands/__tests__/sendmails.tests.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ jest.mock("src/prisma", () => ({
2323
}));
2424

2525
describe("xDaysAgo", () => {
26-
it("should return a formatted relative past date", () => {
26+
it("should return a relative past date", () => {
2727
const someDate = new Date(2019, 9, 3, 10, 0, 0);
2828
const threeDaysBefore = xDaysAgo(someDate, 3);
29-
expect(threeDaysBefore).toEqual("2019-09-30");
29+
expect(threeDaysBefore.toISOString()).toEqual("2019-09-30T00:00:00.000Z");
3030
});
3131
});
3232

back/src/commands/onboarding.helpers.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ import { userMails } from "../users/mails";
77
*
88
* @param baseDate Date
99
* @param daysAgo Integer
10-
* @return a date formatted as "YYYY-MM-DD"
10+
* @return a date at 00:00:00
1111
*/
12-
export const xDaysAgo = (baseDate: Date, daysAgo: number): string => {
12+
export const xDaysAgo = (baseDate: Date, daysAgo: number): Date => {
1313
const clonedDate = new Date(baseDate.getTime()); // avoid mutating baseDate
14-
return new Date(clonedDate.setDate(clonedDate.getDate() - daysAgo))
15-
.toISOString()
16-
.split("T")[0];
14+
clonedDate.setDate(clonedDate.getDate() - daysAgo);
15+
16+
return new Date(clonedDate.toDateString());
1717
};
1818

1919
/**
@@ -31,8 +31,8 @@ export const sendOnboardingEmails = async (daysAgo: number, emailFunction) => {
3131
const recipients = await prisma.user.findMany({
3232
where: {
3333
AND: [
34-
{ createdAt_gt: inscriptionDateGt },
35-
{ createdAt_lt: inscriptionDateLt }
34+
{ createdAt: { gt: inscriptionDateGt } },
35+
{ createdAt: { lt: inscriptionDateLt } }
3636
],
3737
isActive: true
3838
}

back/src/companies/sirene/__tests__/index.integration.ts

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import { UserInputError } from "apollo-server-express";
2+
import prisma from "src/prisma";
13
import * as searchCompanyDecorated from "../searchCompany";
24
import { searchCompany } from "../index";
35
import { resetDatabase } from "../../../../integration-tests/helper";
4-
import { UserInputError } from "apollo-server-express";
5-
import { prisma } from "../../../generated/prisma-client";
66

77
const searchCompanySpy = jest.spyOn(searchCompanyDecorated, "default");
88
// Mock the fact a siret is not found in SIRENE API's
@@ -21,13 +21,15 @@ describe("searchCompany", () => {
2121
// do not bypass sirene client call
2222
process.env.NODE_ENV = "production";
2323
const siret = "11111111111111";
24-
const anonymousCompany = await prisma.createAnonymousCompany({
25-
siret,
26-
name: "GENDARMERIE NATIONALE",
27-
address: "Rue des tropiques, Saint Tropez",
28-
codeNaf: "7150",
29-
libelleNaf: "Service du ministère de la Défense",
30-
codeCommune: "83119 "
24+
const anonymousCompany = await prisma.anonymousCompany.create({
25+
data: {
26+
siret,
27+
name: "GENDARMERIE NATIONALE",
28+
address: "Rue des tropiques, Saint Tropez",
29+
codeNaf: "7150",
30+
libelleNaf: "Service du ministère de la Défense",
31+
codeCommune: "83119 "
32+
}
3133
});
3234
const searchResult = await searchCompany(siret);
3335
expect(searchResult).toMatchObject(anonymousCompany);

back/src/companies/sirene/anonymous.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { CompanySearchResult } from "../../generated/graphql/types";
2-
import { prisma } from "../../generated/prisma-client";
2+
import prisma from "src/prisma";
33

44
/**
55
* "Certaines entreprises demandent à ne pas figurer sur les listes de diffusion publique
@@ -14,7 +14,9 @@ import { prisma } from "../../generated/prisma-client";
1414
export async function searchAnonymousCompany(
1515
siret: string
1616
): Promise<CompanySearchResult> {
17-
const company = await prisma.anonymousCompany({ siret });
17+
const company = await prisma.anonymousCompany.findUnique({
18+
where: { siret }
19+
});
1820
if (company) {
1921
return {
2022
...company,

back/src/events/__tests__/traceability-break.test.ts

+9-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Form } from "@prisma/client";
2-
import axios from "axios";
2+
import * as mailing from "../../mailer/mailing";
33
import { TDEventPayload } from "../emitter";
44

55
import { formsEventCallback } from "../forms";
@@ -45,18 +45,15 @@ describe("mailWhenFormTraceabilityIsBroken", () => {
4545
} as Form
4646
};
4747

48-
const mockedAxiosPost = jest.spyOn(axios, "post");
49-
mockedAxiosPost.mockResolvedValue({} as any);
48+
const mockedSendMail = jest.spyOn(mailing, "sendMail");
5049

5150
await formsEventCallback(formPayload);
5251

53-
expect(mockedAxiosPost as jest.Mock<any>).toHaveBeenCalledTimes(1);
52+
expect(mockedSendMail as jest.Mock<any>).toHaveBeenCalledTimes(1);
5453

55-
const postArgs = mockedAxiosPost.mock.calls[0];
54+
const postArgs = mockedSendMail.mock.calls[0];
5655

57-
expect(postArgs[0]).toEqual("http://mailservice/smtp/email"); // fake url for tests
58-
59-
const payload = postArgs[1];
56+
const payload = postArgs[0];
6057

6158
// Check To & Cc
6259
expect(payload.to[0].email).toEqual(mockedForm.emitterCompanyMail);
@@ -66,9 +63,9 @@ describe("mailWhenFormTraceabilityIsBroken", () => {
6663
expect(payload.cc[0].name).toEqual(mockedForm.recipientCompanyContact);
6764

6865
// check mail body infos
69-
expect(payload.params.body).toContain(mockedForm.readableId);
70-
expect(payload.params.body).toContain(mockedForm.recipientCompanyName);
71-
expect(payload.params.body).toContain(mockedForm.wasteDetailsName);
72-
expect(payload.params.body).toContain(mockedForm.wasteDetailsCode);
66+
expect(payload.body).toContain(mockedForm.readableId);
67+
expect(payload.body).toContain(mockedForm.recipientCompanyName);
68+
expect(payload.body).toContain(mockedForm.wasteDetailsName);
69+
expect(payload.body).toContain(mockedForm.wasteDetailsCode);
7370
});
7471
});

0 commit comments

Comments
 (0)