Changeset 269fdc2 in flexoentity


Ignore:
Timestamp:
11/06/25 08:23:11 (2 months ago)
Author:
Enrico Schwass <ennoausberlin@…>
Branches:
master
Children:
182ba7d
Parents:
223c9d5
Message:

adjustments to domain handling - with_domain constructor added

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • flexoentity/domain.py

    r223c9d5 r269fdc2  
    1010    """
    1111    ENTITY_TYPE = EntityType.DOMAIN
    12 
     12    subtype = "GENERAL"
    1313    fullname: str = ""
    1414    description: str = ""
     
    2525        # Generate FlexOID only if missing
    2626        if not getattr(self, "flexo_id", None):
    27             domain_code = self.domain or "GEN"
    2827            self.flexo_id = FlexOID.safe_generate(
    29                 domain=domain_code,
     28                domain="GENERAL",
    3029                entity_type=EntityType.DOMAIN.value,   # 'D'
    3130                estate=EntityState.DRAFT.value,      # 'D'
     
    4140        """
    4241        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"
    4349
    4450    def to_dict(self):
  • flexoentity/flexo_entity.py

    r223c9d5 r269fdc2  
    126126      - originator_id -> the UUID of the first creator
    127127      - owner_id      -> the UUID of the current responsible person or system
    128       - domain        -> FIXME: Explain reasons, why keep domain mutable. semantic
    129                             domain hint (for filtering or indexing)
    130128
    131129    I am designed to be traceable and reproducible:
     
    147145    """
    148146
    149     domain: str
    150147    subtype: str = "GENERIC"
    151148    flexo_id: Optional[FlexOID] = field(default=None)
     
    190187        raise NotImplementedError("Subclasses must implement default()")
    191188
    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
    200218
    201219    def __post_init__(self):
     
    220238        # Generate a new draft FlexOID
    221239        self.flexo_id = FlexOID.safe_generate(
    222             domain=self.domain_code(),
     240            domain=self.default_domain_code,
    223241            entity_type=etype.value,
    224242            estate=EntityState.DRAFT.value,
     
    238256    def to_dict(self):
    239257        return {
    240             "domain": self.domain_code(),
     258            "domain": self.domain_code,
    241259            "entity_type": self.entity_type.name,
    242260            "state": self.state.name,
     
    302320        if new_fp != self.fingerprint:
    303321            self.fingerprint = new_fp
    304             self.flexo_id = FlexOID.safe_generate(self.domain_code(),
     322            self.flexo_id = FlexOID.safe_generate(self.domain_code,
    305323                                                  self.entity_type.value,
    306324                                                  self.state.value,
     
    367385        """
    368386        if self.state == EntityState.DRAFT:
    369             new_fid = FlexOID.safe_generate(self.domain_code(),
     387            new_fid = FlexOID.safe_generate(self.domain_code,
    370388                                            self.entity_type.value,
    371389                                            EntityState.APPROVED.value,
     
    406424
    407425        new_fid = FlexOID.safe_generate(
    408             self.domain_code(),
     426            self.domain_code,
    409427            self.entity_type.value,
    410428            EntityState.PUBLISHED.value,
     
    432450        self.origin = str(self.flexo_id)
    433451        self.flexo_id = FlexOID.clone_new_base(
    434             self.domain_code(),
     452            self.domain_code,
    435453            self.entity_type.value,
    436454            EntityState.DRAFT.value,
     
    499517
    500518            # 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:
    502520                return False
    503521            if entity.entity_type.value != entity.flexo_id.entity_type:
     
    515533
    516534        except Exception as e:
     535            print(e)
    517536            return False
    518537
  • tests/conftest.py

    r223c9d5 r269fdc2  
    4545        # If no FlexOID yet, generate a draft ID now.
    4646        if not getattr(self, "flexo_id", None):
    47             domain_code = (
    48                 self.domain.domain if isinstance(self.domain, Domain) else "GEN"
    49             )
    5047            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'
    5350                estate=EntityState.DRAFT.value,        # 'D'
    5451                text=self.text_seed or self.text,
     
    5855    @classmethod
    5956    def default(cls):
    60         return cls(domain=Domain(domain="GEN"))
     57        return cls()
    6158
    6259    def to_dict(self):
     
    8077    @classmethod
    8178    def from_dict(cls, data):
    82         obj = cls(domain=Domain(domain="GEN"),
    83             text=data.get("text", ""),
     79        obj = cls(text=data.get("text", ""),
    8480            options=[AnswerOption.from_dict(o) for o in data.get("options", [])],
    8581        )
    8682        # restore FlexoEntity core fields
    87         obj.domain = data.get("domain")
    8883        if "flexo_id" in data:
    8984            obj.flexo_id = FlexOID.parsed(data["flexo_id"])
     
    9691@pytest.fixture
    9792def sample_question():
    98     q = SingleChoiceQuestion(domain=Domain.default(),
    99                              text="What is 2 + 2?",
     93    q = SingleChoiceQuestion(text="What is 2 + 2?",
    10094                             options=[])
    10195    q._update_fingerprint()
  • tests/test_id_lifecycle.py

    r223c9d5 r269fdc2  
    1212    assert q.flexo_id.version == 1
    1313    assert FlexoEntity.verify_integrity(q)
    14 
    1514
    1615def test_approval_does_not_bump_version(sample_question):
  • tests/test_id_stress.py

    r223c9d5 r269fdc2  
    3333    ids = []
    3434    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)
    3636        assert isinstance(oid, FlexOID)
    3737        ids.append(str(oid))
     
    6060    text = "identical question text"
    6161
    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)
    6464    # IDs must be identical because generation is deterministic
    6565    assert id1 == id2
     
    7575#     seed = "reproducibility test seed"
    7676
    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)
    7878#     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)
    8080
    8181#     assert id1 == id2
Note: See TracChangeset for help on using the changeset viewer.