Skip to content

Commit

Permalink
Add zoning and occult zone (#95)
Browse files Browse the repository at this point in the history
* add zoning type

* map zoning

* undefined zoning if not provided

* add introduction subzonage

* add partially public field in decisionMetadata

* add flag to partiallypublic decision

* add occultation for motivation when debat are not public

* update readme

* hide category for annotators

* open categorie on left panel for simple route

* update removeOverlapping annotation to keep the longest annotation

* lint

* move texte to wording

* fix logic

* throw error if zoning not found

* handle multiple motivations

* update with sder master commit

---------

Co-authored-by: Antoine Jeanneney <[email protected]>
  • Loading branch information
ajeanneney and Antoine Jeanneney committed May 13, 2024
1 parent c858220 commit 180e7df
Show file tree
Hide file tree
Showing 39 changed files with 588 additions and 35 deletions.
2 changes: 1 addition & 1 deletion docs/documentStatuses.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A `document` is supposed to follow a specific flow once it enters the label data

- `loaded`: the document has only been imported in LABEL. No treatment has been done on it.
- `nlpAnnotating`: the document is currently being annotated by the NLP annotator.
- `free`: the document is ready to be annotated by a working user. There are already several `treatments` related to that document (one by the `NLP`, one by the `postProcess`, maybe one with the `supplementaryAnnotations` if asked by the clerk)
- `free`: the document is ready to be annotated by a working user. There are already several `treatments` related to that document (one by the `NLP`, maybe one with the `supplementaryAnnotations` if decision is partially public)
- `pending`: the document is proposed to a working user. An `assignation` and a corresponding empty `treatment` have been created. The document won't be proposed to another working user.
- `saved`: the document is being annotated by a working user.
- `toBeConfirmed`: the document needs to be proof-read a second time by an administrator
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,5 @@
"workspaces": [
"packages/generic/*",
"packages/courDeCassation/"
],
"dependencies": {}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function buildNlpApi(nlpApiBaseUrl: string): nlpApiType {
document.decisionMetadata.additionalTermsToAnnotate,
document.decisionMetadata.computedAdditionalTerms,
document.decisionMetadata.additionalTermsParsingFailed,
document.decisionMetadata.debatPublic,
);
const nlpCategories = settingsModule.lib.getCategories(filteredSettings, {
status: ['visible', 'alwaysVisible', 'annotable'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function buildNlpLocalApi(): nlpApiType {
document.decisionMetadata.additionalTermsToAnnotate,
document.decisionMetadata.computedAdditionalTerms,
document.decisionMetadata.additionalTermsParsingFailed,
document.decisionMetadata.debatPublic,
);
const annotations = JSON.parse(
await fs.readFile(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,90 @@ async function mapCourtDecisionToDocument(
source,
);

let moyens = undefined;
if (sderCourtDecision.originalTextZoning?.zones?.moyens) {
if (Array.isArray(sderCourtDecision.originalTextZoning.zones.moyens)) {
moyens = sderCourtDecision.originalTextZoning.zones.moyens;
} else {
moyens = [sderCourtDecision.originalTextZoning.zones.moyens];
}
}

let expose_du_litige = undefined;
if (sderCourtDecision.originalTextZoning?.zones?.['expose du litige']) {
if (
Array.isArray(
sderCourtDecision.originalTextZoning.zones['expose du litige'],
)
) {
expose_du_litige =
sderCourtDecision.originalTextZoning.zones['expose du litige'];
} else {
expose_du_litige = [
sderCourtDecision.originalTextZoning.zones['expose du litige'],
];
}
}

let motivations = undefined;
if (sderCourtDecision.originalTextZoning?.zones?.motivations) {
if (Array.isArray(sderCourtDecision.originalTextZoning.zones.motivations)) {
motivations = sderCourtDecision.originalTextZoning.zones.motivations;
} else {
motivations = [sderCourtDecision.originalTextZoning.zones.motivations];
}
}

const zoningZones = {
introduction:
sderCourtDecision.originalTextZoning?.zones?.introduction || undefined,
moyens: moyens,
'expose du litige': expose_du_litige,
motivations: motivations,
dispositif:
sderCourtDecision.originalTextZoning?.zones?.dispositif || undefined,
'moyens annexes':
sderCourtDecision.originalTextZoning?.zones?.['moyens annexes'] ||
undefined,
};

const introduction_subzonage = {
n_arret:
sderCourtDecision.originalTextZoning?.introduction_subzonage?.n_arret ||
undefined,
formation:
sderCourtDecision.originalTextZoning?.introduction_subzonage?.formation ||
undefined,
publication:
sderCourtDecision.originalTextZoning?.introduction_subzonage
?.publication || undefined,
juridiction:
sderCourtDecision.originalTextZoning?.introduction_subzonage
?.juridiction || undefined,
chambre:
sderCourtDecision.originalTextZoning?.introduction_subzonage?.chambre ||
undefined,
pourvoi:
sderCourtDecision.originalTextZoning?.introduction_subzonage?.pourvoi ||
undefined,
composition:
sderCourtDecision.originalTextZoning?.introduction_subzonage
?.composition || undefined,
};

let zoning = undefined;
if (sderCourtDecision.originalTextZoning) {
zoning = {
zones: zoningZones || undefined,
introduction_subzonage: introduction_subzonage || undefined,
visa: sderCourtDecision.originalTextZoning?.visa || undefined,
is_public: sderCourtDecision.originalTextZoning?.is_public || undefined,
is_public_text:
sderCourtDecision.originalTextZoning?.is_public_text || undefined,
arret_id: sderCourtDecision.originalTextZoning?.arret_id,
};
}

return documentModule.lib.buildDocument({
creationDate: creationDate?.getTime(),
decisionMetadata: {
Expand All @@ -120,6 +204,7 @@ async function mapCourtDecisionToDocument(
occultationBlock: sderCourtDecision.blocOccultation || undefined,
session,
solution,
debatPublic: sderCourtDecision.debatPublic ?? undefined,
},
documentNumber: sderCourtDecision.sourceId,
externalId: idModule.lib.convertToString(sderCourtDecision._id),
Expand All @@ -131,6 +216,7 @@ async function mapCourtDecisionToDocument(
source,
title,
text: sderCourtDecision.originalText,
zoning: zoning,
});
}
function getNumberPrefix(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ async function getParameters() {
});

const parsedSettings = settingsModule.lib.parseFromJson(settings);
const enhancedSettings = settingsModule.lib.additionalAnnotationCategoryHandler.addCategoryToSettings(
parsedSettings,
const enhancedSettings = settingsModule.lib.motivationCategoryHandler.addCategoryToSettings(
settingsModule.lib.additionalAnnotationCategoryHandler.addCategoryToSettings(
parsedSettings,
),
);

return {
Expand Down
2 changes: 1 addition & 1 deletion packages/generic/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.21",
"mongodb": "^3.6.1",
"sder": "https://github.com/Cour-de-cassation/sder#8d2dc027782d040e67d1164cdacdb85800b396b2",
"sder": "https://github.com/Cour-de-cassation/sder#760b00baa45633387f4bc359fd220aff5147bd4f",
"sder-core": "https://github.com/Cour-de-cassation/sder-core#f19400e5832d88b48d076b99bbea3e4cfd6803f4"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { up, down } from '../migrations/29_617030daf3651cbef0d7bbe2';

/* eslint-disable @typescript-eslint/no-unsafe-assignment */
describe('add civil code matter in document model', () => {
const decisionMetadata = {
const decisionMetadata = documentModule.decisionMetadataGenerator.generate({
appealNumber: '',
chamberName: 'Civile',
civilMatterCode: '',
Expand All @@ -22,7 +22,7 @@ describe('add civil code matter in document model', () => {
solution: '',
NACCode: '',
endCaseCode: '',
} as any;
});
const documentsWithNewModel = [
documentModule.generator.generate({
decisionMetadata: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { up, down } from '../migrations/31_61ae1328673817451d5bfd0e';

/* eslint-disable @typescript-eslint/no-unsafe-assignment */
describe('add NACCode in document model', () => {
const decisionMetadata = {
const decisionMetadata = documentModule.decisionMetadataGenerator.generate({
appealNumber: '',
chamberName: 'Civile',
civilMatterCode: '',
Expand All @@ -21,7 +21,7 @@ describe('add NACCode in document model', () => {
session: '',
solution: '',
endCaseCode: '',
} as any;
});
const documentsWithNewModel = [
documentModule.generator.generate({
decisionMetadata: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { up, down } from '../migrations/34_61c2f20f5f28c12d9b54c762';

/* eslint-disable @typescript-eslint/no-unsafe-assignment */
describe('add endCaseCode in document model', () => {
const decisionMetadata = {
const decisionMetadata = documentModule.decisionMetadataGenerator.generate({
appealNumber: '',
chamberName: 'Civile',
civilMatterCode: '',
Expand All @@ -21,7 +21,7 @@ describe('add endCaseCode in document model', () => {
session: '',
solution: '',
NACCode: '',
} as any;
});
const documentsWithNewModel = [
documentModule.generator.generate({
decisionMetadata: {
Expand Down
72 changes: 72 additions & 0 deletions packages/generic/backend/src/lib/annotator/buildAnnotator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
idModule,
settingsType,
treatmentModule,
annotationModule,
} from '@label/core';
import { buildAnnotationReportRepository } from '../../modules/annotationReport';
import { documentService } from '../../modules/document';
Expand Down Expand Up @@ -212,6 +213,39 @@ function buildAnnotator(
msg: 'NLP treatment created in DB',
});

if (document.decisionMetadata.debatPublic === false) {
if (
document.zoning != undefined &&
document.zoning.zones?.motivations != undefined &&
document.zoning.zones.motivations.length > 0
) {
logger.log({
operationName: 'annotateDocument',
msg: 'Annotate motivation zone because decision debat are not public',
});

createMotivationOccultationTreatment(
documentId,
document.zoning.zones.motivations,
document.text,
document.documentNumber,
annotations,
);
} else {
logger.error({
operationName: 'annotateDocument',
msg: `Annotate zone for non public debat decision impossible because motication zone was not found for document ${formatDocumentInfos(
document,
)}`,
});
throw new Error(
`Annotate zone for non public debat decision impossible because motication zone was not found for document ${formatDocumentInfos(
document,
)}`,
);
}
}

//Todo : create report only if report is not null
await createReport(report);
logger.log({
Expand Down Expand Up @@ -311,6 +345,44 @@ function buildAnnotator(
);
}

async function createMotivationOccultationTreatment(
documentId: documentType['_id'],
motivations: { start: number; end: number }[],
documentText: string,
documentNumber: number,
previousAnnotations: annotationType[],
) {
const motivationAnnotations: annotationType[] = [];
motivations.forEach((motivation, index) => {
motivationAnnotations.push(
annotationModule.lib.buildAnnotation({
start: motivation.start + 1,
text: documentText.substring(
motivation.start + 1,
motivation.end - 1,
),
category: 'motivations',
certaintyScore: 1,
entityId: `motivations${index}_${documentNumber}`,
}),
);
});

const annotationWithoutOverlapping = annotationModule.lib.removeOverlappingAnnotations(
[...previousAnnotations, ...motivationAnnotations],
);

await treatmentService.createTreatment(
{
documentId,
previousAnnotations: previousAnnotations,
nextAnnotations: annotationWithoutOverlapping,
source: 'supplementaryAnnotations',
},
settings,
);
}

async function createReport(report: annotationReportType) {
const annotationReportRepository = buildAnnotationReportRepository();
await annotationReportRepository.insert(report);
Expand Down
1 change: 1 addition & 0 deletions packages/generic/backend/src/lib/exporter/buildExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ function buildExporter(
document.decisionMetadata.additionalTermsToAnnotate,
document.decisionMetadata.computedAdditionalTerms,
document.decisionMetadata.additionalTermsParsingFailed,
document.decisionMetadata.debatPublic,
);
const anonymizer = buildAnonymizer(settingsForDocument, annotations, seed);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('fetchAllJurisdictions', () => {
"cour d'appel de Bordeaux",
].map((jurisdiction) =>
documentModule.generator.generate({
decisionMetadata: {
decisionMetadata: documentModule.decisionMetadataGenerator.generate({
appealNumber: '',
additionalTermsToAnnotate: '',
boundDecisionDocumentNumbers: [],
Expand All @@ -30,7 +30,7 @@ describe('fetchAllJurisdictions', () => {
jurisdiction,
NACCode: '',
endCaseCode: '',
} as any,
}),
}),
);
await documentRepository.insertMany(documents);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ async function fetchAnonymizedDocumentText(documentId: documentType['_id']) {
document.decisionMetadata.additionalTermsToAnnotate,
document.decisionMetadata.computedAdditionalTerms,
document.decisionMetadata.additionalTermsParsingFailed,
document.decisionMetadata.debatPublic,
);
const seed = documentModule.lib.computeCaseNumber(document);
const anonymizer = buildAnonymizer(settingsForDocument, annotations, seed);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('fetchPublishableDocuments', () => {
{
status: 'done' as const,
publicationCategory: ['P'],
decisionMetadata: {
decisionMetadata: documentModule.decisionMetadataGenerator.generate({
additionalTermsToAnnotate: '',
appealNumber: '08-16.486',
boundDecisionDocumentNumbers: [],
Expand All @@ -29,7 +29,7 @@ describe('fetchPublishableDocuments', () => {
solution: '',
NACCode: '',
endCaseCode: '',
} as any,
}),
route: 'confirmation' as documentType['route'],
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ async function createTreatment(
document.decisionMetadata.additionalTermsToAnnotate,
document.decisionMetadata.computedAdditionalTerms,
document.decisionMetadata.additionalTermsParsingFailed,
document.decisionMetadata.debatPublic,
);

const treatment = treatmentModule.lib.build(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ async function updateTreatment({
document.decisionMetadata.additionalTermsToAnnotate,
document.decisionMetadata.computedAdditionalTerms,
document.decisionMetadata.additionalTermsParsingFailed,
document.decisionMetadata.debatPublic,
);

const actionToPerform = `update treatment for documentId ${idModule.lib.convertToString(
Expand Down
2 changes: 1 addition & 1 deletion packages/generic/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"axios": "^0.24.0",
"dateformat": "^5.0.3",
"http2": "^3.3.7",
"pelta-design-system": "https://github.com/Cour-de-cassation/pelta-design-system#f33fe593261a4873b165a34466ba75cc2ee67e1c",
"pelta-design-system": "https://github.com/Cour-de-cassation/pelta-design-system#e508f818ac443ad048e5cd1b74f42ec7f0bd046d",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ function DocumentInspector(props: { settings: settingsType }) {
document.decisionMetadata.additionalTermsToAnnotate,
document.decisionMetadata.computedAdditionalTerms,
document.decisionMetadata.additionalTermsParsingFailed,
document.decisionMetadata.debatPublic,
);

const applyAutoSave = buildApplyAutoSave(document._id);
Expand Down
Loading

0 comments on commit 180e7df

Please sign in to comment.