Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
Translation pending
Online booking, calendar and customer management for salons, barbers, spas and other service businesses.
BusinessTypeScript · CSSGitHub @HarmedinoOnlineOwner 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
Loading the full README. The saved excerpt is shown below.
Online booking, a shared calendar and a client list for businesses that run on appointments: barbers, salons, nail techs, makeup artists, spas, massage therapists, trainers and clinics. Built first for small businesses in Nigeria that currently run on WhatsApp, paper diaries and spreadsheets. It works in any currency and time zone.Read the full README ↗Online booking, a shared calendar and a client list for businesses that run on appointments: barbers, salons, nail techs, makeup artists, spas, massage therapists, trainers and clinics. Built first for small businesses in Nigeria that currently run on WhatsApp, paper diaries and spreadsheets. It works in any currency and time zone.
There are three kinds of people in ServiceBook. Each one sees something different.
| They can | Where |
|---|---|
| Open the business's booking link from Instagram, WhatsApp or a printed QR poster | /book/:slug |
| Browse tabs: Book, Team, Our work (photos of finished styles), Reviews, Info (hours, directions, contact) | /book/:slug?tab=… |
| Book: pick a service, optionally a person, a day and a free time, then enter name and phone | /book/:slug |
| Join a waitlist when a day is fully booked | booking page |
| Chat with the business about a booking, cancel it, add it to their calendar, and rate the visit afterwards | /my-booking/:token |
| See all their appointments (past and upcoming) and book again without retyping their details | /c/:token |
| Join the business's client list (name, number, optional birthday) | /join/:slug |
| Ask to chat on WhatsApp, Instagram, Messenger, TikTok, X, Telegram or Snapchat. Their details are saved first, so every chat reaches the Inbox | booking page → "Chat with us" |
Payment happens at the appointment. Nothing is paid online yet.
| Area | What's there |
|---|---|
Home (/dashboard) | Today's schedule, what's next, setup checklist, this week's birthdays with a ready-to-send WhatsApp wish |
| Inbox | Booking chats with customers, and chat requests from social apps |
Bookings (/bookings) | List with search and filters. Each booking opens on its own page with confirm, mark done, no-show, move, cancel, notes and chat |
New booking (/bookings/new) | Search or quick-add a customer, then service, person, day and time |
| Calendar | Day, week and month views, time off shaded. Front desk view (/front-desk) is a full-screen version for a tablet at reception |
Calendar sync (/calendar/sync) | Subscribe from Google, Apple or Outlook, for the whole business or one person |
| Customers | Client list with history; each profile has a private link to send them (their own page) |
| Services, Staff | Prices, durations and who does what. Staff have hours, a bio, a location, ratings and an App access card to invite them |
| Showcase | Photos of finished work tagged by person and service, and the reviews customers leave |
| Time off | Block days or hours for one person or the whole business. Nobody can book those times, and clashes are listed |
| Waitlist | People waiting for a full day. You're notified when a spot opens |
| Settings | Business details, opening hours, chat apps, booking page on/off, your colour, emails, and a printable QR poster (/poster) |
| Notifications | A bell plus push alerts to the owner's phone or computer, even with the site closed |
| Roadmap & ideas | Vote on what gets built next and suggest ideas |
The owner invites someone from their staff page. The staff member opens a one-time link (/join-team/:token) and picks an email and password. After that they see only:
They can book customers in with themselves. Everything else is owner-only, and the server enforces it (see Security).
A typical week, end to end:
Customers are added to the client list automatically when they book. They're matched by phone number within each business.
| Path | Who | What |
|---|---|---|
/, /features, /solutions, /how-it-works, /about, /demo, /roadmap, /design | Everyone | Website, live demo, roadmap and design system |
/register, /login | Owners and staff | Sign up and sign in |
/book/:slug | Customers | Booking page with tabs |
/my-booking/:token | Customers | One booking: details, chat, cancel, rate |
/c/:token | Customers | All their appointments; book again |
/join/:slug | Customers | Join the client list |
/join-team/:token | Staff | Create a staff login from an invite |
/dashboard | Owner | Home |
/inbox | Owner, staff (own chats) | Messages and chat requests |
/bookings, /bookings/new, /bookings/:id | Owner, staff (own) | Bookings |
/calendar, /front-desk, /calendar/sync | Owner (staff: /calendar only) | Calendar views and sync |
/customers, /customers/new, /customers/:id, /customers/:id/edit | Owner (staff can view a customer) | Clients |
/services, /services/new, /services/:id, /services/:id/edit | Owner | Services |
/staff, /staff/new, /staff/:id, /staff/:id/edit | Owner | Team, hours, time off, app access |
/showcase, /showcase/new, /showcase/:id/edit | Owner | Portfolio and reviews |
public/sw.js) for push alerts.packages/types holds the request and response types shared by both apps, so the web and API can't drift apart.servicebook/
├── apps/
│ ├── web/ React app (Vercel)
│ │ ├── public/sw.js Service worker: push alerts when the site is closed
│ │ └── src/
│ │ ├── pages/ One file per page (marketing/ for the website)
│ │ ├── components/ Shared UI (ui/ for primitives)
│ │ └── lib/ Data hooks (one per API area) and helpers
│ └── api/ Express API (Render)
│ └── src/
│ ├── routes/ One router per area
│ ├── models/ Mongoose models
│ ├── lib/ Booking engine, push, ratings, iCalendar, demo…
│ ├── services/ Email, reminders, birthday notices
│ └── middleware/ Auth, business scoping, staff access list
└── packages/
├── types/ Shared TypeScript types
└── config/ Shared tsconfig
| Model | Holds |
|---|---|
User | Login: OWNER or STAFF |
Business | Profile, slug, time zone, currency, colour, settings, calendar-feed token |
BusinessHours, StaffAvailability | Weekly opening hours and each person's working hours |
Service, Staff | What's offered and who does it. Staff have optional userId (login) and invite token |
Customer | Per business, unique by phone. Optional birthday and a private page token |
Booking | Who, what, when, status, price at the time, private access token |
Message | Booking chat (customer ↔ business) |
TimeOff | Unavailable time for a person or the whole business |
WaitlistEntry | Someone waiting for a full day |
Review, WorkPost | Ratings after completed visits; portfolio photos |
Enquiry | Chat requests from social apps |
Notification, PushSubscription | The owner's bell and the devices that get push alerts |
Image | Uploaded photos (stored in MongoDB) |
Idea, AppSetting | Roadmap items and votes; server-wide values such as the push keys |
apps/api/src/lib/bookingEngine.ts is the single path for creating and moving bookings, for both owners and customers.
businessId. requireBusiness derives it on the server from the signed-in user and never trusts one sent by the client.STAFF login may only call the endpoints listed in middleware/staffAccess.ts. Those endpoints then limit data to that person: their bookings, chats and time off. Anything not on the list is owner-only./my-booking/:token and /c/:token use long random tokens. They're private links, the same model as Google's "secret address" calendar links.These run inside the API process:
/health every 10 minutes. The free plan sleeps after 15 idle minutes, which makes the next visitor wait about a minute and pauses the jobs above.You need: Node.js 20+, pnpm (corepack enable), and a MongoDB replica set. A free Atlas cluster works. Locally, a single-node replica set works too:
docker run -d --name mongo -p 27017:27017 mongo:7 --replSet rs0
docker exec mongo mongosh --eval 'rs.initiate()'
Then:
pnpm install
cp apps/api/.env.example apps/api/.env # works as-is against local Mongo
cp apps/web/.env.example apps/web/.env
pnpm dev # API on :4000, web on :5173
pnpm --filter api seed # demo salon with staff, services, clients, bookings and reviews
Demo logins (password password123 for both):
[email protected][email protected]Type checks: run pnpm typecheck from the repo root, or pnpm --filter api typecheck / pnpm --filter web typecheck for one app.
Tests: pnpm test runs both apps' tests (pnpm --filter api test / pnpm --filter web test for one). The API tests need MongoDB: each test file creates its own database from MONGODB_TEST_URI (default mongodb://127.0.0.1:27017/sbx_test, plus a random suffix) and drops it at the end. Against a replica set, also set MONGODB_REPLICA_SET=1 to run the transaction and simultaneous-booking tests:
MONGODB_REPLICA_SET=1 MONGODB_TEST_URI="mongodb://127.0.0.1:27017/sbx_test?directConnection=true" pnpm --filter api test
Without a replica set those tests are skipped and the rest run with DB_TRANSACTIONS=off, a switch the API accepts only when NODE_ENV=test. CI (.github/workflows/ci.yml) runs everything against a MongoDB 7 replica set, builds both apps, and imports the built API with node apps/api/scripts/smoke-dist.mjs.
The API runs on Render, the web app on Vercel. render.yaml describes the API as a Blueprint.
Releases, the frozen multi-business version and the order to deploy in are in docs/RELEASING.md; release notes are in CHANGELOG.md.
| Setting | Value |
|---|---|
| Root Directory | apps/api |
| Build Command | pnpm install --frozen-lockfile && pnpm run build |
| Start Command | pnpm start |
| Health Check Path | /health |
| Variable | Required | Notes |
|---|---|---|
NODE_ENV | yes | production |
MONGODB_URI | yes | Atlas string including the database name. Allow 0.0.0.0/0 in Atlas Network Access |
JWT_SECRET | yes | 32+ characters: openssl rand -base64 48 |
CORS_ORIGIN | yes | https://servicebook-drab.vercel.app. Comma-separate others; https://servicebook-*.vercel.app allows previews |
JWT_EXPIRES_IN | no | Default 7d |
EMAIL_PROVIDER | no | console (default, logs emails) or resend |
EMAIL_FROM, EMAIL_API_KEY | with resend | Sender and Resend API key |
ADMIN_EMAILS | no | Comma-separated emails that can change roadmap statuses |
SEED_DEMO | no | Default true: keeps the demo salon available and fresh. Set false to skip it |
VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, VAPID_SUBJECT | no | Push keys. Generated and stored automatically if unset |
KEEP_AWAKE | no | Default on when Render's RENDER_EXTERNAL_URL is set. false turns it off. KEEP_AWAKE_URL sets the address on other hosts |
The API stops at start-up with a clear message if a required variable is missing.
Import the repo with Root Directory apps/web (framework: Vite).
apps/web/.env.production points at the Render API. Set VITE_API_URL (no trailing slash) to override it. It's baked in at build time, so redeploy after changing it.vercel.json makes links like /dashboard and /book/your-business work on refresh./time-off, /time-off/new | Owner, staff (own) | Time off |
/waitlist | Owner | Waitlist |
/settings, /poster | Owner | Settings and the printable poster |