Coverage for arclith / domain / models / entity.py: 100%
23 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-25 15:02 +0100
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-25 15:02 +0100
1from datetime import datetime, timezone
2from typing import Any
4from pydantic import BaseModel, ConfigDict, Field, field_validator
5from uuid6 import uuid7, UUID
8class Entity(BaseModel):
9 model_config = ConfigDict(arbitrary_types_allowed=True)
11 uuid: UUID = Field(
12 default_factory=uuid7,
13 description="Identifiant unique de l'entité (UUIDv7, ordonné dans le temps).",
14 examples=["01951234-5678-7abc-def0-123456789abc"],
15 )
17 @field_validator("uuid", mode="before")
18 @classmethod
19 def coerce_uuid(cls, v: Any) -> UUID:
20 if isinstance(v, UUID):
21 return v
22 return UUID(str(v))
23 created_at: datetime = Field(
24 default_factory=lambda: datetime.now(timezone.utc),
25 description="Date et heure de création de l'entité (UTC).",
26 examples=["2026-03-17T10:00:00+00:00"],
27 )
28 created_by: str | None = Field(
29 default=None,
30 description="Identifiant de l'auteur de la création (utilisateur, service…).",
31 examples=["user_01951234", None],
32 )
33 updated_at: datetime = Field(
34 default_factory=lambda: datetime.now(timezone.utc),
35 description="Date et heure de la dernière modification (UTC).",
36 examples=["2026-03-17T12:30:00+00:00"],
37 )
38 updated_by: str | None = Field(
39 default=None,
40 description="Identifiant de l'auteur de la dernière modification.",
41 examples=["user_01951234", None],
42 )
43 deleted_at: datetime | None = Field(
44 default=None,
45 description="Date et heure de suppression logique (None si l'entité est active).",
46 examples=["2026-03-17T18:00:00+00:00", None],
47 )
48 deleted_by: str | None = Field(
49 default=None,
50 description="Identifiant de l'auteur de la suppression logique.",
51 examples=["user_01951234", None],
52 )
53 version: int = Field(
54 default=1,
55 description="Numéro de version incrémenté à chaque modification (optimistic locking).",
56 examples=[1, 5],
57 )
59 @property
60 def is_deleted(self) -> bool:
61 return self.deleted_at is not None