TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
Pick a time and book it in seconds. One slot, one guest, never double booked.
Translation pending
ProductivityTypeScript · CSSGitHub @TrajkowOnlineOwner 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
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 ↗A small scheduling app in the shape of a coffee chat / office hours page: one host publishes time slots, and anyone can book one with their name and email. A slot can never be booked twice. Built for the TeamLift internship challenge.
| Brief requirement | Where |
|---|---|
| 1. Create available slots (date, start time, duration) | /host, "Publish slots". One start time plus a count creates back-to-back slots. |
| 2. See the list of available slots | /, time pills grouped by day, in the one time zone. |
| 3. Book a slot with name and email | Pick a time and it turns into "time │ Book →"; press Book, fill in the form, get a confirmation with an "Add to calendar" .ics download. |
| 4. A booked slot is no longer available | Booked slots stay on the page, greyed out and labelled "Booked". The database refuses a second booking. |
Both optional extras are in:
/host. Slots that clash with an event in that
calendar show as "Busy" to guests and cannot be booked. Only free/busy times are read, never event titles.The host can also delete an unbooked slot and cancel a booking (the slot becomes available again).
Browser ──► Vercel (Next.js, proxies /api/*) ──► Render (NestJS API) ──► Neon (PostgreSQL)
├──► Gemini (confirmation message)
└──► Google Calendar (free/busy)
/api/* to the backend, so there is no CORS setup.The guarantee lives in the database, not in app code:
booking.slot_id is UNIQUE. Two requests for the same slot both pass any "is it free?" check, but the database
accepts only one insert. The API turns the unique violation into 409 SLOT_TAKEN.slot (EXCLUDE USING gist (tstzrange(starts_at, ends_at, '[)') WITH &&)) stops two
slots from overlapping. It is mapped to 409 SLOT_OVERLAP.backend/test/bookings.concurrency.e2e-spec.ts fires 20 parallel booking requests at one slot and expects exactly
one 201 and nineteen 409. A similar test covers parallel slot creation.The checks in the service only exist to give clearer error messages. They are not what keeps the data correct.
Needs Node 24, npm and Docker (for PostgreSQL).
# Backend: http://localhost:3000 (starts Postgres in Docker on port 5433)
cd backend
cp .env.example .env
npm install
npm run db:generate
npm run db:migrate
npm run start:dev
# Frontend: http://localhost:3001 (proxies /api to the backend)
cd frontend
cp .env.example .env.local
npm install
npm run dev
Optional demo data (10 half-hour slots over the next 5 weekdays and one booking), from backend/: npm run seed.
Tests (from backend/; the e2e tests use a separate slot_test database on the same Postgres):
npm test # unit tests
npm run test:e2e # API tests, including the 20-parallel-bookings test
From frontend/: npm run typecheck.
Optional settings in backend/.env (all documented in .env.example):
GEMINI_API_KEY (and GEMINI_MODEL): real AI messages. Get a free key in Google AI Studio.GOOGLE_OAUTH_* and CALENDAR_TOKEN_KEY: the "Connect Google Calendar" button.
GOOGLE_CALENDAR_ID and GOOGLE_SERVICE_ACCOUNT_JSON: a fallback calendar without sign-in.
Setup steps are in docs/deploy.md. Without any of these, the app works and the extras switch off.HOST_KEY: when set, /api/host/* needs an X-Host-Key header and /host asks for the key.Deploying (Neon + Render + Vercel) is described in docs/deploy.md.
/host is open on the live demo and reviewers can try it.
An optional HOST_KEY switches protection on; it is off on the demo on purpose.APP_TIME_ZONE (default Europe/Skopje),
and the UI says so. The backend turns a date and start time into an instant in that zone./api/host/* does.POST /api/bookings/:id/confirmation-message ("Writing a note for you…") until it is ready. Output is stripped of
markdown and links, and the first AI text is stored. Booking never depends on it: after about 40 s, or if Gemini
fails, the guest sees the template.409 SLOT_UNAVAILABLE if it clashes.
The host's OAuth refresh token is stored encrypted (AES-256-GCM), is never logged or returned, and only the
free/busy scope is requested.I built this with Claude Code. The work was split into phase plans in docs/plans/ (scaffold, backend, frontend, AI, deploy, README, Google Calendar, host OAuth), and agents executed those plans one phase at a time on their own branches, following the rules in AGENTS.md. A coordinating Claude Code session ran lint and build on each branch, reviewed it and fixed issues before merging, for example clearing lint warnings, logging the reason when the calendar check fails, and rejecting truncated auth tags when decrypting the calendar token. I made the product decisions (theme, both extras, the host connecting their own calendar) and set up the hosting. Gemini is used inside the app for the confirmation message.