Dillo example

Party Planner

One party backend, member-scoped.

What this demonstrates

One backend for the whole party: the party itself, the food, the todos, the photos — four tables, every one scoped to the party's own members. If you are not in the party, you do not see its plans. This is how a group gets a shared space with the access rules built into the schema, not bolted on per page.

How it works

The permissions are the app. This is the whole data model — schema.ts, the first of the app's three files (its import line, not shown, brings these names in from "create-dillo/schema"):

schema.ts
// The schema the live backend serves today (span2/live-schemas filing, re-verified at deploy).
export default schema({
  Food: table({
    bringing: relation.user().optional().nullable(),
    name: string().min(1).max(120),
    partyId: relation.team(),
    quantity: integer().min(1).max(100),
  }).permissions({ view: members, edit: recordOwner.or(roles('admin', 'owner')) }),

  Party: table({
    name: string().min(1).max(120),
    partyId: relation.team(),
    place: string().min(1).max(200),
    startsAt: string().datetime(),
  }).permissions({ view: members, edit: roles('admin', 'owner') }),

  Photo: table({
    caption: string().min(1).max(200),
    image: file().accept('image/jpeg', 'image/png', 'image/webp').maxBytes(5242880),
    partyId: relation.team(),
  }).permissions({ view: members, edit: recordOwner.or(roles('admin', 'owner')) }),

  Todo: table({
    done: boolean(),
    partyId: relation.team(),
    task: string().min(1).max(160),
  }).permissions({ view: members, edit: members }),
});

Try it

  1. Open the live demo
  2. Edit the party plan
  3. Open it signed out — the party's tables stay members-only