# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview SmartBotic is a workflow automation and execution platform with a microservices architecture. The backend is C++20 with gRPC communication, and the frontend is React/TypeScript. ## Build Commands ### C++ Backend ```bash # Debug build mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Debug .. make # Release build cmake -DCMAKE_BUILD_TYPE=Release .. make # With Address Sanitizer cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_ASAN=ON .. make ``` ### Frontend (webui/) ```bash cd webui npm install npm run dev # Dev server (port 3000, proxies to localhost:8090) npm run build # Production build npm run lint # ESLint ``` ## Running Services The database is **not** built from this repo - it is the standalone upstream `smartbotic-database` daemon, installed from the SmartBotics APT repository and managed as a system service. Start it first, then the in-repo services: ```bash # 1. Upstream database daemon (gRPC port 9004) sudo systemctl start smartbotic-database # 2. WebServer (HTTP port 8090, gRPC port 9012) ./build/smartbotic-webserver # 3. Runner(s) (gRPC port 9011) ./build/smartbotic-runner # Or use systemd for the in-repo services systemctl --user start smartbotic.target journalctl --user -u smartbotic-* -f ``` Both the database address and the project namespace are configurable everywhere, via `config/webserver.json` and `config/runner.json`: | Key | Default | Env override | | --- | --- | --- | | `database_address` | `localhost:9004` | `DATABASE_ADDRESS` | | `database_project` | `smartbotic-automation` | `DATABASE_PROJECT` | One `smartbotic-database` instance is shared by several projects. `database_project` is the multi-tenant namespace (upstream client >= 2.3): the client transparently sends every collection as `:`, so our data stays isolated from other services on the same daemon. Never set it to `default` - that is the shared back-compat namespace where projects collide. ## Architecture ### Two In-Repo Services + External Database 1. **WebServer Service** (src/webserver/) - HTTP REST API, WebSocket for real-time updates, JWT auth, runner registry 2. **Runner Service** (src/runner/) - Workflow execution engine with QuickJS for JavaScript node evaluation Both persist through the external **smartbotic-database** daemon (upstream repo: `ssh://git@git.smartbotics.ai:10022/fszontagh/smartbotic-database.git`), consumed as the `libsmartbotic-db-client-dev` APT package. `cmake/FindPackages.cmake` locates it via `find_package(smartbotic-db-client CONFIG REQUIRED)` → target `smartbotic::db-client`. `lib/storage/storage_client.{hpp,cpp}` is a thin PIMPL adapter over `smartbotic::database::Client`, so callers never touch the upstream API directly. ### Data Flow ``` WebUI (React) → HTTP/WebSocket → WebServer → gRPC → smartbotic-database (external) ↓ gRPC → Runner(s) → executes workflows ``` ### Key Directories - `lib/` - Shared libraries (common utilities, config loader, logging, storage client) - `proto/` - Protocol Buffer definitions for gRPC services - `src/` - Microservice implementations - `nodes/` - Built-in workflow node definitions (JavaScript modules) - `webui/` - React frontend - `config/` - Runtime JSON configuration files ### Node System Workflow nodes are JavaScript modules in `nodes/` with this interface: ```javascript module.exports = { configSchema: { /* JSON Schema */ }, inputSchema: { /* JSON Schema */ }, outputSchema: { /* JSON Schema */ }, execute: async (config, input, context) => { /* returns output */ } } ``` Nodes are loaded by the Runner service and executed in QuickJS. Hot-reload is supported. **See [docs/nodes.md](docs/nodes.md) for complete node creation guide.** ### Migrating Nodes to Database After creating or modifying nodes in `nodes/`, migrate them to the running database: ```bash # 1. Login to get JWT token TOKEN=$(curl -s http://localhost:8090/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"username": "admin", "password": "admin"}' | jq -r '.accessToken') # 2. Migrate nodes from filesystem to database curl -X POST http://localhost:8090/api/v1/nodes/migrate \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"nodesPath": "./nodes"}' # 3. Verify nodes are loaded curl -s http://localhost:8090/api/v1/nodes \ -H "Authorization: Bearer $TOKEN" | jq '.nodes[] | "\(.id) - \(.name)"' ``` Runners automatically receive node updates via gRPC streaming - no restart required. ### Configuration Services load JSON configs from `config/` directory: - `webserver.json` - HTTP port, JWT settings, runner load balancing, `database_address` - `runner.json` - Runner ID, max concurrent executions, hot reload settings, `database_address` The database daemon has its own config at `/etc/smartbotic-database/config.json`, owned by the upstream package - not by this repo. Environment variables can override config values using `${VAR_NAME:default}` syntax. ## C++ Standards - C++20 required (strict compliance, no extensions) - Compiler warnings: Wall, Wextra, Wpedantic - Key libraries: gRPC, Protobuf, cpp-httplib, QuickJS, spdlog, nlohmann/json, bcrypt ## Frontend Stack - React 18.2 + TypeScript + Vite - State: Zustand + React Query - UI: TailwindCSS + Lucide icons - Workflow editor: ReactFlow