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
Cleaning scheduling software to schedule crews, send quotes, accept online payments, and close the books — built for residential and commercial cleaning businesses. 7-day free trial, no credit card re
BusinessGitHub @chris-712interactiveOnlineOwner 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.
Professional Scheduling System for Residential and Commercial Cleaning Companies
Loading the full README.
Read the full README ↗Multi-tenant scheduling, quoting, billing, and customer-service platform for residential and commercial cleaning businesses. Three portals served from a single Next.js deployment, switched by subdomain:
| Subdomain | Portal |
|---|---|
admin.<apex> | Founder admin |
my.<apex> | Unified customer |
<tenant-slug>.<apex> | Tenant operations |
<apex> / www.<apex> | Marketing site |
.nvmrc; enforced via engine-strict and CI)See .cursor/docs/plan/implementation-plan.md
for the full plan, and docs/design/portal-mockups/
for portal reference screens.
app/ # Next.js routes (rewritten by middleware per portal)
admin/ # Founder admin portal
customer/ # Unified customer portal (my.<apex>)
marketing/ # Public marketing site
tenant/ # Tenant portal (<tenant-slug>.<apex>)
components/
layout/ # Stack, Cluster, Grid, Container, ...
portal/ # PortalShell + TopBar + Sidebar + PageHeader + ...
theme/ # ThemeProvider, themeScript, ThemeToggle
ui/ # Card, Button, EmptyState, Skeleton, StatusPill, ...
lib/
env.ts # Zod-validated env access (fail-fast at boot)
portal.ts # Server helper for reading portal classification
supabase/
browser.ts # Public anon client (RLS-bound)
server.ts # Cookie-bound + service-role clients
database.types.ts # Generated by `supabase gen types` (placeholder for now)
styles/
_index.scss # Forwarding entry point for tokens + mixins
_theme.scss # Light / dark CSS custom properties
globals.scss # Resets, base typography, .skip-link
mixins/ # breakpoints, focus, a11y, typography
tokens/ # colors, spacing, typography, radii, shadows, z, motion, breakpoints
proxy.ts # Subdomain resolver + portal URL rewriter
pnpm install # or: npm install
cp .env.example .env.local
Fill in the Supabase URL + anon key + service role key from your local
Supabase project. Set NEXT_PUBLIC_APP_DOMAIN=lvh.me:3000 so wildcard
subdomains resolve to 127.0.0.1 automatically.
pnpm dev # or: npm run dev
Visit each portal:
Runtime and dependency lifecycle policy: docs/ops/runtime-eol-policy.md.
pnpm typecheck # tsc --noEmit
pnpm lint # next lint
pnpm lint:styles # stylelint **/*.scss
pnpm format # prettier --write .
pnpm build # next build
styles/tokens/_colors.scss (the only place
hex literals are allowed - stylelint enforces this).styles/_theme.scss) maps tokens to semantic CSS custom
properties (--color-bg, --color-text, --color-brand-primary, ...).components/theme/themeScript.ts) sets
data-theme="light|dark" on <html> before React hydrates, so users
never see a flash of the wrong theme.<ThemeToggle /> exposes a System / Light / Dark control persisted to
localStorage.cs_theme.x-portal (+ x-tenant-slug when applicable) headers to downstream Server
Components./admin/..., /tenant/..., etc.) so each portal owns a distinct route
tree without collisions.current_tenant_id + tenant_role
claims for that purpose.