Skip to main content

Database

Overview

The MakerLab application uses PostgreSQL 16 for all domain data. The schema is applied automatically on first container start.

Snipe-IT uses a separate MariaDB 11.4 instance that is managed internally — the MakerLab application code never connects to it directly.


Schema file

infra/db/init/schema.sql

This file is mounted into the PostgreSQL Docker container as:

/docker-entrypoint-initdb.d/schema.sql

It runs automatically when the PostgreSQL container starts for the first time (i.e., when the makerlab_postgres Docker volume is empty).


Main tables

TablePrimary keyDescription
usersid BIGSERIALRegistered users (auto-created on SSO login)
projectsid BIGSERIALLab projects
project_membersid BIGSERIALUser↔Project membership with role
equipment_modelsid BIGSERIALEquipment model types (synced from Snipe-IT)
equipmentid BIGSERIALPhysical asset instances (synced from Snipe-IT)
equipment_requestid BIGSERIALEquipment requisitions
equipment_request_itemsid BIGSERIALItems within a requisition
equipment_usageid BIGSERIALUsage records per checkout event
status_historyid BIGSERIALImmutable audit log of status changes
notificationsid BIGSERIALIn-app notifications

For the full schema with column definitions and FK relationships, see Data Model.


Status constraints (CHECK constraints)

TableColumnAllowed values
usersrolestudent, professor, lab_technician
projectsstatuspending, active, rejected, completed, archived
project_membersroleleader, member, observer, advisor, supervisor
equipmentstatusavailable, reserved, checked_out, maintenance, retired
equipmentconditionnew, good, fair, damaged, unusable
equipment_usagestatuschecked_out, returned, overdue, lost
status_historyentity_typeproject, equipment_request, equipment_usage, equipment
notificationstypeinfo, warning, request, approval, return, reminder
warning

These CHECK constraints are enforced by PostgreSQL. Inserting a value outside the allowed set will raise a constraint violation error. Ensure application code always uses the exact allowed values.


Legacy ID columns

Several tables have a legacy_id BIGINT UNIQUE column used exclusively by the migration tool to track which records were imported from the legacy wiki. Normal application operations do not use these columns.

Tables with legacy_id:

  • users
  • projects
  • equipment_models
  • equipment

Snipe-IT reference columns

TableColumnReferences
equipment_modelssnipeit_model_idSnipe-IT model ID
equipmentsnipeit_asset_idSnipe-IT asset ID
equipment_requestsnipeit_asset_idSnipe-IT asset ID being requested

Seed data

Test data can be loaded from:

docker compose -f infra/docker/docker-compose.yml exec -T postgres \
psql -U makerlab -d makerlab < infra/db/init/seed.sql

Database reset

To fully reset the schema and data (development only):

docker compose -f infra/docker/docker-compose.yml down -v
docker compose -f infra/docker/docker-compose.yml up -d

The -v flag removes the Docker volume. The schema is re-applied automatically on the next start.

warning

This deletes all data permanently. Use only in development environments.


Schema changes

There is no Alembic migration tooling in the repository. Schema changes are applied by:

  1. Editing infra/db/init/schema.sql.
  2. In development: reset the database (see above) or apply the change manually with psql.
  3. In production: write and execute a manual ALTER TABLE migration.

All changes should be reviewed and tested before deploying to production.


PostgreSQL environment variables

Configured in infra/db/.env.postgres:

POSTGRES_USER=makerlab
POSTGRES_PASSWORD=CHANGE_ME_STRONG_PASSWORD
POSTGRES_DB=makerlab

The application database user makerlab_app (used in DATABASE_URL) should have only the permissions necessary to operate (SELECT, INSERT, UPDATE, DELETE on relevant tables). Using a separate app user instead of the superuser makerlab is best practice.

To verify: the current schema may create the application using the superuser account. A separate, least-privilege app user should be configured for production.