Étape 2 : modèle de données complet et migration initiale
- Tables SQLModel : Edition, DayPart, Volunteer, Skill, Position, Shift, Availability, Assignment, Account, MagicLinkToken + tables d'association - Multi-édition (edition_id partout), énumérations en VARCHAR + CHECK, suppressions ON DELETE CASCADE (droit à l'effacement) - Dates/heures naïves en heure locale Europe/Paris (tzdata + TZ conteneur) - Migration Alembic 0001 écrite à la main, vérifiée par `alembic check` (aucun écart avec les modèles) et par un aller-retour downgrade/upgrade - Tests : graphe complet, unicité email par édition, N-N compétences, aller-retour d'énumération, cascade de suppression d'un bénévole Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017uUsRg7XzopkCPWimwg9ZM
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
09d7d70076
commit
cb2e84adf0
@@ -0,0 +1,28 @@
|
||||
import datetime as dt
|
||||
|
||||
from sqlmodel import Field, SQLModel
|
||||
|
||||
|
||||
def local_now() -> dt.datetime:
|
||||
"""Horodatage naïf en heure locale (Europe/Paris via le TZ du conteneur).
|
||||
|
||||
Toutes les dates/heures du domaine sont naïves et interprétées en heure
|
||||
locale : créneaux, disponibilités, et champs d'audit.
|
||||
"""
|
||||
return dt.datetime.now()
|
||||
|
||||
|
||||
class TimestampMixin(SQLModel):
|
||||
"""Champs d'audit communs. Hérité par les tables, pas une table.
|
||||
|
||||
Pas de `sa_column=` ici : une instance `Column` ne peut pas être partagée
|
||||
entre plusieurs tables. On laisse SQLModel générer une colonne par table
|
||||
et on passe seulement des `sa_column_kwargs`.
|
||||
"""
|
||||
|
||||
created_at: dt.datetime = Field(default_factory=local_now, nullable=False)
|
||||
updated_at: dt.datetime = Field(
|
||||
default_factory=local_now,
|
||||
nullable=False,
|
||||
sa_column_kwargs={"onupdate": local_now},
|
||||
)
|
||||
Reference in New Issue
Block a user