Synaplan
Open-source AI platform for companies: self-hosted AI agents, GDPR-compliant chatbot widget, RAG knowledge base, WhatsApp and Outlook AI, MCP, multi-model routing. Docker, Kubernetes or hosted in Germ
Environment, Health & Safety management for multi-site companies.
Translation pending
BusinessGitHub @fernandotigerOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Multi-tenant Environment, Health & Safety SaaS. Each company (tenant) switches on the modules it subscribes to. Documents, Incidents, Risk and Configuration are live; Audits, Inspections and Law are next and plug into the same shared services (Form Builder, scheduled jobs, follow-up actions). See docs/PLATFORM.md (platform contract) and docs/modules/ (what exists, per module).
See docs/ARCHITECTURE.md for layers, design patterns and coding conventions.
Company structure, users, roles with scoped assignments, Form Builder, scheduled jobs (reminders/digests that also feed My work), pick-lists, numbering formats, branding, module settings, import, subscription and the audit log.
organizationId, tenant-scoped Prisma client). Company structure: business unit → site → location → department.OPENROUTER_API_KEY on the server; chats are not saved.Requirements: Node.js 20.9+ (22 recommended) and a PostgreSQL database.
npm install
cp .env.example .env # then edit values
Database options for local testing
npx prisma dev -n oleoq -d. .env.localdb already points at it
(DATABASE_DRIVER=pg, DATABASE_POOL_MAX=1, DATABASE_IDLE_TIMEOUT_MS=1 – this lightweight server drops idle and
parallel connections); prefix commands with bash scripts/localdb.sh to use it instead of .env, e.g.
bash scripts/localdb.sh npx prisma migrate deploy. For the dev server on another port also set BETTER_AUTH_URL:
BETTER_AUTH_URL=http://localhost:3100 bash scripts/localdb.sh npx next dev -p 3100.docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=ehs postgres:17.DATABASE_DRIVER=neon, DATABASE_URL (pooled) and DIRECT_URL (direct).Store uploaded files on your computer: set STORAGE_DRIVER=local (files go to LOCAL_STORAGE_DIR, default ./storage).
npx prisma migrate deploy # create tables and immutability triggers
npm run db:seed # two demo tenants (Northstar, Oleo Demo) with users and documents
npm run dev # http://localhost:3000
npm run tenant:create -- --name "Acme Ltd" --slug acme --admin-email [email protected] --admin-name "Jo Bloggs" --password "…" [--modules documents,incidents,risk]
Module keys: documents, incidents, risk, audits, inspections, law (change later with npm run tenant:modules).
Password123!)Development only. Full list in docs/modules/platform.md.
| Tenant | Role | |
|---|---|---|
[email protected] | Northstar Manufacturing | Administrator (everything, Configuration) |
[email protected] | Northstar | HR Admin – Document Library, audiences, reports |
[email protected] | Northstar | EHS Manager for the whole company (incidents, risk) |
[email protected] | Northstar | Manager + EHS Manager at site Dublin Plant only |
[email protected] | Northstar | EHS Investigator (Warehouse, Cork) |
[email protected] | Northstar | Employee (Warehouse, Cork) |
[email protected] | Oleo Demo Ltd | Administrator of the second tenant (isolation checks) |
| Script | Purpose |
|---|---|
npm run dev | Dev server (Turbopack) |
npm run build / npm start | Production build / serve |
npm run typecheck · npm run lint · npm test | Quality gates |
npm run db:migrate | Create a migration from schema changes (dev) |
npm run db:deploy | Apply migrations |
npm run db:seed | Seed demo data (idempotent) |
npm run db:seed:incident-types | Re-apply only the demo incident types + their forms to an existing database (local unless ALLOW_REMOTE_SEED=1) |
npm run db:seed:assistant | Give the demo companies their AI assistant settings (built-in guide) if they have none yet (local unless ALLOW_REMOTE_SEED=1) |
npm run tenant:create -- … | Provision a company with default roles, lists, settings and its first administrator |
bash scripts/localdb.sh <cmd> | Run any command against the local prisma dev database instead of .env |
npm run icons | Regenerate PWA icons |
To test the service worker locally, either run a production build (npm run build && npm start) or set NEXT_PUBLIC_ENABLE_SW=true in dev.
DATABASE_DRIVER=neonDATABASE_URL = pooled connection stringDIRECT_URL = direct (non-pooled) connection string, used for migrationsBLOB_READ_WRITE_TOKEN. Set STORAGE_DRIVER=vercel-blob. Files are stored as private blobs and only served through authorised API routes. Browsers upload directly to Blob, so files larger than the 4.5 MB function body limit work.BETTER_AUTH_SECRET (long random string) and BETTER_AUTH_URL (e.g. https://ehs.example.com).CRON_SECRET (random string). vercel.json schedules /api/cron/reminders (06:00 UTC, acknowledgement reminders and escalations) and /api/cron/jobs (09:00 UTC, the scheduled jobs configured per company). Vercel sends the secret automatically. On the Hobby plan crons run at most daily, so a job set for another time runs at the next daily call; on Pro you can call /api/cron/jobs every 15 minutes.OPENROUTER_API_KEY (Project → Settings → Environment Variables, mark it Sensitive, then redeploy). Without it the assistant shows "not set up yet" to administrators and stays hidden for everyone else.
Optional: AUDIT_SIGNING_SECRET (defaults to BETTER_AUTH_SECRET). Never rotate it without keeping the old value, or existing signatures can no longer be verified. Reusing a database you already used locally: copy BETTER_AUTH_SECRET (and AUDIT_SIGNING_SECRET if set) from that .env.vercel-build script runs prisma generate, prisma migrate deploy and next build.DATABASE_URL=<direct url> npm run db:seed. Otherwise sign in with a user you create in the seed or database. Demo incident types only: npm run db:seed:incident-types.
Files seeded or uploaded with STORAGE_DRIVER=local stay on that machine – documents that point to them cannot be opened on Vercel until they are re-uploaded.Existing database from the pre-merge app: the multi-tenant schema replaces the old one (new
initmigration), soprisma migrate deployfails on it. Reset that database first (deletes all its data):DATABASE_URL=<direct url> npx prisma migrate reset, which re-applies all migrations and runs the seed.
Scale: with ~15,000 active users, keep the Neon pooled URL for the app (serverless functions open many short connections) and size compute to your traffic. All user-scaled lists and audience calculations run in SQL with pagination.
No code changes are needed, only configuration:
| Concern | Setting |
|---|---|
| Amazon RDS / Aurora PostgreSQL | DATABASE_DRIVER=pg, DATABASE_URL=postgresql://… (use RDS Proxy for serverless workloads) |
| Amazon S3 | STORAGE_DRIVER=s3, S3_BUCKET, S3_REGION, plus credentials via IAM role or S3_ACCESS_KEY_ID/S3_SECRET_ACCESS_KEY. Keep Block Public Access on, and add a CORS rule that allows PUT from your app origin (browsers upload with presigned URLs). |
| S3-compatible (MinIO, R2) | also set S3_ENDPOINT |
| App server (ECS / App Runner / EC2) | Docker image from the Dockerfile (migrate target once per release) – see docs/deploy-aws.md for variables, secrets and release order |
| Scheduled work | EventBridge Scheduler → HTTP GET with header Authorization: Bearer $CRON_SECRET: /api/cron/jobs every 15 min, /api/cron/reminders daily |
Every stored file records the driver it was written with, so older files stay readable while you migrate objects.
nosniff.