feat: implement tool instances backend and session navigation
Backend: - Create ToolInstance model with status tracking - Add Alembic migration for tool_instances table - Create Docker service for compose template rendering and container execution - Add CRUD API endpoints for tool instances - Add lifecycle endpoints (start/stop/restart) - Add user sessions endpoint for navigation - Register routers in main.py Frontend: - Create SessionsProvider with React context - Create sessions API client - Update AppShell with sessions section in navigation - Add session status indicators and polling - Add CSS for session navigation Quality gates: typecheck ✓, lint ✓, build ✓
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
# Tool Instances Specification
|
||||
|
||||
## Requirements
|
||||
|
||||
### Functional Requirements
|
||||
|
||||
1. **ToolInstance Model**: Store instance metadata with status tracking
|
||||
2. **Session API**: CRUD operations + lifecycle (start/stop/restart/delete)
|
||||
3. **Docker Integration**: Render compose templates and execute commands
|
||||
4. **Status Monitoring**: Real-time container status polling
|
||||
5. **Log Access**: View container logs (last 100 lines)
|
||||
6. **Session Navigation**: Active sessions appear in app shell
|
||||
7. **URL Generation**: Unique access URLs for each running instance
|
||||
|
||||
### Non-Functional Requirements
|
||||
|
||||
1. **Security**: Isolated containers, no privileged mode
|
||||
2. **Resource Limits**: CPU and memory constraints
|
||||
3. **Error Handling**: Graceful failure with cleanup
|
||||
4. **Performance**: Start time < 30 seconds
|
||||
|
||||
## API Specification
|
||||
|
||||
### Create Instance
|
||||
```
|
||||
POST /projects/{project_id}/repositories/{repo_id}/instances
|
||||
Body: {
|
||||
tool_type_id: string,
|
||||
display_name: string (optional)
|
||||
}
|
||||
Response: {
|
||||
id: string,
|
||||
name: string,
|
||||
display_name: string,
|
||||
tool_type_id: string,
|
||||
status: "pending",
|
||||
created_at: string
|
||||
}
|
||||
```
|
||||
|
||||
### List Instances
|
||||
```
|
||||
GET /projects/{project_id}/repositories/{repo_id}/instances
|
||||
Response: {
|
||||
instances: [...]
|
||||
}
|
||||
```
|
||||
|
||||
### Get Instance
|
||||
```
|
||||
GET /projects/{project_id}/repositories/{repo_id}/instances/{instance_id}
|
||||
Response: {
|
||||
id: string,
|
||||
name: string,
|
||||
display_name: string,
|
||||
status: string,
|
||||
container_id: string | null,
|
||||
url: string | null,
|
||||
port: number | null,
|
||||
last_started_at: string | null,
|
||||
last_stopped_at: string | null,
|
||||
created_at: string
|
||||
}
|
||||
```
|
||||
|
||||
### Lifecycle Operations
|
||||
```
|
||||
POST /projects/{project_id}/repositories/{repo_id}/instances/{instance_id}/start
|
||||
POST /projects/{project_id}/repositories/{repo_id}/instances/{instance_id}/stop
|
||||
POST /projects/{project_id}/repositories/{repo_id}/instances/{instance_id}/restart
|
||||
Response: { status: string }
|
||||
```
|
||||
|
||||
### Delete Instance
|
||||
```
|
||||
DELETE /projects/{project_id}/repositories/{repo_id}/instances/{instance_id}
|
||||
Response: 204 No Content
|
||||
```
|
||||
|
||||
### Get User Sessions
|
||||
```
|
||||
GET /users/me/sessions
|
||||
Response: {
|
||||
sessions: [
|
||||
{
|
||||
id: string,
|
||||
display_name: string,
|
||||
tool_type_name: string,
|
||||
tool_icon: string,
|
||||
repository_name: string,
|
||||
project_name: string,
|
||||
status: string,
|
||||
url: string | null
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Docker Compose Template Variables
|
||||
|
||||
- `{{REPO_PATH}}`: Absolute path to git repository on host
|
||||
- `{{INSTANCE_NAME}}`: Unique instance identifier
|
||||
- `{{INSTANCE_ID}}`: UUID of the instance
|
||||
- `{{TOOL_PORT}}`: Assigned port for the tool
|
||||
- `{{USER_ID}}`: Owner user ID
|
||||
- `{{PROJECT_ID}}`: Project ID
|
||||
|
||||
## Status Values
|
||||
|
||||
- `pending`: Instance created, waiting to start
|
||||
- `building`: Docker compose up in progress
|
||||
- `running`: Container is running
|
||||
- `stopped`: Container stopped
|
||||
- `error`: Container failed to start or crashed
|
||||
|
||||
## Database Schema
|
||||
|
||||
```sql
|
||||
CREATE TABLE tool_instances (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
display_name VARCHAR(255) NOT NULL,
|
||||
tool_type_id UUID NOT NULL REFERENCES tool_types(id),
|
||||
repository_id UUID NOT NULL REFERENCES git_repositories(id),
|
||||
project_id UUID NOT NULL REFERENCES projects(id),
|
||||
owner_id UUID NOT NULL REFERENCES users(id),
|
||||
status VARCHAR(50) NOT NULL DEFAULT 'pending',
|
||||
container_id VARCHAR(255),
|
||||
compose_path VARCHAR(1024),
|
||||
url VARCHAR(1024),
|
||||
port INTEGER,
|
||||
last_started_at TIMESTAMP WITH TIME ZONE,
|
||||
last_stopped_at TIMESTAMP WITH TIME ZONE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_tool_instances_owner ON tool_instances(owner_id);
|
||||
CREATE INDEX idx_tool_instances_repo ON tool_instances(repository_id);
|
||||
CREATE INDEX idx_tool_instances_status ON tool_instances(status);
|
||||
```
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
1. **Unit Tests**: Docker command generation, template rendering
|
||||
2. **Integration Tests**: API endpoints, database operations
|
||||
3. **Manual Testing**: Container lifecycle, navigation updates
|
||||
Reference in New Issue
Block a user