DEV Community

Vennbase booking app

Claude Code 66 messages April 07, 2026
by alexdavies74
Vennbase booking app claude-sonnet-4-6
You

<ide_opened_file>The user opened the file /temp/readonly/Bash tool output (qky70r) in the IDE. This may or may not be related to the current task.</ide_opened_file>

Use @vennbase/react and @vennbase/core for data, and puter.js for other backend needs.

Start by installing the packages, then start from the core README and enter planning mode.

I'd like you to plan, and then build, a complete, usable, fitness studio booking web app.

The first user will create and manage a Studio, which has a class schedule. Keep it simple, offer inputs for start and end time for each class, participant limit, with a button to make a new class. No weekly repetition. They should be able to copy a link to provide to their customers.

When others scan and follow the link, after logging in, they enter the booking experience. This is a very simple text-based experience, listing the available classes. Each class has a book button, which immediately reserves a slot in that class for the logged-in user. Other customers should (within a few seconds) see the slots are taken. This should work even if the original owner's client is not online.

Security model: Only the original owner should be able to see everything. Each customer should be able to create/cancel their own bookings, and see the presence of other customers' bookings, but NOT see the identity of the booker, or any other private details of the booking. This security should be robust to customers who can modify their own client code. You are responsible for this security, and if you need my help, you must ask for it.

Interaction model: All create/write actions in the UI should feel instant, using optimistic updates. If the owner is looking at a class when someone books, they should be able to see that the class got a new signup, within several seconds.

You may ask me about problems with your tooling. Avoid other questions, we are practicing to one-shot this task.

Do not explore my file system outside the current directory.

Don't write a custom backend!

Agent
Agent
Agent
Agent

Now let me read PATTERNS.md and look at the appointment-app example:

Agent
Agent
Agent

Now let me check the current project structure:

Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent

Now I have everything I need. Let me write the final plan:

Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent

Now create tsconfig, vite config, and index.html in parallel:

Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent

That App.tsx has some bad patterns I need to fix before moving on:

Agent
Agent

The errors are forward references (components not yet created) and type issues with save. Let me fix App.tsx and then create the remaining files:

Agent
Agent

Just a hint, not a blocker. Let me keep building — creating the remaining files:

Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent
Agent

Clean. Now start the dev server:

Agent
Agent
Agent

TypeScript is clean and the dev server is running at http://localhost:5174.

Here's a summary of what was built:

Files created:
- package.json — scripts + all deps
- tsconfig.json, vite.config.ts, index.html — build scaffold
- src/schema.tsstudios, classes, bookingRoots, bookings, myBookings
- src/db.ts — Vennbase instance
- src/main.tsx — React root with VennbaseProvider
- src/App.tsx — session gate, invite handler, role routing, welcome page
- src/hooks/useCreateStudio.ts — creates the hidden booking inbox + studio atomically
- src/components/OwnerView.tsx — class schedule, add-class form, live booking counts, copy-link button
- src/components/CustomerView.tsx — class list, Book/Cancel buttons, slot availability with 5s cooloff convergence

Security model in effect:
- bookingRoots is never shared as a viewer link — customers only get submitter access via the embedded link
- select: "indexKeys" on bookings exposes only classId + bookedAtMs — no owner identity, no refs, enforced server-side by Vennbase
- studio.owner is set server-side on creation and used for role detection — cannot be spoofed

You

<local-command-caveat>Caveat: The messages below were generated by the user while running local commands. DO NOT respond to these messages or otherwise consider them in your response unless the user explicitly asks you to.</local-command-caveat>

You

<command-name>/context</command-name>
<command-message>context</command-message>
<command-args></command-args>

You

Now you've had experience working with Vennbase, I'd like to get your evaluation of the platform in comparison to other options you know. Where did it cause friction?

Focus on the things that slowed you down or wasted tokens, as well as things that contributed to bugs. You may also share what was a positive surprise about the experience.

Keep it brief and don't describe solutions.

Agent

Friction points

Role/ref type cascade. The save() method on useSavedRow takes a RowHandle in one overload and a RowRef in another, but the type error messages span 8 lines of generic noise. I wrote the wrong variant twice before getting it right. Similar issue with removeParent — it accepts RowInput but the error when you pass the wrong thing gives you the full schema union, not a hint about what's actually wrong.

bookingRef field type conflict. field.ref("bookings") creates a typed ref, but submitters can't resolve refs to collections they don't have access to. The schema compiles fine — the problem would only surface at runtime. Nothing in the API surface warns you at definition time that this field will be opaque to submitters.

select: "indexKeys" return type inference. The type system does handle this correctly, but only if you write the options object inline. Extracting query options into a variable loses the literal type and you get RowHandle[] instead of DbIndexKeyProjection[]. This forced me to keep options inline everywhere.

No where clause on non-indexKey fields. The myBookings query needed where: { studioRef: ... } but studioRef had to be .indexKey() for that to work. Easy to miss — silently becomes a full scan if you forget.

What caused the bug I caught

The WelcomePage intermediate component I wrote that called require("react") — a moment of confusion about how to lazily import a hook. Caught it before running but it wasted tokens on a rewrite.

Positive surprise

The blind-inbox pattern is genuinely elegant. Embedding the submitter link as a plain string field on the readable row means customers self-serve their inbox access with one idempotent call, and the owner never has to manage a member list. That's a meaningful reduction in app-level access-control logic compared to anything I'd build on Supabase RLS or Firebase rules. The explicit-grant model also meant I could reason about the security surface in one pass rather than auditing rule expressions.

You

Give a two-sentence summary evaluation: would you want to use Vennbase again?

Agent

Yes — the access control model is the best I've seen for this class of app, and "no backend" is a genuine promise rather than a marketing hedge. The TypeScript ergonomics need polish (generic error messages, inference loss on extracted options), but none of the friction was a blocker and the core abstractions held up under a non-trivial security requirement.