Index: flexoentity/domain.py
===================================================================
--- flexoentity/domain.py	(revision 3d16c35d3fefcfceff1373475af4a12d4393b8df)
+++ flexoentity/domain.py	(revision 524040ab9259784d3e2c918c532b7488b20c19f1)
@@ -8,4 +8,8 @@
     classification: str = "UNCLASSIFIED"
     owner: str = "unknown"
+
+    @classmethod
+    def default(cls):
+        return cls(domain="GEN", etype=EntityType.DATABASE, state=EntityState.DRAFT)
 
     def __post_init__(self):
@@ -35,4 +39,3 @@
             classification=data.get("classification", "UNCLASSIFIED"),
             owner=data.get("owner", "unknown"),
-            state=EntityState[data.get("state", "DRAFT")],
         )
Index: flexoentity/flexo_entity.py
===================================================================
--- flexoentity/flexo_entity.py	(revision 3d16c35d3fefcfceff1373475af4a12d4393b8df)
+++ flexoentity/flexo_entity.py	(revision 524040ab9259784d3e2c918c532b7488b20c19f1)
@@ -121,4 +121,10 @@
         raise NotImplementedError("Subclasses must define text_seed property")
 
+    @classmethod
+    @abstractmethod
+    def default(cls):
+        """Return a minimal valid instance of this entity (DRAFT state)."""
+        raise NotImplementedError("Subclasses must implement default()")
+
     def __post_init__(self):
         """Generate ID and content fingerprint."""
Index: flexoentity/id_factory.py
===================================================================
--- flexoentity/id_factory.py	(revision 3d16c35d3fefcfceff1373475af4a12d4393b8df)
+++ flexoentity/id_factory.py	(revision 524040ab9259784d3e2c918c532b7488b20c19f1)
@@ -133,9 +133,66 @@
         return part[-1]
 
+    # ──────────────────────────────────────────────────────────────────────────
+    #  Parsed Accessors
+    # ──────────────────────────────────────────────────────────────────────────
+
+    @property
+    def domain(self) -> str:
+        """Return the domain prefix (e.g., 'AF')."""
+        try:
+            return self.flexo_id.split('-', 1)[0]
+        except IndexError:
+            raise ValueError(f"Malformed Flex-O ID: {self.flexo_id}")
+
+    @property
+    def etype(self) -> str:
+        """Return the entity type code (e.g., 'Q', 'CAT', etc.)."""
+        try:
+            part = self.flexo_id.split('-', 1)[1]
+            return ''.join(filter(str.isalpha, part.split('-')[0]))  # up to first dash
+        except IndexError:
+            raise ValueError(f"Malformed Flex-O ID: {self.flexo_id}")
+
+    @property
+    def date_str(self) -> str:
+        """Return the YYMMDD creation date as string."""
+        try:
+            part = self.flexo_id.split('-', 1)[1]
+            # e.g. "Q251019" → skip type prefix, take next 6 digits
+            digits = ''.join(ch for ch in part if ch.isdigit())
+            return digits[:6]
+        except IndexError:
+            raise ValueError(f"Malformed Flex-O ID: {self.flexo_id}")
+
+    @property
+    def date(self) -> datetime:
+        """Return the creation date as datetime.date object (UTC, naive)."""
+        try:
+            ds = self.date_str
+            return datetime.strptime(ds, "%y%m%d").date()
+        except Exception as e:
+            raise ValueError(f"Invalid date in Flex-O ID: {self.flexo_id}") from e
+
+    @property
+    def hash_part(self) -> str:
+        """Return the 6-hex BLAKE hash portion (e.g., '9B3E2')."""
+        try:
+            after_dash = self.flexo_id.split('-', 2)[2]
+            return after_dash.split('@')[0]
+        except IndexError:
+            raise ValueError(f"Malformed Flex-O ID: {self.flexo_id}")
+
+    @property
+    def suffix(self) -> str:
+        """Return the full suffix after '@' (e.g., '001A')."""
+        try:
+            return self.flexo_id.split('@', 1)[1]
+        except IndexError:
+            raise ValueError(f"Malformed Flex-O ID: {self.flexo_id}")
+
     @property
     def version(self) -> int:
         try:
-            ver_state = self.flexo_id.rsplit("@", 1)[-1]
-            return int(ver_state[:-1])  # drop state suffix
+            return int(self.suffix[:-1])  # drop state suffix
         except (ValueError, IndexError):
             return 1
@@ -147,7 +204,15 @@
         # return self.flexo_id.split('@')[0].rsplit('-', 1)[0]
 
-    @property
-    def prefix_old(self) -> str:
-        return self.flexo_id.rsplit("@", 1)[0]
+    def parsed(self) -> dict:
+        """Return a structured breakdown of the Flex-O ID."""
+        return {
+            "domain": self.domain,
+            "etype": self.etype,
+            "date": self.date,
+            "hash": self.hash_part,
+            "version": self.version,
+            "state": self.state_code,
+            "signature": self.signature,
+        }
     # ──────────────────────────────────────────────────────────────────────────
 
Index: tests/conftest.py
===================================================================
--- tests/conftest.py	(revision 3d16c35d3fefcfceff1373475af4a12d4393b8df)
+++ tests/conftest.py	(revision 524040ab9259784d3e2c918c532b7488b20c19f1)
@@ -55,2 +55,11 @@
     )
     return exam
+
+@pytest.fixture
+def null_media():
+    """Provide a default NullMediaItem instance for tests."""
+    return NullMediaItem(
+        domain="GEN",
+        etype=EntityType.MEDIA,
+        state=EntityState.DRAFT
+    )
