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
Live childcare availability, waitlists and subsidies — and the operations software centres use to run them.
BusinessTypeScript · CSSGitHub @UsharabiotechOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
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 ↗Live childcare availability for families and a small ERP for the centres that publish it. Built on a vertical-agnostic booking core so clinics, hospitals and venues can be added later.
Families search licensed centres by city and age group, see open spaces and waitlist sizes, join waitlists, track their position and estimated wait, accept or decline offers, and estimate their fees and subsidy.
Centres see occupancy by room, run their waitlist and send offers, take attendance, split monthly fees between parent / subsidy / program funding and create draft invoices, and check staff-to-child ratios. Every offer and enrolment updates the public listing automatically.
All centres, families and children in the seed data are invented.
Requires Node.js 20+.
npm install
npm run setup # creates tables and loads sample data into ./.data/pglite
npm run dev # http://localhost:3000
Open Sign in and pick a demo account:
Without DATABASE_URL, the app uses PGlite (Postgres compiled to WASM)
stored in ./.data/pglite. It allows one process at a time, so stop npm run dev before
running npm run db:seed again. Reseed from scratch with npm run db:seed -- --reset.
docker compose up -d
cp .env.example .env
# set DATABASE_URL=postgres://openslot:openslot@localhost:5432/openslot
npm run setup
npm run dev
Production must use PostgreSQL. Host it in a Canadian region (see the checklist below).
| Command | What it does |
|---|---|
npm run dev | Development server |
npm run build / npm start | Production build and server |
npm run setup | Migrate + seed |
npm run db:generate | Create a new SQL migration after changing src/db/schema.ts |
npm run db:migrate | Apply migrations |
npm run db:seed | Load sample data (-- --reset to wipe first) |
npm run db:import-ontario | Load real Ontario centres as directory listings (-- --reset-ontario to replace) |
npm test | Unit tests + an end-to-end offer/accept test against in-memory Postgres |
npm run typecheck | TypeScript check |
src/
db/
schema.ts Tables (Drizzle ORM). The generic booking core.
client.ts Postgres (DATABASE_URL) or embedded PGlite
migrate.ts, seed.ts
domain/ Pure logic, no database — safe to share with a mobile app
types.ts Age groups, queue flags, DomainError
queue.ts Admission order, wait estimate, offer hold time
rules/provinces.ts Fees, ratios and subsidy rules per province
services/ Business operations used by both the web UI and the API
listings.ts Public search and availability
queue.ts Join, offer, accept, decline, withdraw, expire
centre.ts Dashboard, attendance, ratios, billing, invoices
capacity.ts Occupancy counts and publishing to the listing
auth.ts Demo sign-in (replace before a pilot)
app/ Next.js App Router
page.tsx Find care
waitlists/ Family's waitlists and offers
subsidy/ Fee & subsidy estimator
centre/[locationId]/ ERP: dashboard, waitlist, attendance, billing, staff
actions.ts Server actions behind the web forms
api/v1/ REST API for the mobile app and centre website widgets
drizzle/ SQL migrations
tests/
Organization ─┬─ Location (vertical, province, licence, base fee, funding programs)
│ └─ Resource (room / practitioner / court; capacity; attrs e.g. ageGroup;
│ publishedOpen + publishedAt = what the public sees)
└─ User (centre_admin)
Customer (parent) ── Dependant (child) ── User (family)
QueueEntry resource × dependant; status waiting → offered → accepted | declined | expired | withdrawn
Booking the enrolment; active | ended; approved subsidy per month
Attendance one row per booking per day
Staff assigned to a resource; on/off shift
Invoice per booking per month, split into parent / subsidy / program shares
Key rules live in code, not the database:
domain/queue.ts).GET /api/cron/expire-offers releases unanswered ones.Alongside the invented demo centres, you can load every licensed childcare centre in Ontario from the province's open data — about 6,350 active centres under 2,600 licensees:
# 1. Download the latest monthly file from the Ontario Data Catalogue (XLSX) into data/ontario/
# 2. Turn it into the importer's JSON (keeps only active facilities):
python scripts/extract_ontario.py data/ontario/<file>.xlsx data/ontario/active_facilities.json
# 3. Load it:
npm run db:import-ontario # add -- --reset-ontario to replace a previous import
This is the beginning of the README. Read the rest at the original. Read the full README ↗