jason 062fd194b0
Build and Push Docker Image / build (push) Successful in 1m36s
ci: unify to canonical docker-build workflow (drift labels baked in)
2026-07-19 13:55:33 -05:00
2026-06-15 16:21:53 -05:00

V11 Enterprise QMS

Full-stack quality management system — Next.js 15 (pages router) + Prisma + SQLite, packaged as a single Docker container for self-hosting on Unraid. Starts from zero data and learns as your team uses it.

Status — partial build. The implemented modules are: authentication, the first-build Form builder (admin), Fill / Report an issue (production), Nonconformances + Resolutions library (QC), Client release / Shipments, Client issues / Quality escapes, and the living Shipping standard. The remaining nav items (Admin dashboard, Users, Audit trail, Settings, QC dashboard, CAPA, Audits, Documents, Risk, Suppliers, Standards, My submissions, Management dashboard & Reports) are wired into navigation but render a "Coming soon" placeholder — the data model for them already exists in prisma/schema.prisma.

Roles & access

Role Access
Admin Everything: form builder, users, settings, audit trail
QC CAPA, audits, NCRs, resolutions, documents, risk, suppliers, standards, shipping standard
Production Fill first-build forms, report issues
Production lead Production + client release, client issues, shipping standard, NCRs
Logistics lead Client release, client issues, shipping standard, NCRs
Management Read-only dashboards and reports

Only Admin / Production lead / Logistics lead can email a client release package.


Deploy on Unraid (the intended setup)

CI/CD: push to Gitea → Gitea Actions builds the image → pushes to registry.alwisp.com/jason/qms:latest → install/Force-update from the Unraid Docker GUI.

1. Build & push (automatic)

.gitea/workflows/docker-build.yml builds and pushes the image to registry.alwisp.com/<owner>/<repo>:latest on every push to main. It needs two repo secrets: REGISTRY_USER and REGISTRY_TOKEN.

2. Run on Unraid

Either docker compose up -d with the bundled docker-compose.yml, or add a container in the Unraid Docker GUI with the equivalent settings:

Setting Value
Repository registry.alwisp.com/jason/qms:latest
Network Custom: br0 — assign a free IP in 10.2.0.0/24
Volume /mnt/user/appdata/qms/data
DATABASE_URL file:/data/qms.db
NEXT_PUBLIC_APP_URL http://<the-br0-ip>:3000
ADMIN_EMAIL / ADMIN_PASSWORD / ADMIN_NAME first-run admin (created only if no admin exists)
SMTP_* (optional) enables outbound email; omit to keep notifications in-app only

On first start the container runs prisma db push (creates /data/qms.db), then create-admin (creates the admin from ADMIN_* only if none exists), then serves on port 3000. The SQLite file lives entirely in the mapped volume, so the container is disposable — update by pulling a new image.

The app is reached at http://<the-br0-ip>:3000. Sign in with the admin credentials and change the password.


Local development

npm install
cp .env.example .env          # DATABASE_URL defaults to file:./dev.db
npm run db:push               # create the SQLite schema
npm run create-admin          # seed the first admin from ADMIN_* in .env
npm run dev                   # http://localhost:3000

Useful scripts: npm run build, npm run start, npm run db:studio.


Why SQLite (not Postgres)

This deploy targets a single self-contained container, so the schema was converted from PostgreSQL to SQLite. SQLite (via Prisma) supports neither native enums nor Json/scalar-list columns, so:

  • former enums are stored as String and validated in app code (union types in types/index.ts);
  • former Json columns (AuditLog.before/after, FormSubmission.data, QualityStandard.specs) and the FormField.options list are stored as JSON-encoded strings, (de)serialised at the DB boundary (see lib/forms.ts).

Project structure

/pages
  /api          ← backend API routes (auth, forms, submissions, ncrs, escapes, shipments, …)
  /admin /qc /fill /management  ← role-scoped pages
/components     ← layout shell, shared UI kit, form field renderer
/lib            ← prisma client, auth/session, email, form (de)serialisation helpers
/prisma         ← schema.prisma (SQLite)
/scripts        ← create-admin.js (first-run bootstrap)
Dockerfile · docker-compose.yml · docker-entrypoint.sh · .gitea/workflows/build.yml

init-source/ holds the original delivery (base snapshot + fix/update overlays) for provenance; it is excluded from the build and the image.

S
Description
V11 Enterprise QMS — quality management: form builder, first-build forms, NCRs/resolutions, client release, quality escapes, living shipping standard. Next.js + Prisma + SQLite, single container (partial build).
Readme 83 MiB
v0.5 Latest
2026-07-17 16:04:23 -05:00
Languages
JavaScript 95.6%
TypeScript 4.4%