DubbleBooked · Practice OS · Platform architecture
Built for the whole map, not one workflow: a universal spine, a seedable jurisdiction registry, and versioned practice-area packs. Geoff's WA-DUI spreadsheet — 11 entities, 59 picklists — becomes pack #1, not the schema.
Four layers. A Jurisdiction (state) registers its courts, prosecutors, and the packs it offers. A Pack (state × practice-area, versioned) defines the fields, templates, and rules for that kind of case. The Client → Case spine is state-agnostic; a case names its jurisdiction + pack, and its pack-specific data lives in one Case Detail — never smeared on the spine. New state = seed a jurisdiction. New practice area = author a pack.
erDiagram
JURISDICTION ||--o{ COURT : "registers"
JURISDICTION ||--o{ PROSECUTOR : "registers"
JURISDICTION ||--o{ PRACTICE_PACK : "offers"
PRACTICE_PACK ||--o{ FIELD_SCHEMA : "defines"
PRACTICE_PACK ||--o{ TEMPLATE : "defines"
PRACTICE_PACK ||--o{ RULE : "defines"
CLIENT ||--o{ CASE : "has"
CASE }o--|| JURISDICTION : "in"
CASE }o--|| PRACTICE_PACK : "typed by (pinned version)"
CASE }o--|| COURT : "filed in"
CASE ||--|| CASE_DETAIL : "pack-validated fields"
CASE ||--o{ HEARING : "criminal + admin"
CASE ||--o{ CONTACT : "cast"
CASE ||--o{ ACTIVITY : "billable log"
CASE ||--o{ TASK : "to-dos"
CASE ||--|| DISPOSITION : "outcome"
CASE ||--o{ DOCUMENT : "merged from templates"
CASE ||--o{ PAYMENT : "money + IOLTA"
JURISDICTION {
enum state "WA (OR, CA…)"
string court_system
}
PRACTICE_PACK {
enum practice_area "DUI (assault, drug…)"
string version "cases pin to a version"
json enums "charges, defenses, ladder"
}
CASE {
ref jurisdiction "which state"
ref practice_pack "WA-DUI v1"
ref court
string cause_number
enum lifecycle_status "intake|unfiled|filed|closed"
date arrest_date
}
CASE_DETAIL {
json values "validated vs pack FIELD_SCHEMA"
string pack_version "the schema it was entered under"
}
HEARING {
enum track "criminal (3.4) | admin (DOL)"
date date
enum type "from pack hearing-ladder"
}
FIELD_SCHEMA {
string group "e.g. arrest-report review"
json fields "typed field defs + picklists"
}
The spine entities (Case, Hearing, Contact, Activity, Task, Disposition, Payment) are universal — every pack fills them. What's DUI-specific — the affirmative-defense list, the DOL track, the arrest-report checklist — is supplied by the WA-DUI pack, not baked into the schema. Fields marked ▾ enum come from the pack's picklists; → point at jurisdiction reference tables.
One per matter. The spine link that's missing today — everything else attaches here.
The criminal hearings. This is what drives the four-phase lifecycle and the Google-Calendar sync.
The separate license-suspension admin track. Its own deadlines — the time-critical clock a solo can miss.
Every person on the case, typed by role. Feeds conflict checks and the doc-merge witness lists.
The billable diary — calls, meetings, discovery review. Feeds time & the QuickBooks bridge.
One entity, three lenses — Client / Legal-Assistant / Attorney. Type vocabulary differs by assignee.
How it ended. One per case. Drives the move to Closed and the calendar of deferred-dismissal dates.
The DUI arrest-report review — the issue-spotting checklist. Deep, structured, and the hardest to model well.
Client payments and the IOLTA trust ledger. Thin by design — LawPay & QuickBooks hold the source of truth; we mirror & link.
These aren't just dropdowns. Geoff's picklists encode which prosecutor sits in which court, which jurisdiction charges what, the full hearing ladder. As shared reference tables they power auto-fill, the NOA merge, and conflict checks — and no competitor has them.
state, so this same shape holds Washington today and Oregon after a seed job. A case picks KCDC-Seattle → the plaintiff, prosecuting-attorney office, and caption defaults follow automatically into the Notice of Appearance. Oregon's courts drop into the identical table — no schema change.| Reference table | Rows | Sample values (from Geoff's sheet) |
|---|---|---|
| Court | 47 | KCDC-Seattle · Seattle Municipal · Pierce County District · Kittitas County Superior · SCDC-Everett… |
| Prosecuting Attorney | 44 | King County PA · Issaquah — Moberly & Roberts · Edmonds — Zachor & Thomas… (mapped per court) |
| Plaintiff / Jurisdiction | 35 | State of Washington · City of Seattle · City of Bellevue · City of Kirkland… |
| Charge Type | 17 | DUI-refusal · DUI-BAC · DUI-drug · physical control · assault 4-DV · reckless driving… |
| Hearing Type | 23 | 1st appearance · Arraign · PTR1-7 · Case setting · Motions · Trial · Dispo · DOL#1/#2 |
| Party Role | 21 | Client · Atty-Prosecutor · LE-Primary officer · F&F-husband · Victim · Witness… |
| Negotiated Outcome | 14 | Neg1 · Reckless driving · DUI to under .15 · Deferred prosecution · Dismissed w/ prej… |
| Treatment / Proof item | 26 | Alcohol eval · ADIS · Anger mngmt · IID · VP · MRT · Talk therapy… (get proof) |
| Legal Issue | 13 | PC stop · PC detain · PC arrest · Right to counsel · Refusal reason · Mouth check… |
Phase 0 shipped the Client spine and the four-phase lifecycle. The model slots a Case between Client and everything else — the one structural change, made carefully because Client is live with real customers.
→ has many CasesCase — a JIS hit is what flips unfiled → filedMulti-state ambition, so the primitives come first and WA-DUI rides on them as pack #1. A thin second pack is authored immediately to keep the abstraction honest — an engine with one pack isn't a platform, it's a disguise.
Client, intake, consent, four-phase lifecycle with JIS auto-promotion. Live on prod.
Jurisdiction registry (WA seeded: courts, prosecutors), the Pack system (versioned field-schema / template / rule), and Case under Client with a pinned pack. WA-DUI authored as pack #1; a thin WA-assault (or OR-DUI) pack proves the seams. Reference data scoped by state from the first row.
Jurisdiction · Court · Prosecutor · PracticePack · Case · CaseDetail
Hearings on a case → the DubbleBooked calendar + Google Calendar sync, with the DOL deadline clock surfaced. Closes the loop from the case-management vision.
CourtHearing · DOLHearing
Typed contacts (feeding conflict checks & the NOA witness list) and the billable activity diary.
Contact · Activity
Outcome capture (drives → Closed) and the deep DUI arrest-report checklist — the issue-spotter.
Disposition · DiscoveryReview · Task
Thin payment + trust mirror that integrates rather than rebuilds; LawPay carries IOLTA compliance so we never touch trust funds.
Payment · TrustLedger