Commit Graph

11 Commits

Author SHA1 Message Date
7ad425ffc3 feat(ui): completed-only view + inline verdict + no polling
Two product simplifications per user feedback:

1. TopicList shows ONLY completed debates. Status filter dropdown
   removed — debates in earlier lifecycle states (signup / debating)
   are agent internals; human readers care about the finished record.
   API call hardcodes status=completed. Page title is now 'completed
   debates' + 'archive' eyebrow.

2. TopicDetail merges verdict inline. Loads topic + arguments +
   verdict concurrently on mount, renders transcript followed by
   structured verdict + judge rationale on the same page. Drops the
   8-second polling loop (completed debates don't change).

The /topics/:id/verdict route is kept as a shareable permalink for
the verdict alone, but the in-page link to it from the detail view
is gone since the same content is already there.

Build delta: 179 → 178 KB / gzip 57.70 → 57.40 (-300 bytes; one
less route imported on the critical path).
2026-05-24 03:36:38 +01:00
d1d2ae2fb1 feat(auth): real OIDC login + remove agents page
Replaces the dev-bypass-only AuthProvider with a real backend-mediated
OIDC client. Backend ships the OIDC plumbing in
Dialectic.Backend@2463129; this SPA drives it.

Auth flow:
  1. On mount: GET /api/auth/oidc/status (is OIDC configured?) + GET
     /api/auth/me (who am I — reads the dialectic_session HttpOnly
     cookie if present).
  2. Anon + click 'login' → window.location = /api/auth/oidc/start
     (backend redirects to IdP authorize URL with PKCE + state).
  3. IdP returns to backend /api/auth/oidc/callback → backend redirects
     here to /oidc/callback#oidc_ticket=<base64url>.
  4. OidcCallbackPage POSTs the ticket to /api/auth/oidc/exchange →
     backend Set-Cookie's the session JWT → refresh() AuthProvider →
     navigate to /.
  5. Header shows user.name + 'logout' button. Logout → POST
     /api/auth/logout (cookie cleared by backend) → user state cleared.

UI changes:
  - Header gets a Login button (acid primary style) when anon + OIDC
    enabled; logged-in pill (name + logout) when authenticated.
  - 'oidc not configured' message when backend reports
    /api/auth/oidc/status enabled=false (operator needs to run
    dialectic-cli config oidc first).
  - Removed /agents/:id route + AgentActivity page + nav link entirely
    (per user request; admin endpoint stays on backend for curl).
  - Removed Link to /agents/* from TopicDetail + Verdict pages.

api.ts:
  - Adds credentials:'same-origin' on every fetch so the session cookie
    rides along.
  - Drops the admin: opt + x-dialectic-admin-key header path (no more
    AgentActivity consumer).
  - Keeps dev-bypass header support gated on VITE_OIDC_DEV_BYPASS for
    dev convenience — backend's OIDC_ONLY=true env disables it server-
    side anyway.

types.ts: AgentSummary type removed.

Build delta: 178KB → 179KB / gzip 57.12 → 57.70 (oidc-client overhead
is just the AuthProvider polling code; no oidc-client-ts lib needed
since the backend drives the redirect flow).
2026-05-24 01:43:06 +01:00
7dca2c3110 fix(api): normalize null lists to [] (backend serializes empty as null)
The Go backend serializes empty slices as JSON null in several places
(e.g. {count:0, topics:null} when no rows match). The SPA assumed
arrays and crashed on .length:

  TypeError: Cannot read properties of null (reading 'length')
    at Hh (TopicList.tsx:64:45)

Fix in api.ts so every list-returning helper normalizes null → [] once,
centrally. Three call sites covered:
  - listTopics       — topics field
  - listArguments    — arguments field
  - getAgentSummary  — recent_topics field

Components stay as-is; nullable handling moves out of UI code where it
belongs in the data layer. getTopic preserves camps:null vs camps:[]
distinction (null = not yet allocated, [] would be allocated-with-zero
which the allocator contract forbids — keep them meaningfully distinct).

No backend change. Tested on prod with empty topics — list page now
renders 'no topics match this filter' instead of crashing.
2026-05-24 01:18:26 +01:00
a6258da84e chore: gitignore tsc -b build cache + vite.config emit
Build pipeline 'tsc -b && vite build' produces .tsbuildinfo + an
accidental vite.config.{js,d.ts} emit from project references.
Untrack + ignore so they don't keep coming back to dirty git status.
2026-05-24 00:15:54 +01:00
3dbb5abaf6 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.
2026-05-24 00:15:35 +01:00
f7c4ed9e3b docker fix backend url 2026-02-14 15:38:09 +00:00
bba77326f1 docker fix env name 2026-02-14 15:34:29 +00:00
f9665c92ce docker config 2026-02-14 15:16:45 +00:00
bd03492ef4 init dialectic 2026-02-13 16:14:12 +00:00
16630b6999 init dialectic 2026-02-13 15:44:25 +00:00
29ae2ba1f4 init 2026-02-13 03:42:04 +00:00