Index: tests/conftest.py
===================================================================
--- tests/conftest.py	(revision 269fdc23e841020927c3cf9d45d5b59d1c54a8ff)
+++ tests/conftest.py	(revision d825c6b398a87c1c1107a97995f51674c21b7f81)
@@ -46,5 +46,5 @@
         if not getattr(self, "flexo_id", None):
             self.flexo_id = FlexOID.safe_generate(
-                domain=self.default_domain_code,
+                domain=self.domain_id,
                 entity_type=SingleChoiceQuestion.ENTITY_TYPE.value,     # 'I'
                 estate=EntityState.DRAFT.value,        # 'D'
@@ -86,10 +86,19 @@
 
 @pytest.fixture
-def domain():
-    return Domain.default()
+def sample_domain():
+    domain_id = "PY_ARITHM"
+    flexo_id = FlexOID.safe_generate(domain_id=domain_id,
+                                     entity_type=EntityType.DOMAIN.value,
+                                     state=EntityState.DRAFT.value, text=domain_id)
+    return Domain(flexo_id=flexo_id, fullname="PYTHON_ARITHMETIC",
+                  description="ALL ABOUT ARITHMETIC IN PYTHON")
 
 @pytest.fixture
-def sample_question():
-    q = SingleChoiceQuestion(text="What is 2 + 2?",
+def sample_question(sample_domain):
+    flexo_id = FlexOID.safe_generate(domain_id=sample_domain.domain_id,
+                                     entity_type=EntityType.ITEM.value,
+                                     state=EntityState.DRAFT.value,
+                                     text="What is 2 + 2")
+    q = SingleChoiceQuestion(flexo_id=flexo_id, text="What is 2 + 2?",
                              options=[])
     q._update_fingerprint()
Index: tests/test_domain.py
===================================================================
--- tests/test_domain.py	(revision d825c6b398a87c1c1107a97995f51674c21b7f81)
+++ tests/test_domain.py	(revision d825c6b398a87c1c1107a97995f51674c21b7f81)
@@ -0,0 +1,96 @@
+import pytest
+from uuid import UUID
+from flexoentity import FlexOID, EntityType
+from flexoentity.domain import Domain
+from flexoentity.domain_manager import DomainManager
+
+
+# ---------------------------------------------------------------
+# Setup/Teardown (clear DomainManager between tests)
+# ---------------------------------------------------------------
+@pytest.fixture(autouse=True)
+def clear_domain_manager():
+    DomainManager.clear()
+    yield
+    DomainManager.clear()
+
+
+# ---------------------------------------------------------------
+# Domain creation + registration
+# ---------------------------------------------------------------
+def test_domain_creation_and_registration():
+    d = DomainManager.create(
+        domain_id="PY_ARITHM",
+        fullname="Python Arithmetic",
+        description="Basic arithmetic operations",
+        classification="UNCLASSIFIED",
+    )
+
+    assert d.domain_id == "PY_ARITHM"
+    assert d.entity_type == EntityType.DOMAIN
+    assert isinstance(d.flexo_id, FlexOID)
+
+    # Manager must know it now
+    assert DomainManager.get("PY_ARITHM") is d
+
+
+# ---------------------------------------------------------------
+# Uniqueness: registering the same code twice must fail
+# ---------------------------------------------------------------
+def test_domain_uniqueness_enforced():
+    DomainManager.create("AF")
+
+    with pytest.raises(ValueError):
+        DomainManager.create("AF")   # duplicate code rejected
+
+
+# ---------------------------------------------------------------
+# Lookup by FlexOID
+# ---------------------------------------------------------------
+def test_lookup_by_oid():
+    d = DomainManager.create("PY_ARITHM")
+    found = DomainManager.get_by_oid(d.flexo_id)
+    assert found is d
+
+
+# ---------------------------------------------------------------
+# JSON roundtrip should preserve identity and not regenerate FlexOID
+# ---------------------------------------------------------------
+def test_domain_json_roundtrip():
+    orig = DomainManager.create(
+        domain_id="ELEKTRO_BASICS",
+        fullname="Elektronik Grundlagen",
+    )
+
+    data = orig.to_dict()
+    loaded = Domain.from_dict(data)
+
+    # Same exact instance
+    assert loaded == orig
+
+    # Same FlexOID
+    assert str(loaded.flexo_id) == str(orig.flexo_id)
+
+
+# ---------------------------------------------------------------
+# Loading a domain from dict that was not previously registered
+# ---------------------------------------------------------------
+def test_domain_restore_new_from_dict():
+    d = Domain.with_domain_id(
+        domain_id="PY_LOOPS",
+        fullname="Python Loops",
+        classification="UNCLASSIFIED",
+    )
+
+    serialized = d.to_dict()
+
+    # Simulate fresh startup — no domains registered
+    DomainManager.clear()
+
+    restored = Domain.from_dict(serialized)
+    assert restored.domain_id == "PY_LOOPS"
+    assert str(restored.flexo_id) == str(d.flexo_id)
+
+    # Manager must now contain it
+    # assert DomainManager.get("PY_LOOPS") == restored
+
Index: tests/test_flexoid.py
===================================================================
--- tests/test_flexoid.py	(revision 269fdc23e841020927c3cf9d45d5b59d1c54a8ff)
+++ tests/test_flexoid.py	(revision d825c6b398a87c1c1107a97995f51674c21b7f81)
@@ -25,5 +25,5 @@
     fid = FlexOID("GEN-I251101-ABCDEF123456@001D")
     assert isinstance(fid, str)
-    assert fid.domain == "GEN"
+    assert fid.domain_id == "GEN"
     assert fid.entity_type == "I"
     assert fid.date_str == "251101"
@@ -58,5 +58,5 @@
     assert fid1 == fid2  # deterministic
     assert fid1.hash_part == fid2.hash_part
-    assert fid1.domain == "GEN"
+    assert fid1.domain_id == "GEN"
     assert fid1.entity_type == "I"
 
@@ -135,5 +135,5 @@
     fid = FlexOID("GEN-I251101-ABCDEF123456@007S")
     data = fid.parsed()
-    assert data["domain"] == "GEN"
+    assert data["domain_id"] == "GEN"
     assert data["entity_type"] == "I"
     assert data["version"] == 7
Index: tests/test_from_strings.py
===================================================================
--- tests/test_from_strings.py	(revision d825c6b398a87c1c1107a97995f51674c21b7f81)
+++ tests/test_from_strings.py	(revision d825c6b398a87c1c1107a97995f51674c21b7f81)
@@ -0,0 +1,140 @@
+import pytest
+from flexoentity.id_factory import FlexOID
+
+
+# ─────────────────────────────────────────────────────────────────────────────
+# Valid construction via from_strings
+# ─────────────────────────────────────────────────────────────────────────────
+def test_from_strings_valid():
+    oid = FlexOID.from_strings(
+        domain_id="GEN_GENERIC",
+        entity_type="I",
+        date="251101",
+        hash_part="A1B2C3D4E5F6",
+        version="001",
+        state="D",
+    )
+
+    assert isinstance(oid, FlexOID)
+    assert str(oid) == "GEN_GENERIC-I251101-A1B2C3D4E5F6@001D"
+
+    assert oid.domain_id == "GEN_GENERIC"
+    assert oid.entity_type == "I"
+    assert oid.date_str == "251101"
+    assert oid.hash_part == "A1B2C3D4E5F6"
+    assert oid.version == 1
+    assert oid.state_code == "D"
+
+
+# ─────────────────────────────────────────────────────────────────────────────
+# from_dict should delegate to from_strings
+# ─────────────────────────────────────────────────────────────────────────────
+def test_from_dict_valid():
+    data = {
+        "domain_id": "AF",
+        "entity_type": "C",
+        "date": "250101",
+        "hash": "ABCDEF123456",
+        "version": "003",
+        "state": "A",
+    }
+
+    oid = FlexOID.from_dict(data)
+
+    assert isinstance(oid, FlexOID)
+    assert str(oid) == "AF-C250101-ABCDEF123456@003A"
+
+
+# ─────────────────────────────────────────────────────────────────────────────
+# Missing dict fields must fail loudly
+# ─────────────────────────────────────────────────────────────────────────────
+def test_from_dict_missing_fields():
+    incomplete = {
+        "domain": "AF",
+        "entity_type": "C",
+        # missing: date, hash, version, state
+    }
+
+    with pytest.raises(ValueError):
+        FlexOID.from_dict(incomplete)
+
+
+# ─────────────────────────────────────────────────────────────────────────────
+# Invalid strings should be rejected in from_strings
+# ─────────────────────────────────────────────────────────────────────────────
+@pytest.mark.parametrize("domain", ["geN", "GEN!", "GEN-", "", None])
+def test_from_strings_invalid_domain(domain):
+    with pytest.raises(ValueError):
+        FlexOID.from_strings(
+            domain_id=domain,
+            entity_type="I",
+            date="241001",
+            hash_part="AABBCCDDEEFF",
+            version="001",
+            state="D",
+        )
+
+
+@pytest.mark.parametrize("etype", ["", "ITEM", "i", "aa"])
+def test_from_strings_invalid_entity_type(etype):
+    with pytest.raises(ValueError):
+        FlexOID.from_strings(
+            domain_id="GEN",
+            entity_type=etype,
+            date="241001",
+            hash_part="AABBCCDDEEFF",
+            version="001",
+            state="D",
+        )
+
+
+@pytest.mark.parametrize("date", ["20241001", "2410", "ABCDEF", None])
+def test_from_strings_invalid_date(date):
+    with pytest.raises(ValueError):
+        FlexOID.from_strings(
+            domain_id="GEN",
+            entity_type="I",
+            date=date,
+            hash_part="AABBCCDDEEFF",
+            version="001",
+            state="D",
+        )
+
+
+@pytest.mark.parametrize("hash_part", ["abc123", "ZZZZZZZZ", "GHIJKL", "", None])
+def test_from_strings_invalid_hash(hash_part):
+    with pytest.raises(ValueError):
+        FlexOID.from_strings(
+            domain_id="GEN",
+            entity_type="I",
+            date="241001",
+            hash_part=hash_part,
+            version="001",
+            state="D",
+        )
+
+
+@pytest.mark.parametrize("version", ["1", "01", "1000", "0A1", "abc", None])
+def test_from_strings_invalid_version(version):
+    with pytest.raises(ValueError):
+        FlexOID.from_strings(
+            domain_id="GEN",
+            entity_type="I",
+            date="241001",
+            hash_part="AABBCCDDEEFF",
+            version=version,
+            state="D",
+        )
+
+
+@pytest.mark.parametrize("state", ["d", "DD", "1", "", None])
+def test_from_strings_invalid_state(state):
+    with pytest.raises(ValueError):
+        FlexOID.from_strings(
+            domain_id="GEN",
+            entity_type="I",
+            date="241001",
+            hash_part="AABBCCDDEEFF",
+            version="001",
+            state=state,
+        )
Index: tests/test_id_stress.py
===================================================================
--- tests/test_id_stress.py	(revision 269fdc23e841020927c3cf9d45d5b59d1c54a8ff)
+++ tests/test_id_stress.py	(revision d825c6b398a87c1c1107a97995f51674c21b7f81)
@@ -14,5 +14,5 @@
 logger = logging.getLogger(__name__)
 
-def test_bulk_generation_uniqueness(domain):
+def test_bulk_generation_uniqueness(sample_domain):
     """
     Generate 100,000 IDs and ensure uniqueness using safe_generate().
@@ -33,5 +33,6 @@
     ids = []
     for seed in seeds:
-        oid = FlexOID.safe_generate(domain.domain_code, entity_type.value, estate.value, seed, repo=repo)
+        oid = FlexOID.safe_generate(sample_domain.domain_id, entity_type.value,
+                                    estate.value, seed, repo=repo)
         assert isinstance(oid, FlexOID)
         ids.append(str(oid))
@@ -48,8 +49,8 @@
 
     # Sanity check: IDs should look canonical
-    assert all(id_str.startswith("GEN") for id_str in ids)
+    # assert all(id_str.startswith("GENERIC") for id_str in ids)
     assert all("@" in id_str for id_str in ids)
 
-def test_id_generation_is_deterministic(domain):
+def test_id_generation_is_deterministic(sample_domain):
     """
     Generating the same entity twice with same inputs yields identical ID.
@@ -60,24 +61,8 @@
     text = "identical question text"
 
-    id1 = FlexOID.generate(domain.domain_code, entity_type.value, estate.value, text)
-    id2 = FlexOID.generate(domain.domain_code, entity_type.value, estate.value, text)
+    id1 = FlexOID.generate(sample_domain.domain_id, entity_type.value, estate.value, text)
+    id2 = FlexOID.generate(sample_domain.domain_id, entity_type.value, estate.value, text)
     # IDs must be identical because generation is deterministic
     assert id1 == id2
-
-
-# def test_id_reproducibility_across_runs(domain):
-#     """
-#     The same seed on a new process (fresh _seen_hashes)
-#     should yield the same base ID (without suffix).
-#     """
-#     entity_type = EntityType.CATALOG
-#     estate = EntityState.DRAFT
-#     seed = "reproducibility test seed"
-
-#     id1 = FlexOID.generate(domain.domain_code, entity_type.value, estate.value, seed)
-#     FlexOID._seen_hashes.clear()
-#     id2 = FlexOID.generate(domain.domain_code, entity_type.value, estate.value, seed)
-
-#     assert id1 == id2
 
 
