Farpost · Data Modeling
$ Fixing a Design Without Tearing Out What It Replaced
Diagnosing why an identity/roles model felt overcomplicated turned up a real duplication: a Professional record carries a roles: list[str] field, and separately has ten per-role child tables — adjuster, contractor, agent, and so on — joined back to it by a bare string, with no actual foreign key. 'Role' was modeled twice, two different ways, at the same time.
The root cause wasn't a bad decision. User-as-root-identity was the right correction to an earlier, role-first design — but the retrofit that introduced it never removed the old skeleton it was meant to replace, so both versions kept running side by side. That's a generalizable failure mode, not a one-off mistake: fixing part of a design without tearing out what it replaced.
class Professional(Document):
roles: list[str] # source of truth #1
class Adjuster(Document):
professional_id: str # joined back by a bare string, no real FK
# ...9 more per-role tables shaped exactly like this oneThe fix
The lesson generalizes past this one schema: when a correct architectural fix lands on top of an existing structure, the old structure has to actually be removed, not left running in parallel next to its replacement. Two sources of truth for the same fact don't average out to one correct answer — they just create a place for the two to quietly disagree.
Why this matters
Catching and explaining your own design drift reads as more senior than a highlight reel of wins only, and it generalizes past this one project — anyone who's inherited or built an accreted codebase will recognize the exact pattern: a good fix, arriving late, that never finished the job of removing what it was fixing.
