# WT1 — Infra upload générique `Shared` (ticket 1.2 / ERP-154) > Créer le worktree puis lancer Claude dedans : > ```bash > git fetch origin > git worktree add ../sb-erp154-upload -b feat/erp-154-upload origin/develop > cd ../sb-erp154-upload && claude > ``` > **Base** : `origin/develop` (aucune dépendance — peut démarrer tout de suite, même avant le merge du socle Transport). --- ## Prompt à coller Tu travailles sur le projet Starseed (modular monolith DDD, Symfony 8 / API Platform 4). Lis `CLAUDE.md` et `.claude/rules/backend.md` avant de coder. Charge le skill `backend-entity-conventions`. **Mission** : poser une infra d'upload de fichiers **générique et réutilisable** dans `src/Shared/` (la « Décharge » du M4 en sera le 1er consommateur, mais ce ticket ne touche PAS au module Transport). **Spec** : `docs/specs/M4-transporteurs/spec-back.md § 2.7`. **À livrer** : 1. Table `uploaded_document` (migration namespace racine `DoctrineMigrations` dans `migrations/`, postérieure à la dernière présente — vérifie `ls migrations/`). Colonnes : `id`, `original_filename`, `stored_path`, `mime_type`, `size_bytes`, `checksum`, `created_at`, `created_by`. 2. Service `Shared\Infrastructure\Upload\FileUploader` : - validation MIME **server-side via `$file->getMimeType()`** (JAMAIS `getClientMimeType()`), - whitelist MIME explicite (PDF + images), - bornage taille, checksum sha256, écriture disque `var/uploads/{yyyy}/{mm}/`. 3. Endpoint `POST /api/uploaded_documents` (multipart) → renvoie l'IRI. MIME hors whitelist → **422**. **Gardes-fous (cassent `make test` sinon)** : - **`COMMENT ON COLUMN` sur TOUTES les colonnes** de `uploaded_document` (FR, ≤200 car., règle n°12) ET ajoute le bloc `'uploaded_document' => [...]` dans `src/Shared/Infrastructure/Database/ColumnCommentsCatalog.php` — sinon `make test-db-setup` drope les COMMENT et `ColumnsHaveSqlCommentTest` casse. - Pagination : si tu exposes une `GetCollection`, elle reste paginée (`CollectionsArePaginatedTest`). **Scope STRICT** : uniquement `src/Shared/` + migration + catalog. Ne crée AUCUN fichier sous `src/Module/Transport/`. Pas d'antivirus/S3/purge (hors périmètre, § 9). **Tests à écrire** (PHPUnit) : MIME hors whitelist → 422 ; MIME valide → IRI + ligne persistée + checksum calculé. **Fini quand** : `make test` vert + `make php-cs-fixer-allow-risky` propre. Commit (`--no-verify` OK si `make test` déjà vert), puis **ouvre la PR** : ```bash git push -u origin feat/erp-154-upload tea pr create --base develop --head feat/erp-154-upload \ --title "feat(shared) : infra upload générique (ERP-154)" \ --description "Table uploaded_document + FileUploader + endpoint POST. Ticket ERP-154." ``` Puis labellise la PR via l'API Gitea (tea ne pose pas les labels en CLI). Cible **develop**. Aucune mention IA.