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. - Production build settings are read from
.env.production:VITE_KEYCLOAK_URL=https://auth.eshaansood.orgVITE_KEYCLOAK_REALM=eshaan-osVITE_KEYCLOAK_CLIENT_ID=eshaan-os-hub
- 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.
- Owner creates an invite for your email from the hub owner panel.
- Sign in at
https://eshaansood.orgwith your Keycloak account. - Pending invites are consumed by the hub policy service to grant project membership.
- Hub authorization is owner-email anchored: set
HUB_OWNER_EMAILin the sidecar env. - The owner role is derived only from that canonical email, not Keycloak 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 - Notes (project-scoped, async):
GET/POST /api/hub/projects/:projectId/notes,PATCH /api/hub/projects/:projectId/notes/:noteId - Notes collaboration session mint (project-scoped):
POST /api/hub/projects/:projectId/notes/:noteId/collab/session - 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
- Canonical public WS endpoint:
wss://collab.eshaansood.org - Hub sidecar mints short-lived scoped tokens with room scope (
noteId) for this endpoint. - Dedicated collab deploy assets:
apps/hub-collabdocs/collab-socket-contract.md
- Hub API sidecar deploy:
npm run deploy:hub-api - Collab service deploy:
npm run deploy:collab - Full deploy:
npm run deploy
- Canonical live base URL:
https://eshaansood.org - Ensure regression project fixture exists:
HUB_BASE_URL=https://eshaansood.org HUB_PROJECT_ID=backend-pilot HUB_OWNER_ACCESS_TOKEN=... npm run fixture:hub-project(or useHUB_ACCESS_TOKENinstead) - Hub policy checks:
npm run check:hub-policy-live - Collaboration preflight parity checks:
npm run check:collab-preflight - Collaboration WS checks:
npm run check:collab-live
- 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 Keycloak defaults:
KEYCLOAK_URL(defaulthttps://auth.eshaansood.org)KEYCLOAK_REALM(defaulteshaan-os)KEYCLOAK_CLIENT_ID(defaulteshaan-os-hub)KEYCLOAK_REDIRECT_URI(defaulthttps://eshaansood.org/)
- 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
- 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.