Claude commited on
Commit
894cbe3
·
unverified ·
1 Parent(s): cf9842a

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 CHANGED
@@ -882,9 +882,9 @@ Layer : PENDING → RUNNING → DONE → FAILED → NEEDS_REVIEW → VALIDATED
882
  ## 12. Endpoints API — liste complète
883
 
884
  ```
885
- # Configuration & modèles IA
886
- POST /api/v1/settings/api-key
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
- GET /api/v1/manuscripts/{id}/search?q=
 
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