Commit Graph

5 Commits

Author SHA1 Message Date
e3mrah
896dc041d7
feat(wizard): job dependencies SVG DAG + (stretch) timeline view (closes #206) (#212)
Implements item 11 of epic #204 — job dependency visualisation. Ships
both a primary surface and a stretch surface per the proposal at
`docs/proposals/jobs-dependencies-viz.md`:

  PRIMARY  — pure-SVG topological-layered DAG inline on the JobDetail
             Dependencies tab. Color-coded by status (succeeded / running
             / failed / pending), click-a-node to navigate, keyboard
             accessible (Enter / Space). 350-450px clamp.

  STRETCH  — fullscreen Gantt timeline at /sovereign/provision/$id/jobs/
             timeline. One row per job, bars from startedAt → finishedAt
             (or now if running), nice-tick time axis, hover tooltips.

New files:

  • src/widgets/job-deps-graph/JobDependenciesGraph.tsx — SVG DAG widget,
    structurally typed against any Job-like shape so it works with both
    today's jobs.ts model and the evolved-but-not-yet-merged backend
    contract from #205.
  • src/shared/lib/depsLayout.ts — pure topological-layered layout. Kahn
    topo-sort + cycle break + within-layer sort by descendant count.
    Zero external graph deps (no reactflow / cytoscape / d3-dag — per
    the issue hard rules + INVIOLABLE-PRINCIPLES.md #2).
  • src/pages/sovereign/JobsTimeline.tsx — Gantt page chrome.
  • src/test/fixtures/deps-graph.fixture.ts — shared mock graph for
    sibling agents per the contract in the epic.
  • src/pages/designs/JobsDepsVizDemo.tsx — visual lock-in surface at
    /sovereign/designs/jobs-deps-viz for reviewer eye-checks.
  • docs/proposals/jobs-dependencies-viz.md — recommendation rationale.

Integration into the merged JobDetail surface (PR #208):

  • src/components/JobDependencies.tsx — replaces the placeholder list-
    only surface with DAG-on-top-of-list. List preserved for keyboard
    accessibility + screen readers.

Tests:

  • depsLayout.test.ts (15 cases): topo order, no overlap, cycle break,
    unknown-id drop, custom options, edge geometry.
  • JobDependenciesGraph.test.tsx (8 cases): render counts, status data
    attribute, click + keyboard handlers, height clamp.

Cosmetic verification: 4 screenshots at 1440px under
`.playwright-mcp/jobs-deps-viz/` showing the DAG (5-job + 3-node
fixtures), the integrated Dependencies tab on a real JobDetail page,
and the Gantt timeline route.

Refs #204
Closes #206

Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 21:40:43 +02:00
e3mrah
a894b54a2f
fix(wizard): pixel-port core/console (apps + app detail sections + jobs expand-in-place) (#197)
Replaces the invented AdminPage / AdminShell / ApplicationCard /
ApplicationPage / PhaseBanners with a 1:1 React port of the canonical
Svelte components in core/console/src/components/. Same chrome, same
tabs, same auto-fit card grid, same expand-in-place jobs rows, no
invented sections, no per-job route.

Routes (basepath=/sovereign):
  /provision/$deploymentId           → AppsPage    (Deployments|Catalog tabs)
  /provision/$deploymentId/app/$id   → AppDetail   (sections, NOT tabs)
  /provision/$deploymentId/jobs      → JobsPage    (expand-in-place rows)
  /provision/legacy/$deploymentId    → ProvisionPage (legacy DAG, sub-path)

NEW files (products/catalyst/bootstrap/ui/src/pages/sovereign/):
  PortalShell.tsx + .test.tsx (skipped — covered transitively)
  Sidebar.tsx + Sidebar.test.tsx
  AppsPage.tsx + AppsPage.test.tsx
  AppDetail.tsx + AppDetail.test.tsx
  JobsPage.tsx + JobsPage.test.tsx
  JobCard.tsx + JobCard.test.tsx
  jobs.ts + jobs.test.ts                (Job model + reducer adapter:
                                         4 Phase 0 tofu jobs +
                                         1 cluster-bootstrap job +
                                         per-bp-* HelmRelease jobs)

DELETED invented files:
  AdminPage.tsx + .test.tsx
  AdminShell.tsx
  ApplicationCard.tsx
  ApplicationPage.tsx + .test.tsx
  PhaseBanners.tsx

UNTOUCHED data layer (kept as-is per spec):
  applicationCatalog.ts + .test.ts
  eventReducer.ts + .test.ts
  useDeploymentEvents.ts
  StatusPill.tsx

CSS tokens: globals.css gains the canonical core/console --color-*
surface (--color-bg, --color-surface, --color-border, --color-accent,
--color-text-strong, --color-text-dim, --color-text-dimmer,
--color-success, --color-warn, --color-danger, --color-bg-2,
--color-surface-hover, --color-border-strong, --color-accent-hover).
Values copied verbatim from core/console/src/styles/global.css.

Gates:
  • tsc --noEmit clean
  • npm run build clean
  • vitest: 238 tests passing (was 185 pre-port; +53 new)

Playwright evidence (1440px, dark theme):
  .playwright-mcp/console-port-evidence/wizard-apps-1440-dark.png
  .playwright-mcp/console-port-evidence/wizard-apps-catalog-1440-dark.png
  .playwright-mcp/console-port-evidence/wizard-app-detail-cilium-1440-dark.png
  .playwright-mcp/console-port-evidence/wizard-jobs-1440-dark.png
  .playwright-mcp/console-port-evidence/wizard-apps-1440-light.png

Note: canonical https://console.openova.io/nova/* requires sign-in;
auth-gated reference screenshots are not capturable from this session.
The ports lock to the canonical Svelte source files at
core/console/src/components/{PortalShell,Sidebar,AppsPage,AppDetail,
JobsPage}.svelte — same class strings, same selectors, same DOM
structure. Visual conformance is asserted by tests on testid + class
membership.

Co-authored-by: hatiyildiz <hatice.yildiz@openova.io>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 20:09:36 +02:00
hatiyildiz
319d510a1f docs(wizard): Playwright evidence for sovereign admin landing + per-app tabs
Captures the new admin surface in mid-flight (Hetzner-infra DONE,
Cluster-bootstrap RUNNING, mixed application states) using the dev
server with mocked /events buffer responses, then walks every tab on
two representative ApplicationPages — Cilium (no upstream deps,
bootstrap-kit, INSTALLED) and Harbor (3 component dependencies, mid-
provisioning).

Six PNGs under .playwright-mcp/admin-evidence/:

  01-admin-page-grid.png             AdminPage — top bar, sidebar
                                     (deployment metadata + family
                                     rollup), phase banners, bootstrap
                                     kit grid + selected applications.
  02-app-page-logs-tab.png           Cilium · Logs tab (filtered by
                                     event.component === 'bp-cilium').
  03-app-page-dependencies-tab.png   Cilium · Dependencies tab — the
                                     CNI sits at the bottom of the
                                     dep graph; "no upstream
                                     dependencies" copy verifies the
                                     empty-state surface.
  04-app-page-status-tab.png         Cilium · Status tab — install
                                     state, helm release, namespace,
                                     chart version from per-component
                                     event payload.
  05-app-page-overview-tab.png       Cilium · Overview tab — long-form
                                     copy from marketplaceCopy.ts
                                     (SPINE family tagline + "What it
                                     does" positioning).
  06-app-page-dependencies-harbor.png  Harbor · Dependencies tab —
                                     three component deps rendered as
                                     clickable mini-cards (CloudNative
                                     PG, SeaweedFS, Valkey) with
                                     family chips.

Verified gates: tsc clean, vite build clean, vitest 188/188 green.
Route /sovereign/provision/$deploymentId/app/$componentId reachable
via card click; /sovereign/provision/$deploymentId still mounts
AdminPage so StepReview's redirect target is preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 17:31:02 +02:00
e3mrah
9a878336e3 revert: remove accidentally committed untracked files 2026-03-30 14:44:16 +02:00
e3mrah
52358eb8e7 feat(axon): CronJob for automatic OAuth token refresh
The Claude Agent SDK does not handle OAuth token refresh — it reads the
accessToken from .credentials.json and uses it directly. When the token
expires (~8h), Axon returns 401 until manually refreshed.

Adds a CronJob (every 4h by default) that:
1. Reads the refreshToken from the K8s secret
2. Calls Anthropic's OAuth token endpoint to get a fresh accessToken
3. Updates the K8s secret with the new credentials
4. Restarts the Axon deployment to pick up the new token

Includes ServiceAccount, Role, and RoleBinding for least-privilege access.
Disabled by default (axon.tokenRefresh.enabled: false).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 14:42:51 +02:00