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
Three bugs found deploying a fresh clone to seedproject.com, each fatal
to the documented "spin up a new site" flow:
- .gitignore: the unanchored `public/` pattern (meant for the root build
output) also ignored api/public/ (the framework's front controller,
controllers, models, views) and app/public/ (theme static assets:
fonts, avatar placeholder). Neither was ever committed, so every fresh
clone 500'd on all /api routes and 404'd on theme assets. Anchor the
pattern to /public/ and commit both directories.
- api/install/dump.sql: stray `CREATE DATABASE ochenta80_db123` (SQLyog
export artifact) aborted `php console app:install` for any
non-privileged DB user. The schema must import into whatever database
the installer connects to.
- PluginManager::boot() queries sp_plugins on every request, but no
shipped schema creates it — even a successful install 500'd on every
endpoint. Add migration 002_create_sp_plugins.sql matching the columns
PluginManager reads/writes.
Also empty api/system/errors.json, which shipped with stale error logs
from an unrelated project.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C3JqxTe7TKaR7xufcMr7Ds