How a Project portal reaches a client
Each Project has its own source repository — neon-law/spotonix, say — holding a React application under portal/.
That bundle is never committed anywhere in Navigator, and it never touches git on the way to a client. It is built in
the Project repository's own CI, published to the deployment's private -applications bucket, and streamed from there
by web — same-origin, and only after the session and Project participation row are checked.
flowchart LR
subgraph repo["Project repo — neon-law/spotonix"]
src["portal/ — React + Vite"]
ci["CI on push to main:<br/>validate + application-publish"]
src --> ci
end
subgraph gcp["Deployment project — neon-law"]
bucket[("neon-law-prod-applications<br/>spotonix/portal/ — private, UBLA")]
end
subgraph nav["Navigator — neon-server"]
web["web streams the bundle at<br/>/app/projects/spotonix/portal/"]
end
client(["Client browser"])
ci -- "keyless WIF (navigator-app-publisher):<br/>upload dist/ — hashed assets first,<br/>index.html last, never delete" --> bucket
client -- "GET /app/projects/spotonix/portal/" --> web
web -- "check session + participation" --> web
web -- "stream objects, same-origin" --> bucket