This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Workflow is a human-AI workflow orchestration platform. AI agents process tasks autonomously via Spring AI, escalating to human operators when confidence drops below a configurable threshold. Every state change is recorded in an append-only audit log.
- Backend: Java 21, Spring Boot 3.4.1, Spring AI 1.0.0, PostgreSQL 16, Flyway migrations
- Frontend: React 18 + Vite + Tailwind + React Query + React Router
- AI: Spring AI ChatClient with multi-provider support (Ollama default, Anthropic, OpenAI)
- Auth: Spring Security + JWT (BCrypt-12), rate limiting via Bucket4j
- Docker Compose: 4 services — db (Postgres), redis, api (Spring Boot), frontend (nginx)
- Package:
com.workflow— all Java code lives under this package
- Workflows are DAGs of nodes (AI_AGENT, HUMAN_TASK, QUALITY_CHECK, etc.) connected by edges with optional conditions
- WorkflowEngine starts runs, dispatches entry nodes as Tasks, and advances the DAG when tasks complete
- TaskRouter assigns human tasks using deterministic scoring: 70% skill match + 30% inverse workload, ties broken by UUID
- AgentWorker polls for pending AI tasks; TaskAgent runs a 2-step LLM pipeline (analyze → execute) with confidence gating
- Tasks below the confidence threshold auto-escalate to human review; humans can approve, reject, or correct via feedback
- Jackson uses
SNAKE_CASEglobally (application.yml) - Java enums serialize as UPPERCASE; the frontend calls
.toLowerCase()for display - Auth endpoint returns
{ token }(notaccess_token) - Audit API returns
Page<AuditLog>(paginated); frontend extracts.content WorkflowDefinitionresponse hasnodesandedgesat the top level (not nested underdefinition)WorkflowRunhascurrent_nodes(a List), notcurrent_node
# Build (compile + tests + coverage check)
cd backend && ./mvnw clean install
# Run tests only (JaCoCo enforces 30% line coverage minimum)
cd backend && ./mvnw test
# Run a single test class
cd backend && ./mvnw test -Dtest=TaskRouterTest
# Run a single test method
cd backend && ./mvnw test -Dtest=TaskRouterTest#testFindBestOperator
# Run locally (seeds demo data on first run with dev profile)
cd backend && ./mvnw spring-boot:run -Dspring-boot.run.profiles=dev
# Frontend dev server
cd frontend && npm install && npm run dev
# E2E tests (requires both backend + frontend running)
cd frontend && npx playwright test
# E2E with UI mode
cd frontend && npx playwright test --ui
# Full stack via Docker
export WORKFLOW_DB_PASSWORD='<secret>'
export WORKFLOW_JWT_SECRET='<64+ char secret>'
docker compose up -d- Flyway migrations in
backend/src/main/resources/db/migration/ - V1: initial schema (users, workflow_definitions, workflow_runs, tasks, documents, audit_log, agent_feedback, quality_rules)
- V2: fixes enum CHECK constraints to match Java UPPERCASE enum names
- Audit log is truly append-only — DB triggers prevent UPDATE/DELETE on
audit_logtable - Tests use H2 in PostgreSQL compatibility mode with
ddl-auto: create-drop(Flyway disabled)
- DTOs are Java records (immutable), located in
api/dto/ - Domain entities use
@PrePersist/@PreUpdatefor timestamps - State transitions validated by enum methods (e.g.,
TaskStatus.canTransitionTo()) - All collections stored as defensive copies (
List.copyOf,Map.copyOf) - Error responses use RFC 7807 ProblemDetail format
- No secrets in code — all from environment variables prefixed with
WORKFLOW_ - The
-parameterscompiler flag is enabled in pom.xml for@RequestParamname resolution - In dev profile, Anthropic and OpenAI auto-configurations are excluded (only Ollama active)
WorkflowEdgehas@JsonIgnoreProperties(ignoreUnknown = true)to handle itsisUnconditional()getter
src/lib/api.js— singletonApiClientwith all API methods, JWT stored in localStorage asworkflow_tokensrc/hooks/useAuth.jsx— auth context providersrc/pages/— Dashboard, Inbox, TaskDetail, Workflows, WorkflowRun, Audit, Logine2e/— Playwright tests with auth fixture inauth.setup.js- Vite proxies
/apitohttp://localhost:8000in dev
| Password | Role | |
|---|---|---|
| admin@workflow.dev | admin123 | Admin |
| manager@workflow.dev | manager123 | Manager |
| operator1@workflow.dev | operator123 | Operator |
| operator2@workflow.dev | operator123 | Operator |