- cja_media table; POST /api/media/upload (admin-gated, multipart).
- Images optimised with GD (downscale to 1600px, re-encode; WebP for
transparency, JPG for photos). Video via ffmpeg (scale, compress, drop audio).
- Stored in app/public/media/ (source tree) so uploads survive rebuilds and are
copied into public/ on build.
- requireAdmin() moved to PublicController base (fixes a static/non-static
clash with AdminAuth). Type detection uses getimagesize (fileinfo ext absent).
Note: php-fpm must be in the caweb group to write app/public/media (restart
after adding www to caweb).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DoFYZY9gkGPNDqZ7NuEa9a
Establishes the deploy baseline on main so the admin agent's publish/rollback
has a clean starting point. Everything built to date: sumi-e brand system,
homepage, projects (DB-driven case studies), resume, about, services +
website-design detail, contact form + DB, changelog, favicon + share card.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DoFYZY9gkGPNDqZ7NuEa9a
Two self-contained framework fixes, no schema dependencies:
- throttle(): exempt trusted callers via new Functions::isTrustedIp() — loopback, the
server's own IP, and an optional TRUSTED_IPS config allowlist (IPs/CIDRs). Fixes the SSG
build (which fetches the read API from the box thousands of times per build) tripping the
public rate limit and baking empty data into the deploy. Public client IPs stay limited.
- public/index.php: set secure session cookie params (httponly, SameSite=Lax, secure on
https) before session_start, so session/login state rides on a hardened cookie.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FMQeUnUrAeexcZ7P2Hxa6G
Clean-room copy of the reusable engines from comiida, with all
instance data, secrets, dependencies, and build output excluded:
- app/ Astro theme skeleton (no comiida blog posts; hero image -> placeholder)
- api/ SeedProject PHP framework (no vendor/.env/config.php)
- content-pipeline/ engine only (scripts/admin/prompts; empty runtime state)
- astroagent.config.json + app/.astroagent/skills
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SYHWLHihq3v9nxNwoPCKSn