Javis OS
Javis OS is an Agentic AI that assists entrepreneurs in business tasks, helping them grow their work.
AI translation
Live demo of a staff scheduling app by Lucien Andrieux, freelance developer. Try it, then have your own built with your rules and branding.
BusinessTypeScript · PythonGitHub @LucienAndrieuxOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Staff scheduling app: live rule validation, one-click fixes, OR-Tools month generation and plain-language requests. Demo with fictional data.
Taken from the repository README
Loading the full README.
Read the full README ↗Self-hosted web app for the monthly staff schedules of a small hotel (about 25–30 employees in six sections): month and week views, scheduling rules and validation, an hour bank, one-click repairs, full-month generation with OR-Tools, natural-language constraints and three visitor roles (manager, employee, read-only).
Stack: Next.js 16 (App Router) · TypeScript · Tailwind CSS 4 + shadcn/ui · PostgreSQL 18 · Drizzle ORM · Better Auth · pg-boss · any OpenAI-compatible LLM · Python FastAPI + OR-Tools CP-SAT · Vitest · Biome · Docker Compose + Caddy.
apps/web Next.js app (UI, Server Actions, jobs, domain logic)
apps/web/src/lib/domain Pure TypeScript: durations, day codes, hour bank, validator, repairs
services/solver OR-Tools CP-SAT schedule generator (FastAPI)
docs/seed-data.json Fictional demo data (single source of truth for the seed)
infra Production compose file, Caddyfile, backup script
infra/windows Native Windows Server install, update and backup scripts
Every person, hotel, place, employee number, birthday, leave period and schedule
in docs/seed-data.json is fictional. The demo hotel is "Demo Alpine Lodge", an
invented mountain hotel in an invented French Alps village; public holidays are
generated for France and the demo months are November 2026 to January 2027.
The November 2026 reference schedule is produced by
scripts/generate-demo-schedule.ts: it builds a schedule that respects the rules,
then adds a handful of deliberate mistakes (a birthday worked, a late shift followed
by an early one, a rest day worked, a couple without a shared rest day, a
short-staffed restaurant, two colleagues off the same weekend, a shift outside an
employee's skills) so the validator and the "Fix" button have something to show.
The seed also holds five example natural-language constraints (approved, awaiting review and rejected) with their parsed operations, so the Constraints page is not empty; every visitor sees them and managers can approve or reject them.
There are no accounts: the start page creates an anonymous session (Better Auth anonymous plugin) with the role the visitor picks.
Every night at 03:00 the demo data is restored and the guests are removed. An hourly job removes guests older than 24 hours, and when the current month has no published schedule it empties the data and imports the seed again with rolling demo months (the current month and the next two), each with a freshly generated published schedule; the current month contains the deliberate mistakes.
The start page also presents the custom-build offer, a contact form and a
"Schedule a meeting" dialog. The visitor picks a weekday, then a free 30-minute
slot (Paris time, starts 09:00–14:30 and 17:00–18:30); the slots busy in the
developer's Google Calendar are hidden (free/busy API through a service account,
GOOGLE_*). Messages, and calendar invitations (.ics) from the visitor's
address, are emailed to CONTACT_EMAIL through SMTP (SMTP_*; printed to the
console when SMTP_HOST is empty), with a honeypot field and a per-address rate
limit.
Quotas (DEMO_* variables) limit generations per hour (one at a time on the whole
site) and LLM calls per visitor and per day.
Prerequisites: Node.js 24+, pnpm (npm i -g pnpm), Docker Desktop.
cp .env.example .env
Edit .env: set BETTER_AUTH_SECRET (openssl rand -base64 32) and, to parse natural-language constraints, LLM_API_KEY / LLM_BASE_URL /
LLM_MODEL (OpenAI, Groq or any OpenAI-compatible API with structured outputs).
docker compose up -d --build
pnpm install
pnpm db:migrate
pnpm db:seed
pnpm dev
Open http://localhost:3000 and pick a role on the start page.
| Command | Description |
|---|---|
pnpm dev | Dev server on :3000 (also starts the pg-boss worker) |
pnpm check | Typecheck + Biome lint + Vitest |
pnpm format | Biome format and safe fixes |
pnpm db:generate | New SQL migration from the Drizzle schema (apps/web/drizzle/) |
pnpm db:migrate | Apply migrations |
pnpm db:seed | Idempotent import of docs/seed-data.json, then a validator report for the reference month |
pnpm db:generate-demo | Regenerate the demo reference schedule inside docs/seed-data.json |
pnpm db:reset | Drop every table of the local database (refuses any non-local host) |
pnpm db:studio | Drizzle Studio |
The seed only inserts rows that are missing (matched on natural keys), so it never
overwrites changes made in the app. To start from scratch:
pnpm db:reset && pnpm db:migrate && pnpm db:seed.
A day is either a shift (codes A–E, per section) or one of these codes:
| Code | Label | Kind | Due day | Credits time |
|---|---|---|---|---|
| OF | Day off (weekly rest) | rest | no | no |
| PH | Public holiday | absence | yes | yes |
| AL | Annual leave | absence | yes | yes |
| SL | Sick leave | absence | yes | yes |
| BD | Birthday leave | absence | yes | yes |
| TL | Time off in lieu | absence | yes | no |
| TR | Training | absence | yes | yes |
| OL | Other paid leave | absence | yes | yes |
| UL | Unpaid leave | absence | no | no |
Requirements: Docker Engine with the compose plugin, a DNS record pointing
APP_DOMAIN to the server, ports 80 and 443 open.
git clone <repo> /opt/shift-smith && cd /opt/shift-smith
cp .env.example .env
In .env, set at least APP_DOMAIN (e.g. planning.example.com),
POSTGRES_PASSWORD, BETTER_AUTH_SECRET, the LLM_* variables, APP_TIMEZONE and HOTEL_NAME. DATABASE_URL and
BETTER_AUTH_URL are derived by the compose file.
docker compose -f infra/docker-compose.prod.yml --env-file .env up -d --build
docker compose -f infra/docker-compose.prod.yml --env-file .env exec web node scripts/seed.mjs
postgres is not published on the host; data lives in the pgdata volume.web applies pending migrations at every start, then serves Next.js
(standalone build) and runs the background job worker.caddy obtains and renews the HTTPS certificate for APP_DOMAIN automatically.Update: git pull && docker compose -f infra/docker-compose.prod.yml --env-file .env up -d --build.
See infra/windows/README.md: PostgreSQL, Node.js and the Python solver run as Windows services behind an existing reverse proxy.
infra/backup.sh writes a gzipped pg_dump to ./backups and deletes dumps older
than KEEP_DAYS (14 by default). Install it as a daily cron job:
chmod +x infra/backup.sh
( crontab -l; echo "15 3 * * * /opt/shift-smith/infra/backup.sh >> /var/log/planner-backup.log 2>&1" ) | crontab -
Copy backups/ off the server regularly (e.g. rclone or rsync). Backups are
ignored by git and must never be committed.
Restore a dump (the dump contains DROP … IF EXISTS, so it replaces the current data):
docker compose -f infra/docker-compose.prod.yml --env-file .env stop web
gunzip -c backups/planner-YYYYMMDD-HHMMSS.sql.gz \
| docker compose -f infra/docker-compose.prod.yml --env-file .env exec -T postgres psql -U planner -d planner
docker compose -f infra/docker-compose.prod.yml --env-file .env start web
requireUser() / requireManager()), and every mutation is written
to audit_log.lib/domain/validator.ts checks every hard rule (rest time across
midnight, consecutive days, two rest days per ISO week, monthly weekend off,
birthday, couples, approved leave, eligibility, unavailability, staffing) and
computes hours per employee and ISO week.monthly_close entry per employee
with a complete month.source = constraint).