Files
project-manager/docs/history.md
T
aneurinandClaude Sonnet 5 f1309b4c10 Rebuild the Docker image on Alpine: ~735MB -> ~89MB
Stage 2 was php:8.3-apache (Debian), which compiles PHP from source
with --with-apxs2 for mod_php -- that base image alone is 719MB of
our 735MB, before any app code. Replaced with alpine:3.24 + apk's own
prebuilt php83/php83-apache2/apache2 packages: same architecture (one
process, mod_php, .htaccess-driven rewriting), no fpm/nginx rewrite
needed.

- docker/apache.conf: rewritten for Alpine's apache2 (mod_rewrite ships
  but isn't loaded by default; a different default document root/log
  paths). Logs redirected to stdout/stderr so `docker logs` still shows
  them -- Alpine's own defaults write to a real file under ServerRoot,
  unlike the official Debian image's symlinked paths.
- docker/entrypoint.sh: su-exec instead of su -- BusyBox's su doesn't
  take the same -c/user argument order as the GNU one the previous
  entrypoint relied on. Also moved earlier in the Dockerfile (with the
  other rarely-changing setup, before COPY . .) so it no longer re-runs
  on every build for a file that essentially never changes.
- Composer's binary is still borrowed from the official composer:2
  image via multi-stage COPY, not apk's own `composer` package, which
  turned out to pull in an entire second PHP interpreter (php85) as a
  dependency just to run itself.
- ext-iconv needed adding explicitly (symfony/polyfill-mbstring depends
  on it; the official Debian image bundles it by default, apk doesn't).

Verified against the real compose stack, not just that it builds: apk
install; composer install; migrations on startup; PHPUnit 88/88 (runs
on the host, but confirms nothing else broke); and by hand, all
through the actual container -- health check, SPA fallback for unknown
routes, static assets served directly, the API's 401 guard, and a full
magic-link -> verify -> JWT -> authenticated project create/list round
trip via the real Mailpit catcher.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 02:15:39 +01:00

2.9 KiB

Development history

A stage-by-stage log of major features, in the order they landed. Each row describes the app as it was at that point — later stages sometimes superseded earlier ones (e.g. password login, added in stage 1, was removed again in stage 12); see docs/api.md and web/README.md for how things work now.

Stage Scope State
1 Auth API — register, login, GET /me done
2 Frontend shell — Vite PWA, auth-gated routing, register/login pages done
3 Project + card CRUD API done
4 Frontend projects view — project index + create form done
5 Frontend project detail — cards UI with drag-and-drop reorder done
6 Project view — inline title/description editing, delete via a Manage menu done
7 Email verification (magic links) + profile page (resend, change email) done
8 Passwordless login — magic-link by default, password login behind a toggle done
9 Per-project card statuses ("To do" / "Doing" / "Done"); status chip, new cards start with none done
10 Project view — full-width, tabbed: alphabetical "All tasks" list + "Kanban" board, per-column drag ordering done
11 Persistent left sidebar (Dashboard link + project dropdown); dashboard = grid of project tiles + a "Create a project" tile done
12 Passwordless-only auth — registration and password login removed; a magic link is the sole way in, and creates the account if needed done
13 Global inbox — cards can have no project; moved into the sidebar, drag in/out of any project's kanban columns done
14 New-project form moved to the dashboard; sidebar project list is now a switcher dropdown; Kanban is a project's default tab done
15 Passkeys (WebAuthn) — register from the profile page, sign in with one instead of a magic link; a dismissible notice nudges users with none done
16 Project configuration view — manage a project's statuses: add, drag to reorder, delete (reassigning any cards on it first) done
17 Card detail view (/cards/:id) + its own configuration view — a card's text is no longer inline-editable; every list links to its own page instead done
18 Project view split into real routes — Explore (/projects/:id) and Kanban (/projects/:id/kanban) are separate pages under a shared layout, not client-side tab state done
19 Backend/frontend refactoring pass — deduplicated controller/repository boilerplate and CSS, dropped the never-surfaced project description field, squashed the SQL migration history into one clean initial schema done
20 Docker image rebuilt on Alpine (apk's own php83/apache2 packages instead of compiling PHP from source on Debian) — ~735MB down to ~90MB, same architecture otherwise; .dockerignore trimmed to match done