Commit Graph
5 Commits
Author SHA1 Message Date
aneurinandClaude Sonnet 5 16f94293ab Make the per-owner project cap configurable via env
CI / php-tests (pull_request) Successful in 19s
Self-hosters shouldn't be stuck with a hardcoded 100-project limit;
MAX_PROJECTS_PER_OWNER now controls it, defaulting to 0 (unlimited).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 09:34:08 +00:00
aneurinandClaude Sonnet 5 5c8f2dbf07 Un-hard-wrap all Markdown documentation
Every prose paragraph and list item was manually wrapped at ~80-100
columns; joined each back into a single line. Headings, table rows,
and fenced code blocks are untouched -- tables already had one row per
line, and wrapping inside a code fence is the code's own formatting,
not something this applies to.

Also fixed two pre-existing typos this surfaced (both from wrapping
without leaving the space that was actually intended): a missing space
in "{ challenge_id, options }" and a stray "+ TypeScript" that had
accidentally been written as if it were a new line, in web/README.md
and README.md respectively.

Code comments are explicitly out of scope for this -- left exactly as
they were.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 02:29:08 +01:00
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
aneurinandClaude Sonnet 5 fb67b57807 Reorganize docs: simple README + organized docs/
Removed docs/stage-1-auth-api.md -- an early planning doc, badly out
of date (predates passwordless auth, statuses, the inbox, and
everything after).

README.md is now just: what this is, a pointer to docs/, an end-user
getting-started guide (Docker up, first-time login via the bundled
Mailpit catcher, adding a passkey), and provenance -- everything else
it used to carry moved out:

- docs/api.md -- the full REST API reference (auth, passkeys,
  projects, cards, statuses, error shape) + the curl walkthrough.
- docs/setup.md -- running without Docker, every environment
  variable, the test suite.
- docs/architecture.md -- backend file layout; points to
  web/README.md for the frontend, which already documented itself in
  enough depth to stand alone.
- docs/history.md -- the stage-by-stage feature log, with a new row
  for this session's refactoring work (which hadn't been logged yet).
- docs/README.md -- an index tying the above together.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 01:41:55 +01:00
aneurinandClaude Sonnet 5 7faef6fbff Add stage 1: authentication REST API
Slim 4 + SQLite todo-list API providing email/password registration,
login, and an authenticated GET /me endpoint. Stateless HS256 JWTs,
bcrypt password hashing, uniform JSON error envelope, and a SQL
migration runner. Includes PHPUnit feature tests and stage-1 docs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 17:35:10 +01:00