src/: React app source (UI, features, services, policy, auth)apps/hub-api/: Hub API sidecar service (hub-api.mjs) deploy assetsapps/hub-collab/: Dedicated Yjs/Lexical collaboration WebSocket servicescripts/: validation and compliance checksdocs/: architecture contracts and runbooksworking files/: local-only sensitive context and secrets (git-ignored)
This project uses Tailwind v4 with the Vite plugin (@tailwindcss/vite) and a CSS-first token setup.
- Tailwind is imported in
tokens.cssvia@import "tailwindcss". - Tailwind config is explicitly present in
tailwind.config.js. tokens.cssis wired to that config via@config "./tailwind.config.js";.- Theme tokens/utilities are defined in
tokens.csswith@themeand@utility.
Core app/config files remain at root:
package.jsonvite.config.tstailwind.config.jstsconfig*.jsonglobals.css,tokens.cssindex.html
Generated files (dist, node_modules, tsconfig.app.tsbuildinfo) are build/runtime artifacts.
- The hub uses Keycloak OIDC with PKCE through
keycloak-js. - Deployment-specific auth settings are provided through environment variables.
- Use .env.example as the source of variable names and placeholder values.
- After login, the UI loads session capabilities from server source-of-truth at
/api/hub/me.
Access is invite-only at the hub policy layer.
- A space owner creates an invite for your email.
- Sign in at the public URL configured for your deployment.
- Pending invites are consumed by the hub policy service to grant space membership.
- Hub authorization is owner-email anchored through
HUB_OWNER_EMAIL. - The owner role is derived from that canonical email, not IdP realm roles.
- If
HUB_OWNER_EMAILis missing, authenticated hub policy endpoints fail closed with503.
- Edge gate grant flow (owner only):
POST /api/hub/edge/grants - Collaboration authorization:
GET /api/hub/collab/authorize - Document snapshots:
GET/PUT /api/hub/docs/:docId - Governance trail (owner):
GET /api/hub/audit - Snapshot registry (owner):
GET/POST /api/hub/snapshots - Recovery workflows (owner):
POST /api/hub/recovery/restore-snapshot,POST /api/hub/recovery/revert-window,GET /api/hub/recovery/jobs
- Collaboration, chat, and live-update endpoints are deployment-configured.
- Keep public hostnames, routing, and operations runbooks outside the public README.
- Use .env.example for the relevant variable names.
- Matrix integration is optional and configured entirely by environment variables.
- Deployment-specific homeserver URLs and discovery details are intentionally omitted here.
- Create local-only user credential file (gitignored):
.env.contract-smoke.users.local - Required keys:
HUB_SMOKE_USER_A_USERNAMEHUB_SMOKE_USER_A_PASSWORDHUB_SMOKE_USER_B_USERNAMEHUB_SMOKE_USER_B_PASSWORD
- Optional IdP defaults:
KEYCLOAK_URLKEYCLOAK_REALMKEYCLOAK_CLIENT_IDKEYCLOAK_REDIRECT_URI
- Ensure users exist (one-time/persistent):
- Set
KEYCLOAK_ADMIN_USERNAME+KEYCLOAK_ADMIN_PASSWORD(or place in.env.contract-smoke.admin.local) - Run:
npm run smoke:ensure-users
- Set
- Mint fresh tokens before each smoke run:
- Run:
npm run smoke:mint-tokens - This writes
.env.contract-smoke.tokens.localwithTOKEN_AandTOKEN_B.
- Run:
- Install once:
npx playwright install - Regression suite (explicit opt-in):
PLAYWRIGHT_E2E_ENABLED=true BASE_URL=http://127.0.0.1:5173 npm run test:e2e
- Workflow suite (extra explicit opt-in because it mints auth tokens):
PLAYWRIGHT_E2E_ENABLED=true PLAYWRIGHT_WORKFLOW_ENABLED=true BASE_URL=http://127.0.0.1:5173 npm run test:e2e:workflow
Use the secure local stack when you need to verify frontend, API, auth, and collab behavior without deploying.
npm run dev:secure:bootstrap- Generates gitignored local env files with synthetic users, random local-only passwords, and localhost-only service bindings.
npm run dev:secure- Starts local Keycloak, provisions the synthetic users, then runs Vite,
hub-api, andhub-collab.
- Starts local Keycloak, provisions the synthetic users, then runs Vite,
npm run dev:secure:verify- Mints local test tokens, ensures the local fixture space and memberships exist, and runs the local authz/policy/collab smoke checks against the running stack.
npm run dev:secure:auth:down- Stops the local Keycloak container when you are done.
Security properties of this workflow:
- Local Keycloak binds only to
127.0.0.1. - Generated env files remain gitignored.
- The local stack uses synthetic users and a local SQLite database under
.local/. - External integrations are not pointed at production by default, so missing integration env stays fail-closed instead of falling through to prod.
Local credentials are written to .env.local.users.local. Local smoke tokens are written to .env.local.tokens.local.
- For any task that touches more than one file, add a short summary entry to
working files/change-log.md. - Minimum entry fields: UTC timestamp, one-line scope summary, and key files changed.