mirror of
https://github.com/siop-spelev/siop2.git
synced 2026-08-08 12:41:54 +00:00
feat(r5.1): socle apps/ai — ingestion anonymisée + recherche sémantique
ADR-004 : embeddings locaux sur CPU (fastembed ONNX, paraphrase-multilingual-MiniLM-L12-v2, 384 dims — les textes du client ne quittent jamais le serveur), pgvector dans le Postgres existant (RagChunk possédé par Prisma, migration r5_ia + état de corpus sur Document), génération opt-in (mode extractif par défaut : la recette passe sans clé API), service siop2-ai jamais exposé — joint par l'API NestJS seule (X-Service-Token). apps/ai (FastAPI + uv) : pipeline PDF MinIO → texte paginé (pypdf) → anonymisation D4 (e-mails, téléphones marocains, noms connus de la base, insensible casse/accents — fonction pure testée) → découpage avec chevauchement (testé) → embeddings → RagChunk localisé (« p. 42 », « bilan du 17/07 »). Bilans codés clôturés ingérés. Exclusion de corpus (D3) appliquée à l'ingestion ET à la lecture. 14 pytest + ruff, embeddeur déterministe en CI (aucun téléchargement), job CI ai (uv), deploy en dépend. Vérifié en réel avec le vrai modèle : corpus seedé réindexé en 7 s (PDF réel → 31 extraits paginés + 3 bilans), recherche sémantique concluante, e-mails → ⟨contact⟩, 0 identité dans les chunks (contrôle SQL). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -233,6 +233,7 @@ model WorkOrder {
|
||||
completedAt DateTime?
|
||||
cancelledAt DateTime?
|
||||
events WorkOrderEvent[]
|
||||
ragChunks RagChunk[]
|
||||
checklist ChecklistItem[]
|
||||
report InterventionReport?
|
||||
request Request?
|
||||
@@ -513,7 +514,36 @@ model Document {
|
||||
uploadedById String? @db.Uuid
|
||||
uploadedBy User? @relation(fields: [uploadedById], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
// R5 (D3) : le corpus est visible et réversible, document par document.
|
||||
inCorpus Boolean @default(true)
|
||||
indexedAt DateTime? // null = jamais indexé
|
||||
chunkCount Int @default(0)
|
||||
chunks RagChunk[]
|
||||
|
||||
@@index([assetId])
|
||||
@@index([workOrderId])
|
||||
}
|
||||
|
||||
/// R5 — extraits indexés du corpus (ADR-004) : bibliothèque + bilans codés,
|
||||
/// ANONYMISÉS À L'INGESTION (D4). Écrit par apps/ai, schéma possédé par Prisma.
|
||||
model RagChunk {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
sourceType RagSourceType
|
||||
documentId String? @db.Uuid
|
||||
document Document? @relation(fields: [documentId], references: [id], onDelete: Cascade)
|
||||
workOrderId String? @db.Uuid
|
||||
workOrder WorkOrder? @relation(fields: [workOrderId], references: [id], onDelete: Cascade)
|
||||
/// Repère humain de la source : « p. 42 », « bilan du 17/07/2026 »…
|
||||
locator String
|
||||
content String
|
||||
embedding Unsupported("vector(384)")
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([documentId])
|
||||
@@index([workOrderId])
|
||||
}
|
||||
|
||||
enum RagSourceType {
|
||||
DOCUMENT
|
||||
WORK_ORDER
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user