Skip to content

Latest commit

 

History

History
103 lines (76 loc) · 4.64 KB

File metadata and controls

103 lines (76 loc) · 4.64 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

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.

Architecture

  • 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

How the system works

  1. Workflows are DAGs of nodes (AI_AGENT, HUMAN_TASK, QUALITY_CHECK, etc.) connected by edges with optional conditions
  2. WorkflowEngine starts runs, dispatches entry nodes as Tasks, and advances the DAG when tasks complete
  3. TaskRouter assigns human tasks using deterministic scoring: 70% skill match + 30% inverse workload, ties broken by UUID
  4. AgentWorker polls for pending AI tasks; TaskAgent runs a 2-step LLM pipeline (analyze → execute) with confidence gating
  5. Tasks below the confidence threshold auto-escalate to human review; humans can approve, reject, or correct via feedback

Key serialization behavior

  • Jackson uses SNAKE_CASE globally (application.yml)
  • Java enums serialize as UPPERCASE; the frontend calls .toLowerCase() for display
  • Auth endpoint returns { token } (not access_token)
  • Audit API returns Page<AuditLog> (paginated); frontend extracts .content
  • WorkflowDefinition response has nodes and edges at the top level (not nested under definition)
  • WorkflowRun has current_nodes (a List), not current_node

Commands

# 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

Database

  • 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_log table
  • Tests use H2 in PostgreSQL compatibility mode with ddl-auto: create-drop (Flyway disabled)

Conventions

  • DTOs are Java records (immutable), located in api/dto/
  • Domain entities use @PrePersist/@PreUpdate for 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 -parameters compiler flag is enabled in pom.xml for @RequestParam name resolution
  • In dev profile, Anthropic and OpenAI auto-configurations are excluded (only Ollama active)
  • WorkflowEdge has @JsonIgnoreProperties(ignoreUnknown = true) to handle its isUnconditional() getter

Frontend structure

  • src/lib/api.js — singleton ApiClient with all API methods, JWT stored in localStorage as workflow_token
  • src/hooks/useAuth.jsx — auth context provider
  • src/pages/ — Dashboard, Inbox, TaskDetail, Workflows, WorkflowRun, Audit, Login
  • e2e/ — Playwright tests with auth fixture in auth.setup.js
  • Vite proxies /api to http://localhost:8000 in dev

Demo accounts (dev profile)

Email Password Role
admin@workflow.dev admin123 Admin
manager@workflow.dev manager123 Manager
operator1@workflow.dev operator123 Operator
operator2@workflow.dev operator123 Operator