Notes

Notes

Reference CRUD feature at /dashboard/notes. Simple per-user note management.

Purpose

Notes is a reference implementation showing the simple form CRUD pattern (inline form, list view, minimal UI chrome). Use it as a template for features that don't need table sorting, filtering, or bulk actions.

Notes is the reference pattern for porting every feature to shared Postgres , see architecture/postgres-port.md for the full model. It demonstrates:

  • A Drizzle pgTable schema, scoped by userId
  • createServerFn queries and mutations
  • withUserTransaction + logUserEvent together, using the tx handle for every query inside
  • checkEntitlement for plan limits, fetched read-only before the transaction, enforced with a fresh count inside it (see gate ordering)
  • Feature barrel (index.ts) exporting queryOptions and mutations
  • Integration tests with withTestDb() (real Postgres, transaction-per-test, forced rollback)

Key files

src/features/notes/
├── index.ts                    -- barrel
├── notes.constants.ts          -- Zod schemas, types
├── server/
│   ├── notes.queries.ts        -- listNotes, getNote
│   ├── notes.mutations.ts      -- createNote, updateNote, deleteNote
│   ├── notes.server.ts         -- DB logic (listNotesFromDb, etc.)
│   └── notes-crud.test.ts      -- 8 integration tests
└── pages/
    └── index.tsx               -- NotesList page component

Schema: notes table in src/lib/db/schema.ts. Add/change columns there, then bun run db:generate (drizzle-kit) and bun run db:migrate.

Plan limit

config.stripe.limits[plan].maxNotes controls how many notes a user on each plan can create. -1 = unlimited.

Using as a template

To build a new feature, copy the notes feature structure and replace note/notes with your entity name. Keep the test file -- it documents all the expected behaviors.