Skip to main content

Data Model

Illumera stores everything in PostgreSQL, accessed through Drizzle ORM. The schema lives in lib/db/src/schema/ — one file per domain area — and is the single source of truth for table shapes and enumerations.

Entity groups

AreaRepresentative tables
Tenancy & identitytenants, users, user_company_memberships, impersonation_tokens
Companiescompany_profiles, company_pipeline_stages, company_candidate_notes
Talentperson_profiles, person_skills, person_certifications, education
Projects & staffingprojects, project_slots, slot_skill_requirements, role_templates
Engagementsengagements, engagement_events, engagement_ratings
Skills & cultureskills, certifications, skill_relationships, culture (CVF)
Matching & AImatch_scores, match_score_history, ai_assessments
Capability Intelligencecompany_capability_goals, company_capability_recommendations, company_capability_goal_snapshots
Financialinvoices, project_budget_overrides, submission_reports
Cataloguecatalogue_submissions, catalogue_external_imports, catalogue_remediation_actions
Integrations & systemalign, communication, notifications, audit_logs, email_logs

Key enumerations

These pgEnum values are the vocabulary the whole platform shares. They are defined in the schema and reflected through the OpenAPI contract into the frontend.

EnumValues
User roles (users.roles, a text array)platform_admin, company_admin, company_member, person (legacy company still honored by the rate limiter)
Availability (availability_status)available, limited, booked, not_looking
Seniority (seniority_level)junior, mid, senior, lead, principal, fellow
Proficiency (proficiency_level)aware, beginner, intermediate, advanced, expert
Skill category (skill_category)frontend, backend, data_analytics, devops_cloud, security, design_ux, domain_industry, leadership_management
Project status (project_status)draft, active, paused, completed, archived
Slot status (slot_status)open, filled, cancelled
Engagement status (engagement_status)shortlisted, invited, accepted, active, paused, completed, terminated, declined, withdrawn, archived
Visibility (visibility)private, tenant, federated, marketplace
tip

User roles are not a database enum — they're a text[] on users, so a single user can hold several roles (a dual-role admin who also runs a company is common). Authorization checks whether the user's roles array contains any of the roles a route requires.

Tenancy & isolation

Most rows carry a tenantId. Isolation is enforced in the API layer, not by trusting the client:

  • The tenant is derived server-side from the authenticated user's DB record. The raw x-tenant-id request header is never honored as a tenant source.
  • A platform admin gains tenant context only through an active impersonation session; a dual-role admin who also owns a company falls back to their own tenant.
  • Partnership agreements between tenants are what allow talent visibility to cross tenant boundaries in the federated marketplace.

Migrations

Schema changes are not applied ad hoc. After editing a file under lib/db/src/schema, run pnpm --filter @workspace/db generate and commit the generated migration, snapshot, and journal entry. CI regenerates migrations from the schema and fails on drift — a schema edit without its migration will not merge.