Files
gems/opal-task/srv/README.md
T
joakim 4c54814eb5 docs: Phase 5 - Comprehensive deployment documentation
- Created detailed srv/README.md with:
  - Quick start guide
  - SystemD service setup instructions
  - Reverse proxy configuration (Caddy & Nginx)
  - Complete API endpoint reference
  - Client configuration examples
  - Troubleshooting guide
  - Security considerations
  - Future enhancement roadmap
- Updated main README.md with server & sync features
- Added sync command quick reference
- Documented offline support and conflict resolution
2026-01-05 16:21:09 +01:00

369 lines
7.7 KiB
Markdown

# Opal-Task Server
Opal-task server provides a REST API for syncing tasks across multiple devices. This enables household task sharing and access from anywhere.
## Features
- **REST API** - Chi-based HTTP API for task management
- **API Key Authentication** - Secure authentication using bcrypt-hashed keys
- **Bidirectional Sync** - Push and pull changes with conflict resolution
- **Offline Support** - Queue changes when server is unreachable
- **Change Tracking** - Automatic change log with configurable retention
- **Single Database** - Shared household task database (v1)
## Quick Start
### 1. Build the Binary
```bash
cd opal-task
go build -o opal main.go
```
### 2. Generate API Key
On your server (with direct database access):
```bash
./opal server keygen --name "My Device" --db /var/lib/opal/opal.db
```
Output:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
API Key Generated Successfully
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Name: My Device
Key: oak_abc123...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️ IMPORTANT: Save this key securely!
It will not be displayed again.
```
### 3. Start the Server
```bash
./opal server start --addr :8080 --db /var/lib/opal/opal.db
```
### 4. Configure Client
On your local machine or phone:
```bash
opal sync init --url https://opal.yourdomain.com --key oak_abc123...
```
Or use interactive mode:
```bash
opal sync init
# Enter server URL: https://opal.yourdomain.com
# Enter API key: oak_abc123...
```
### 5. Sync Your Tasks
```bash
# Full bidirectional sync
opal sync now
# Push local changes only
opal sync up
# Pull server changes only
opal sync down
# Initial merge (for existing local database)
opal sync merge --prefer-local
```
## Server Deployment
### Option 1: SystemD Service (Recommended)
**1. Install Binary**
```bash
# Build
go build -o opal main.go
# Copy to system location
sudo cp opal /usr/local/bin/
# Create data directory
sudo mkdir -p /var/lib/opal
sudo chown $USER:$USER /var/lib/opal
```
**2. Generate First API Key**
```bash
opal server keygen --name "Admin" --db /var/lib/opal/opal.db
# Save the generated key!
```
**3. Create SystemD Service**
Create `/etc/systemd/system/opal.service`:
```ini
[Unit]
Description=Opal Task API Server
After=network.target
[Service]
Type=simple
User=your-user
WorkingDirectory=/var/lib/opal
ExecStart=/usr/local/bin/opal server start --addr :8080 --db /var/lib/opal/opal.db
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
```
**4. Enable and Start Service**
```bash
sudo systemctl daemon-reload
sudo systemctl enable opal
sudo systemctl start opal
sudo systemctl status opal
```
### Option 2: Direct Execution
```bash
# Run in background
nohup ./opal server start --addr :8080 --db /var/lib/opal/opal.db > opal.log 2>&1 &
```
## Reverse Proxy Setup
### Caddy (Recommended)
Add to your Caddyfile:
```
opal.yourdomain.com {
reverse_proxy localhost:8080
}
```
Reload Caddy:
```bash
sudo systemctl reload caddy
```
### Nginx
```nginx
server {
listen 443 ssl http2;
server_name opal.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
## API Endpoints
### Authentication
All endpoints (except `/health`) require authentication via API key:
```
Authorization: Bearer oak_abc123...
```
### Health Check
```
GET /health
```
Returns server status.
### Tasks
```
GET /tasks - List tasks (with filters)
GET /tasks/{uuid} - Get specific task
POST /tasks - Create task
PUT /tasks/{uuid} - Update task
DELETE /tasks/{uuid} - Delete task
POST /tasks/{uuid}/complete - Mark task complete
POST /tasks/{uuid}/start - Start task
POST /tasks/{uuid}/stop - Stop task
```
**Query Parameters for GET /tasks:**
- `status` - pending, completed, deleted
- `project` - Project name
- `priority` - L, M, H, D
- `tag` - Tag name (can specify multiple)
### Tags
```
GET /tasks/{uuid}/tags - Get task tags
POST /tasks/{uuid}/tags - Add tag
DELETE /tasks/{uuid}/tags/{tag} - Remove tag
GET /tags - List all tags
```
### Projects
```
GET /projects - List all projects
```
### Sync
```
POST /sync/changes - Get changes since timestamp
POST /sync/push - Push local changes
```
### API Keys
```
GET /auth/keys - List API keys
DELETE /auth/keys/{id} - Revoke API key
```
## Client Configuration
Sync settings are stored in `~/.config/jade/opal.yml`:
```yaml
# Task settings
default_filter: status:pending
default_sort: due,priority
color_output: true
week_start_day: monday
default_due_time: ""
# Sync settings
sync_enabled: true
sync_url: https://opal.yourdomain.com
sync_api_key: oak_abc123...
sync_client_id: 550e8400-e29b-41d4-a716-446655440000
sync_strategy: last-write-wins
sync_queue_offline: true
```
## Sync Strategies
- **last-write-wins** (default) - Most recently modified version wins
- **server-wins** - Server version always wins
- **client-wins** - Client version always wins
## Change Log Retention
By default, the change log retains entries for 30 days. This can be configured in the database:
```sql
UPDATE sync_config SET value = '60' WHERE key = 'change_log_retention_days';
```
Or programmatically:
```go
engine.SetChangeLogRetentionDays(60)
```
Cleanup runs manually or can be scheduled:
```bash
# In your cron or systemd timer
./opal server cleanup --db /var/lib/opal/opal.db
```
## Troubleshooting
### Server won't start
- Check if port 8080 is already in use: `sudo lsof -i :8080`
- Verify database path exists and is writable
- Check logs: `journalctl -u opal -f`
### Client can't connect
- Test server health: `curl https://opal.yourdomain.com/health`
- Verify API key is correct
- Check firewall allows traffic on port 8080
- Ensure reverse proxy is properly configured
### Sync conflicts
- View conflict log: `opal sync log`
- Conflicts are automatically resolved based on strategy
- By default, last-write-wins is used
### Offline changes not syncing
- Check queue status: `opal sync status`
- Verify `sync_queue_offline: true` in config
- Clear queue if needed: Delete `~/.config/jade/sync_queue.json`
## Database Schema
### Core Tables
- `tasks` - Main task storage
- `tags` - Task tags (many-to-many)
- `working_set` - Display ID mapping (client-local)
### Sync Tables
- `users` - User accounts (currently single shared user)
- `api_keys` - Authentication keys
- `sync_state` - Per-client sync state
- `change_log` - Change tracking (key:value format)
- `sync_config` - Server configuration
## Security Considerations
- API keys are hashed with bcrypt before storage
- Never log full API keys
- Use HTTPS in production (via reverse proxy)
- Implement rate limiting for production use
- Backup database regularly
- Rotate API keys periodically
## Future Enhancements
- OAuth2 with Authentik for web/mobile clients
- Per-user task separation with sharing
- Real-time sync via WebSockets
- Web/mobile frontend (SvelteKit PWA)
- Access control (share specific tags/projects)
- Audit logging
- Database backup automation
## Support
For issues or questions:
- Check logs: `journalctl -u opal -f`
- View sync status: `opal sync status`
- View conflicts: `opal sync log`
- Test connectivity: `curl https://opal.yourdomain.com/health`
## License
Same as opal-task main project.