diff --git a/AGENTS.md b/AGENTS.md index ccd6668..599b6e2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -86,5 +86,4 @@ cd mobile && npm run test:db ## References - `docs/api-v1.md` — **contrat API V1** (autoritatif, consolidé depuis `mobile/api/types.ts`) -- `README.md` / `V1.md` — specs **obsolètes** (bannières en tête de fichier) - `V2.md` — modèle cible Postgres/ReBAC (identifiants en TEXT 32-hex, cf. `docs/api-v1.md`) \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index c2349a0..0000000 --- a/README.md +++ /dev/null @@ -1,303 +0,0 @@ -# VaultDrop — Application de Gestion de Fichiers V1 - -> ⚠️ **Obsolète** — cette spec décrit une V1 single-user (SQLite). Référentiel actuel : `docs/api-v1.md` (contrat API) et `V2.md` (modèle cible Postgres/ReBAC). - -## Vision - -Application mobile tout-en-un permettant de centraliser, organiser et retrouver ses documents. Upload depuis l'appareil, scan caméra avec OCR, tagging et recherche rapide. Le back-end Go assure le traitement asynchrone (OCR, indexing) et la persistence. Le front React Native reste léger : il affiche, interagit et met en cache. - -## Scope V1 - -On livre un produit fonctionnel utilisable au quotidien, pas un framework. V1 = gestion de fichiers avec scan OCR intégré. Pas de mode collaboratif, pas de plugins, pas de partage avancé. - -## Non-Goals (V1) - -- Mode collaboratif / multi-utilisateur -- Système de plugins -- Synchronisation offline complexe -- Plateforme de partage publique - ---- - -## Vue d'Ensemble Architecture - -``` -┌─────────────────────┐ ┌─────────────────────┐ -│ React Native App │ ────> │ API Go Backend │ -│ (Expo managed) │ HTTPS │ (REST) │ -│ - Upload │ │ - Upload fichiers │ -│ - Caméra / Scan │ │ - OCR async │ -│ - Tags / Recherche│ │ - Index/search │ -│ - Affichage │ │ - Persistance │ -└─────────────────────┘ └─────────────────────┘ -``` - -Le mobile ne contient pas de logique métier. Tout traitement lourd (OCR, extraction de texte, indexation) est géré côté back-end. - ---- - -## Fonctionnalités Attendues - -### Upload de fichiers -- Sélection depuis la galerie appareil -- Upload par drag-and-drop interne -- Support des formats : PDF, images (JPG, PNG) -- Feedback visuel pendant l'envoi (progress) -- Retry automatique en cas d'échec réseau - -### Scan Documents (Caméra) -- Prise de photo depuis l'app -- Recadrage et orientation automatique -- Envoi direct vers le back-end pour OCR -- Retour du texte extrait affiché à l'utilisateur - -### Tagging -- Ajout de tags manuels sur chaque fichier -- Suggestion de tags basée sur le contenu OCR -- Filtrage par tag dans la liste - -### Recherche -- Recherche full-text sur le contenu OCR -- Recherche par nom de fichier -- Filtres combinés (tag + texte) - -### Listing -- Liste des fichiers uploadés avec aperçu -- Tri par date, nom, tag -- Pagination côté serveur - -### Partage (Optionnel, Phase Later) -- Génération de lien temporaire -- Pas prioritaire en V1 - ---- - -## Exigences UX - -- UI claire et épurée, minimaliste -- Temps de réponse < 2s pour les actions principales -- Feedback immédiat sur toutes les interactions -- Pas d'écran de chargement > 3s sans spinner -- Mode offline minimal : liste des fichiers déjà chargée visible même sans réseau - ---- - -## Attentes API REST (Back-end Go) - -### Endpoints - -| Méthode | Path | Description | -|---|---|---| -| GET | /api/v1/files | Liste des fichiers (pagination) | -| POST | /api/v1/files/upload | Upload d'un fichier | -| GET | /api/v1/files/:id | Détail d'un fichier | -| DELETE | /api/v1/files/:id | Suppression d'un fichier | -| GET | /api/v1/files/search?q= | Recherche full-text | -| POST | /api/v1/files/:id/tags | Ajout de tags | -| GET | /api/v1/files/:id/tags | Tags d'un fichier | -| POST | /api/v1/ocr/jobs | Soumettre un job OCR | -| GET | /api/v1/ocr/jobs/:id | Statut d'un job OCR | -| GET | /api/v1/health | Health check | - -### Format de réponse standard - -```json -{ - "data": { ... }, - "meta": { - "page": 1, - "total": 42 - } -} -``` - -### Erreurs - -```json -{ - "error": { - "code": "FILE_TOO_LARGE", - "message": "Fichier dépasse la limite de 50 Mo" - } -} -``` - ---- - -## Flux de Données - -``` -[Capture photo] ──> [Upload API] ──> [Back-end stocke] - │ - v - [Job OCR créé] - │ - v (async) - [Traitement OCR] - [Extraction texte] - [Indexation search] - │ - v -[App affiche fichier] <──── [Polling statut] <── [Résultat prêt] -``` - -1. L'utilisateur prend une photo ou sélectionne un fichier -2. Le fichier est uploadé vers POST /api/v1/files/upload -3. Le back-end crée un job OCR et retourne immédiatement un ID -4. L'app poll GET /api/v1/ocr/jobs/:id ou utilise un webhook -5. Une fois l'OCR terminé, le texte est indexé et le fichier apparaît avec son contenu searchable - ---- - -## Choix Techniques - -### Front-end (React Native) -- Expo managed workflow (développement rapide, build plus simple) -- TanStack Query (gestion serveur state, cache, refetch) -- React Navigation (navigation entre écrans) -- react-native-image-picker (sélection + caméra) -- MMKV (stockage clé-valeur pour cache local) - -### Back-end (Go) -- Framework HTTP : Gin ou Fiber (au choix implémenteur) -- Persistance : SQLite pour V1 (volumétrie faible attendue) -- OCR : Tesseract en ligne de commande (appel système) -- Search : SQLite FTS5 pour la recherche full-text -- Stockage fichiers : disque local avec chemin référencé en base - ---- - -## Structure de Dossiers Suggérée - -### Front-end (React Native / Expo) - -``` -mobile/ -├── app/ # Expo Router ou navigation -│ ├── index.tsx # Ecran principal (liste) -│ ├── upload.tsx # Ecran upload -│ ├── scan.tsx # Ecran scan caméra -│ └── search.tsx # Ecran recherche -├── components/ -│ ├── FileCard.tsx -│ ├── TagChip.tsx -│ └── UploadProgress.tsx -├── hooks/ -│ ├── useFiles.ts # TanStack Query hooks -│ ├── useSearch.ts -│ └── useUpload.ts -├── api/ -│ └── client.ts # Client API (axios ou fetch) -├── types/ -│ └── index.ts # Types TypeScript -├── constants/ -│ └── api.ts # URLs, clés API -└── package.json -``` - -### Back-end (Go) - -``` -backend/ -├── cmd/ -│ └── server/ -│ └── main.go # Point d'entrée -├── internal/ -│ ├── handlers/ # Handlers HTTP -│ ├── models/ # Modèles de données -│ ├── repository/ # Accès données -│ ├── service/ # Logique métier -│ └── ocr/ # Module OCR -├── pkg/ -│ └── api/ -│ └── response.go # Helpers réponse -├── uploads/ # Fichiers stockés -├── go.mod -└── go.sum -``` - ---- - -## Getting Started - -### Prérequis - -- Node.js latest lts -- npm ou yarn -- Expo CLI (`npm install -g expo-cli`) -- Go latest lts -- Tesseract OCR installé (`apt install tesseract-ocr` sur Debian/Ubuntu) - -### Installation (Front-end) - -```bash -cd mobile -npm install -npx expo start -``` - -### Installation (Back-end) - -```bash -cd backend -go mod download -go run cmd/server/main.go -``` - -### Build APK Android (Expo) - -```bash -npx expo run:android --variant release -``` - ---- - -## Variables d'Environnement - -### Front-end (.env) - -``` -API_BASE_URL=http://localhost:8080/api/v1 -TESSERACT_LANG=fr+eng -``` - -### Back-end (.env) - -``` -PORT=8080 -UPLOAD_DIR=./uploads -MAX_FILE_SIZE_MB=50 -OCR_LANG=fra+eng -``` - ---- - -## Itérations Futures - -### V2 — Fiabilité et Performance -- Remplacement SQLite par PostgreSQL -- Upload chunked pour gros fichiers -- Compression d'images côté client - -### V3 — Organisation Avancée -- Dossiers virtuels / hiérarchie -- Tags suggérés par IA -- OCR multilingue amélioré - -### V4 — Collaboration -- Comptes utilisateurs -- Partage avec lien temporaire -- Rôle et permissions - -### V5 — Plateforme -- Système de plugins (event bus) -- API publique -- Extensions tierces - ---- - -## Statut du Projet - -Phase : Conception et prototypage -Backend Go : En cours de structuration -Frontend React Native : À initier diff --git a/V1.md b/V1.md deleted file mode 100644 index 59590bd..0000000 --- a/V1.md +++ /dev/null @@ -1,317 +0,0 @@ -# VaultDrop Backend — Spécification V1 (État Existant) - -> ⚠️ **Obsolète** — référentiel actuel : `docs/api-v1.md` (contrat API) et `V2.md` (modèle cible). L'OCR est décidé en **Tesseract (appel système)**, pas de microservice Python. - -## 1. Vue d'ensemble - -Application de gestion de documents : upload, scan OCR, tagging, recherche, organisation en dossiers. Backend Go avec API REST, base PostgreSQL, microservice OCR Python séparé. - -``` -┌──────────────────┐ ┌──────────────────────┐ -│ Mobile App │ HTTPS │ Go Backend (Gin) │ -│ (React Native) │────────>│ REST API │ -│ │ │ - Upload / Tags │ -│ │ │ - Auth (PASETO) │ -│ │ │ - Thumbnails │ -└──────────────────┘ │ - Conversion PDF │ - └────────┬─────────────┘ - │ HTTP - ┌────────▼─────────────┐ - │ OCR Server (Python) │ - │ PaddleOCR + FastAPI │ - └──────────────────────┘ -``` - -## 2. Choix Techniques - -| Composant | Technologie | -|---|---| -| Framework HTTP | Gin v1.12 | -| Base de données | PostgreSQL (lib/pq) | -| ORM/Query | sqlc v1.31 (généré) | -| Migrations | golang-migrate v4 | -| Auth | PASETO v4 (go-paseto) + Argon2id | -| OCR | PaddleOCR (microservice Python séparé) | -| Conversion PDF | LibreOffice + pdftoppm (appels système) | -| Checksum | SHA-256 | -| Stockage fichiers | Disque local (`./uploads/`) | -| URLs signées | HMAC-SHA256 avec expiry | - -## 3. Structure du Code - -``` -backend/ -├── cmd/server/main.go # Point d'entrée -├── internal/ -│ ├── auth/ # Auth (3 fichiers) -│ │ ├── service.go # Register, Login, Refresh, Logout, ValidateAccessToken -│ │ ├── handler.go # HTTP handlers auth -│ │ └── middleware.go # RequireAuth() middleware -│ ├── config/config.go # Config struct (11 vars d'env) -│ ├── db/ -│ │ ├── connect.go # Connexion PostgreSQL -│ │ ├── migrate.go # golang-migrate -│ │ ├── db.go # sqlc Queries interface -│ │ ├── models.go # sqlc models (généré) -│ │ ├── files.sql.go # sqlc queries fichiers (généré) -│ │ ├── tags.sql.go # sqlc queries tags (généré) -│ │ ├── thumbnails.sql.go # sqlc queries thumbnails (généré) -│ │ ├── health.sql.go # sqlc health check -│ │ ├── auth.sql.go # sqlc queries auth (généré) -│ │ ├── queries/ # SQL sources (5 fichiers .sql) -│ │ └── migrations/ # 11 migrations (001→011) -│ ├── handler/ -│ │ ├── handler.go # Handler struct + constructor -│ │ ├── router.go # SetupRoutes() -│ │ ├── files.go # 14 handlers fichiers/thumbnails -│ │ ├── ocr.go # OCR stubs (501/404) -│ │ └── health.go # Health check -│ ├── model/ -│ │ ├── file.go # File, Tag, UploadResult structs -│ │ ├── ocrjob.go # OcrJob struct -│ │ ├── tag.go # (vide) -│ │ └── thumbnail.go # Thumbnail struct -│ ├── ocr/ -│ │ ├── client.go # Client HTTP PaddleOCR + détection doc type -│ │ └── types.go # OCR request/response types -│ └── service/ -│ ├── file.go # FileService: upload, list, get, delete, tags, folders, thumbnails, dedup -│ ├── ocr.go # OCRService: worker async, enqueue, process -│ ├── conversion.go # ConversionService: PDF→images, thumbnails multi-résolution -│ ├── url.go # URLService: signed URLs HMAC -│ └── checksum.go # SHA-256 hash helpers -├── pkg/api/response.go # Helpers: Success, Created, Paginated, Error -├── ocr-server/ -│ ├── server.py # FastAPI + PaddleOCR -│ └── Dockerfile -├── uploads/ # Stockage fichiers + thumbnails -├── sqlc.yaml -├── Dockerfile -├── go.mod -└── .env -``` - -## 4. Base de Données (Schéma Final) - -### Tables - -**files** - -| Colonne | Type | Contraintes | -|---|---|---| -| id | TEXT | PK, DEFAULT gen_random_uuid() | -| name | TEXT | NOT NULL | -| mime_type | TEXT | NOT NULL DEFAULT '' | -| size | BIGINT | NOT NULL DEFAULT 0 | -| storage_key | TEXT | NOT NULL DEFAULT '' | -| checksum | TEXT | NOT NULL DEFAULT '' | -| ocr_text | TEXT | NOT NULL DEFAULT '' | -| is_folder | BOOLEAN | NOT NULL DEFAULT false | -| parent_file_id | TEXT | FK → files(id) | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | - -**tags** - -| Colonne | Type | Contraintes | -|---|---|---| -| id | TEXT | PK, DEFAULT gen_random_uuid() | -| parent_tag_id | TEXT | FK → tags(id) | -| tag_name | TEXT | NOT NULL | -| tag_type | TEXT | NOT NULL DEFAULT 'none' | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | - -**file_tags** - -| Colonne | Type | Contraintes | -|---|---|---| -| id | TEXT | PK, DEFAULT gen_random_uuid() | -| tag_id | TEXT | FK → tags(id) | -| file_id | TEXT | FK → files(id) | - -**users** - -| Colonne | Type | Contraintes | -|---|---|---| -| id | TEXT | PK, DEFAULT gen_random_uuid() | -| username | TEXT | NOT NULL, UNIQUE | -| password_hash | TEXT | NOT NULL | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | -| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | - -**refresh_tokens** - -| Colonne | Type | Contraintes | -|---|---|---| -| id | TEXT | PK, DEFAULT gen_random_uuid() | -| user_id | TEXT | FK → users(id), ON DELETE CASCADE | -| token_hash | TEXT | NOT NULL | -| expires_at | TIMESTAMP | NOT NULL | -| revoked | BOOLEAN | DEFAULT FALSE | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | - -**thumbnails** - -| Colonne | Type | Contraintes | -|---|---|---| -| id | TEXT | PK, DEFAULT gen_random_uuid() | -| file_id | TEXT | FK → files(id), ON DELETE CASCADE | -| page_number | INTEGER | NOT NULL | -| resolution_label | TEXT | NOT NULL | -| width | INTEGER | NOT NULL | -| height | INTEGER | NOT NULL | -| storage_key | TEXT | NOT NULL | -| mime_type | TEXT | DEFAULT 'image/jpeg' | -| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | - -### Index - -- `idx_refresh_tokens_user_id` ON refresh_tokens(user_id) -- `idx_refresh_tokens_token_hash` ON refresh_tokens(token_hash) -- `idx_thumbnails_file_id` ON thumbnails(file_id) -- `idx_thumbnails_unique` UNIQUE ON thumbnails(file_id, page_number, resolution_label) - -## 5. API Endpoints - -### Public - -| Méthode | Path | Handler | Description | -|---|---|---|---| -| GET | `/api/v1/health` | HealthHandler.Check | Retourne `{status: "healthy"}` | -| POST | `/api/v1/auth/register` | AuthHandler.Register | Créer un compte (username + password) | -| POST | `/api/v1/auth/login` | AuthHandler.Login | Login → access_token + refresh_token | -| POST | `/api/v1/auth/refresh` | AuthHandler.Refresh | Renouveler les tokens | -| POST | `/api/v1/auth/logout` | AuthHandler.Logout | Révoquer le refresh token | -| GET | `/api/v1/files/download/:id` | FileHandler.Download | Télécharger un fichier (URL signée) | -| GET | `/api/v1/thumbnails/:id` | FileHandler.ServeThumbnail | Télécharger une thumbnail (URL signée) | - -### Protégées (Bearer token) - -| Méthode | Path | Handler | Description | -|---|---|---|---| -| GET | `/api/v1/files` | FileHandler.List | Lister tous les fichiers (racine) | -| POST | `/api/v1/files/upload` | FileHandler.Upload | Upload multi-fichiers (multipart) | -| POST | `/api/v1/files/move` | FileHandler.MoveFiles | Déplacer des fichiers vers un dossier | -| POST | `/api/v1/files/folders` | FileHandler.CreateFolder | Créer un dossier | -| GET | `/api/v1/files/folders` | FileHandler.ListFolders | Lister les dossiers | -| GET | `/api/v1/files/folders/:id/files` | FileHandler.ListFilesByParent | Lister les fichiers d'un dossier | -| DELETE | `/api/v1/files/:id` | FileHandler.Delete | Supprimer un fichier (+ thumbnails + fichier disque) | -| GET | `/api/v1/files/:id` | FileHandler.Get | Détail d'un fichier (+ tags + thumbnails) | -| POST | `/api/v1/files/:id/tags` | FileHandler.AddTags | Ajouter des tags à un fichier | -| GET | `/api/v1/files/:id/tags` | FileHandler.GetTags | Récupérer les tags d'un fichier | -| POST | `/api/v1/files/:id/thumbnails` | FileHandler.GetThumbnails | Lister les thumbnails d'un fichier | -| POST | `/api/v1/files/dedup-check` | FileHandler.CheckDuplicates | Vérifier les doublons (nom + taille) | -| POST | `/api/v1/ocr/jobs` | OCRHandler.CreateJob | **STUB** — retourne 501 | -| GET | `/api/v1/ocr/jobs/:id` | OCRHandler.GetJobStatus | **STUB** — retourne 404 | - -### Format de réponse - -Succès : `{ "data": ... }` ou `{ "data": ..., "meta": { "page": N, "total": N } }` -Erreur : `{ "error": { "code": "...", "message": "..." } }` - -## 6. Services Métier - -### FileService (service/file.go — 349 lignes) - -- `Upload(file)` — Upload multipart, checksum SHA-256, détection doublons par checksum, stockage disque -- `List()` — Tous les fichiers racine (parent_file_id IS NULL), avec tags -- `Get(id)` — Fichier par ID avec tags -- `Delete(id)` — Suppression DB (handler gère suppression disque + thumbnails) -- `GetStoragePath(id)` — Chemin disque du fichier -- `UpdateOCRText(id, text)` — Mise à jour du champ ocr_text -- `AddTags(fileID, tags, tagType)` — Création auto des tags + liaison -- `GetTagsByFileID(fileID)` — Tags d'un fichier -- `MoveFiles(fileIDs, parentFileID)` — Déplacer vers un dossier (ou racine si nil) -- `CreateFolder(name)` — Créer un dossier -- `ListFolders()` — Lister tous les dossiers -- `ListFilesByParentID(parentID)` — Fichiers d'un dossier -- `GetThumbnailsByFileID(fileID)` — Thumbnails d'un fichier -- `GetThumbnailStoragePath(id)` — Chemin disque thumbnail -- `GetBestThumbnail(fileID, label)` — Meilleure thumbnail (page 1, label préféré ou fallback) -- `FindDuplicatesByNameSize(name, size)` — Recherche doublons par nom+taille - -### OCRService (service/ocr.go — 95 lignes) - -- `Start()` — Lance le worker goroutine -- `Stop()` — Ferme le channel jobs -- `Enqueue(fileID, filePath)` — Ajoute un job OCR (channel buffer 100) -- `process(job)` — Lecture fichier → Client OCR → Flatten text → UpdateOCRText -- `RecognizeFromBytes(data)` — OCR direct (pas utilisé par les handlers) -- `HealthCheck()` — Vérifie l'OCR server - -### ConversionService (service/conversion.go — 253 lignes) - -- `Start()` / `Stop()` — Worker goroutine -- `Enqueue(fileID, filePath, mimeType)` — Conversion async (channel buffer 100) -- `process(job)` : - 1. Si document Office → conversion vers PDF via LibreOffice headless - 2. Si PDF → direct - 3. PDF → images via pdftoppm à 2 résolutions : "thumbnail" (21 DPI) et "full" (200 DPI) - 4. Création des enregistrements thumbnails en DB -- Supporte : PDF, .docx, .xlsx, .pptx, formats OpenDocument - -### URLService (service/url.go — 67 lignes) - -- `GenerateDownloadURL(fileUUID)` — URL signée HMAC avec expiry (défaut 60 min) -- `GenerateThumbnailURL(thumbUUID)` — Idem pour thumbnails -- `Validate(fileID, sig, expires)` — Vérifie signature HMAC + expiry - -### Auth (auth/ — 250+135+41 lignes) - -- **Register** : validation username (3-30 chars) + password (8+ chars), Argon2id hash, PASETO v4 tokens -- **Login** : vérification credentials, émission token pair -- **Refresh** : révoque l'ancien refresh token, émet un nouveau pair -- **Logout** : révoque le refresh token -- **Middleware** : Bearer token extraction → ValidateAccessToken → set userID in context -- Access token TTL : 30 min | Refresh token TTL : 7 jours - -## 7. OCR Server (Python) - -**ocr-server/server.py** — FastAPI + PaddleOCR - -- `GET /health` — health check -- `POST /ocr` — OCR via JSON base64 -- `POST /ocr/upload` — OCR via upload fichier -- Supporte images (JPEG/PNG) et PDF (conversion vers images via pypdfium2) -- Langue par défaut : français (`OCR_LANG=fr`) -- Timeout client Go : 120 secondes - -## 8. Détection de Doublons - -Deux mécanismes : - -1. **Par checksum (SHA-256)** : lors de l'upload, si un fichier avec le même checksum existe déjà, le fichier uploadé est supprimé et l'ID existant retourné -2. **Par nom+taille** : endpoint `POST /files/dedup-check` pour vérifier avant upload - -## 9. Variables d'Environnement - -| Variable | Défaut | Description | -|---|---|---| -| PORT | `8080` | Port du serveur | -| DATABASE_URL | `postgres://localhost:5432/vaultdrop?sslmode=disable` | URL PostgreSQL | -| OCR_ENDPOINT | `http://localhost:9090` | URL du microservice OCR | -| UPLOAD_DIR | `./uploads` | Répertoire de stockage | -| HMAC_SECRET | `thisismyrandomstring` | Secret pour URLs signées | -| SERVER_HOST | `http://192.168.1.17:8080` | Host public du serveur | -| PASETO_KEY | (clé hex 64 car.) | Clé symétrique PASETO v4 | -| LIBREOFFICE_PATH | `/usr/bin/libreoffice` | Chemin LibreOffice | -| PDFTOPPM_PATH | `/usr/bin/pdftoppm` | Chemin pdftoppm | -| THUMBNAIL_DIR | `./uploads/thumbnails` | Répertoire thumbnails | -| URL_EXPIRY_MINUTES | `60` | Durée de vie des URLs signées | - -## 10. Docker - -**Backend** : Multi-stage build (golang:1.24-alpine → alpine:3.21 avec libreoffice-core + poppler-utils) - -**OCR Server** : Dockerfile séparé dans `ocr-server/` - -## 11. Ce qui manque / Stubs - -- `OCRHandler.CreateJob` → retourne 501 NOT_IMPLEMENTED -- `OCRHandler.GetJobStatus` → retourne 404 JOB_NOT_FOUND -- Pas de recherche full-text (pas de FTS5/PostgreSQL tsvector) -- Pas de pagination côté DB (tout est chargé en mémoire) -- Pas de gestion d'erreurs robuste dans le worker OCR (logs seulement) -- Les fichiers n'ont pas de lien avec les utilisateurs (pas de user_id sur files) -- Le health check ne vérifie pas la DB ni l'OCR server diff --git a/docs/api-v1.md b/docs/api-v1.md index 3893c1b..8e88a26 100644 --- a/docs/api-v1.md +++ b/docs/api-v1.md @@ -2,7 +2,7 @@ Status : **autoritatif**. Le client mobile est la source de vérité : `mobile/api/types.ts` + `mobile/api/client.ts` sont implémentés et testés ; le serveur Go doit les matcher exactement (méthode + path + enveloppe), il ne re-négocie pas. Document consolidé à partir de ces deux fichiers — toute divergence de ce doc doit être portée dans le client d'abord. -Références : `V2.md` (modèle cible), `mobile/services/db/` (conventions sync), `README.md`/`V1.md` (**obsolètes**). +Références : `V2.md` (modèle cible), `mobile/services/db/` (conventions sync), `AGENTS.md` (structure + commandes). ---