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>
31 lines
2.9 KiB
Markdown
31 lines
2.9 KiB
Markdown
# 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](api.md) and
|
|
[web/README.md](../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 |
|