Files
Vaessl/CLAUDE.md
T

5.3 KiB

CLAUDE.md

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

Project Overview

Vaessl is an AI-powered integration bridge that accepts user text/image inputs, processes them through an LLM pipeline (via LiteLLM), and exports structured data to management systems (Homebox, WikiJS). The backend uses a provider pattern for extensibility. The frontend has a working connection management dashboard.

Commands

Backend (Spring Boot + Gradle, inside backend/)

./gradlew build           # compile and package
./gradlew test            # run all tests
./gradlew test --tests com.vaessl.app.connection.ConnectionServiceTest  # single test class

Frontend (React + Vite, inside frontend/)

npm run dev       # start dev server
npm run build     # TypeScript check + Vite build
npm run lint      # ESLint
npm run test      # Vitest watch mode
npm run test:ui   # Vitest visual dashboard

Environment

Copy .env.local (not committed) into backend/ with:

  • DB_URL, DB_TEST_URL, DB_USERNAME, DB_PASSWORD — PostgreSQL (test container on port 5434)
  • PG_DRIVER_CLASS_NAME — PostgreSQL JDBC driver class
  • OPENAI_KEY, OPENAI_BASE_URL — LiteLLM gateway (provider-agnostic, configured for gpt-4o-mini)
  • FRONTEND_LOCAL_URL, FRONTEND_PUBLIC_URL — allowed CORS origins for the backend

Frontend (optional, defaults to /api):

  • VITE_API_URL — backend base URL used by api/client.ts

Architecture

Backend (backend/src/main/java/com/vaessl/app/)

Package-by-feature layout. Server context path is /api. Main endpoints:

  • POST /api/login — authenticates a service, stores connection ID in session
  • GET /api/connections/status — lists connected services for the current session
  • DELETE /api/connections/{serviceType} — removes a service from the session; invalidates the session if no connections remain
  • POST /api/search — paged search against the requested service; returns 401 if no active session

Five packages:

shared/ — cross-cutting types used by more than one feature package

  • ServiceType (enum): identifies each integrated app (e.g. HOMEBOX); used in both connection/ and search/
  • ServiceProvider (interface): base for ConnectionProvider and SearchProvider; declares getServiceType()
  • Endpoint (enum): API path constants for all external service calls
  • SessionKeys: builds session attribute names of the form {SERVICE_TYPE}_CONNECTION_ID

config/

  • CorsConfig: env-driven allowed origins (FRONTEND_LOCAL_URL, FRONTEND_PUBLIC_URL); allowCredentials(true) is required for session cookies to work cross-origin
  • SessionConfig: JDBC-backed Spring Session with a persistent cookie (SameSite=Lax, HttpOnly)

connection/ — connecting to and persisting service credentials

  • ConnectionProvider interface: extends ServiceProvider; each integrated app implements login() and credential checking
  • ConnectionService: auto-discovers providers via Spring injection, dispatches login by ServiceType
  • ConnectionController: stores {serviceType}_CONNECTION_ID in HttpSession after login; reads session attributes to build status responses
  • Entity (ConnectionEntity) uses Single Table Inheritance — one connections table with app-specific nullable columns
  • HomeboxConnectionProvider / HomeboxEntity: Homebox-specific implementation

search/ — querying connected services

  • SearchProvider interface: extends ServiceProvider; each integrated app implements getSearchResults()
  • SearchService: auto-discovers providers via Spring injection, dispatches by ServiceType
  • SearchController: guards with session check before delegating to SearchService
  • HomeboxSearchProvider: Homebox-specific search implementation using bearer token from session

exception/GlobalExceptionHandler via @ControllerAdvice

Frontend (frontend/src/)

React 19 + TypeScript + SCSS, Vite 6 build. Package-by-feature under components/.

  • api/client.ts — typed apiFetch wrapper; always sends credentials: 'include' for session cookies; base URL from VITE_API_URL (defaults to /api)
  • api/connections.ts — connection-specific API calls (getStatuses, login, logout)
  • api/searches.ts — search API call (search)
  • types/connection.tsServiceType, LoginRequest, AuthResponse, ConnectionStatus
  • types/search.tsSearchRequest, SearchResponse, PagedSearchResponse
  • components/connections/Dashboard, ConnectModal, ServiceCard (connection management UI)
  • components/search/SearchModal — search dialog; posts to /api/search and renders paged results
  • components/ui/ — shared UI primitives (ActionButton, Modal)

Data & AI

  • PostgreSQL + pgvector (semantic search via embeddings); also used as the Spring Session store (JDBC)
  • LiteLLM as a unified AI proxy; Spring AI OpenAI starter wired to it
  • Processing pipeline (Phase 2): stage in DB → LLM inference → refine via UI → export to target app

Testing Strategy

Integration tests spin up a mirrored PostgreSQL container on port 5434 (same schema as production). WireMock mocks external HTTP APIs (Homebox, WikiJS). Do not mock the database in integration tests — the mirrored container strategy exists specifically to catch schema/migration divergence.