Contract-first API with DTOs, validation, and server-side OpenAPI post-processing
All checks were successful
CI / build (push) Successful in 1m27s
CI / docker (push) Successful in 2m6s
CI / deploy (push) Successful in 30s

Add dedicated request/response DTOs for all controllers, replacing raw
JsonNode parameters with validated types. Move OpenAPI path-prefix stripping
and ProcessorNode children injection into OpenApiCustomizer beans so the
spec served at /api/v1/api-docs is already clean — eliminating the need for
the ui/scripts/process-openapi.mjs post-processing script.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-14 15:33:37 +01:00
parent 50bb22d6f6
commit 465f210aee
43 changed files with 1561 additions and 509 deletions

View File

@@ -5,8 +5,8 @@ import {
useSaveOidcConfig,
useTestOidcConnection,
useDeleteOidcConfig,
type OidcConfigRequest,
} from '../../api/queries/oidc-admin';
import type { OidcAdminConfigRequest } from '../../api/types';
import styles from './OidcAdminPage.module.css';
interface FormData {
@@ -87,7 +87,7 @@ function OidcAdminForm() {
}
async function handleSave() {
const payload: OidcConfigRequest = {
const payload: OidcAdminConfigRequest = {
...form,
clientSecret: secretTouched ? form.clientSecret : '********',
};

View File

@@ -1,5 +1,5 @@
import { useProcessorSnapshot } from '../../api/queries/executions';
import type { ExecutionSummary } from '../../api/schema-types';
import type { ExecutionSummary } from '../../api/types';
import styles from './ExchangeDetail.module.css';
interface ExchangeDetailProps {

View File

@@ -1,5 +1,5 @@
import { useExecutionDetail } from '../../api/queries/executions';
import type { ProcessorNode as ProcessorNodeType } from '../../api/schema-types';
import type { ProcessorNode as ProcessorNodeType } from '../../api/types';
import styles from './ProcessorTree.module.css';
const ICON_MAP: Record<string, { label: string; className: string }> = {

View File

@@ -1,5 +1,5 @@
import { useState, useMemo } from 'react';
import type { ExecutionSummary } from '../../api/schema-types';
import type { ExecutionSummary } from '../../api/types';
import { StatusPill } from '../../components/shared/StatusPill';
import { DurationBar } from '../../components/shared/DurationBar';
import { AppBadge } from '../../components/shared/AppBadge';

View File

@@ -7,7 +7,7 @@ import { ScopeTabs } from '../../components/command-palette/ScopeTabs';
import { ResultsList } from '../../components/command-palette/ResultsList';
import { PaletteFooter } from '../../components/command-palette/PaletteFooter';
import { FilterChip } from '../../components/shared/FilterChip';
import type { ExecutionSummary, AgentInstance } from '../../api/schema-types';
import type { ExecutionSummary, AgentInstance } from '../../api/types';
import styles from './SearchFilters.module.css';
export function SearchFilters() {

View File

@@ -1,5 +1,5 @@
import { create } from 'zustand';
import type { SearchRequest } from '../../api/schema-types';
import type { SearchRequest } from '../../api/types';
function todayMidnight(): string {
const d = new Date();