Commit Graph

229 Commits

Author SHA1 Message Date
hsiegeln
891dcaef32 feat(ui/alerts): mount NotificationBell in TopBar
Renders the `<NotificationBell />` as the first child of `<TopBar>` (before
`<SearchTrigger>`). The bell links to `/alerts/inbox` and shows the unread
alert count for the currently selected environment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 13:47:16 +02:00
hsiegeln
54e4217e21 feat(ui/alerts): Alerts sidebar section with Inbox/All/Rules/Silences/History
Adds `buildAlertsTreeNodes` to sidebar-utils and renders an Alerts section
between Applications and Starred in LayoutShell. The section uses an
accordion pattern — entering `/alerts/*` collapses apps/admin/starred and
restores their state on leave.

gitnexus_impact(LayoutContent, upstream) = LOW (0 direct callers; rendered
only by LayoutShell's provider wrapper).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 13:46:49 +02:00
hsiegeln
019e79a362 feat(ui/alerts): MustacheEditor component (CM6 shell with completion + linter)
Wires the mustache-completion source and mustache-linter into a CodeMirror 6
EditorView. Accepts kind (filters variables) and reducedContext (env-only for
connection URLs). singleLine prevents newlines for URL/header fields. Host
ref syncs when the parent replaces value (promotion prefill).
2026-04-20 13:41:46 +02:00
hsiegeln
ac2a943feb feat(ui/alerts): CM6 completion + linter for Mustache templates
completion fires after {{ and narrows as the user types; apply() closes the
tag automatically. Linter raises an error on unclosed {{, a warning on
references that aren't in the allowed-variable set for the current condition
kind. Kind-specific allowed set comes from availableVariables().
2026-04-20 13:39:10 +02:00
hsiegeln
18e6dde67a fix(ui/alerts): align ALERT_VARIABLES registry with NotificationContextBuilder
Plan prose had spec §8 idealized leaves, but the backend NotificationContext
only emits a subset:
  ROUTE_METRIC / EXCHANGE_MATCH → route.id + route.uri (uri added)
  LOG_PATTERN → log.pattern + log.matchCount (renamed from log.logger/level/message)
  app.slug / app.id → scoped to non-env kinds (removed from 'always')
  exchange.link / alert.comparator / alert.window / app.displayName → removed (backend doesn't emit)

Without this alignment the Task 11 linter would (1) flag valid route.uri as
unknown, (2) suggest log.{logger,level,message} as valid paths that render
empty, and (3) flag app.slug on env-wide rules.
2026-04-20 13:35:42 +02:00
hsiegeln
5ddd89f883 feat(ui/alerts): Mustache variable metadata registry for autocomplete
ALERT_VARIABLES mirrors the spec §8 context map. availableVariables(kind)
returns the kind-specific filter (always vars + kind vars). extractReferences
+ unknownReferences drive the inline amber linter. Backend NotificationContext
adds must land here too.
2026-04-20 13:31:55 +02:00
hsiegeln
38083d7c3f fix(ui/alerts): remove dead usePageVisible subscription; align alerts test mock with DTO
NotificationBell used a usePageVisible() subscription that re-rendered on
every visibilitychange without consuming the value. TanStack Query's
refetchIntervalInBackground:false already pauses polling; the extra
subscription was speculative generality. Dropped the import + call + JSDoc
reference; usePageVisible hook + test retained as a reusable primitive.

Also: alerts.test.tsx 'returns the server payload unmodified' asserted a
pre-plan {total, bySeverity} shape, but UnreadCountResponse is actually
{count}. Fixed mock + assertion to {count: 3}.
2026-04-20 13:30:07 +02:00
hsiegeln
197c60126c feat(ui/alerts): NotificationBell with Page Visibility poll pause
Adds a header bell component linking to /alerts/inbox with an unread-count
badge for the selected environment. Polling pauses when the tab is hidden
via TanStack Query's refetchIntervalInBackground:false (already set on
useUnreadCount); the new usePageVisible hook gives components a
re-renders-on-visibility-change signal for future defense-in-depth.

Plan-prose deviation: the plan assumed UnreadCountResponse carries a
bySeverity map for per-severity badge coloring, but the backend DTO only
exposes a scalar `count`. The bell reads `data?.count` and renders a single
var(--error) tint; a TODO references spec §13 for future per-severity work
that would require expanding the DTO.

Tests: usePageVisible toggles on visibilitychange events; NotificationBell
renders the bell with no badge at count=0 and shows "3" at count=3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 13:26:58 +02:00
hsiegeln
31ee974830 feat(ui/alerts): AlertStateChip + SeverityBadge components
State colors follow the convention from @cameleer/design-system (CRITICAL->error,
WARNING->warning, INFO->auto). Silenced pill stacks next to state for the spec
section 8 audit-trail surface.
2026-04-20 13:21:37 +02:00
hsiegeln
e7fbf5a7b2 feat(ui): admin page for outbound connections list + navigation
Adds OutboundConnectionsPage (list view with delete), lazy route at
/admin/outbound-connections, and Outbound Connections nav node in the
admin sidebar tree. No test file created — UI codebase has no existing
test infrastructure to build on.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 16:55:35 +02:00
hsiegeln
4f9ee57421 feat(ui): LogTab — surface source badge on per-exchange log rows 2026-04-17 12:57:06 +02:00
hsiegeln
7f233460aa fix(ui): stabilize infinite-stream callbacks + suppress empty-state flash
- useInfiniteStream: wrap fetchNextPage and refresh in useCallback so
  InfiniteScrollArea's IntersectionObserver does not re-subscribe on
  every parent render.
- InfiniteScrollArea: do not render 'End of stream' until at least one
  item has loaded and the initial query has settled (was flashing on
  mount before first fetch).
- AgentHealth: pass isLoading + hasItems to both InfiniteScrollArea
  wrappers.
2026-04-17 12:52:39 +02:00
hsiegeln
c2ce508565 feat(ui): add InfiniteScrollArea component
Scrollable container with top/bottom IntersectionObserver sentinels.
Fires onTopVisibilityChange when the top is fully in view and
onEndReached when the bottom is within 100px. Used by infinite log
and event streams.
2026-04-17 12:41:17 +02:00
hsiegeln
d02fa73080 fix: scope correlation-chain query to the exchange's own env
Correlated exchanges always share the env of the one being viewed —
using the globally-selected env from the picker was wrong if the user
switched envs after opening a detail view (or arrived via permalink).

Thread `environment` through:
- `ExecutionStore.ExecutionRecord` gains `environment` field; the
  ClickHouse `executions` table already stores this, just not read back.
- `ClickHouseExecutionStore.findById` SELECT adds the column; mapper
  populates it.
- `ExecutionDetail` gains `environment`; `DetailService` passes through.
- `IngestionService.toExecutionRecord` passes null — this legacy PG
  ingestion path isn't active when ClickHouse is enabled, and the
  read-side is what drives the correlation UI.
- UI `ExchangeHeader` reads `detail.environment ?? storeEnv` and
  extends the TS type locally (schema.d.ts catches up on next regen).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 10:19:42 +02:00
hsiegeln
873e1d3df7 feat!: move query/logs/routes/diagram/agent-view endpoints under /environments/{envSlug}/
P3C — the last data/query wave of the taxonomy migration. Every user-
facing read endpoint that was keyed on env-as-query-param is now under
the env-scoped URL, making env impossible to omit and unambiguous in
server-side tenant+env filtering.

Server:
- SearchController: /api/v1/search/** → /api/v1/environments/{envSlug}/...
  Endpoints: /executions (GET), /executions/search (POST), /stats,
  /stats/timeseries, /stats/timeseries/by-app, /stats/timeseries/by-route,
  /stats/punchcard, /attributes/keys, /errors/top. Env comes from path.
- LogQueryController: /api/v1/logs → /api/v1/environments/{envSlug}/logs.
- RouteCatalogController: /api/v1/routes/catalog → /api/v1/environments/
  {envSlug}/routes. Env filter unconditional (path).
- RouteMetricsController: /api/v1/routes/metrics →
  /api/v1/environments/{envSlug}/routes/metrics (and /metrics/processors).
- DiagramRenderController: /{contentHash}/render stays flat (hashes are
  globally unique). Find-by-route moved to /api/v1/environments/{envSlug}/
  apps/{appSlug}/routes/{routeId}/diagram — the old GET /diagrams?...
  handler is removed.
- Agent views split cleanly:
  - AgentListController (new): /api/v1/environments/{envSlug}/agents
  - AgentEventsController: /api/v1/environments/{envSlug}/agents/events
  - AgentMetricsController: /api/v1/environments/{envSlug}/agents/
    {agentId}/metrics — now also rejects cross-env agents (404) as a
    defense-in-depth check, fulfilling B3.
  Agent self-service endpoints (register/refresh/heartbeat/deregister)
  remain flat at /api/v1/agents/** — JWT-authoritative.

SPA:
- queries/agents.ts, agent-metrics.ts, logs.ts, catalog.ts (route
  metrics only; /catalog stays flat), processor-metrics.ts,
  executions.ts (attributes/keys, stats, timeseries, search),
  dashboard.ts (all stats/errors/punchcard), correlation.ts,
  diagrams.ts (by-route) — all rewritten to env-scoped URLs.
- Hooks now either read env from useEnvironmentStore internally or
  require it as an argument. Query keys include env so switching env
  invalidates caches.
- useAgents/useAgentEvents signature simplified — env is no longer a
  parameter; it's read from the store. Callers (LayoutShell,
  AgentHealth, AgentInstance) updated accordingly.
- LogTab and useStartupLogs thread env through to useLogs.
- envFetch helper introduced in executions.ts for env-prefixed raw
  fetch until schema.d.ts is regenerated against the new backend.

BREAKING CHANGE: All these flat paths are removed:
  /api/v1/search/**, /api/v1/logs, /api/v1/routes/catalog,
  /api/v1/routes/metrics (and /processors), /api/v1/diagrams
  (lookup), /api/v1/agents (list), /api/v1/agents/events-log,
  /api/v1/agents/{id}/metrics, /api/v1/agent-events.
Clients must use the /api/v1/environments/{envSlug}/... equivalents.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 23:48:25 +02:00
hsiegeln
969cdb3bd0 feat!: move config & settings under /api/v1/environments/{envSlug}/...
P3A of the taxonomy migration. Env-scoped config and settings endpoints
now live under the env-prefixed URL shape, making env a first-class
path segment instead of a query param. Agent-authoritative config is
split off into a dedicated endpoint so agent env comes from the JWT
only — never spoofable via URL.

Server:
- ApplicationConfigController: @RequestMapping("/api/v1/environments/
  {envSlug}"). Handlers use @EnvPath Environment env, appSlug as
  @PathVariable. Removed the dual-mode resolveEnvironmentForRead —
  user flow only; agent flow moved to AgentConfigController.
- AgentConfigController (new): GET /api/v1/agents/config. Reads
  instanceId from JWT subject, resolves (app, env) from registry,
  returns AppConfigResponse. Registry miss → falls back to JWT env
  claim for environment, but 404s if application cannot be derived
  (no other source without registry).
- AppSettingsController: @RequestMapping("/api/v1/environments/
  {envSlug}"). List at /app-settings, per-app at /apps/{appSlug}/
  settings. Access class-wide PreAuthorize preserved (ADMIN/OPERATOR).

SPA:
- commands.ts: useAllApplicationConfigs, useApplicationConfig,
  useUpdateApplicationConfig, useProcessorRouteMapping,
  useTestExpression — rewritten URLs to /environments/{env}/apps/
  {app}/... shape. environment now required on every call. Query
  keys include environment so cache is env-scoped.
- dashboard.ts: useAppSettings, useAllAppSettings, useUpdateAppSettings
  rewritten.
- TapConfigModal: new required environment prop; callers updated.
- RouteDetail, ExchangesPage: thread selectedEnv into test-expression
  and modal.

Config changes in SecurityConfig for the new shape landed earlier in
P0.2; no security rule changes needed in this commit.

BREAKING CHANGE: /api/v1/config/** and /api/v1/admin/app-settings/**
paths removed. Agents must use /api/v1/agents/config instead of
GET /api/v1/config/{app}; users must use /api/v1/environments/{env}/
apps/{app}/config and /api/v1/environments/{env}/apps/{app}/settings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 23:33:25 +02:00
hsiegeln
78396a2796 fix: sidebar route selection and missing routes after server restart
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m20s
CI / docker (push) Successful in 1m10s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 38s
Two sidebar bugs fixed:

1. Route entries never highlighted on navigation because sidebar-utils
   generated /apps/ paths for route children while effectiveSelectedPath
   normalizes to /exchanges/. The design system does exact string matching.

2. Routes disappeared from sidebar when agents had no recent exchange
   data. Heartbeat carried routeStates (with route IDs as keys) but
   AgentRegistryService.heartbeat() never updated AgentInfo.routeIds.
   After server restart, auto-heal registered agents with empty routes,
   leaving ClickHouse (24h window) as the only discovery source.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 12:42:01 +02:00
hsiegeln
a4a5986f38 feat: use cameleer.processorId MDC key for precise log-to-processor correlation
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m52s
CI / docker (push) Successful in 1m54s
CI / deploy (push) Successful in 56s
CI / deploy-feature (push) Has been skipped
LogTab now checks mdc['cameleer.processorId'] first when filtering logs
for a selected processor node, falling back to fuzzy message/loggerName
matching for older agents without the new MDC key.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 00:19:02 +02:00
hsiegeln
64af49e0b5 fix: improve sidebar layout with scrollable sections and bottom-pinned admin
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 2m1s
CI / docker (push) Successful in 2m25s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 43s
- Applications section: maxHeight 50vh with scroll overflow
- Starred section: maxHeight 30vh with scroll overflow
- Admin section: pinned to bottom of sidebar via position="bottom"
- Update design-system to 0.1.54 (sidebar section maxHeight, position props)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 22:09:10 +02:00
hsiegeln
457650012b fix: resolve UI glitches and improve consistency
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m22s
CI / docker (push) Successful in 1m36s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 38s
- Sidebar: make +App button more subtle (lower opacity, brightens on hover)
- Sidebar: add filter chips to hide empty routes and offline/stale apps
- Sidebar: hide filter chips and +App button when sidebar is collapsed
- Exchange table: reorder columns to Status, Attributes, App, Route, Started, Duration; remove ExchangeId and Agent columns
- Exchange detail log tab: query by exchangeId only (no applicationId required), filter by processorId when processor selected
- KPI tooltips: styled tooltips with current/previous values, time period labels, percentage change, themed with DS variables
- KPI tooltips: fix overflow by left-aligning first two and right-aligning last two
- Exchange detail: show full datetime (YYYY-MM-DD HH:mm:ss.SSS) for start/end times
- Status labels: unify to title-case (Completed, Failed, Running) across all views
- Status filter buttons: match title-case labels (Completed, Warning, Failed, Running)
- Create app: show full external URL using routingDomain from env config or window.location.origin fallback
- Create app: add Runtime Type selector and Custom Arguments to Resources tab
- Create app: add Sensitive Keys tab with agent defaults, global keys, and app-specific keys (matching admin page design)
- Create app: add placeholder text to all Input fields for consistency
- Update design-system to 0.1.52 (sidebar collapse toggle fix)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 19:41:36 +02:00
hsiegeln
cb3ebfea7c chore: rename cameleer3 to cameleer
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Failing after 18s
CI / docker (push) Has been skipped
CI / deploy (push) Has been skipped
CI / deploy-feature (push) Has been skipped
Rename Java packages from com.cameleer3 to com.cameleer, module
directories from cameleer3-* to cameleer-*, and all references
throughout workflows, Dockerfiles, docs, migrations, and pom.xml.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:28:42 +02:00
hsiegeln
33b0bc4d98 fix: cast LogEntryResponse to LogEntry for StartupLogPanel type safety
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / docker (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / deploy-feature (push) Has been cancelled
CI / build (push) Has been cancelled
The DS LogViewer expects level as a string union, but the API response
type uses plain string. Cast at the call site to fix the TS build error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 23:56:01 +02:00
hsiegeln
e7732703a6 feat: add StartupLogPanel component for deployment startup logs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 23:21:26 +02:00
hsiegeln
96780db9ad feat: wire SensitiveKeysPage into router and admin sidebar 2026-04-14 18:24:13 +02:00
hsiegeln
0827fd21e3 feat: persist and display exchange properties from agent
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m59s
CI / docker (push) Successful in 2m13s
CI / deploy (push) Successful in 58s
CI / deploy-feature (push) Has been skipped
Add support for exchange properties sent by the agent alongside headers.
Properties flow through the same pipeline as headers: ClickHouse columns
(input_properties, output_properties) on both executions and
processor_executions tables, MergedExecution record, ChunkAccumulator
extraction, DetailService snapshot, and REST API response.

UI adds a Properties tab next to Headers in the process diagram detail
panel, with the same input/output split table layout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 14:23:53 +02:00
hsiegeln
199d0259cd feat: add "+ App" shortcut button to sidebar Applications header
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m20s
CI / docker (push) Successful in 1m12s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 37s
Adds a subtle "+ App" button in the sidebar section header for quick
app creation without navigating to the Deployments tab first. Only
visible to OPERATOR and ADMIN roles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 09:10:41 +02:00
hsiegeln
6b558b649d fix: use absolute asset paths and prevent route-level runtime navigation
Some checks failed
CI / build (push) Has been cancelled
CI / docker (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / deploy-feature (push) Has been cancelled
CI / cleanup-branch (push) Has been cancelled
Change vite base from './' to '/' so asset paths are absolute. With
relative paths, direct navigation to multi-segment URLs like
/runtime/app/instance resolved assets to /runtime/assets/ which 404'd.

Also fix sidebar navigation: clicking a route while on the runtime tab
no longer navigates to /runtime/{appId}/{routeId} (which the runtime
page interprets as an instanceId). It stays at /runtime/{appId}.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:24:15 +02:00
hsiegeln
d34abeb5cb fix: diagram zoom not working on initial render
All checks were successful
CI / build (push) Successful in 2m10s
CI / cleanup-branch (push) Has been skipped
CI / docker (push) Successful in 1m32s
CI / deploy (push) Successful in 52s
CI / deploy-feature (push) Has been skipped
The wheel event listener was attached in a useEffect with empty deps,
but the SVG element doesn't exist during the loading state. Switch
svgRef from a plain ref to a callback ref that triggers re-attachment
when the SVG element becomes available after data loads.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 22:05:35 +02:00
hsiegeln
aaf9a00d67 fix: replace native SVG tooltip with styled heatmap tooltip overlay
Some checks failed
CI / build (push) Successful in 2m12s
CI / cleanup-branch (push) Has been skipped
CI / deploy (push) Has been cancelled
CI / deploy-feature (push) Has been cancelled
CI / docker (push) Has been cancelled
Renders an HTML tooltip below hovered diagram nodes with processor
metrics (avg, p99, % time, invocations, error rate). Styled inline
with the existing NodeToolbar pattern — positioned via screen-space
coordinates, uses DS tokens for background/border/shadow/typography.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 22:03:05 +02:00
hsiegeln
98ce7c2204 feat: combine process diagram and processor table into toggled card
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m25s
CI / docker (push) Successful in 1m9s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 40s
Dashboard L3 now shows a single Processor Metrics card with
Diagram/Table toggle buttons. The diagram shows native tooltips on
hover with full processor metrics (avg, p99, invocations, error rate,
% time).

Also fixes:
- Chart x-axis uses actual timestamps instead of bucket indices
- formatDurationShort uses locale formatting with max 3 decimals

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 21:40:43 +02:00
hsiegeln
c8cdd846c0 feat: fetch server capabilities and hide infra tabs when disabled
Adds a useServerCapabilities hook that fetches /api/v1/health once per
session (staleTime: Infinity) and extracts the infrastructureEndpoints
flag. buildAdminTreeNodes now accepts an opts parameter so ClickHouse
and Database tabs are hidden when the server reports infra endpoints as
disabled. LayoutShell wires the hook result into the admin tree memo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 23:12:30 +02:00
hsiegeln
1a45235e30 feat: multi-format env var editor for deployment config
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m12s
CI / docker (push) Successful in 1m32s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 38s
Replace simple key-value rows with EnvEditor component that supports
editing variables as Table, Properties, YAML, or .env format.
Switching views converts data seamlessly. Includes file import
(drag-and-drop .properties/.yaml/.env) with auto-detect and merge.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 08:16:09 +02:00
hsiegeln
491bdfe1ff fix: type-safe ExchangeStatus cast in ButtonGroup onChange
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m9s
CI / docker (push) Successful in 1m30s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 37s
Cast the Set<string> from ButtonGroup.onChange to Set<ExchangeStatus>
before iterating, fixing TS2345 from DS TopBar decomposition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 20:10:08 +02:00
hsiegeln
2863ceef12 refactor: compose TopBar center slot with server-specific controls
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Failing after 52s
CI / docker (push) Has been skipped
CI / deploy (push) Has been skipped
CI / deploy-feature (push) Has been skipped
Update to @cameleer/design-system@0.1.40 which decomposes TopBar into a
composable shell. Move status filters, time range, search trigger, and
auto-refresh toggle from the DS TopBar into LayoutShell as composed
children. Fixes cameleer/cameleer-saas#53.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 17:06:03 +02:00
hsiegeln
4bc38453fe fix: nice-to-have polish — breadcrumbs, close button, status badges
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Failing after 40s
CI / docker (push) Has been skipped
CI / deploy (push) Has been skipped
CI / deploy-feature (push) Has been skipped
CI / cleanup-branch (pull_request) Has been skipped
CI / build (pull_request) Failing after 35s
CI / docker (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / deploy-feature (pull_request) Has been skipped
- 7.1: Add deployment status badge (StatusDot + Badge) to AppsTab app
  list, sourced from catalog.deployment.status via slug lookup
- 7.3: Add X close button to top-right of exchange detail right panel
  in ExchangesPage (position:absolute, triggers handleClearSelection)
- 7.5: PunchcardHeatmap shows "Requires at least 2 days of data"
  when timeRangeMs < 2 days; DashboardL1 passes the range down
- 7.6: Command palette exchange results truncate IDs to ...{last8}
  matching the exchanges table display

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 18:51:49 +02:00
hsiegeln
7ec56f3bd0 fix: add shared number formatting utilities (formatMetric, formatCount, formatPercent)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 18:43:52 +02:00
hsiegeln
fb53dc6dfc fix: standardize button order, add confirmation dialogs for destructive actions
- Fix Cancel|Save order and add primary/loading props (AppConfigDetailPage)
- Add AlertDialog before stopping deployments (AppsTab)
- Add ConfirmDialog before deleting taps (TapConfigModal)
- Add AlertDialog before killing queries with toast feedback (DatabaseAdminPage)
- Add AlertDialog before removing roles from users (UsersTab)
- Standardize Cancel button to variant="ghost" (TapConfigModal, RouteDetail)
- Add loading prop to ConfirmDialogs (OidcConfigPage, RouteDetail)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 18:39:22 +02:00
hsiegeln
ba0a1850a9 fix: WCAG AA contrast compliance for --text-muted/--text-faint, 12px font floor
Override design system tokens in app root CSS: --text-muted raised to 4.5:1
contrast in both light (#766A5E) and dark (#9A9088) modes; --text-faint dark
mode raised from catastrophic 1.4:1 to 3:1 (#6A6058). Migrate --text-faint
usages on readable text (empty states, italic notes, buttons) to --text-muted.
Raise all 10px and 11px font-size declarations to 12px floor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-09 18:31:51 +02:00
hsiegeln
3f94c98c5b refactor: replace native HTML with design system components (Phase 5)
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m26s
CI / docker (push) Successful in 1m12s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 37s
- EnvironmentSelector: bare <select> -> DS Select
- LogTab: raw <table> + <input> + <button> -> DS LogViewer + Input + Button
- AppsTab: 3 homegrown sub-tab bars -> DS Tabs, remove unused CSS
- AppConfigDetailPage: 4x <select> -> DS Select, 2x <input checkbox> ->
  DS Toggle, 7x <label> -> DS Label, 4x <button> -> DS Button
- AgentHealth: 4x <select> -> DS Select, 7x <button> -> DS Button

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 15:22:14 +02:00
hsiegeln
ff62a34d89 refactor: UI consistency — shared CSS, design system colors, no inline styles
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m22s
CI / docker (push) Successful in 1m9s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 36s
Phase 1: Extract 6 shared CSS modules (table-section, log-panel,
rate-colors, refresh-indicator, chart-card, section-card) eliminating
~135 duplicate class definitions across 11 files.

Phase 2: Replace all hardcoded hex colors in CSS modules with design
system variables. Strip ~55 hex fallbacks from var() patterns. Fix 4
undefined variable names (--accent, --bg-base, --surface, --bg-surface-raised).

Phase 3: Replace ~45 hardcoded hex values in ProcessDiagram SVG
components with var() CSS custom properties. Fix Dashboard.tsx color prop.

Phase 4: Create CSS modules for AdminLayout, DatabaseAdminPage,
OidcCallback (previously 100% inline). Extract shared PageLoader
component (replaces 3 copy-pasted spinner patterns). Move AppsTab
static inline styles to CSS classes. Extract LayoutShell StarredList styles.

58 files changed, net -219 lines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 14:55:54 +02:00
hsiegeln
04c90bde06 refactor: extract duplicated utility functions into shared modules
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Failing after 41s
CI / docker (push) Has been skipped
CI / deploy (push) Has been skipped
CI / deploy-feature (push) Has been skipped
Consolidate 20+ duplicate function definitions across UI components into
three shared util files (format-utils, agent-utils, config-draft-utils).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 08:28:31 +02:00
hsiegeln
2df5e0d7ba feat: active config snapshot, composite StatusDot with tooltip
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Failing after 43s
CI / docker (push) Has been skipped
CI / deploy (push) Has been skipped
CI / deploy-feature (push) Has been skipped
Part 1 — Config snapshot:
- V8 migration adds resolved_config JSONB to deployments table
- DeploymentExecutor saves the full resolved config at deploy time
- Deployment record includes resolvedConfig for auditability

Part 2 — Composite health StatusDot:
- CatalogController computes composite health from deployment status +
  agent health (green only when RUNNING AND agent live)
- CatalogApp includes healthTooltip (e.g. "Deployment: RUNNING,
  Agents: live (1 connected)")
- StatusDot added to app detail header with deployment status Badge
- StatusDot added to deployment table rows
- Sidebar passes composite health + tooltip through to tree nodes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 08:00:54 +02:00
hsiegeln
eb7cd9ba62 fix: keep sidebar selection when switching tabs
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m10s
CI / docker (push) Successful in 1m8s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 37s
Normalize the sidebar selectedPath so the app highlight persists across
tab switches (Dashboard, Runtime, Deployments). Also make sidebar clicks
tab-aware: clicking an app navigates to the current tab's path instead
of always going to /exchanges/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 07:13:04 +02:00
hsiegeln
b86e95f08e feat: unified catalog endpoint and slug-based app navigation
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m19s
CI / docker (push) Successful in 1m7s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 37s
SonarQube / sonarqube (push) Successful in 3m47s
Consolidate route catalog (agent-driven) and apps table (deployment-
driven) into a single GET /api/v1/catalog?environment={slug} endpoint.
Apps table is authoritative; agent data enriches with live health,
routes, and metrics. Unmanaged apps (agents without App record) appear
with managed=false.

- Add CatalogController merging App records + agent registry + ClickHouse
- Add CatalogApp DTO with deployment summary, managed flag, health
- Change AppController and DeploymentController to accept slugs (not UUIDs)
- Add AppRepository.findBySlug() and AppService.getBySlug()
- Replace useRouteCatalog() with useCatalog() across all UI components
- Navigate to /apps/{slug} instead of /apps/{UUID}
- Update sidebar, search, and all catalog lookups to use slug

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:43:14 +02:00
hsiegeln
a4a569a253 fix: improve deployment progress UI and prevent duplicate deployment rows
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m55s
CI / docker (push) Successful in 1m7s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 1m6s
- Redesign DeploymentProgress component: track-based layout with amber
  brand color, checkmarks for completed steps, user-friendly labels
  (Prepare, Image, Network, Launch, Verify, Activate, Live)
- Delete terminal (STOPPED/FAILED) deployments before creating new ones
  for the same app+environment, preventing duplicate rows in the UI
- Update CLAUDE.md with comprehensive key class locations, correct deploy
  stages, database migration reference, and REST endpoint summary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 23:10:59 +02:00
hsiegeln
977bfc1c6b feat: DeploymentProgress step indicator component
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 20:29:57 +02:00
hsiegeln
0a0733def7 refactor: consolidate tabs — remove standalone Logs and Config tabs
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m18s
CI / docker (push) Successful in 1m5s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 42s
Logs functionality already exists in Runtime tab (AgentHealth/AgentInstance).
Config functionality moved to Deployments tab ConfigSubTab.
Old routes redirect to /runtime and /apps respectively.
Navigation links updated throughout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 18:02:29 +02:00
hsiegeln
c4fe992179 feat: redesign Deployments tab with Overview + Configuration sub-tabs
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m20s
CI / docker (push) Successful in 1m4s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 37s
Overview sub-tab:
- Deployments table with env badge, version, status, URL, deployed time
- Actions (Start/Stop) scoped to selected environment; other envs show
  "switch env to manage" hint with muted rows
- Versions list with per-env deploy target picker

Configuration sub-tab:
- Read-only by default with Edit mode gate (Cancel/Save banner)
- Agent observability: engine level, payload capture with size unit
  selector, log levels, metrics toggle, sampling, replay and route
  control (default enabled)
- Container resources: memory/CPU limits, exposed ports as deletable
  pills with inline add input
- Environment variables: key-value editor with add/remove
- Reuses existing ApplicationConfig API for agent config push via SSE

Tab renamed from "Apps" to "Deployments" in the tab bar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:36:09 +02:00
hsiegeln
1c5ecb02e3 fix: make environment list accessible to all authenticated users
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m25s
CI / docker (push) Successful in 1m10s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 38s
The list endpoint on EnvironmentAdminController now overrides the
class-level ADMIN guard with isAuthenticated(), so VIEWERs can see
the environment selector. The LayoutShell merges environments from
both the table and agent heartbeats, so the selector always shows
configured environments even when no agents are connected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:50:31 +02:00
hsiegeln
de4ca10fa5 feat: move Apps from admin to main tab bar with container config
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m20s
CI / docker (push) Successful in 1m8s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Failing after 2m16s
- Apps tab visible to OPERATOR+ (hidden for VIEWER), scoped by
  sidebar app selection and environment filter
- List view: DataTable with name, environment, updated, created columns
- Detail view: deployments across all envs, version upload with
  per-env deploy target, container config form (resources, ports,
  custom env vars) with explicit Save
- Memory reserve field disabled for non-production environments
  with info hint
- Admin sidebar sorted alphabetically, Applications entry removed
- Old admin AppsPage deleted

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 16:23:30 +02:00