# 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 ```bash 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. | | `NEXT_PUBLIC_APP_URL` | Public HTTPS address of the app, used if a link request has no Origin header. Set it to the deployed domain, for example `https://planner.apphub.co.za`. | | `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 ```bash npm run dev ``` ## Applying the schema ```bash set -a source .env.local set +a 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 ```bash npm run seed ``` Creates one client, one project with its default columns, an owner account, a client-manager account, and a few cards. ## Tests ```bash 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. ## Collaborative planning `/plan` reads live cards in Inbox, Backlog, To Do, and other working columns. Review, Done, archived cards, and inactive projects are omitted. Undated cards stay visible with a **Set dates** action. The week view is for precise ranges; the year view shows the wider schedule. Clients may edit draft ranges for their own projects and submit a project plan. The owner may approve it or request changes, optionally pointing to a card. An approved copy remains visible while another draft is prepared. Ranges live in `projects.plan_data`, separate from `cards.start_date` (which also controls commit linking). Client plan writes verify the signed-in account and project ownership before updating the project through the admin connection. Before using the new planner on the hosted instance, load `.env.local` as shown above and run `npm run setup-plan-schema`. This targeted command only adds the optional `projects.plan_data` JSON field; it does not run the full setup script or rewrite existing records. Existing projects start with an empty draft, and no existing card dates are overwritten. ## Work areas Each project has its own named work areas. A card can link to one area while keeping its independent Kanban column, priority, and plan dates. The board shows an area-colored edge and label on linked cards; the area legend filters the visible cards. The Plan page shows the same area labels alongside its existing priority-colored schedule bars. Existing cards remain uncategorised until assigned on their card page. The quick-add and intake forms ask for an existing area or a new name. New areas receive the next unused color from a fixed palette; the color is saved on the area record. `work_areas` is related to `projects`, and client reads follow the project's client access rule. Client writes are validated by the app before using the admin connection. Run `npm run setup-work-area-schema` with `.env.local` loaded to add only the `work_areas` collection and optional `cards.work_area` relation. The same schema addition is included in `npm run setup-remote` for new environments. ## Specs and plans - `docs/superpowers/specs/` — design documents - `docs/superpowers/plans/` — implementation plans