westfarnandCursor f9d39f6589
Unit Tests / test (pull_request) Successful in 37s
Give public pages crawler-ready HTML and production analytics.
Crawlers were reading one shared shell, so titles, descriptions, links, and markup were missing or the same on every URL. HeyCatch and Google Analytics load only on the production site and the iOS and Android apps.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-19 09:56:49 -05:00

Hesychia (chat_web_app)

Frontend for Hesychia — a React + TypeScript single-page app for a calm AI assistant experience (quiet, rest, stillness).

Public product domain: hesychia.ai (replacing chat.aimloperations.com).

Companion backend: chat_backend

Production serve is node-static (not Docker). Hosts build with npm into a document root; the shared web-static nginx container from server-infra serves those assets. Same pattern as dta_webapp.

Android ships the same CRA build/ via Capacitor (display name Hesychia; see llm-fe/ANDROID.md).

Domain migration

Role Current (still live) Target
Web UI chat.aimloperations.com hesychia.ai
REST / WS API chatbackend.aimloperations.com TBD under hesychia.ai (infra cutover)
Deploy webroot /var/www/{env}.chat.aimloperations/html Keep until server-infra renames

Committed .env.production / .env.beta still point at the current *.aimloperations.com API hosts so builds keep working. Flip those URLs (and deploy webroots / NPM) when DNS and server-infra cut over to hesychia.ai.

Stack

  • React 18, TypeScript, Create React App (react-scripts 5)
  • Material UI (MUI) 5 + Emotion for components and theming
  • React Router 6 for routing (BrowserRouter on web; HashRouter under Capacitor)
  • Axios for REST against chat_backend (JWT Authorization header)
  • WebSocket for live chat (REACT_APP_BACKEND_WS_API_BASE_URL)
  • Capacitor 7 for Android (and later iOS) WebView shells
  • Jest + React Testing Library for unit tests

Repository layout

chat_web_app/
├── README.md
├── .gitea/workflows/          # Unit tests + deploy-prod / deploy-beta
└── llm-fe/                    # CRA + Capacitor npm root
    ├── package.json
    ├── capacitor.config.ts
    ├── ANDROID.md             # Android build, signing, Play Store notes
    ├── android/               # Native Android project (committed)
    ├── assets/                # Source icon/splash for @capacitor/assets
    ├── .env.development       # Local dev API/WS URLs
    ├── .env.beta
    ├── .env.production
    ├── .env.mobile            # Capacitor shell API/WS URLs
    ├── public/
    └── src/
        ├── axiosApi.js        # Axios instances (JWT Authorization)
        ├── App.tsx
        ├── index.tsx
        └── llm-fe/
            ├── pages/         # Route-level views
            ├── components/    # Shared & feature UI
            ├── contexts/      # Auth, account, WebSocket, theme
            ├── platform/      # Capacitor routing / native chrome
            └── ui-kit/        # MD* design-system wrappers

Prerequisites

  • Node.js 20 (matches CI)
  • npm (lockfile: llm-fe/package-lock.json)
  • Running chat_backend locally for full chat/auth (default in .env.development: port 8001)
  • For Android: JDK 17+, Android Studio / SDK (see llm-fe/ANDROID.md)

Local setup

1. Clone and install

git clone ssh://git@git.aimloperations.com:30009/ai_ml_operations/chat_web_app.git
cd chat_web_app/llm-fe
npm ci

2. Configure environment

CRA loads mode-specific env files. Variables must be prefixed with REACT_APP_ to be visible in the browser bundle.

File Used when Backend (current)
.env.development npm start http://127.0.0.1:8001
.env.production npm run build / build:prod https://chatbackend.aimloperations.com + prod Tianji ID
.env.beta npm run build:beta https://beta.chatbackend.aimloperations.com + beta Tianji ID
.env.mobile npm run build:mobile prod by default (override for beta shell)

Each committed env sets REACT_APP_DEPLOY_ENV (production / beta) and REACT_APP_TIANJI_WEBSITE_ID.

Required keys (already set in the committed env files):

REACT_APP_BACKEND_REST_API_BASE_URL=http://127.0.0.1:8001/api/
REACT_APP_BACKEND_WS_API_BASE_URL=ws://127.0.0.1:8001/ws/chat_again/

These are baked into the JS at build time. There is no host secret file for this frontend (unlike Django apps under ~/Documents/secrets/). Change the committed .env.* files if API domains change, then redeploy.

SSO (Google / Microsoft)

OAuth client IDs/secrets live in chat_backend env (GOOGLE_OAUTH_*, MICROSOFT_OAUTH_*). The SPA only redirects to /api/auth/oauth/<provider>/start/ and lands on /auth/callback/ with JWTs. SSO buttons appear when /public/settings/ reports the provider as configured.

Capacitor / mobile: IdP redirect URIs must match the backend callback URL (not the WebView origin). Custom URL schemes / in-app browser for native OAuth are out of scope for the initial web SSO; use the web app for Google/Microsoft sign-in until native redirect handling is added.

Optional local overrides (gitignored): .env.local, .env.development.local, .env.production.local, .env.mobile.local.

3. Start the backend

From the chat_backend repo (adjust to however that service is run locally):

# example — follow chat_backend README for the current command
cd chat_backend
# run Django on the port matching .env.development (8001)

4. Start the dev server

cd llm-fe
npm start

Open http://localhost:3000.

5. Android (Capacitor)

cd llm-fe
npm run build:mobile
npm run android:open

Full signing / Play Store notes: llm-fe/ANDROID.md.

npm scripts

Command Purpose
npm start CRA dev server (port 3000)
npm run build Production build into llm-fe/build/
npm run build:prod Prod build + copy to /var/www/prod.chat.aimloperations/html
npm run build:beta Beta env build + copy to /var/www/beta.chat.aimloperations/html
npm run build:mobile Mobile env build + cap sync android
npm run android:open Open android/ in Android Studio
npm run android:sync cap sync android only
npm run assets:generate Regenerate Android icons/splash from assets/
npm test Jest watch mode
npm run test:ci Single CI run (CI=true, no watch)

build:prod / build:beta are intended for deploy hosts (or a machine that can write those /var/www/... paths). Paths must match server-infra app_catalog.chat_web_app.webroot_pattern until renamed:

/var/www/{env}.chat.aimloperations/html

Tests

cd llm-fe
npm test          # watch
npm run test:ci   # one-shot (matches Gitea Unit Tests)

CI / deployment

Gitea Actions workflows in .gitea/workflows/ (same pattern as dta_webapp):

Workflow Trigger Behavior
unit-tests.yml push/PR to master npm ci + npm run test:ci in llm-fe/
deploy-beta.yml push to master (after unit tests in-workflow) server-infra/scripts/deploy.sh --app chat_web_app --env beta --ref <sha>
deploy-prod.yml manual workflow_dispatch only tests, then deploy --env prod

Push/merge to master auto-deploys beta only. Prod requires the Gitea Run workflow button on Deploy Prod.

Deploy flow (on each webserver listed in host_apps):

  1. Git checkout at the pinned ref under /opt/apps/src/chat_web_app_<env>
  2. npm ci in llm-fe/
  3. npm run build:<env> → writes the static tree under /var/www/...
  4. web-static nginx serves that root on the host port (prod 8082, beta 8083)

Manual deploy from the control node:

~/Documents/repos/server-infra/scripts/deploy.sh \
  --app chat_web_app --env prod --ref <sha>

NPM (not managed by Ansible) should balance public Hesychia domains to:

  • adama:8082 + roslin:8082 + ai-server-4080:8082 (prod)
  • beta hosts on 8083 / beta.chat.aimloperations.com (see server-infra)

See server-infra IMPLEMENTATION.md.

Tianji analytics

Build Env file Website ID
prod .env.production REACT_APP_TIANJI_WEBSITE_ID (prod site)
beta .env.beta distinct beta site ID (set after creating website in Tianji)
  • Script: https://tianji.aimloperations.com/tracker.js
  • Page views always load on prod/beta (no consent gate)
  • Custom events / identify require analytics consent (AnalyticsConsentBanner + trackEvent / identifyUser)
  • Consent choice stored in localStorage key hesychia_analytics_consent_v1 (granted / denied)
  • Banner links to /terms_of_service/#analytics for the always-on vs optional split
  • Event catalog: llm-fe/ANALYTICS.md
  • Backend: chat_backend — Django API + WebSocket
  • Infra: server-infra — app_catalog, host_apps, deploy.sh, web-static
  • Pattern reference: dta_webapp — node-static frontend deploy
S
Description
Front end react app for chat site
Readme
28 MiB
0 Stars 2 Watchers 0 Forks
Languages
JavaScript 49.6%
TypeScript 48.3%
Java 0.9%
HTML 0.6%
Swift 0.4%
Other 0.2%