Skip to content

Commit

Permalink
Allow rules to be updated on successive imports and change the nomina…
Browse files Browse the repository at this point in the history
…tion files <> reports sync logic
  • Loading branch information
Maxime Naulleau committed Nov 5, 2024
1 parent 30c4697 commit 30acb82
Show file tree
Hide file tree
Showing 48 changed files with 1,169 additions and 578 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Eléments du dossier Règles automatisées de gestion (pour débat) et statutaires (bloquantes) Règles statutaires (bloquantes) et éléments qualitatifs à vérifier dans le dossier
Point(s) d'attention(s) repéré(s) dans le dossier N° dossier Magistrat Formation Date d'échéance Etat Transparence Rapporteur(s) (pré-traitement pour import) Rapporteur(s) Grade actuel Poste actuel Poste pressenti Rang Date de naissance Historique Observants Mutation en - de 3 ans Passer au 1er grade Passe au grade "HH" Prendre son grade sur place Poste "profilé" Nomination à la CC "Outremer sur Outremer" Siège <> Parquet et TJ <> CA Siège <> Parquet du même ressort Siège <> Parquet d'une même juridiction Prendre son grade sur place après 7 ans Ministère de la Justice à - de 3 ans d'exercice Cabinet du ministre Inscription au tableau pour prise de grade Accéder à la HH sans avoir fait 2 postes au 1er grade Prof. jur. dans le ressort du TJ il y a - de 5 ans Conflit d'intérêt avec parcours pré magistrature Conflit d'intérêt avec la prof. d'un proche Evaluations Eléments disciplinaires Conditions de nomination HH Point d'attention sur ce dossier ? Grade actuel Intitulé du poste actuel Reformulation du poste actuel Date de prise du poste actuel Lieu d'exercice du poste actuel (nom de la juridiction) Localisation du poste actuel (Métropole ou Outremer) Cour d'appel de rattachement du poste actuel Poste au Ministère ? Grade du poste pressenti Titre du poste pressenti Poste profilé ? Intitulé du poste pressenti Reformulation du poste pressenti, sans le grade II Reformulation du poste pressenti, sans les grades II et I Reformulation du poste pressenti, sans les grades II, I et HH Lieu d'exercice du poste pressenti (nom de la juridiction) Localisation du poste pressenti (Métropole ou Outremer) Cour d'appel de rattachement du poste pressenti Date pour la prise de poste (si nomination confirmée) Observations
TRUE 1 (parq.) Julien Pierre Siège 10/11/2024 Nouveau Automne 2024 ROUSSIN Jules ROUSSIN Jules I Vice-président TJ BEAUVAIS Premier vice-président chargé de l'instruction TJ MARSEILLE - I (1 sur une liste de 4) 11/10/1979 - blabla julien pierre - blabla. - blabla BEAUVAIS (1er grade), 11/10/2013 (Ins.11/10/2013). - VPLILLES 25/06/2014 (Ins.03/09/2018). LUCIEN MARC VPI TJ NANTES (2 sur une liste de 4) FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE I Vice-président TJ BEAUVAIS Vice-président septembre 2018 BEAUVAIS Métropole CA AMIENS FALSE I Premier FALSE Premier vice-président chargé de l'instruction TJ MARSEILLE - I Premier vice-président chargé de l'instruction TJ MARSEILLE - I Premier vice-président chargé de l'instruction TJ MARSEILLE Premier vice-président chargé de l'instruction TJ MARSEILLE MARSEILLE Métropole CA AIX EN PROVENCE septembre 2024 LUCIEN MARC VPI TJ NANTES (2 sur une liste de 4)
TRUE 1 (parq.) Julien Pierre Siège 10/11/2024 Nouveau Automne 2024 ROUSSIN Jules ROUSSIN Jules I Vice-président TJ BEAUVAIS Premier vice-président chargé de l'instruction TJ MARSEILLE - I (1 sur une liste de 4) 11/10/1979 - blabla julien pierre - blabla. - blabla BEAUVAIS (1er grade), 11/10/2013 (Ins.11/10/2013). - VPLILLES 25/06/2014 (Ins.03/09/2018). LUCIEN MARC VPI TJ NANTES (2 sur une liste de 4) TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE TRUE I Vice-président TJ BEAUVAIS Vice-président septembre 2018 BEAUVAIS Métropole CA AMIENS FALSE I Premier FALSE Premier vice-président chargé de l'instruction TJ MARSEILLE - I Premier vice-président chargé de l'instruction TJ MARSEILLE - I Premier vice-président chargé de l'instruction TJ MARSEILLE Premier vice-président chargé de l'instruction TJ MARSEILLE MARSEILLE Métropole CA AIX EN PROVENCE septembre 2024 LUCIEN MARC VPI TJ NANTES (2 sur une liste de 4)
TRUE 2 (parq.) Dupont Marcel Siège 01/12/2025 Avis restitué Automne 2024 ROUSSIN Jules ROUSSIN Jules I Premier substitut à l'administration centrale du ministère de la justice AC MARSEILLE Premier vice-président adjoint TJ RENNES - I (1 sur une liste de 1) 16/1/1981 - blabla dupont marcel - blabla. - blabla BEAUVAIS (1er grade), 11/10/2013 (Ins.11/10/2013). - VPLILLES 25/06/2014 (Ins.03/09/2018). TRUE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE I Premier substitut à l'administration centrale du ministère de la justice AC MARSEILLE Premier mai 2024 MARSEILLE Métropole CA AIX EN PROVENCE FALSE I Premier TRUE Premier vice-président adjoint TJ RENNES - I Premier vice-président adjoint TJ RENNES - I Premier vice-président adjoint TJ RENNES Premier vice-président adjoint TJ RENNES RENNES Métropole CA RENNES septembre 2024
TRUE 5 (parq.) Brusse Emilien Ep. François Parquet Nouveau Mars 2025 ROUSSIN Jules<cell_line_break>JOSSELIN-MARTEL Martin-Luc ROUSSIN Jules JOSSELIN-MARTEL Martin-Luc I DETACHEMENT Premier substitut à l'administration centrale du ministère de la justice AC PARIS - I 1 sur une liste de 12) 24/2/1987 - blabla brusse émilien - blabla. - blabla BEAUVAIS (1er grade), 11/10/2013 (Ins.11/10/2013). - VPLILLES 25/06/2014 (Ins.03/09/2018). LUDIVINE Jeanne VPI TJ PARIS (9 sur une liste de 12) FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE TRUE I DETACHEMENT DETACHEMENT janvier 2021 DETACHEMENT #N/A #N/A TRUE I Premier TRUE Premier substitut à l'administration centrale du ministère de la justice AC PARIS - I Premier substitut à l'administration centrale du ministère de la justice AC PARIS - I Premier substitut à l'administration centrale du ministère de la justice AC PARIS Premier substitut à l'administration centrale du ministère de la justice AC PARIS PARIS Métropole CA PARIS septembre 2024 LUDIVINE Jeanne VPI TJ PARIS (9 sur une liste de 12)
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { eq } from 'drizzle-orm';
import { NestApplication } from '@nestjs/core';
import { Test } from '@nestjs/testing';
import path from 'node:path';
Expand All @@ -8,7 +9,10 @@ import { IMPORT_NOMINATION_FILE_FROM_LOCAL_FILE_CLI } from 'src/data-administrat
import { nominationFiles } from 'src/data-administrator-context/adapters/secondary/gateways/repositories/drizzle/schema';
import { ImportNominationFileFromLocalFileCli } from 'src/data-administrator-context/business-logic/gateways/providers/import-nominations-from-local-file.cli';
import { NominationFileRead } from 'src/data-administrator-context/business-logic/models/nomination-file-read';
import { reports } from 'src/reporter-context/adapters/secondary/gateways/repositories/drizzle/schema';
import {
reportRules,
reports,
} from 'src/reporter-context/adapters/secondary/gateways/repositories/drizzle/schema';
import { DRIZZLE_DB } from 'src/shared-kernel/adapters/primary/nestjs/shared-kernel.module';
import { drizzleConfigForTest } from 'src/shared-kernel/adapters/secondary/repositories/drizzle/drizzle-config';
import {
Expand Down Expand Up @@ -69,7 +73,6 @@ describe('Import Nominations from local file', () => {
...getExpectedContents().map((content) => ({
id: expect.any(String),
createdAt: expect.any(Date),
reportId: expect.any(String),
rowNumber: expect.any(Number),
content,
})),
Expand All @@ -80,14 +83,107 @@ describe('Import Nominations from local file', () => {
.map((content) =>
content.reporters?.length
? content.reporters.map((reporterName) =>
getNominationFile({ ...content, reporterName }),
getReportPm({ ...content, reporterName }),
)
: [getNominationFile({ ...content, reporterName: null })],
: [getReportPm({ ...content, reporterName: null })],
)
.flat(),
);
});

describe('when a nomination file is already imported', () => {
const nominationFileId = 'a725b384-f07a-4b19-814e-3610f055ea5c';
const reportId = '8d9fc5f2-7254-4d04-b99a-e4d15fefee29';
const transferTimeRuleId = 'b820be91-343f-478a-9e7e-58fe178e3ed1';

it.only('updates the transfer time rule', async () => {
const firstTsvContent = getExpectedContents()[0]!;
const previousTransferTimePreValidated = false;
await db.insert(nominationFiles).values({
id: nominationFileId,
rowNumber: 1,
content: {
...firstTsvContent,
rules: {
...firstTsvContent.rules,
management: {
...firstTsvContent.rules.management,
TRANSFER_TIME: previousTransferTimePreValidated,
},
},
},
});
await db.insert(reports).values({
id: reportId,
nominationFileId: nominationFileId,
createdAt: new Date(),
state: NominationFile.ReportState.NEW,
dueDate: DateOnly.fromJson(firstTsvContent.dueDate!).toDbString(),
formation: firstTsvContent.formation,
name: firstTsvContent.name,
reporterName: firstTsvContent.reporters![0]!,
transparency: firstTsvContent.transparency,
grade: firstTsvContent.grade,
currentPosition: firstTsvContent.currentPosition,
targettedPosition: firstTsvContent.targettedPosition,
rank: firstTsvContent.rank,
birthDate: DateOnly.fromJson(firstTsvContent.birthDate).toDbString(),
biography: firstTsvContent.biography,
comment: null,
});
await db.insert(reportRules).values({
id: transferTimeRuleId,
reportId,
ruleGroup: NominationFile.RuleGroup.MANAGEMENT,
ruleName: NominationFile.ManagementRule.TRANSFER_TIME,
preValidated: previousTransferTimePreValidated,
validated: false,
comment: 'some comment',
});

await importNominationFileFromLocalFileCli.execute(fileToImportPath);
await setTimeout(1500);

await expectNominationFiles(
...getExpectedContents().map((content, index) =>
index === 0
? {
id: nominationFileId,
createdAt: expect.any(Date),
rowNumber: 1,
content: {
...content,
rules: {
...content.rules,
management: {
...content.rules.management,
TRANSFER_TIME: !previousTransferTimePreValidated,
},
},
},
}
: {
id: expect.any(String),
createdAt: expect.any(Date),
rowNumber: expect.any(Number),
content,
},
),
);

await expectReportRule({
id: transferTimeRuleId,
createdAt: expect.any(Date),
reportId,
ruleGroup: NominationFile.RuleGroup.MANAGEMENT,
ruleName: NominationFile.ManagementRule.TRANSFER_TIME,
preValidated: !previousTransferTimePreValidated,
validated: false,
comment: 'some comment',
});
});
});

const expectNominationFiles = async (
...expectedNominationFiles: (typeof nominationFiles.$inferSelect)[]
) => {
Expand All @@ -98,6 +194,17 @@ describe('Import Nominations from local file', () => {
);
};

const expectReportRule = async (
expectedReportRule: typeof reportRules.$inferSelect,
) => {
const reportRulesPm = await db
.select()
.from(reportRules)
.where(eq(reportRules.id, expectedReportRule.id))
.execute();
expect(reportRulesPm).toEqual([expectedReportRule]);
};

const expectReports = async (
...expectedReports: (typeof reports.$inferSelect)[]
) => {
Expand All @@ -106,10 +213,11 @@ describe('Import Nominations from local file', () => {
expect(reportsPm).toEqual(expect.arrayContaining(expectedReports));
};

const getNominationFile = (
const getReportPm = (
content: NominationFileRead['content'] & { reporterName: string | null },
): typeof reports.$inferSelect => ({
id: expect.any(String),
nominationFileId: expect.any(String),
createdAt: expect.any(Date),
state: content.state,
dueDate: content.dueDate
Expand Down Expand Up @@ -152,31 +260,31 @@ function getExpectedContents(): NominationFileRead['content'][] {
reporters: ['ROUSSIN Jules'],
rules: {
management: {
CASSATION_COURT_NOMINATION: true,
TRANSFER_TIME: true,
CASSATION_COURT_NOMINATION: false,
GETTING_FIRST_GRADE: false,
GETTING_GRADE_HH: false,
GETTING_GRADE_IN_PLACE: false,
JUDICIARY_ROLE_AND_JURIDICTION_DEGREE_CHANGE: false,
JUDICIARY_ROLE_CHANGE_IN_SAME_RESSORT: false,
OVERSEAS_TO_OVERSEAS: false,
PROFILED_POSITION: false,
TRANSFER_TIME: false,
},
qualitative: {
CONFLICT_OF_INTEREST_PRE_MAGISTRATURE: true,
CONFLICT_OF_INTEREST_WITH_RELATIVE_PROFESSION: true,
DISCIPLINARY_ELEMENTS: true,
EVALUATIONS: true,
HH_NOMINATION_CONDITIONS: true,
},
statutory: {
GRADE_ON_SITE_AFTER_7_YEARS: false,
GRADE_REGISTRATION: false,
HH_WITHOUT_2_FIRST_GRADE_POSITIONS: false,
JUDICIARY_ROLE_CHANGE_IN_SAME_JURIDICTION: false,
LEGAL_PROFESSION_IN_JUDICIAL_COURT_LESS_THAN_5_YEARS_AGO: false,
MINISTER_CABINET: false,
MINISTRY_OF_JUSTICE_IN_LESS_THAN_3_YEARS: false,
GRADE_ON_SITE_AFTER_7_YEARS: true,
GRADE_REGISTRATION: true,
HH_WITHOUT_2_FIRST_GRADE_POSITIONS: true,
JUDICIARY_ROLE_CHANGE_IN_SAME_JURIDICTION: true,
LEGAL_PROFESSION_IN_JUDICIAL_COURT_LESS_THAN_5_YEARS_AGO: true,
MINISTER_CABINET: true,
MINISTRY_OF_JUSTICE_IN_LESS_THAN_3_YEARS: true,
},
qualitative: {
CONFLICT_OF_INTEREST_PRE_MAGISTRATURE: false,
CONFLICT_OF_INTEREST_WITH_RELATIVE_PROFESSION: false,
DISCIPLINARY_ELEMENTS: false,
EVALUATIONS: false,
HH_NOMINATION_CONDITIONS: false,
},
},
state: NominationFile.ReportState.NEW,
Expand Down
13 changes: 13 additions & 0 deletions apps/api/drizzle/0005_nomination_file_id_in_report_pm.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BEGIN;

ALTER TABLE "reports_context"."reports" ADD COLUMN "nomination_file_id" uuid;--> statement-breakpoint

UPDATE reports_context.reports
SET
nomination_file_id = nf.report_id
FROM data_administration_context.nomination_files nf
WHERE reports.id = nf.report_id;

ALTER TABLE "data_administration_context"."nomination_files" DROP COLUMN "report_id";

COMMIT;
Loading

0 comments on commit 30acb82

Please sign in to comment.