# Onebox Development Notes ## ⚠️ CRITICAL DEVELOPMENT RULES ⚠️ ### NEVER GUESS - ALWAYS READ THE ACTUAL CODE **FUCKING ALWAYS look at the dependency actual code. Don't start fucking guessing stuff.** When working with any dependency: 1. **READ the actual source code** in `node_modules/` or check the package documentation 2. **CHECK the exact API** - don't assume based on similar libraries 3. **VERIFY method names, return types, and property structures** before using them 4. **TEST with the actual implementation** - APIs change between versions Common mistakes to avoid: - ❌ Assuming API structure based on similar libraries - ❌ Guessing method names or property paths - ❌ Using outdated documentation without checking current version - ✅ Read the actual TypeScript definitions in node_modules - ✅ Check the package's README and changelog - ✅ Test the actual behavior before implementing ## Architecture Changes ### Reverse Proxy Implementation - **Replaced Nginx** with native Deno reverse proxy (`ts/classes/reverseproxy.ts`) - Features: - HTTP/HTTPS dual servers (ports 80/443) - TLS/SSL certificate management with hot-reload - WebSocket bidirectional proxying - Dynamic routing from database - SNI (Server Name Indication) support ### Code Organization - Removed "onebox." prefix from all TypeScript files - Organized into subfolders: - `ts/classes/` - All class implementations - `ts/` - Root level utilities (logging, types, plugins, cli, info) ### WebSocket Real-time Communication - **Backend**: WebSocket endpoint at `/api/ws` (`ts/classes/httpserver.ts:96-174`) - Connection management with client Set tracking - Broadcast methods: `broadcast()`, `broadcastServiceUpdate()`, `broadcastServiceStatus()` - Integrated with service lifecycle (start/stop/restart actions) - Status monitoring loop broadcasts changes automatically - **Frontend**: Angular WebSocket service (`ui/src/app/core/services/websocket.service.ts`) - Auto-connects on app initialization - Exponential backoff reconnection (max 5 attempts) - RxJS Observable-based message streaming - Components subscribe to real-time updates - **Message Types**: - `connected` - Initial connection confirmation - `service_update` - Service lifecycle changes (action: created/updated/deleted/started/stopped) - `service_status` - Real-time status changes from monitoring loop - `system_status` - System-wide updates - **Testing**: Use `.nogit/test-ws-updates.ts` to monitor WebSocket messages ### Docker Configuration - **System Docker**: Uses root Docker at `/var/run/docker.sock` (NOT rootless) - **Swarm Mode**: Enabled for service orchestration - **API Access**: Interact with Docker via direct API calls to the socket - ❌ DO NOT switch Docker CLI contexts - ✅ Use curl/HTTP requests to `/var/run/docker.sock` - **Network**: Overlay network `onebox-network` with `Attachable: true` - **Services vs Containers**: All workloads run as Swarm services (not standalone containers) ## Debugging Tips ### Backend Logs Use the background bash task to check server logs: ```bash # Check for specific patterns (e.g., Login attempts) BashOutput tool with filter: "Login|error|Error" # Check all recent output BashOutput tool without filter ``` The dev server runs with `--watch` so it auto-restarts on file changes. ### Frontend Testing Use Playwright for UI testing: ```typescript // Navigate to app mcp__playwright__browser_navigate({ url: "http://localhost:3000" }) // Fill login form mcp__playwright__browser_fill_form({ fields: [ { name: "Username", type: "textbox", ref: "...", value: "admin" }, { name: "Password", type: "textbox", ref: "...", value: "admin" } ] }) // Click button mcp__playwright__browser_click({ element: "Sign in button", ref: "..." }) // Check console errors // Playwright automatically shows console messages in results ``` ### Common Issues #### Login Issue (Fixed) **Problem**: `admin/admin` credentials returned "Invalid credentials" **Root Cause**: `rowToUser()` function in database.ts was accessing rows as arrays `row[2]` instead of objects `row.password_hash`. The @db/sqlite library returns rows as objects with snake_case column names. **Fix**: Updated `rowToUser()` to support both access patterns: ```typescript private rowToUser(row: any): IUser { return { passwordHash: String(row.password_hash || row[2]), // ... other fields }; } ``` **Location**: `ts/classes/database.ts:506-515` ## Default Credentials - Username: `admin` - Password: `admin` - ⚠️ Change immediately after first login! ## Development Server ```bash # Main server (port 3000) deno task dev # Check server status curl http://localhost:3000/api/status ``` ## API Endpoints - `POST /api/auth/login` - Login (returns JWT-like token) - `GET /api/status` - System status (requires auth) - `GET /api/services` - List services (requires auth) - See `ts/classes/httpserver.ts` for full API