139 lines
4.9 KiB
Markdown
139 lines
4.9 KiB
Markdown
# 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
|