No description
Find a file
Dave 9ddf8571f6 fix(dashboard): truncate subject to the schema's 300-char limit
logWorkAction wrote the full polished/typed message into both `summary`
and `subject`, but `subject` exists to hold a short git commit subject
line and is capped at 300 characters at the schema level. Any note over
300 characters (trivially reachable — a 2-3 sentence polished note
routinely runs 350-450 characters) failed the create call outright, and
the generic catch surfaced only "Could not save that entry" with the
real reason discoverable only by reproducing the write directly against
PocketBase.

`subject` is only ever a fallback for when `summary` is empty
(`commit.summary || commit.subject`), and a logged entry's summary is
always populated at creation — so truncating subject costs nothing
functionally. Also logs the underlying error server-side on any future
create failure, so this class of bug doesn't require re-deriving the
cause from scratch again.

Reproduced against the live PocketBase instance with the exact message
that failed for the user (348 chars) before and after the fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-19 14:49:39 +02:00
.superpowers/brainstorm/24862-1789651152 chore(config): update .gitignore and enhance Next.js configuration 2026-09-19 07:52:09 +02:00
docs/superpowers docs(plan): Phase 7 — logged work entries implementation plan 2026-09-19 13:47:59 +02:00
pocketbase/pb_migrations feat(users): active flag, backfilled, enforced at sign-in 2026-09-16 11:26:16 +02:00
public chore(config): update .gitignore and enhance Next.js configuration 2026-09-19 07:52:09 +02:00
scripts fix(commits): set source on ingest/backfill writes, tidy Task 1 review findings 2026-09-19 10:22:26 +02:00
src fix(dashboard): truncate subject to the schema's 300-char limit 2026-09-19 14:49:39 +02:00
tests/integration fix(test): tighten log-work assertions, repair summarise.test.ts for source exclusion, add owner-only UI check 2026-09-19 13:44:34 +02:00
.dockerignore chore(config): update .gitignore and enhance Next.js configuration 2026-09-19 07:52:09 +02:00
.env.example feat(board): drop position arithmetic with same-column handling 2026-09-16 10:00:57 +02:00
.gitignore chore(config): update .gitignore and enhance Next.js configuration 2026-09-19 07:52:09 +02:00
Dockerfile chore(config): update .gitignore and enhance Next.js configuration 2026-09-19 07:52:09 +02:00
next.config.ts chore(config): update .gitignore and enhance Next.js configuration 2026-09-19 07:52:09 +02:00
package-lock.json feat(ai): OpenAI-compatible adapter for MiniMax 2026-09-16 15:53:34 +02:00
package.json chore(dev): add dev:webpack script as a Turbopack fallback 2026-09-17 12:24:40 +02:00
postcss.config.mjs chore(scaffold): Next.js 16 + Tailwind 4 + vitest project skeleton 2026-09-16 09:37:43 +02:00
README.md docs: Coolify-only setup, and mark pb_migrations as non-executing 2026-09-16 10:32:26 +02:00
tsconfig.json chore(scaffold): Next.js 16 + Tailwind 4 + vitest project skeleton 2026-09-16 09:37:43 +02:00
vitest.config.ts test(metrics): cached figures agree with stored commits + vitest stubs 2026-09-16 15:19:32 +02:00

Client Board

Project tracking for client work. A developer runs their own board across several client companies; each client's manager signs in, sees only their own projects, and sets the priorities and target dates that matter to them.

Next.js 16 + PocketBase.

There is no local PocketBase

This project uses one PocketBase instance, hosted on Coolify. There is no local server to start and no local database to keep in sync. Point NEXT_PUBLIC_PB_URL at the hosted instance and run the app against it.

That means every developer and every test run shares one database. See "Tests touch real data" below before running the integration suite.

Setup

npm install
cp .env.example .env.local

Fill in .env.local:

Variable Notes
NEXT_PUBLIC_PB_URL The Coolify PocketBase URL. Public by design — the browser connects to it directly.
PB_SUPERUSER_EMAIL Server-side only. Never exposed to the browser.
PB_SUPERUSER_PASSWORD Server-side only. Never commit this.

.env.local is gitignored. .env.example is not — it is tracked, so anything written there is published to every clone and stays in history. Put placeholders in it, never real credentials.

Running

npm run dev

Applying the schema

npm run setup-remote

scripts/setup-remote.ts is the single source of truth for the schema. It creates every collection and applies the API rules against the hosted instance through the admin API. It is idempotent and non-destructive: re-running reuses existing collections and never deletes anything.

pocketbase/pb_migrations/ holds the same schema as PocketBase migration files. They are reference only and never execute — migrations run on server start, and this project does not start a PocketBase server. If you change the schema, change scripts/setup-remote.ts. Editing a migration file does nothing at all.

Seeding demo data

npm run seed

Creates one client, one project with its default columns, an owner account, a client-manager account, and a few cards.

Tests

npm test              # unit — pure logic, no network
npm run test:integration   # requires npm run dev to be running
npm run test:all

Tests touch real data. The integration suite signs in against the hosted PocketBase, creates and deletes a throwaway client and project, and changes priorities on seeded cards. That is fine while the database holds demo data only. Before a real client's board lives there, stand up a second PocketBase instance for tests — otherwise a test run edits their project.

Permissions, in one paragraph

PocketBase API rules are record-level and cannot express "this user may update priority but not column". So client managers are denied all writes at the database, and their edits go through /api/client/* route handlers that authenticate as a superuser and copy across only whitelisted fields. The owner writes through /api/owner/* using their own token, because the auth cookie is httpOnly and the browser SDK therefore has no credentials. If you find yourself relaxing a write rule to make a form work, that form should be posting to a route handler instead.

Specs and plans

  • docs/superpowers/specs/ — design documents
  • docs/superpowers/plans/ — implementation plans