|
| 1 | +# Concepts |
| 2 | + |
| 3 | +TypeID exists because identifiers are used for much more than uniqueness. |
| 4 | + |
| 5 | +They appear in logs, URLs, dashboards, tickets, alerts, database rows, and Slack messages. |
| 6 | +Yet most identifiers—especially UUIDs—are opaque. They carry no meaning, no context, and no affordances for inspection. |
| 7 | + |
| 8 | +TypeID is an attempt to fix that, without breaking the properties that make UUIDs useful. |
| 9 | + |
| 10 | +--- |
| 11 | + |
| 12 | +## TypeID as an identifier |
| 13 | + |
| 14 | +A TypeID is a string identifier composed of two independent parts: |
| 15 | + |
| 16 | +```text |
| 17 | +<prefix>_<suffix> |
| 18 | +``` |
| 19 | + |
| 20 | +For example: |
| 21 | + |
| 22 | +```text |
| 23 | +user_01h45ytscbebyvny4gc8cr8ma2 |
| 24 | +``` |
| 25 | + |
| 26 | +The **suffix** is the identity. It is globally unique and backed by a UUID. |
| 27 | +The **prefix** is context. It tells a human (and tooling) what kind of thing the identifier refers to. |
| 28 | + |
| 29 | +Crucially, the prefix does *not* participate in uniqueness. Two TypeIDs with different prefixes but the same suffix represent the same underlying UUID. The prefix is a semantic layer, not a storage primitive. |
| 30 | + |
| 31 | +This separation is intentional. It allows TypeID to add meaning without interfering with existing UUID-based systems. |
| 32 | + |
| 33 | +## UUID compatibility by design |
| 34 | + |
| 35 | +TypeID is not a replacement for UUIDs. It is a layer on top of them. |
| 36 | + |
| 37 | +Every TypeID corresponds to exactly one UUID, and that UUID can always be extracted or reconstructed. This makes it possible to: |
| 38 | + |
| 39 | +* store native UUIDs in databases |
| 40 | +* use existing UUID indexes and constraints |
| 41 | +* introduce TypeID without schema migrations |
| 42 | +* roll back or interoperate with systems that know nothing about TypeID |
| 43 | + |
| 44 | +The recommended pattern is simple: **store UUIDs, expose TypeIDs**. |
| 45 | + |
| 46 | +TypeID lives at the boundaries of your system—APIs, logs, tooling—not at the lowest storage level. |
| 47 | + |
| 48 | +## Sortability and time |
| 49 | + |
| 50 | +The suffix used by TypeID is time-sortable. When two TypeIDs are compared lexicographically, the one created earlier sorts before the one created later. |
| 51 | + |
| 52 | +This property is not about business semantics; it is about ergonomics. |
| 53 | + |
| 54 | +Sortable identifiers make logs readable, pagination predictable, and debugging less frustrating. When you scan a list of IDs, you can usually infer their relative age without additional metadata. |
| 55 | + |
| 56 | +There are important limits to this property. Ordering reflects **generation time**, not transaction time or business events. Clock skew and distributed systems still exist. TypeID does not attempt to impose global ordering or causality. |
| 57 | + |
| 58 | +Sortability is a convenience, not a guarantee. |
| 59 | + |
| 60 | +## Explainability |
| 61 | + |
| 62 | +Once an identifier carries structure, it becomes possible to inspect it. |
| 63 | + |
| 64 | +TypeID can be *explained*: given a string, the system can determine whether it is a valid TypeID, extract its UUID, derive its creation time, and report these facts in a structured way. |
| 65 | + |
| 66 | +This is useful in places where identifiers normally appear as dead text: |
| 67 | + |
| 68 | +* logs |
| 69 | +* error messages |
| 70 | +* database dumps |
| 71 | +* incident reports |
| 72 | +* CI output |
| 73 | + |
| 74 | +Explainability is designed to be safe. Invalid identifiers do not crash the system. Unknown prefixes are accepted. Each identifier is handled independently, which makes batch processing robust. |
| 75 | + |
| 76 | +## Schemas as optional meaning |
| 77 | + |
| 78 | +Derived facts are always available, but they are not always enough. In real systems, prefixes often correspond to domain concepts: users, orders, events, aggregates. |
| 79 | + |
| 80 | +Schemas allow you to describe that meaning explicitly. |
| 81 | + |
| 82 | +A schema can say that a `user` ID represents an end-user account, that it contains PII, that it is owned by a particular team, or that related logs and dashboards can be found at specific URLs. |
| 83 | + |
| 84 | +Schemas are optional and additive. If a schema is missing, outdated, or invalid, TypeID still works. The identifier does not become invalid because metadata could not be loaded. |
| 85 | + |
| 86 | +This separation keeps the core identifier system stable while allowing richer interpretation where it is useful. |
| 87 | + |
| 88 | +## Unknown and invalid identifiers |
| 89 | + |
| 90 | +TypeID makes a clear distinction between identifiers that are **invalid** and those that are merely **unknown**. |
| 91 | + |
| 92 | +An invalid identifier is structurally wrong: it cannot be parsed or decoded. |
| 93 | +An unknown identifier is structurally valid, but its prefix is not recognized by any schema. |
| 94 | + |
| 95 | +Unknown identifiers are first-class citizens. They allow systems to evolve independently and avoid tight coupling between producers and consumers of IDs. |
| 96 | + |
| 97 | +This distinction is essential for forward compatibility and safe tooling. |
| 98 | + |
| 99 | +## A note on safety |
| 100 | + |
| 101 | +TypeID is deliberately conservative. |
| 102 | + |
| 103 | +It does not infer meaning. |
| 104 | +It does not mutate state. |
| 105 | +It does not enforce authorization. |
| 106 | +It does not treat identifiers as secrets. |
| 107 | + |
| 108 | +Its goal is to make identifiers **more understandable**. |
| 109 | + |
| 110 | +## Closing thoughts |
| 111 | + |
| 112 | +TypeID treats identifiers as part of the system’s interface, not as incidental implementation details. |
| 113 | + |
| 114 | +By combining UUID compatibility, time-based sortability, and structured explainability, it aims to make everyday engineering tasks—debugging, inspection, reasoning—slightly less painful. |
| 115 | + |
| 116 | +Identifiers should not be mysterious. They should be inspectable, understandable, and boring in the best possible way. |
0 commit comments