Changeset 269fdc2 in flexoentity
- Timestamp:
- 11/06/25 08:23:11 (2 months ago)
- Branches:
- master
- Children:
- 182ba7d
- Parents:
- 223c9d5
- Files:
-
- 5 edited
-
flexoentity/domain.py (modified) (3 diffs)
-
flexoentity/flexo_entity.py (modified) (11 diffs)
-
tests/conftest.py (modified) (4 diffs)
-
tests/test_id_lifecycle.py (modified) (1 diff)
-
tests/test_id_stress.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
flexoentity/domain.py
r223c9d5 r269fdc2 10 10 """ 11 11 ENTITY_TYPE = EntityType.DOMAIN 12 12 subtype = "GENERAL" 13 13 fullname: str = "" 14 14 description: str = "" … … 25 25 # Generate FlexOID only if missing 26 26 if not getattr(self, "flexo_id", None): 27 domain_code = self.domain or "GEN"28 27 self.flexo_id = FlexOID.safe_generate( 29 domain= domain_code,28 domain="GENERAL", 30 29 entity_type=EntityType.DOMAIN.value, # 'D' 31 30 estate=EntityState.DRAFT.value, # 'D' … … 41 40 """ 42 41 return f"{self.fullname}|{self.classification}|{self.owner_id}" 42 43 @property 44 def domain_code(self) -> str: 45 """ 46 I am self-domaining — I use my own subtype as domain code. 47 """ 48 return self.subtype or "GENERAL" 43 49 44 50 def to_dict(self): -
flexoentity/flexo_entity.py
r223c9d5 r269fdc2 126 126 - originator_id -> the UUID of the first creator 127 127 - owner_id -> the UUID of the current responsible person or system 128 - domain -> FIXME: Explain reasons, why keep domain mutable. semantic129 domain hint (for filtering or indexing)130 128 131 129 I am designed to be traceable and reproducible: … … 147 145 """ 148 146 149 domain: str150 147 subtype: str = "GENERIC" 151 148 flexo_id: Optional[FlexOID] = field(default=None) … … 190 187 raise NotImplementedError("Subclasses must implement default()") 191 188 192 def domain_code(self) -> str: 193 """ 194 I return a canonical domain code for serialization and ID generation. 195 As domains have their own domain code, I need to distinguish between Domains and 196 other FlexoEntities to avoid cyclic structures. 197 FIXME: Write a better comment 198 """ 199 return self.domain.domain if hasattr(self.domain, "domain") else self.domain 189 @property 190 def domain_code(self): 191 return self.flexo_id.domain 192 193 @property 194 def default_domain_code(self): 195 return "GENERAL" 196 197 @classmethod 198 def with_domain(cls, domain, **kwargs): 199 """ 200 I create an entity in a specific domain. 201 """ 202 203 etype = getattr(cls, "ENTITY_TYPE", None) 204 if not etype: 205 raise ValueError(f"{cls.__name__} must define ENTITY_TYPE") 206 207 flexo_id = FlexOID.safe_generate( 208 domain=domain, 209 entity_type=etype.value, 210 estate=EntityState.DRAFT.value, 211 text=kwargs.get("text_seed", ""), 212 version=1, 213 ) 214 215 obj = cls(flexo_id=flexo_id, **kwargs) 216 obj.fingerprint = obj._compute_fingerprint() 217 return obj 200 218 201 219 def __post_init__(self): … … 220 238 # Generate a new draft FlexOID 221 239 self.flexo_id = FlexOID.safe_generate( 222 domain=self.d omain_code(),240 domain=self.default_domain_code, 223 241 entity_type=etype.value, 224 242 estate=EntityState.DRAFT.value, … … 238 256 def to_dict(self): 239 257 return { 240 "domain": self.domain_code (),258 "domain": self.domain_code, 241 259 "entity_type": self.entity_type.name, 242 260 "state": self.state.name, … … 302 320 if new_fp != self.fingerprint: 303 321 self.fingerprint = new_fp 304 self.flexo_id = FlexOID.safe_generate(self.domain_code (),322 self.flexo_id = FlexOID.safe_generate(self.domain_code, 305 323 self.entity_type.value, 306 324 self.state.value, … … 367 385 """ 368 386 if self.state == EntityState.DRAFT: 369 new_fid = FlexOID.safe_generate(self.domain_code (),387 new_fid = FlexOID.safe_generate(self.domain_code, 370 388 self.entity_type.value, 371 389 EntityState.APPROVED.value, … … 406 424 407 425 new_fid = FlexOID.safe_generate( 408 self.domain_code (),426 self.domain_code, 409 427 self.entity_type.value, 410 428 EntityState.PUBLISHED.value, … … 432 450 self.origin = str(self.flexo_id) 433 451 self.flexo_id = FlexOID.clone_new_base( 434 self.domain_code (),452 self.domain_code, 435 453 self.entity_type.value, 436 454 EntityState.DRAFT.value, … … 499 517 500 518 # Validate domain and ID coherence 501 if entity.domain and entity.domain_code()!= entity.flexo_id.domain:519 if entity.domain_code != entity.flexo_id.domain: 502 520 return False 503 521 if entity.entity_type.value != entity.flexo_id.entity_type: … … 515 533 516 534 except Exception as e: 535 print(e) 517 536 return False 518 537 -
tests/conftest.py
r223c9d5 r269fdc2 45 45 # If no FlexOID yet, generate a draft ID now. 46 46 if not getattr(self, "flexo_id", None): 47 domain_code = (48 self.domain.domain if isinstance(self.domain, Domain) else "GEN"49 )50 47 self.flexo_id = FlexOID.safe_generate( 51 domain= domain_code,52 entity_type= EntityType.ITEM.value, # 'I'48 domain=self.default_domain_code, 49 entity_type=SingleChoiceQuestion.ENTITY_TYPE.value, # 'I' 53 50 estate=EntityState.DRAFT.value, # 'D' 54 51 text=self.text_seed or self.text, … … 58 55 @classmethod 59 56 def default(cls): 60 return cls( domain=Domain(domain="GEN"))57 return cls() 61 58 62 59 def to_dict(self): … … 80 77 @classmethod 81 78 def from_dict(cls, data): 82 obj = cls(domain=Domain(domain="GEN"), 83 text=data.get("text", ""), 79 obj = cls(text=data.get("text", ""), 84 80 options=[AnswerOption.from_dict(o) for o in data.get("options", [])], 85 81 ) 86 82 # restore FlexoEntity core fields 87 obj.domain = data.get("domain")88 83 if "flexo_id" in data: 89 84 obj.flexo_id = FlexOID.parsed(data["flexo_id"]) … … 96 91 @pytest.fixture 97 92 def sample_question(): 98 q = SingleChoiceQuestion(domain=Domain.default(), 99 text="What is 2 + 2?", 93 q = SingleChoiceQuestion(text="What is 2 + 2?", 100 94 options=[]) 101 95 q._update_fingerprint() -
tests/test_id_lifecycle.py
r223c9d5 r269fdc2 12 12 assert q.flexo_id.version == 1 13 13 assert FlexoEntity.verify_integrity(q) 14 15 14 16 15 def test_approval_does_not_bump_version(sample_question): -
tests/test_id_stress.py
r223c9d5 r269fdc2 33 33 ids = [] 34 34 for seed in seeds: 35 oid = FlexOID.safe_generate(domain.domain , entity_type.value, estate.value, seed, repo=repo)35 oid = FlexOID.safe_generate(domain.domain_code, entity_type.value, estate.value, seed, repo=repo) 36 36 assert isinstance(oid, FlexOID) 37 37 ids.append(str(oid)) … … 60 60 text = "identical question text" 61 61 62 id1 = FlexOID.generate(domain.domain , entity_type.value, estate.value, text)63 id2 = FlexOID.generate(domain.domain , entity_type.value, estate.value, text)62 id1 = FlexOID.generate(domain.domain_code, entity_type.value, estate.value, text) 63 id2 = FlexOID.generate(domain.domain_code, entity_type.value, estate.value, text) 64 64 # IDs must be identical because generation is deterministic 65 65 assert id1 == id2 … … 75 75 # seed = "reproducibility test seed" 76 76 77 # id1 = FlexOID.generate(domain.domain , entity_type.value, estate.value, seed)77 # id1 = FlexOID.generate(domain.domain_code, entity_type.value, estate.value, seed) 78 78 # FlexOID._seen_hashes.clear() 79 # id2 = FlexOID.generate(domain.domain , entity_type.value, estate.value, seed)79 # id2 = FlexOID.generate(domain.domain_code, entity_type.value, estate.value, seed) 80 80 81 81 # assert id1 == id2
Note:
See TracChangeset
for help on using the changeset viewer.
