Skip to content

Database Schema

This document describes the current PostgreSQL schema direction for Nexus.

  • Source: live database metadata via information_schema and pg_constraint
  • Generated: 2026-06-25

Schema Direction

Nexus is moving away from a single-schema PostgreSQL layout.

  • Current state: almost all tables live in public
  • Target state: Nexus uses multiple PostgreSQL schemas to separate platform concerns from domain modules
  • First namespace: platform

Planned PostgreSQL Schemas

platform

System objects for accounts, tenancy, sessions, preferences, token revocation, and group authorization.

  • platform.users
  • platform.user_preferences
  • platform.user_sessions
  • platform.revoked_tokens
  • platform.user_groups
  • platform.user_group_memberships
  • platform.tenants

This schema is the first extraction from public because it contains the tenancy boundary, authentication records, and authorization relationships used by every other module.

public

For now, the remaining module tables can continue to live in public until each domain gets its own namespace strategy.

census

Person and identity records used across modules.

  • census.persons
  • census.identities

education

Education records. These tables currently live in the census namespace while the product module is named Education.

  • census.schools
  • census.school_years
  • census.school_calendars
  • census.school_enrollments
  • census.school_employments
  • census.school_employment_assignments

assets

Asset catalog, inventory, assignment, circulation, and repair records.

  • assets.asset_manufacturers
  • assets.asset_types
  • assets.asset_models
  • assets.assets
  • assets.asset_assignments
  • assets.asset_circulations
  • assets.asset_repairs

locations

Place hierarchy and location typing records.

  • locations.location_types
  • locations.locations

Initial examples:

  • public.issues
  • public.projects
  • public.configuration_items
  • public.configuration_item_relationships

Schema Pages

Use these focused pages for module-level schema reference:

This page remains the schema hub and design reference. The lower snapshot section still reflects the current single-schema database state and has not yet been rewritten into namespace-qualified tables.

alembic_version

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
version_numcharacter varyingNO-YesYesNo--
  • None

asset_assignments

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
asset_idcharacterNO-NoNoYesassetsCASCADE
person_idcharacterYES-NoNoYespersonsRESTRICT
location_idcharacterYES-NoNoYeslocationsRESTRICT
start_datedateNO-NoNoNo--
end_datedateYES-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • CHECK (((((person_id IS NOT NULL))::integer + ((location_id IS NOT NULL))::integer) = 1))
  • CHECK (((end_date IS NULL) OR (end_date >= start_date)))

asset_circulations

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
asset_idcharacterNO-NoNoYesassetsCASCADE
circulation_typetextNO-NoNoNo--
person_idcharacterYES-NoNoYespersonsRESTRICT
location_idcharacterYES-NoNoYeslocationsRESTRICT
occurred_attimestamp with time zoneNOnow()NoNoNo--
notestextYES-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • CHECK ((circulation_type = ANY (ARRAY['issued_to_person'::text, 'returned_from_person'::text, 'moved_to_location'::text, 'received_at_location'::text, 'location_confirmation'::text])))

asset_manufacturers

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
tenant_idcharacterNO-NoYesYestenantsRESTRICT
namecharacter varyingNO-NoYesNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
  • None

asset_models

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
nametextNO-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tracking_typetextNO'serialized'::textNoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
manufacturer_idcharacterNO-NoNoYesasset_manufacturersRESTRICT
end_of_supportdateYES-NoNoNo--
asset_type_idcharacterNO-NoNoYesasset_typesRESTRICT
  • CHECK ((tracking_type = ANY (ARRAY['serialized'::text, 'countable'::text])))

asset_repairs

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
asset_idcharacterNO-NoNoYesassetsCASCADE
titletextNO-NoNoNo--
descriptiontextYES-NoNoNo--
location_idcharacterYES-NoNoYeslocationsRESTRICT
statustextNO'open'::textNoNoNo--
prioritytextNO'normal'::textNoNoNo--
reported_attimestamp with time zoneNOnow()NoNoNo--
resolved_attimestamp with time zoneYES-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • CHECK (((resolved_at IS NULL) OR (resolved_at >= reported_at)))
  • CHECK ((priority = ANY (ARRAY['low'::text, 'normal'::text, 'high'::text, 'critical'::text])))
  • CHECK ((status = ANY (ARRAY['open'::text, 'in_progress'::text, 'resolved'::text, 'cancelled'::text])))
  • CHECK ((char_length(title) > 0))

asset_types

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
tenant_idcharacterNO-NoYesYestenantsRESTRICT
namecharacter varyingNO-NoYesNo--
end_of_support_labelcharacter varyingYES-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
  • None

assets

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
nametextNO-NoNoNo--
serial_numbertextYES-NoYesNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
model_idcharacterNO-NoNoYesasset_modelsRESTRICT
quantityintegerNO1NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • CHECK ((quantity > 0))

identities

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
person_idcharacterNO-NoNoYespersonsCASCADE
last_nametextNO-NoNoNo--
first_nametextNO-NoNoNo--
middle_nametextYES-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • None

location_types

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
namecharacter varyingNO-NoYesNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • None

locations

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
parent_idcharacterYES-NoNoYeslocationsSET NULL
namecharacter varyingNO-NoNoNo--
type_idcharacterNO-NoNoYeslocation_typesRESTRICT
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • None

persons

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
current_identity_idcharacterYES-NoNoYesidentitiesSET NULL
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • None

revoked_tokens

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
jticharacterNO-YesYesNo--
user_idcharacterNO-NoNoYesusersCASCADE
expires_attimestamp with time zoneNO-NoNoNo--
revoked_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • None

school_calendars

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
school_idcharacterNO-NoNoYesschoolsCASCADE
calendar_idcharacterNO-NoNoYesschool_yearsRESTRICT
namecharacter varyingNO-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • None

school_employment_assignments

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
person_idcharacterNO-NoNoYespersonsCASCADE
school_idcharacterNO-NoNoYesschoolsCASCADE
start_datedateNO-NoNoNo--
end_datedateYES-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
  • CHECK (((end_date IS NULL) OR (end_date >= start_date)))

school_employments

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
person_idcharacterNO-NoNoYespersonsCASCADE
start_datedateNO-NoNoNo--
end_datedateYES-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
  • CHECK (((end_date IS NULL) OR (end_date >= start_date)))

school_enrollments

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
person_idcharacterNO-NoNoYespersonsCASCADE
calendar_idcharacterNO-NoNoYesschool_calendarsCASCADE
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • None

school_years

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
namecharacter varyingNO-NoYesNo--
start_datedateNO-NoNoNo--
end_datedateNO-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • CHECK ((end_date >= start_date))

schools

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
namecharacter varyingNO-NoYesNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • None

tenants

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesYesuser_groupsRESTRICT
namecharacter varyingNO-NoYesNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
tenant_admin_group_idcharacterNO-NoNoYesuser_groupsRESTRICT
tenant_users_group_idcharacterNO-NoNoYesuser_groupsRESTRICT
  • None

user_group_memberships

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
tenant_idcharacterNO-NoYesYestenantsRESTRICT
user_idcharacterNO-NoYesYesusersCASCADE
user_group_idcharacterNO-NoYesYesuser_groupsCASCADE
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
  • None

user_groups

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
tenant_idcharacterNO-NoYesYestenantsRESTRICT
namecharacter varyingNO-NoYesNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
  • None

users

ColumnTypeNullableDefaultPKUniqueFKFK TargetOn Delete
idcharacterNO-YesYesNo--
usernametextNO-NoYesNo--
emailtextNO-NoYesNo--
password_hashtextNO-NoNoNo--
created_attimestamp with time zoneNOnow()NoNoNo--
updated_attimestamp with time zoneNOnow()NoNoNo--
person_idcharacterYES-NoNoYespersonsSET NULL
tenant_idcharacterNO-NoNoYestenantsRESTRICT
  • None

Nexus by McGuire Technology