feat(frontend): v2 rewrite — Vite + React + TS readonly SPA
Replaces the v1 CRA app (which targeted the obsolete Python Dialectic
backend) with a fresh Vite + React 18 + TypeScript scaffold that talks
to Dialectic.Backend Go v2.
Pages (all readonly — propose/signup/post are agent-only by design):
- / TopicList — filter by status, paginated
- /topics/:id TopicDetail — meta + camps + transcript
(polling every 8s)
- /topics/:id/verdict Verdict permalink (shareable)
- /agents/:id AgentActivity — admin diagnostics card
Stack:
- Vite 5 + React 18 + react-router-dom 6
- Pure ESM, NodeNext-style imports, .tsx
- Style: ~/STYLE.md tokens (IBM Plex Mono + Major Mono Display +
--acid #d8ff3e on --ink #080a0d, with subtle blueprint grid wash)
Auth:
- v1 dev-bypass only — VITE_OIDC_DEV_BYPASS auto-attaches
x-dev-bypass header. Real Keycloak OIDC redirect ships as v2.
- Admin endpoints (x-dialectic-admin-key) prompt on first visit
and store key in localStorage. Never baked into bundle. Never
sent to non-admin endpoints.
Backend pairing:
- Dialectic.Backend@0b16b52 adds GET /api/admin/agents/{id} for the
AgentActivity page. AgentActivity calls it via the admin-key
branch in api.ts.
Deploy:
- Multi-stage Dockerfile (node:22-alpine build → nginx:1.27-alpine
serve). nginx.conf reverse-proxies /api/ → dialectic-backend:8090
so the browser sees one origin (no CORS).
Reuses the existing hzhang/Dialectic.Frontend repo — old CRA contents
nuked in this commit. History preserved on master.
This commit is contained in:
40
nginx.conf
Normal file
40
nginx.conf
Normal file
@@ -0,0 +1,40 @@
|
||||
# nginx config for the Dialectic SPA.
|
||||
# - Static SPA assets under /; falls back to /index.html for client-side
|
||||
# router (BrowserRouter needs all unknown paths to serve the shell).
|
||||
# - /api/ reverse-proxies to the dialectic-backend container. The compose
|
||||
# service name + port is settable via DIALECTIC_BACKEND env at run time
|
||||
# (default = http://dialectic-backend:8090). We inject it via envsubst
|
||||
# at container start so the same image works for sim + prod.
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Long-lived caching for hashed asset bundles.
|
||||
location /assets/ {
|
||||
access_log off;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# SPA fallback: any unknown path serves index.html so React Router
|
||||
# can take over client-side.
|
||||
location / {
|
||||
try_files $uri /index.html;
|
||||
}
|
||||
|
||||
# API reverse-proxy. Same-origin from the browser's POV so we sidestep
|
||||
# CORS. nginx upstream must point to the dialectic-backend service.
|
||||
# Substitution happens at container start via envsubst (see Dockerfile
|
||||
# entrypoint pattern; for v1 we hard-code the compose default).
|
||||
location /api/ {
|
||||
proxy_pass http://dialectic-backend:8090/api/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user