Spaces:
Build error
Build error
Claude commited on
fix: Sprint 6 — CLAUDE.md endpoint sync, UncertaintyConfig validator, annotation docs
Browse files- Sync CLAUDE.md section 12 with actual implemented endpoints
- Remove undocumented/renamed endpoints, add missing ones
- Mark 4 unimplemented endpoints as Sprint 6+
- Add model_validator on UncertaintyConfig (flag_below >= min_acceptable)
- Add clarification docstring on AnnotationLayer (planned for Sprint 6)
- 2 new validation tests
https://claude.ai/code/session_012NCh8yLxMXkRmBYQgHCTik
- CLAUDE.md +12 -7
- backend/app/schemas/annotation.py +6 -0
- backend/app/schemas/corpus_profile.py +9 -1
- backend/tests/test_profiles.py +18 -0
CLAUDE.md
CHANGED
|
@@ -882,9 +882,9 @@ Layer : PENDING → RUNNING → DONE → FAILED → NEEDS_REVIEW → VALIDATED
|
|
| 882 |
## 12. Endpoints API — liste complète
|
| 883 |
|
| 884 |
```
|
| 885 |
-
#
|
| 886 |
-
|
| 887 |
-
GET /api/v1/models
|
| 888 |
POST /api/v1/models/refresh
|
| 889 |
PUT /api/v1/corpora/{id}/model
|
| 890 |
GET /api/v1/corpora/{id}/model
|
|
@@ -898,6 +898,10 @@ POST /api/v1/corpora
|
|
| 898 |
GET /api/v1/corpora
|
| 899 |
GET /api/v1/corpora/{id}
|
| 900 |
DELETE /api/v1/corpora/{id}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 901 |
|
| 902 |
# Ingestion
|
| 903 |
POST /api/v1/corpora/{id}/ingest/files
|
|
@@ -913,9 +917,9 @@ POST /api/v1/jobs/{job_id}/retry
|
|
| 913 |
# Pages
|
| 914 |
GET /api/v1/pages/{id}
|
| 915 |
GET /api/v1/pages/{id}/master-json
|
| 916 |
-
PUT /api/v1/pages/{id}/master-json
|
| 917 |
GET /api/v1/pages/{id}/layers
|
| 918 |
-
POST /api/v1/pages/{id}/layers/{layer_type}/regenerate
|
| 919 |
|
| 920 |
# Export
|
| 921 |
GET /api/v1/manuscripts/{id}/iiif-manifest
|
|
@@ -924,13 +928,14 @@ GET /api/v1/pages/{id}/alto
|
|
| 924 |
GET /api/v1/manuscripts/{id}/export.zip
|
| 925 |
|
| 926 |
# Validation
|
| 927 |
-
POST /api/v1/pages/{id}/validate
|
| 928 |
POST /api/v1/pages/{id}/corrections
|
| 929 |
GET /api/v1/pages/{id}/history
|
| 930 |
|
| 931 |
# Recherche
|
| 932 |
GET /api/v1/search?q=
|
| 933 |
-
|
|
|
|
| 934 |
```
|
| 935 |
|
| 936 |
---
|
|
|
|
| 882 |
## 12. Endpoints API — liste complète
|
| 883 |
|
| 884 |
```
|
| 885 |
+
# Providers & modèles IA
|
| 886 |
+
GET /api/v1/providers
|
| 887 |
+
GET /api/v1/providers/{provider_type}/models
|
| 888 |
POST /api/v1/models/refresh
|
| 889 |
PUT /api/v1/corpora/{id}/model
|
| 890 |
GET /api/v1/corpora/{id}/model
|
|
|
|
| 898 |
GET /api/v1/corpora
|
| 899 |
GET /api/v1/corpora/{id}
|
| 900 |
DELETE /api/v1/corpora/{id}
|
| 901 |
+
GET /api/v1/corpora/{id}/manuscripts
|
| 902 |
+
|
| 903 |
+
# Manuscrits
|
| 904 |
+
GET /api/v1/manuscripts/{id}/pages
|
| 905 |
|
| 906 |
# Ingestion
|
| 907 |
POST /api/v1/corpora/{id}/ingest/files
|
|
|
|
| 917 |
# Pages
|
| 918 |
GET /api/v1/pages/{id}
|
| 919 |
GET /api/v1/pages/{id}/master-json
|
| 920 |
+
PUT /api/v1/pages/{id}/master-json # Sprint 6+
|
| 921 |
GET /api/v1/pages/{id}/layers
|
| 922 |
+
POST /api/v1/pages/{id}/layers/{layer_type}/regenerate # Sprint 6+
|
| 923 |
|
| 924 |
# Export
|
| 925 |
GET /api/v1/manuscripts/{id}/iiif-manifest
|
|
|
|
| 928 |
GET /api/v1/manuscripts/{id}/export.zip
|
| 929 |
|
| 930 |
# Validation
|
| 931 |
+
POST /api/v1/pages/{id}/validate # Sprint 6+
|
| 932 |
POST /api/v1/pages/{id}/corrections
|
| 933 |
GET /api/v1/pages/{id}/history
|
| 934 |
|
| 935 |
# Recherche
|
| 936 |
GET /api/v1/search?q=
|
| 937 |
+
POST /api/v1/search/reindex
|
| 938 |
+
GET /api/v1/manuscripts/{id}/search?q= # Sprint 6+
|
| 939 |
```
|
| 940 |
|
| 941 |
---
|
backend/app/schemas/annotation.py
CHANGED
|
@@ -22,6 +22,12 @@ class LayerStatus(str, Enum):
|
|
| 22 |
|
| 23 |
|
| 24 |
class AnnotationLayer(BaseModel):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
id: str
|
| 26 |
page_id: str
|
| 27 |
layer_type: LayerType
|
|
|
|
| 22 |
|
| 23 |
|
| 24 |
class AnnotationLayer(BaseModel):
|
| 25 |
+
"""Couche d'annotation de page.
|
| 26 |
+
|
| 27 |
+
NOTE: Schéma prévu pour Sprint 6 (validation humaine + couches individuelles).
|
| 28 |
+
Pas encore utilisé dans les endpoints API ni les modèles SQLAlchemy.
|
| 29 |
+
"""
|
| 30 |
+
|
| 31 |
id: str
|
| 32 |
page_id: str
|
| 33 |
layer_type: LayerType
|
backend/app/schemas/corpus_profile.py
CHANGED
|
@@ -5,7 +5,7 @@ Schémas Pydantic pour le profil de corpus — entité centrale du pipeline.
|
|
| 5 |
from enum import Enum
|
| 6 |
|
| 7 |
# 2. third-party
|
| 8 |
-
from pydantic import BaseModel, ConfigDict, Field
|
| 9 |
|
| 10 |
|
| 11 |
class LayerType(str, Enum):
|
|
@@ -40,6 +40,14 @@ class UncertaintyConfig(BaseModel):
|
|
| 40 |
flag_below: float = Field(0.4, ge=0.0, le=1.0)
|
| 41 |
min_acceptable: float = Field(0.25, ge=0.0, le=1.0)
|
| 42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
class CorpusProfile(BaseModel):
|
| 45 |
model_config = ConfigDict(frozen=True)
|
|
|
|
| 5 |
from enum import Enum
|
| 6 |
|
| 7 |
# 2. third-party
|
| 8 |
+
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
| 9 |
|
| 10 |
|
| 11 |
class LayerType(str, Enum):
|
|
|
|
| 40 |
flag_below: float = Field(0.4, ge=0.0, le=1.0)
|
| 41 |
min_acceptable: float = Field(0.25, ge=0.0, le=1.0)
|
| 42 |
|
| 43 |
+
@model_validator(mode='after')
|
| 44 |
+
def flag_must_exceed_min(self) -> 'UncertaintyConfig':
|
| 45 |
+
if self.flag_below < self.min_acceptable:
|
| 46 |
+
raise ValueError(
|
| 47 |
+
f"flag_below ({self.flag_below}) doit être >= min_acceptable ({self.min_acceptable})"
|
| 48 |
+
)
|
| 49 |
+
return self
|
| 50 |
+
|
| 51 |
|
| 52 |
class CorpusProfile(BaseModel):
|
| 53 |
model_config = ConfigDict(frozen=True)
|
backend/tests/test_profiles.py
CHANGED
|
@@ -119,3 +119,21 @@ def test_early_modern_print_no_iconography():
|
|
| 119 |
def test_modern_handwritten_no_iconography():
|
| 120 |
profile = load_profile("modern-handwritten.json")
|
| 121 |
assert LayerType.ICONOGRAPHY_DETECTION not in profile.active_layers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
def test_modern_handwritten_no_iconography():
|
| 120 |
profile = load_profile("modern-handwritten.json")
|
| 121 |
assert LayerType.ICONOGRAPHY_DETECTION not in profile.active_layers
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
# ---------------------------------------------------------------------------
|
| 125 |
+
# Tests UncertaintyConfig cross-field validation
|
| 126 |
+
# ---------------------------------------------------------------------------
|
| 127 |
+
|
| 128 |
+
def test_uncertainty_config_flag_below_must_exceed_min():
|
| 129 |
+
"""flag_below < min_acceptable doit lever une erreur."""
|
| 130 |
+
from app.schemas.corpus_profile import UncertaintyConfig
|
| 131 |
+
with pytest.raises(ValidationError):
|
| 132 |
+
UncertaintyConfig(flag_below=0.2, min_acceptable=0.5)
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
def test_uncertainty_config_valid():
|
| 136 |
+
"""flag_below >= min_acceptable est accepté."""
|
| 137 |
+
from app.schemas.corpus_profile import UncertaintyConfig
|
| 138 |
+
uc = UncertaintyConfig(flag_below=0.5, min_acceptable=0.3)
|
| 139 |
+
assert uc.flag_below == 0.5
|