Replace the made-up Security Layer abstraction with accurate direct
connections: all APIs (REST/GraphQL/Realtime) talk directly to Cache
and Queue; AntiVirus connects only from Storage, which is the only
service that actually scans files via ClamAV.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Group Cache, Queue, AV, Database, Executor and Docker into an
Infrastructure subgraph to reduce cross-boundary edges from Workers
from 14+ down to 2-3, fixing the broken vertical layout.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the static draw.io SVG with an embedded Mermaid diagram that
renders natively in GitHub markdown. Updated component names and added
new services (Sites, Messaging, VCS, Tokens, Proxy) and workers
(Messaging, Migrations, Executions) that were added since the original
diagram was created.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
utopia-php/framework was the old name for utopia-php/http. Replacing it
with utopia-php/http 0.34.19 which fixes getCookie() to use Swoole's
native cookie store (populated via php_raw_url_decode) instead of
re-parsing the raw Cookie header without URL-decoding.
This fixes a production auth bug where Swoole's setcookie() URL-encodes
base64 session values (+ → %2B, / → %2F, = → %3D) in Set-Cookie headers.
RFC 6265 clients (Dart, Swift) reflect these verbatim; the old getCookie()
returned %2B/%2F/%3D to base64_decode() which produced corrupted output,
rejecting valid sessions.
Also updates the e2e test client to use cURL's built-in RFC 6265 cookie
engine (CURLOPT_COOKIEFILE) instead of parse_str() which silently
URL-decoded values, masking the bug in tests. Adds a cookie roundtrip
assertion to testCreateAccountSession.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
parse_str() URL-decodes cookie values, causing the test client to behave
differently from real clients (Dart, Swift) which store values verbatim
per RFC 6265. This masked a production bug where base64 session values
containing %3D%3D would fail to decode on real devices.
Replaces the manual Set-Cookie header parsing with cURL's built-in cookie
engine (CURLOPT_COOKIEFILE='') and reads cookies via CURLINFO_COOKIELIST,
which stores and returns values verbatim without any decoding.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The project.updateLabels route uses AuthType::KEY which makes it
available on the server platform, but the Project model had public=false
causing it to be filtered out during spec generation.
Spec generation silently produced a fatal error when a response model
string could not be resolved to a registered model object. Now throws a
clear RuntimeException in both Swagger2 and OpenAPI3 formats, for both
single and array model responses.
Also adds a CI job to run spec generation on every PR so unresolved
models are caught before merge.
Adds testEmailPasswordSessionNotCorruptedByConcurrentRequests which
reproduces the cross-worker Redis cache race that caused 401s after
login. The test fires a login request, waits for it to reach the cache
purge point, then injects concurrent GET /v1/account requests that
re-cache a stale user document. Verifies the new session is immediately
usable.
Fails against the old ordering (purge before create), passes with the
fix (create before purge).