Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(backend): add a specific colum for text search #3437

Merged
merged 3 commits into from
Aug 6, 2024
Merged
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
6 changes: 4 additions & 2 deletions .talismanrc
Original file line number Diff line number Diff line change
@@ -41,8 +41,10 @@ fileignoreconfig:
checksum: 3b2a7e24e6e69fb3b81f473ceb43a00a2191c0358f2cbc314f5eb3b0e2a95672
- filename: packages/backend/src/_migrations/1721817064651-auto-migration.ts
checksum: 4c1f4f912bebc23465a8ed8bf0729091774483f2c15025b60f7cbe7a4cbd0d12
- filename: packages/backend/src/_migrations/1722521444554-auto-migration.ts
checksum: 4a28aeadfff8f388ef4a0ea9709fbb471f9ec931215ffcf28e71a95fc3171e73
- filename: packages/backend/src/_migrations/_init-db/1603812391580-pr-env-create-database.ts
checksum: 99133de99ba8a6760310d62b686e25ec978fdbb0d658b5e18d06f387f366ed7e
checksum: 9c4984cbb8b435b626b2b26fd1cba740542aed18aa568bd03af517651de1aacd
- filename: packages/backend/src/modules/portail-usagers/controllers/portail-usagers-manager/portail-usagers-manager.controller.ts
checksum: 6cb66d899577621ac9f796b2fde88a68263b7422c3f369854d94236c15c0807f
- filename: packages/backend/src/stats/services/publicStats.service.ts
@@ -82,5 +84,5 @@ fileignoreconfig:
- filename: packages/portail-admins/src/environments/environment.ts
checksum: 65d0b914b6baa33b2e8ec95786ef0c9d9960787295f1f02450d0262f71fd3d0e
- filename: yarn.lock
checksum: 475dccf18d63d458543b0dd98a1ee54e6743cf2b011b1e8be8e14957b929f99f
checksum: dce41db10fe65e26fb8b1ca281e9a4672e65131e94a881a5ad6fadbfbcfd9058
version: "1.0"
3 changes: 0 additions & 3 deletions packages/backend/.env.preset/dist-prod.preset.env
Original file line number Diff line number Diff line change
@@ -15,6 +15,3 @@ DOMIFA_CRON_EMAIL_USER_GUIDE_DELAY="7 days"
DOMIFA_CRON_EMAIL_IMPORT_GUIDE_CRONTIME="0 15 * * TUE"
DOMIFA_CRON_EMAIL_IMPORT_GUIDE_DELAY="7 days"


# 50 connexions max en prod: https://docs.microsoft.com/fr-fr/azure/postgresql/concepts-limits
POSTGRES_POOL_MAX_CONNEXIONS="100"
5 changes: 0 additions & 5 deletions packages/backend/.env.preset/dist.preset.env
Original file line number Diff line number Diff line change
@@ -24,8 +24,3 @@ DOMIFA_SWAGGER_ENABLE=false

DOMIFA_SENTRY_ENABLED=true
DOMIFA_SENTRY_DEBUG_MODE_ENABLED=false


# 50 connexions en tout à partager entre la preprod + les environnements de dev :
# https://docs.microsoft.com/fr-fr/azure/postgresql/concepts-limits
POSTGRES_POOL_MAX_CONNEXIONS="100"
1 change: 1 addition & 0 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
@@ -60,6 +60,7 @@
"@opentelemetry/semantic-conventions": "^1.25.0",
"@sentry/node": "^8.18.0",
"@sentry/opentelemetry-node": "^7.117.0",
"@sentry/profiling-node": "^8.22.0",
"@socialgouv/streaming-file-encryption": "^1.1.0",
"@types/source-map-support": "^0.5.10",
"aws-sdk": "^2.1659.0",
30 changes: 30 additions & 0 deletions packages/backend/src/_migrations/1722521444554-auto-migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { MigrationInterface, QueryRunner } from "typeorm";
import { domifaConfig } from "../config";

export class AutoMigration1722521444554 implements MigrationInterface {
name = "AutoMigration1722521444554";

public async up(queryRunner: QueryRunner): Promise<void> {
if (
domifaConfig().envId === "prod" ||
domifaConfig().envId === "preprod" ||
domifaConfig().envId === "local"
) {
await queryRunner.query(
`ALTER TABLE "usager" ADD "nom_prenom_ref" character varying GENERATED ALWAYS AS (LOWER(nom || ' ' || prenom || ' ' || COALESCE("customRef", ''))) STORED NOT NULL;`
);
await queryRunner.query(
`CREATE INDEX "IDX_3af7a33a589c062bb6151d0969" ON "usager" ("nom_prenom_ref") `
);
}
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "usager" DROP COLUMN "nom_prenom_ref"`
);
await queryRunner.query(
`ALTER TABLE "usager" ADD "nom_prenom_ref" character varying NOT NULL`
);
}
}
Original file line number Diff line number Diff line change
@@ -377,10 +377,12 @@ async function createTables(queryRunner: QueryRunner) {
"pinnedNote" jsonb NULL,
nationalite text NULL,
statut text DEFAULT 'INSTRUCTION'::text NOT NULL,
nom_prenom_ref varchar GENERATED ALWAYS AS (lower((((nom || ' '::text) || prenom) || ' '::text) || COALESCE("customRef", ''::text))) STORED NOT NULL,
CONSTRAINT "PK_1bb36e24229bec446a281573612" PRIMARY KEY (uuid),
CONSTRAINT "UQ_e76056fb098740de66d58a5055a" UNIQUE ("structureId", ref),
CONSTRAINT "FK_a44d882d224e368efdee8eb8c80" FOREIGN KEY ("structureId") REFERENCES public."structure"(id) ON DELETE CASCADE
);
CREATE INDEX "IDX_3af7a33a589c062bb6151d0969" ON public.usager USING btree (nom_prenom_ref);
CREATE INDEX "IDX_a44d882d224e368efdee8eb8c8" ON public.usager USING btree ("structureId");
CREATE INDEX "IDX_b4d09870ec6cad2d2d98b7cc3a" ON public.usager USING btree (migrated);
CREATE INDEX idx_usager_statut ON public.usager USING btree ("structureId", statut);
@@ -753,7 +755,6 @@ async function createTables(queryRunner: QueryRunner) {
CREATE INDEX "IDX_ef9fade8e5a6dac06ef5031986" ON public.interactions USING btree (type);
CREATE INDEX "IDX_f9c3ee379ce68d4acfe4199a33" ON public.interactions USING btree ("usagerUUID");
CREATE INDEX idx_interactions_date ON public.interactions USING btree ("structureId", "usagerUUID", "dateInteraction");
CREATE INDEX idx_interactions_type ON public.interactions USING btree ("structureId", "usagerUUID", type);
`
CREATE INDEX idx_interactions_type ON public.interactions USING btree ("structureId", "usagerUUID", type); `
);
}
Original file line number Diff line number Diff line change
@@ -147,12 +147,12 @@ export class AdminStructuresController {

@Get("last-update")
@AllowUserProfiles("super-admin-domifa")
public async getLastUpdate(): Promise<Date> {
public async getLastUpdate(): Promise<Date | null> {
const lastUsager = await structureRepository.findOne({
where: {},
order: { createdAt: "DESC" },
});
return lastUsager.createdAt;
return lastUsager?.createdAt ?? null;
}

@Get("")
1 change: 1 addition & 0 deletions packages/backend/src/app.bootstrap.ts
Original file line number Diff line number Diff line change
@@ -59,6 +59,7 @@ export async function bootstrapApplication(): Promise<{
} else {
app.enableCors({
origin: whitelist,
maxAge: 600,
});
}

24 changes: 18 additions & 6 deletions packages/backend/src/auth/guards/AppUserGuard.guard.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { addLogContext } from "../../util";
import {
UserAuthenticated,
UserProfile,
UserStructureAuthenticated,
} from "../../_common/model";
import { UserProfile, UserStructureAuthenticated } from "../../_common/model";
import { authChecker } from "../services";
import { expiredTokenRepositiory } from "../../database";
import { UserStructureRole } from "@domifa/common";
import { getCurrentScope } from "@sentry/node";

@Injectable()
export class AppUserGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}

public async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const user = request.user as UserAuthenticated;
const user = request.user as UserStructureAuthenticated;

addLogContext({
auth: {
@@ -26,6 +23,21 @@ export class AppUserGuard implements CanActivate {
},
});

if (request?.body) {
addLogContext({
body: request?.body,
});
}

getCurrentScope().setUser({
email: user.email,
username:
"STRUCTURE " + user.structureId?.toString() + " : " + user.prenom,
id: user._userId,
role: user.role,
structureId: user.structureId,
});

let allowUserProfiles = this.reflector.get<UserProfile[]>(
"allowUserProfiles",
context.getHandler()
5 changes: 0 additions & 5 deletions packages/backend/src/auth/services/structures-auth.service.ts
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ import { JwtService } from "@nestjs/jwt";
import { differenceInCalendarDays } from "date-fns";
import { domifaConfig } from "../../config";
import { userStructureRepository, structureRepository } from "../../database";
import { appLogger } from "../../util";
import {
CURRENT_JWT_PAYLOAD_VERSION,
UserStructure,
@@ -107,10 +106,6 @@ export class StructuresAuthService {
select: APP_USER_PUBLIC_ATTRIBUTES,
});

if (typeof user.structureId === "undefined") {
appLogger.debug("[TRACK BUG] " + JSON.stringify(user));
}

const structure: StructureCommon = await structureRepository.findOne({
where: { id: user.structureId },
select: [
9 changes: 0 additions & 9 deletions packages/backend/src/config/domifaConfig.service.ts
Original file line number Diff line number Diff line change
@@ -136,14 +136,6 @@ export function loadConfig(x: Partial<DomifaEnv>): DomifaConfig {
required: false,
defaultValue: false,
}),

poolMaxConnections: configParser.parseInteger(
x,
"POSTGRES_POOL_MAX_CONNEXIONS",
{
defaultValue: 10, // 10 is also driver default: https://node-postgres.com/api/pool#constructor
}
),
},
typeorm: {
runOnStartup: configParser.parseBoolean(
@@ -272,7 +264,6 @@ export function loadConfig(x: Partial<DomifaEnv>): DomifaConfig {
defaultValue: CronExpression.EVERY_DAY_AT_11PM,
}
),

delay: configParser.parseDelay(
x,
"DOMIFA_CRON_MONITORING_CLEANER_DELAY",
Original file line number Diff line number Diff line change
@@ -5,5 +5,4 @@ export type DomifaConfigPostgres = {
password: string; // POSTGRES_PASSWORD
database: string; // POSTGRES_DATABASE
ssl: boolean; // POSTGRES_SSL
poolMaxConnections: number; // POSTGRES_POOL_MAX_CONNEXIONS
};
2 changes: 0 additions & 2 deletions packages/backend/src/config/model/DomifaEnv.type.ts
Original file line number Diff line number Diff line change
@@ -34,15 +34,13 @@ export type DomifaEnv = {
DOMIFA_CRON_EMAIL_CONSUMER_CRONTIME: string;
DOMIFA_CRON_SMS_CONSUMER_CRONTIME: string;
DOMIFA_CRON_FETCH_END_DOM_CRONTIME: string;

DOMIFA_ANONYMIZER_PASSWORD: string;
POSTGRES_HOST: string;
POSTGRES_PORT: string;
POSTGRES_USERNAME: string;
POSTGRES_PASSWORD: string;
POSTGRES_DATABASE: string;
POSTGRES_SSL: boolean;
POSTGRES_POOL_MAX_CONNEXIONS: string;
DOMIFA_TYPEORM_RUN_ON_STARTUP: string;
DOMIFA_MAIL_SMTP_ID: string;
DOMIFA_MAIL_SMTP_MAILTRAP_HOST: string;
5 changes: 3 additions & 2 deletions packages/backend/src/config/services/configParser.service.ts
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ import {
DomifaEnv,
DomifaEnvKey,
DOMIFA_CONFIG_DELAY_UNITS,
DomifaConfigDelay,
} from "../model";

export const configParser = {
@@ -153,7 +154,7 @@ function parseDelay<T extends string>(
} = {
required: true,
}
) {
): DomifaConfigDelay {
const value = parseString(envConfig, key, {
defaultValue,
required,
@@ -178,7 +179,7 @@ function parseDelay<T extends string>(
}
return { amount, unit };
}
return undefined;
return defaultValue as unknown as DomifaConfigDelay;
}

function parseIntegerFromString(value: string): number | undefined {
Original file line number Diff line number Diff line change
@@ -52,6 +52,14 @@ export class UsagerTable
@JoinColumn({ name: "structureId", referencedColumnName: "id" })
public structureId!: number;

@Column({
nullable: false,
name: "nom_prenom_ref",
select: false,
})
@Index()
public nom_prenom_ref: string;

@Column({ type: "text", nullable: false })
public nom!: string;

@@ -152,6 +160,7 @@ export class UsagerTable
this.nom = this.nom.trim();
this.prenom = this.prenom.trim();
}

public constructor(entity?: Partial<UsagerTable>) {
super(entity);
Object.assign(this, entity);
Original file line number Diff line number Diff line change
@@ -42,6 +42,7 @@ export const PG_CONNECT_OPTIONS: PostgresConnectionOptions = {
username: domifaConfig().postgres.username,
password: domifaConfig().postgres.password,
database: domifaConfig().postgres.database,
poolSize: domifaConfig().envId === "test" ? 1 : 100,
ssl: domifaConfig().postgres.ssl
? {
rejectUnauthorized: false,
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ async function connect(

if (domifaConfig().envId !== "test") {
appLogger.warn(
`[appTypeormManager] Connecting to postgres database "${pgConfig.database}" at ${pgConfig.host}:${pgConfig.port} (max poolMaxConnections=${pgConfig.poolMaxConnections}")`
`[appTypeormManager] Connecting to postgres database "${pgConfig.database}" at ${pgConfig.host}:${pgConfig.port}`
);
}

Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@ export const usagerRepository = myDataSource
_parseCounts: baseRepository._parseCounts,
countBy: baseRepository.countBy,
getUsager,

customCountBy: baseRepository.countBy,
countAyantsDroits,
countUsagersByMonth,
Original file line number Diff line number Diff line change
@@ -255,7 +255,7 @@ describe("interactionsCreator", () => {
});

expect(resultat.usager.lastInteraction.dateInteraction).toEqual(
MOCKED_NEW_DATE
new Date(MOCKED_NEW_DATE)
);
expect(resultat.interaction.nbCourrier).toEqual(0);
});
@@ -273,7 +273,7 @@ describe("interactionsCreator", () => {
});

expect(resultat.usager.lastInteraction.dateInteraction).toEqual(
MOCKED_NEW_DATE
new Date(MOCKED_NEW_DATE)
);

expect(resultat.interaction.nbCourrier).toEqual(0);
@@ -514,7 +514,7 @@ describe("interactionsCreator", () => {
interaction,
});
expect(resultat.usager.lastInteraction.dateInteraction).toEqual(
MOCKED_NEW_DATE
new Date(MOCKED_NEW_DATE)
);

expect(resultat.interaction.nbCourrier).toEqual(0);
4 changes: 2 additions & 2 deletions packages/backend/src/open-data-places/load-mss.ts
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ export const loadMssData = async () => {
!domifaConfig().openDataApps.mssUrl ||
!domifaConfig().openDataApps.mssToken
) {
appLogger.log("[IMPORT DATA MSS] Fail, token or url is not in env");
appLogger.info("[IMPORT DATA MSS] Fail, token or url is not in env");
return;
}
appLogger.info("Import MSS start 🏃‍♂️... ");
@@ -44,7 +44,7 @@ const getFromMss = async () => {
const position = await getLocation(address);

if (!position) {
appLogger.log("Adresse not found " + address);
appLogger.warn("Adresse not found " + address);
continue;
}

11 changes: 5 additions & 6 deletions packages/backend/src/open-telemetry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as Sentry from "@sentry/node";
import {
SentrySpanProcessor,
SentryPropagator,
@@ -19,16 +18,16 @@ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-grpc";
import { domifaConfig } from "./config";
import { appLogger } from "./util";
import { format } from "date-fns";
import { captureMessage, init, sessionTimingIntegration } from "@sentry/node";

if (domifaConfig().dev.sentry.enabled) {
Sentry.init({
init({
debug: domifaConfig().dev.sentry.debugModeEnabled,
dsn: domifaConfig().dev.sentry.sentryDsn,
environment: domifaConfig().envId,
tracesSampleRate: 1.0,
// logLevels: domifaConfig().dev.sentry.debugModeEnabled
// ? ["log", "error", "warn", "debug", "verbose"] // Verbose,
// : ["log", "error", "warn", "debug"],
profilesSampleRate: 1,
integrations: [sessionTimingIntegration()],
});

const sdk = new opentelemetry.NodeSDK({
@@ -53,7 +52,7 @@ if (domifaConfig().dev.sentry.enabled) {
appLogger.warn(`SENTRY DNS enabled: ${domifaConfig().dev.sentry.sentryDsn}`);

if (domifaConfig().envId === "prod") {
Sentry.captureMessage(
captureMessage(
`[API START] [${domifaConfig().envId}] ${format(
new Date(),
"dd/MM/yyyy - HH:mm"
Loading