# work

Operations app for Bowden Works. Next.js (App Router) + Supabase Cloud.

## Definition of done (READ FIRST)

The long-term plan is to be able to **rebuild this app from
`docs/` alone**. That only works if docs stay current. The rule:

A **substantive** feature isn't done until ALL of these are true:

1. Code ships clean — `npx tsc --noEmit` + `npx vitest run` pass,
   `srv-gw deploy --project work --build` succeeds.
2. **Feature doc updated** in `docs/features/`. Edit an existing
   `*.md` (Changelog section + the affected sections — Behavior,
   Constraints, Permissions, etc.) OR create a new feature doc
   following the template in `docs/README.md`. New features also
   need a row added to `docs/features/INDEX.md`.
3. **`docs/decisions.md` ADR appended** if any of these changed:
   - DB schema (new table, FK, column with semantic meaning)
   - Lock / permission / precedence rule
   - A feature replaced or removed another
   - A non-obvious choice was made between viable alternatives
4. **Removed features get deleted, not tombstoned** — per
   `docs/README.md`, delete the `features/*.md` file and let the
   ADR carry the history. No "(LEGACY)" tombstones.

A feature is **substantive** if it involves any of:
- A new or altered Supabase migration in `supabase/migrations/`
- A new page or route under `app/(app)/`
- A new server action or significant change to an existing one
- A change to a lock / permission / precedence / eligibility rule
- A new column or constraint on `time_entries` / `projects` /
  `team_members` / similar core tables

Tiny tweaks (copy edits, styling, small refactors, internal
renames) don't trigger the rule — but if you're unsure, treat it
as substantive.

Per `docs/README.md`, the workflow for substantive features is
"**propose the doc update before writing code**", not after.
Drafting the doc first surfaces edge cases.

If a feature ships without all the above, surface it in the
response as **`DOCS-DEBT: <what's missing>`** AND append a line
to `docs/UNDOCUMENTED.md` so the gap is visible. Don't pretend
the feature is done. Cleared as docs are written.

## Project Info
- Type: custom (Next.js container)
- Port: 3094 (host) -> 3000 (container)
- URL: https://work.bowden.works
- Auth/DB: Supabase Cloud
- Created by: rian, 2026-05-20

## Stack
- Next.js 14 App Router (TypeScript, React Server Components, Server Actions)
- Supabase Cloud (Auth + Postgres) via `@supabase/ssr`
- Plain CSS (no Tailwind yet — add when UI grows)

## Layout
```
app/
  page.tsx                  # Landing (auth-gated, shows user + orgs)
  login/                    # Email + password sign-in
  change-password/          # First-login forced password change
  auth/signout/route.ts
lib/supabase/               # Browser, server, and middleware clients
middleware.ts               # Session refresh + auth-gate + must-change-password redirect
supabase/migrations/        # SQL files — paste into Supabase SQL Editor
scripts/seed.ts             # Seed users/orgs/memberships via admin API
```

## Data model (initial)
- `profiles` — extends `auth.users`. Holds `is_super_admin` and `must_change_password`.
- `organizations` — name, slug.
- `organization_members` — (org_id, user_id, role). `role` is enum: owner / manager / member.

RLS is enabled. A user can read their own profile and the orgs they're a member of.

## First-time setup
1. Create a Supabase Cloud project at https://supabase.com/dashboard.
2. Fill `/srv/apps/work/.env` — replace the three `REPLACE_WITH_*` values
   (Project URL, publishable key, secret key). Keep `.env` at chmod 600.
3. In the Supabase dashboard, open the SQL Editor and run the contents of
   `supabase/migrations/0001_init.sql`.
4. From `/srv/apps/work`: `npm install`, then `npm run seed`. Capture the
   temporary passwords from terminal output — they're not stored.
5. Deploy the container: `srv-gw deploy --project work --build`.

## Managing the container
```bash
srv-gw deploy --project work --build   # Rebuild + redeploy after code changes
srv-gw status --project work
srv-gw logs --project work
srv-gw restart --project work
```

Local dev (without Docker) — runs against the same Supabase project:
```bash
npm install
npm run dev   # http://localhost:3000
```
