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

1from datetime import datetime, timezone 

2from typing import Any 

3 

4from pydantic import BaseModel, ConfigDict, Field, field_validator 

5from uuid6 import uuid7, UUID 

6 

7 

8class Entity(BaseModel): 

9 model_config = ConfigDict(arbitrary_types_allowed=True) 

10 

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 ) 

16 

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 ) 

58 

59 @property 

60 def is_deleted(self) -> bool: 

61 return self.deleted_at is not None 

62