The backend was renamed from group→application but Docker build cache
may serve old code. Accept 'group' as a fallback alias so the UI works
with both old and new backends. Applies to GET /search/executions,
/search/stats, and /search/stats/timeseries.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Split pane: card layout with border, border-radius, box-shadow
matching mock's bordered panel look
- List pane: bg-surface background, padded header with border-bottom
- Entity items: border-bottom separators instead of gap spacing,
flex-start alignment for multi-line content
- Detail pane: bg-surface background, 20px padding, right border-radius
- User meta line: show email + group path (like mock's "email · group")
- Create form: raised background with bottom border
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add AdminLayout wrapper with Tabs component for navigating between
admin sections: User Management, Audit Log, OIDC, Database, OpenSearch.
Nest all /admin/* routes under AdminLayout using React Router's
Outlet pattern so the tab bar persists across admin page navigation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Loading fonts from fonts.googleapis.com sends user IP addresses to
Google on every page load — a GDPR violation. Self-host DM Sans and
JetBrains Mono as woff2 files bundled with the UI.
- Download DM Sans (400/500/600/700 + 400 italic) woff2 files
- Download JetBrains Mono (400/500/600) woff2 files
- Replace @import url(googleapis) with local @font-face declarations
- Both fonts are OFL-licensed (free to self-host)
- Total size: ~135KB for all 8 font files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Two places in Dashboard used toISOString() for display, which always
renders UTC. Changed to toLocaleString() for the user's local timezone.
- Exchanges table "Started" column
- Detail panel "Timestamp" field
API query parameters correctly continue using toISOString() (UTC).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PostgreSQL JDBC driver can't infer SQL type for java.time.Instant.
Convert from/to parameters to java.sql.Timestamp before binding.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DetailPanel: switch from tabs to flat children layout (fixes stale
tab state bug), add position:fixed override, key on agent id
- Stat strip: colored status breakdown (live/stale/dead), msg/s detail
on TPS, "requires attention" on dead count
- Scope trail: simplified to "X/Y live" label
- Event card header: rename "Event Log" to "Timeline" with count badge
- Remove unused Breadcrumb, scopeItems, groupHealth
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use browser default locale instead of hardcoded 'en-US' and 'en-GB'
for number and time formatting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TimescaleDB add_continuous_aggregate_policy and add_compression_policy
cannot run inside a transaction block. Move all policy calls to V2
with flyway:executeInTransaction=false directive.
Also fix stats_1m_processor_detail: add WITH NO DATA and
materialized_only = false.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The render endpoint returns a union type (SVG string | JSON object).
Cast to DiagramLayout interface so .nodes is accessible. Also rename
useDiagramByRoute parameter from group to application.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Consolidate V1-V7 Flyway migrations into single V1__init.sql with
all columns renamed from group_name to application_name. Requires
fresh database (wipe flyway_schema_history, all data).
- DB columns: executions.group_name → application_name,
processor_executions.group_name → application_name
- Continuous aggregates: all views updated to use application_name
- OpenSearch field: group_name → application_name in index/query
- All Java SQL strings updated to match new column names
- Delete V2-V7 migration files (folded into V1)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The execution-related "group" concept actually represents the
application name. Rename all Java fields, API parameters, and frontend
types from groupName→applicationName and group→application for clarity.
- Java records: ExecutionSummary, ExecutionDetail, ExecutionDocument,
ExecutionRecord, ProcessorRecord
- API params: SearchRequest.group→application, SearchController
@RequestParam group→application
- Services: IngestionService, DetailService, SearchIndexer, StatsStore
- Frontend: schema.d.ts, Dashboard, ExchangeDetail, RouteDetail,
executions query hooks
Database column names (group_name) and OpenSearch field names are
unchanged — only the API-facing Java/TS field names are renamed.
RBAC group references (groups table, GroupRepository, GroupsTab) are
a separate domain concept and are NOT affected by this change.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The deployed backend doesn't return groupName on ExecutionDetail or
ExecutionSummary (Docker build cache issue). Switch diagram lookup to
use diagramContentHash which is always available in the detail response.
- Dashboard: useDiagramLayout(detail.diagramContentHash) instead of
useDiagramByRoute(groupName, routeId)
- ExchangeDetail: same change
Route Flow now renders correctly in both the slide-in panel and the
full exchange detail page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Java record was updated but the OpenAPI schema was not regenerated,
causing a TypeScript build error in CI.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add groupName field to ExecutionDetail record and DetailService
- Dashboard: fix TDZ error (rows referenced before definition), add
selectedRow fallback for diagram groupName lookup
- ExchangeDetail: rewrite to match mock layout — auto-select first
processor, Message IN/OUT split panels with header key-value rows,
error panel for failed processors, Timeline/Flow toggle buttons
- Track diagram-mapping utility (was untracked, caused CI build failure)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Only render DetailPanel when detail data is loaded (key={selectedId} forces remount
so internal activeTab state resets correctly)
- Override DetailPanel CSS with position:fixed to overlay on right side
(AppShell layout doesn't support detail prop from child pages)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Added groupName field to ExecutionSummary Java record and OpenSearch mapper
- Dashboard stat cards use locale-formatted numbers (en-US)
- Added inspect column (↗) linking directly to exchange detail page
- Fixed duplicate React key warning from two columns sharing executionId key
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dashboard: correct stat card labels (Exchanges/Success Rate/Errors/Throughput/Latency p99),
add detail text, trends, sparklines on all cards, Agent column, LIVE badge,
expanded detail panel with Agent/Correlation/Timestamp, "Open full details" link.
Agent Health: per-group meta (TPS/routes) in GroupCard header, proper HTML table
with column headers for instance list.
Agent Instance: stat card detail props (heap info, start date), scope trail with
inline status/version/routes badges.
Routes: 5th In-Flight stat card, enriched stat card props (detail/trend/sparkline),
SLA threshold line on latency chart.
Exchange Detail: Agent stat box in header.
Also: vite proxy CORS fix, cross-env dev scripts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces the filtered RoutesMetrics view at /routes/:appId/:routeId with a
dedicated RouteDetail page showing route diagram, processor stats table,
performance charts, recent executions, and client-side grouped error patterns.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a Default Roles section with Tag components for viewing/removing roles and an Input+Button for adding new ones. Replaces the plain delete button with a ConfirmDialog requiring typed confirmation. Introduces OidcConfigPage.module.css for CSS module layout classes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a recursive processor count stat to the exchange header, and a
Correlation Chain section that visualises related executions sharing
the same correlationId, with the current exchange highlighted.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bumped @cameleer/design-system from ^0.0.1 to ^0.0.2 (adds onLogout prop to TopBar).
Fetched openapi.json from remote backend, stripped /api/v1 prefix, patched
ExecutionDetail with groupName and children fields to match UI expectations,
then regenerated schema.d.ts via openapi-typescript. TypeScript compiles clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comprehensive spec and 20-task plan to close all gaps between
@cameleer/design-system v0.0.2 mocks and the current server UI.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace inline styles with semantic CSS module classes for proper visual
structure: card wrappers with borders/shadows, grid layouts for stat
strips and charts, section headers, and typography classes.
Pages updated: Dashboard, ExchangeDetail, RoutesMetrics, AgentHealth,
AgentInstance.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- SearchResult uses 'data' not 'items', 'total' not 'totalCount'
- ExecutionStats uses 'p99LatencyMs' not 'p99DurationMs'
- TimeseriesBucket uses 'time' not 'timestamp'
- Add user Dropdown with logout action to LayoutShell
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dashboard was sending page/size but backend expects offset/limit.
Schema also had sort/order instead of sortField/sortDir.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rename admin/ → Admin/ and swagger/ → Swagger/ to match router imports.
Windows is case-insensitive so the mismatch was invisible locally.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Agents are transient and should not be persisted in the users table.
The assignRoleToUser call caused a FK violation (user_roles → users),
resulting in HTTP 500 on registration. The AGENT role is already
embedded directly in the JWT claims.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously the refresh endpoint only returned a new accessToken, causing
agents to lose their refreshToken after the first refresh cycle and
forcing a full re-registration every ~2 hours.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Single JSONB key-value table replaces two singleton config tables, making
future config types trivial to add. Also fixes pre-existing IT failures:
Flyway URL not overridden by Testcontainers, threshold test ordering.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Database tables filtered to current_schema(), active queries to
current_database(), OpenSearch indices to configured index-prefix.
Delete endpoint rejects indices outside application scope.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>