Upgrade configuration and Docker stack to v2.0.0

This commit is contained in:
2026-06-22 14:49:56 -04:00
parent 2f2a5e9b4a
commit 0d2ecbd218
19 changed files with 779 additions and 495 deletions
+21 -13
View File
@@ -5,7 +5,7 @@ import enum
from datetime import datetime, timezone
from sqlalchemy import (
Column, Integer, String, Text, DateTime,
JSON, Float, Enum as SAEnum, BigInteger, Boolean, ForeignKey
JSON, Float, Enum as SAEnum, BigInteger, Boolean, ForeignKey, Index
)
from sqlalchemy.orm import relationship
from app.database import Base
@@ -31,11 +31,11 @@ class Image(Base):
# ── Fichier ───────────────────────────────────────────────
original_name = Column(String(512), nullable=False)
filename = Column(String(512), nullable=False) # nom sur disque (uuid-based)
filename = Column(String(512), nullable=False)
file_path = Column(String(1024), nullable=False)
thumbnail_path = Column(String(1024))
mime_type = Column(String(128))
file_size = Column(BigInteger) # bytes
file_size = Column(BigInteger)
width = Column(Integer)
height = Column(Integer)
uploaded_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
@@ -52,18 +52,18 @@ class Image(Base):
processing_done_at = Column(DateTime(timezone=True))
# ── Métadonnées EXIF ──────────────────────────────────────
exif_raw = Column(JSON) # dict complet brut
exif_make = Column(String(256)) # Appareil — fabricant
exif_model = Column(String(256)) # Appareil — modèle
exif_raw = Column(JSON)
exif_make = Column(String(256))
exif_model = Column(String(256))
exif_lens = Column(String(256))
exif_taken_at = Column(DateTime(timezone=True)) # DateTimeOriginal EXIF
exif_taken_at = Column(DateTime(timezone=True))
exif_gps_lat = Column(Float)
exif_gps_lon = Column(Float)
exif_altitude = Column(Float)
exif_iso = Column(Integer)
exif_aperture = Column(String(32)) # ex: "f/2.8"
exif_shutter = Column(String(32)) # ex: "1/250"
exif_focal = Column(String(32)) # ex: "50mm"
exif_aperture = Column(String(32))
exif_shutter = Column(String(32))
exif_focal = Column(String(32))
exif_flash = Column(Boolean)
exif_orientation = Column(Integer)
exif_software = Column(String(256))
@@ -71,18 +71,26 @@ class Image(Base):
# ── OCR ───────────────────────────────────────────────────
ocr_text = Column(Text)
ocr_language = Column(String(64))
ocr_confidence = Column(Float) # 0.0 – 1.0
ocr_confidence = Column(Float)
ocr_has_text = Column(Boolean, default=False)
# ── AI Vision ─────────────────────────────────────────────
ai_description = Column(Text)
ai_tags = Column(JSON) # ["nature", "paysage", ...]
ai_confidence = Column(Float) # score de confiance global
ai_tags = Column(JSON)
ai_confidence = Column(Float)
ai_model_used = Column(String(128))
ai_processed_at = Column(DateTime(timezone=True))
ai_prompt_tokens = Column(Integer)
ai_output_tokens = Column(Integer)
# ── Indexes composites ────────────────────────────────────
__table_args__ = (
# Pour les listings paginés par client (requête la plus fréquente)
Index("ix_images_client_uploaded", "client_id", "uploaded_at"),
# Pour le filtrage par statut + client
Index("ix_images_client_status", "client_id", "processing_status"),
)
def __repr__(self):
return f"<Image id={self.id} name={self.original_name} status={self.processing_status}>"