Glossary & Data Model
Terms
| Term | Meaning |
|---|---|
| Region | An independent deployment unit with its own database, Redis, and (usually) storage bucket — e.g. EU-1, ME-1. Identified everywhere by a REGION_CODE like EU-1 or ME-1. |
| Global database | The one shared PostgreSQL database (schema.global.prisma) holding admins, referrals, the region directory, routing/mapping tables, and shared catalogs. Read-only from regional servers; writable only via the Auth Server. |
| Regional database | A per-region PostgreSQL database (schema.regional.prisma, auto-generated) holding all tenant data: companies, patients, appointments, invoices, etc. |
| Auth Server | New standalone service (packages/auth-server) that resolves "which region is this account in" and hosts admin login, cross-region registration, and the admin dashboard's cross-region GraphQL API. |
| Regional server | The existing packages/server API/cron/queue processes, one deployment per region, each backed by that region's own database. |
| Region lookup | The REST call (/api/lookup, /api/lookup-company, etc.) a client makes before login/registration/public-link access to find which region's API to talk to. |
| Fake region | A deterministic-but-meaningless region returned by a lookup for an email/company that doesn't exist, so failed lookups can't be used to enumerate real accounts. |
| Company routing hint | A short encoded string (?c=...) appended to public/QR links so the recipient's browser can resolve the right region without a slow all-region scan. |
| Internal GraphQL | A second, separately-authenticated GraphQL endpoint (/internal/graphql) on each regional server, used only for server-to-server admin/cron/redis calls from the Auth Server — not reachable via normal user login. |
INTERNAL_API_KEY | Shared static bearer token that authenticates internal-GraphQL and user/company-mapping-sync calls between the Auth Server and regional servers. |
| Migration ledger | The CompanyRegionMigration record (plus its progress/lock tables) in the global database that tracks the state of one company's region-to-region move — status, row counts, timestamps, last error. |
| Fence (Redis) | A temporary marker set during a real company migration that write paths are expected to check and reject/skip writes for a fenced company, so no new writes land mid-copy. |
| Blocker | In-flight company work (pending upload, unpaid online payment, in-progress e-invoice submission) that prevents a migration from freezing and copying the company's data. |
| Cutover | The point in a company migration where global routing tables are updated to point at the target region — before cutover, undoing the migration just means discarding target data; after cutover, the source is the one considered stale. |
| Soft reference | A foreign-key column kept on a regional model that used to @relation to a now-global model (e.g. Company.referralId); the column stays, but Prisma can no longer traverse the relation across the two separate databases. |
Global-schema data model (selected)
Region— one row per deployment region (code, name, status).CompanyRegion— which region currently owns a given company; the record cutover updates.CompanyRegionMigration(+CompanyRegionMigrationTableProgress,CompanyRegionMigrationStorageProgress,CompanyRegionMigrationCompanyLock) — the migration ledger described above.UserRegionMapping— email → region, kept in sync by regional servers via the/internal/user-mappingwebhook.CompanyLoginNameMapping— clinic login name → region, kept in sync via/internal/company-mapping.RegistrationWorkflow— idempotency/state tracking for cross-region signups in progress.Admin,Referral— Dentolize staff and referral-partner accounts; these stay global since they're not scoped to a single clinic/region.CompanyPayment— kept global specifically because it referencesAdmin.GlobalInventoryItem,GlobalMedication,GlobalCondition— shared catalogs every region reads but doesn't own.FeatureFlag— global feature-flag definitions.
Regional-schema data model
Everything else — Company, User, Patient, Appointment, Invoice, and the other ~130 models that make up the existing clinic product — lives unchanged (same fields, same relationships to each other) in the regional schema. The regional schema is generated automatically from the pre-existing monolith schema.prisma, so there is no new data modeling here — only a new boundary around where that data is hosted.