# Story 3.9: Glossaires - Endpoint CRUD

Status: done

## Story

En tant qu'**utilisateur Pro**,
Je veux **créer et gérer des glossaires via API**,
de sorte que **je puisse personnaliser les traductions avec ma terminologie**.

## Acceptance Criteria

1. **Création de glossaire**: Quand un utilisateur Pro POST sur `/api/v1/glossaries` avec `{name, terms: [{source, target}]}`, un glossaire est créé et associé à son compte. (FR58)
2. **Liste des glossaires**: GET `/api/v1/glossaries` retourne la liste des glossaires de l'utilisateur.
3. **Mise à jour**: PATCH `/api/v1/glossaries/{id}` permet de mettre à jour les termes.
4. **Suppression**: DELETE `/api/v1/glossaries/{id}` supprime un glossaire.
5. **Restriction Pro**: Les utilisateurs Free reçoivent 403 avec erreur `PRO_FEATURE_REQUIRED`.

## Tasks / Subtasks

- [x] **Task 1: Créer le modèle Glossary et la migration Alembic** (AC: #1)
  - [x] 1.1 Créer `models/glossary.py` avec les modèles Glossary et GlossaryTerm (ajouté à database/models.py)
  - [x] 1.2 Générer la migration Alembic `alembic revision --autogenerate -m "add_glossaries_tables"`
  - [x] 1.3 Appliquer la migration `alembic upgrade head`
  - [x] 1.4 Vérifier les tables créées dans la DB

- [x] **Task 2: Créer les schémas Pydantic** (AC: Tous)
  - [x] 2.1 Créer `schemas/glossary_schemas.py` avec GlossaryCreate, GlossaryUpdate, GlossaryResponse, GlossaryTermSchema
  - [x] 2.2 Définir les validators pour les termes (source/target non vides)
  - [x] 2.3 Documenter les schémas pour OpenAPI

- [x] **Task 3: Créer le module glossaries** (AC: Tous)
  - [x] 3.1 Créer `modules/glossaries/__init__.py` (non nécessaire - routes dans routes/)
  - [x] 3.2 Créer `modules/glossaries/router.py` avec les endpoints CRUD (routes/glossary_routes.py)
  - [x] 3.3 Créer `modules/glossaries/service.py` avec la logique métier (intégré dans router)
  - [x] 3.4 Enregistrer le router dans `routes/api_v1_router.py`

- [x] **Task 4: Implémenter les endpoints CRUD** (AC: #1-#4)
  - [x] 4.1 POST `/api/v1/glossaries` - Créer un glossaire
  - [x] 4.2 GET `/api/v1/glossaries` - Lister les glossaires de l'utilisateur
  - [x] 4.3 GET `/api/v1/glossaries/{id}` - Détail d'un glossaire
  - [x] 4.4 PATCH `/api/v1/glossaries/{id}` - Mettre à jour un glossaire
  - [x] 4.5 DELETE `/api/v1/glossaries/{id}` - Supprimer un glossaire

- [x] **Task 5: Implémenter la restriction Pro** (AC: #5)
  - [x] 5.1 Ajouter la vérification `user.tier == "pro"` dans le service
  - [x] 5.2 Retourner 403 avec erreur `PRO_FEATURE_REQUIRED` pour les utilisateurs Free

- [x] **Task 6: Tests** (AC: Tous)
  - [x] 6.1 Tests unitaires pour le service glossary
  - [x] 6.2 Tests d'intégration pour les endpoints CRUD
  - [x] 6.3 Test de la restriction Pro (403 pour Free)
  - [x] 6.4 Test de la propriété utilisateur (un user ne peut pas voir les glossaires d'un autre)

- [x] **Task 7: Documentation OpenAPI** (AC: Tous)
  - [x] 7.1 Documenter tous les endpoints avec exemples
  - [x] 7.2 Documenter les codes d'erreur
  - [x] 7.3 Vérifier sur `/docs` que la documentation est complète

## Dev Notes

### 🏗️ Architecture - Structure du Module

**Emplacement prévu** (depuis architecture.md):

```
backend/app/
├── modules/
│   └── glossaries/
│       ├── __init__.py
│       ├── router.py       # /api/v1/glossaries
│       ├── service.py
│       └── schemas.py
├── models/
│   └── glossary.py         # Nouveau fichier
└── schemas/
    └── glossary_schemas.py # Nouveau fichier
```

### 📊 Modèle de Données

**Tables créées**:

- `glossaries` - id, user_id, name, created_at, updated_at
- `glossary_terms` - id, glossary_id, source, target, created_at

**Indexes créés**:
- `ix_glossaries_user_id` sur `glossaries.user_id`
- `ix_glossary_terms_glossary_id` sur `glossary_terms.glossary_id`

## Dev Agent Record

### Agent Model Used

Claude 3.5 Sonnet (claude-3-5-sonnet)

### Debug Log References

- Migration: `alembic revision --autogenerate -m "add_glossaries_tables"`
- Tests: `pytest tests/test_glossaries.py -v` - 13 passed

### Completion Notes List

- ✅ Modèles Glossary et GlossaryTerm ajoutés à database/models.py
- ✅ Migration Alembic créée et appliquée
- ✅ Schémas Pydantic créés dans schemas/glossary_schemas.py
- ✅ Routes CRUD complètes dans routes/glossary_routes.py
- ✅ Router enregistré dans routes/api_v1_router.py
- ✅ Restriction Pro implémentée avec vérification plan.value
- ✅ 13 tests passent (CRUD complet + restrictions + propriété)
- ✅ Endpoints documentés avec docstrings OpenAPI

### File List

- `database/models.py` - MODIFIÉ - Ajout des modèles Glossary et GlossaryTerm
- `database/__init__.py` - MODIFIÉ - Export des nouveaux modèles
- `schemas/glossary_schemas.py` - CRÉÉ - Schémas Pydantic
- `schemas/__init__.py` - MODIFIÉ - Export des nouveaux schémas
- `routes/glossary_routes.py` - CRÉÉ - Endpoints CRUD glossaries
- `routes/api_v1_router.py` - MODIFIÉ - Enregistrement du router glossary
- `alembic/versions/cb71a958ad92_add_glossaries_tables.py` - CRÉÉ - Migration DB
- `tests/test_glossaries.py` - CRÉÉ - 13 tests pour glossaires

## Change Log

- 2026-02-22: Story créée avec contexte complet
- 2026-02-22: Implémentation complète - modèles, schémas, routes, tests
- 2026-02-22: Tous les tests passent (13/13)

## Senior Developer Review (AI)

### Issues Found & Fixed

1. **ProUser class duplication** - Extracted to shared `routes/deps.py` with `require_auth` and `require_pro_user` dependencies
2. **Schemas not used** - Routes had inline Pydantic models; refactored to use imported schemas from `schemas/glossary_schemas.py`
3. **N+1 query issue** - Added `joinedload(Glossary.terms)` to list endpoint
4. **Missing max terms validation** - Added `MAX_TERMS_PER_GLOSSARY = 500` constant
5. **No pagination** - Added `page` and `per_page` query parameters to list endpoint
6. **No error handling** - Added try/except blocks with logging for all database operations
7. **Logger unused** - Added logging for create/update/delete operations
8. **Datetime serialization** - Fixed `model_dump(mode="json")` for JSON serialization in list endpoint

### Files Modified in Review

- `routes/deps.py` - NEW - Shared auth dependencies
- `routes/glossary_routes.py` - REFACTORED - All fixes applied

### Final Test Results

```
13 passed, 154 warnings in 5.60s
```
