Phase 3 Implementation Plan - Backend API Integration
Date: 2025-10-14 Status: ๐ PLANNING - Ready for Implementation Goal: Implement 18 HTTP endpoints, 4 middleware components, and 5 frontend integrations
๐ Executive Summaryโ
What's Already Done (Phase 1 & 2)โ
- โ 10 FDB Models - Complete data layer (2,860 lines)
- โ 10 FDB Repositories - Full CRUD operations with indexes
- โ Basic API Handlers - Health, login, register, basic sessions
What Phase 3 Addsโ
- ๐ง 18 HTTP Endpoints - Complete REST API coverage
- ๐ก๏ธ 4 Middleware Components - JWT auth, tenant isolation, rate limiting, audit
- ๐จ 5 Frontend Services - Full React integration
Impactโ
- Before Phase 3: Backend has data layer but no complete API
- After Phase 3: Production-ready REST API with full frontend integration
- Timeline: ~1 week (solo) | 4-5 days (2-person) | 3-4 days (4-person)
๐ฏ Phase 3 Endpoints Overviewโ
Summary by Categoryโ
| Category | Endpoints | Already Done | To Add | Priority |
|---|---|---|---|---|
| Auth | 4 | 3 (login, register, logout) | 1 (refresh) | P0 - Critical |
| Sessions | 7 | 4 (create, get, list, delete) | 3 (update, fork, related) | P0 - Critical |
| Conversations | 4 | 0 | 4 (all) | P1 - High |
| Users | 3 | 0 | 3 (all) | P1 - High |
| Settings | 3 | 0 | 3 (all) | P2 - Medium |
| Health | 2 | 2 (health, ready) | 0 | โ Complete |
| Total | 23 | 9 | 14 | - |
๐ Detailed Endpoint Specificationsโ
1. Auth Handlers (4 endpoints)โ
โ POST /api/v5/auth/registerโ
Status: โ
Already implemented in backend/src/handlers/auth.rs
Purpose: Create new user + tenant atomically
Request Body:
{
"email": "user@example.com",
"password": "SecureP@ssw0rd!",
"first_name": "John",
"last_name": "Doe"
}
Response (201 Created):
{
"success": true,
"data": {
"user": {
"user_id": "uuid",
"tenant_id": "uuid",
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe",
"role": "Admin",
"created_at": "2025-10-14T12:00:00Z"
},
"tokens": {
"access_token": "jwt...",
"refresh_token": "jwt...",
"expires_at": "2025-10-14T13:00:00Z",
"refresh_expires_at": "2025-11-13T12:00:00Z"
}
}
}
โ POST /api/v5/auth/loginโ
Status: โ
Already implemented in backend/src/handlers/auth.rs
Purpose: Authenticate user and create auth session
Request Body:
{
"email": "user@example.com",
"password": "SecureP@ssw0rd!"
}
Response (200 OK):
{
"success": true,
"data": {
"user": {
"user_id": "uuid",
"tenant_id": "uuid",
"email": "user@example.com",
"full_name": "John Doe",
"role": "Admin"
},
"tokens": {
"access_token": "jwt...",
"refresh_token": "jwt...",
"expires_at": "2025-10-14T13:00:00Z",
"refresh_expires_at": "2025-11-13T12:00:00Z"
}
}
}
โ POST /api/v5/auth/logoutโ
Status: โ
Already implemented in backend/src/handlers/auth.rs
Purpose: Invalidate current auth session
Headers: Authorization: Bearer <access_token>
Response (200 OK):
{
"success": true,
"message": "Logged out successfully"
}
โณ POST /api/v5/auth/refreshโ
Status: โณ TO IMPLEMENT (Priority: P0 - Critical)
Purpose: Rotate JWT tokens using refresh token
Request Body:
{
"refresh_token": "jwt..."
}
Response (200 OK):
{
"success": true,
"data": {
"access_token": "new_jwt...",
"refresh_token": "new_refresh_jwt...",
"expires_at": "2025-10-14T13:00:00Z",
"refresh_expires_at": "2025-11-13T12:00:00Z"
}
}
Implementation Notes:
- Use
AuthSessionRepository::rotate_tokens() - Invalidate old token family
- Create new session with new token_family
- Return new JWT pair
2. Session Handlers (7 endpoints)โ
โ POST /api/v5/sessionsโ
Status: โ
Already implemented in backend/src/handlers/sessions.rs
Purpose: Create new workspace session
Headers: Authorization: Bearer <access_token>
Request Body:
{
"workspace_path": "/projects/my-app",
"name": "Feature Branch Session"
}
Response (201 Created):
{
"success": true,
"data": {
"session_id": "uuid",
"workspace_path": "/projects/my-app",
"name": "Feature Branch Session",
"created_at": "2025-10-14T12:00:00Z"
}
}
โ GET /api/v5/sessionsโ
Status: โ
Already implemented in backend/src/handlers/sessions.rs
Purpose: List user's workspace sessions
Headers: Authorization: Bearer <access_token>
Query Parameters:
limit(optional, default: 20, max: 100)
Response (200 OK):
{
"success": true,
"data": {
"sessions": [
{
"session_id": "uuid",
"workspace_path": "/projects/my-app",
"name": "Feature Branch Session",
"created_at": "2025-10-14T12:00:00Z",
"updated_at": "2025-10-14T12:30:00Z"
}
],
"count": 1
}
}
โ GET /api/v5/sessions/:idโ
Status: โ
Already implemented in backend/src/handlers/sessions.rs
Purpose: Get session details with full state
Headers: Authorization: Bearer <access_token>
Response (200 OK):
{
"success": true,
"data": {
"session_id": "uuid",
"tenant_id": "uuid",
"user_id": "uuid",
"workspace_path": "/projects/my-app",
"name": "Feature Branch Session",
"editor_state": {
"open_files": ["/src/main.rs"],
"active_file": "/src/main.rs",
"cursor_position": {"line": 42, "column": 10}
},
"terminal_state": {
"open_terminals": [
{"id": "term1", "cwd": "/projects/my-app", "command": "bash"}
],
"active_terminal": "term1"
},
"breakpoints": [
{"file": "/src/main.rs", "line": 10}
],
"conversation_id": "uuid",
"context_files": ["/src/main.rs", "/cargo.toml"],
"memory": {
"facts": {"language": "Rust"},
"decisions": ["Use actix-web for API"]
},
"parent_session_id": null,
"related_sessions": [],
"tags": ["rust", "api", "feature-x"],
"created_at": "2025-10-14T12:00:00Z",
"updated_at": "2025-10-14T12:30:00Z",
"last_accessed_at": "2025-10-14T12:30:00Z"
}
}
โ DELETE /api/v5/sessions/:idโ
Status: โ
Already implemented in backend/src/handlers/sessions.rs
Purpose: Delete workspace session
Headers: Authorization: Bearer <access_token>
Response (200 OK):
{
"success": true,
"message": "Session deleted successfully"
}
โณ PUT /api/v5/sessions/:idโ
Status: โณ TO IMPLEMENT (Priority: P0 - Critical)
Purpose: Update session state (editor, terminal, breakpoints, memory)
Headers: Authorization: Bearer <access_token>
Request Body (partial update supported):
{
"name": "Updated Session Name",
"editor_state": {
"open_files": ["/src/main.rs", "/src/lib.rs"],
"active_file": "/src/lib.rs",
"cursor_position": {"line": 100, "column": 5}
},
"terminal_state": {
"open_terminals": [
{"id": "term1", "cwd": "/projects/my-app", "command": "bash"},
{"id": "term2", "cwd": "/projects/my-app", "command": "cargo watch"}
],
"active_terminal": "term2"
},
"breakpoints": [
{"file": "/src/main.rs", "line": 10},
{"file": "/src/lib.rs", "line": 50}
],
"conversation_id": "new_uuid",
"context_files": ["/src/main.rs", "/src/lib.rs", "/cargo.toml"],
"memory": {
"facts": {"language": "Rust", "framework": "actix-web"},
"decisions": ["Use actix-web for API", "Use FoundationDB for persistence"]
},
"tags": ["rust", "api", "feature-x", "database"]
}
Response (200 OK):
{
"success": true,
"data": {
"session_id": "uuid",
"updated_at": "2025-10-14T12:35:00Z",
"fields_updated": ["name", "editor_state", "terminal_state", "memory", "tags"]
}
}
Implementation Notes:
- Use
workspaceSessionRepository::update() - Support partial updates (only update provided fields)
- Update
updated_atandlast_accessed_attimestamps - Return list of updated fields for client confirmation
โณ POST /api/v5/sessions/:id/forkโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Create child session (fork current state)
Headers: Authorization: Bearer <access_token>
Request Body (optional overrides):
{
"name": "Feature X Branch",
"workspace_path": "/projects/my-app-feature-x"
}
Response (201 Created):
{
"success": true,
"data": {
"session_id": "new_uuid",
"parent_session_id": "parent_uuid",
"workspace_path": "/projects/my-app-feature-x",
"name": "Feature X Branch",
"editor_state": {}, // Copied from parent
"terminal_state": {}, // Copied from parent
"memory": {}, // Copied from parent
"created_at": "2025-10-14T12:40:00Z"
}
}
Implementation Notes:
- Use
workspaceSession::fork()method - Copy editor_state, terminal_state, memory from parent
- Set
parent_session_idto parent's ID - Allow name and workspace_path overrides
โณ GET /api/v5/sessions/relatedโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Get sessions related by tags (cross-session intelligence)
Headers: Authorization: Bearer <access_token>
Query Parameters:
tags(required, comma-separated): "rust,api,feature-x"limit(optional, default: 10, max: 50)
Response (200 OK):
{
"success": true,
"data": {
"sessions": [
{
"session_id": "uuid1",
"name": "Backend Refactor",
"workspace_path": "/projects/my-app",
"tags": ["rust", "api", "refactor"],
"relevance_score": 0.85,
"last_accessed_at": "2025-10-14T10:00:00Z"
},
{
"session_id": "uuid2",
"name": "API Testing",
"workspace_path": "/projects/my-app-tests",
"tags": ["rust", "api", "testing"],
"relevance_score": 0.75,
"last_accessed_at": "2025-10-14T09:00:00Z"
}
],
"count": 2,
"query_tags": ["rust", "api", "feature-x"]
}
}
Implementation Notes:
- Use
workspaceSessionRepository::get_related_sessions() - Calculate relevance score by tag overlap
- Sort by relevance score DESC, then last_accessed_at DESC
- Filter by tenant_id and user_id for security
3. Conversation Handlers (4 endpoints)โ
โณ POST /api/v5/conversationsโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Create new AI conversation (linked to workspace session)
Headers: Authorization: Bearer <access_token>
Request Body:
{
"workspace_session_id": "uuid",
"title": "Backend Refactoring Discussion",
"description": "Discussing how to refactor auth module",
"ai_provider": "lmstudio",
"tags": ["backend", "refactor", "auth"]
}
Response (201 Created):
{
"success": true,
"data": {
"conversation_id": "uuid",
"workspace_session_id": "uuid",
"user_id": "uuid",
"title": "Backend Refactoring Discussion",
"description": "Discussing how to refactor auth module",
"ai_provider": "lmstudio",
"status": "Active",
"message_count": 0,
"token_count": 0,
"tags": ["backend", "refactor", "auth"],
"created_at": "2025-10-14T12:00:00Z"
}
}
Implementation Notes:
- Use
ConversationRepository::create() - Link to workspace_session_id for context-aware AI
- Initialize message_count and token_count to 0
- Set status to Active
โณ GET /api/v5/conversations/:idโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Get conversation metadata (without messages for performance)
Headers: Authorization: Bearer <access_token>
Response (200 OK):
{
"success": true,
"data": {
"conversation_id": "uuid",
"workspace_session_id": "uuid",
"user_id": "uuid",
"title": "Backend Refactoring Discussion",
"description": "Discussing how to refactor auth module",
"ai_provider": "lmstudio",
"status": "Active",
"message_count": 25,
"token_count": 12500,
"tags": ["backend", "refactor", "auth"],
"related_conversations": ["uuid1", "uuid2"],
"summary": "Discussed splitting auth module into auth_service and token_service...",
"created_at": "2025-10-14T12:00:00Z",
"updated_at": "2025-10-14T14:00:00Z"
}
}
Implementation Notes:
- Use
ConversationRepository::get_by_id() - DO NOT include messages (use separate endpoint for pagination)
- Include summary and related_conversations for context
โณ POST /api/v5/conversations/:id/messagesโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Add message to conversation
Headers: Authorization: Bearer <access_token>
Request Body:
{
"role": "User",
"content": "How should I split the auth module?",
"model": null
}
Response (201 Created):
{
"success": true,
"data": {
"message_id": "uuid",
"conversation_id": "uuid",
"role": "User",
"content": "How should I split the auth module?",
"model": null,
"token_count": 8,
"created_at": "2025-10-14T14:00:00Z"
}
}
Implementation Notes:
- Use
MessageRepository::create() - If role is "Assistant", require
modelfield - Calculate token_count (simple word count * 1.3 for now)
- Update conversation's message_count and token_count
- Use
ConversationRepository::update()to increment counts
โณ GET /api/v5/conversations/:id/messagesโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Get conversation messages (paginated)
Headers: Authorization: Bearer <access_token>
Query Parameters:
offset(optional, default: 0)limit(optional, default: 50, max: 200)
Response (200 OK):
{
"success": true,
"data": {
"messages": [
{
"message_id": "uuid1",
"conversation_id": "uuid",
"role": "User",
"content": "How should I split the auth module?",
"model": null,
"token_count": 8,
"created_at": "2025-10-14T14:00:00Z"
},
{
"message_id": "uuid2",
"conversation_id": "uuid",
"role": "Assistant",
"content": "I suggest splitting into auth_service for authentication logic and token_service for JWT management...",
"model": "qwen/qwq-32b",
"token_count": 250,
"created_at": "2025-10-14T14:01:00Z"
}
],
"total_count": 25,
"offset": 0,
"limit": 50,
"has_more": false
}
}
Implementation Notes:
- Use
MessageRepository::list_by_conversation()with offset/limit - Sort by created_at ASC (chronological order)
- Include total_count and has_more for pagination UI
- Validate user has access to this conversation (tenant_id + user_id)
4. User Profile Handlers (3 endpoints)โ
โณ GET /api/v5/users/meโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Get current authenticated user profile
Headers: Authorization: Bearer <access_token>
Response (200 OK):
{
"success": true,
"data": {
"user_id": "uuid",
"tenant_id": "uuid",
"email": "user@example.com",
"first_name": "John",
"last_name": "Doe",
"full_name": "John Doe",
"role": "Admin",
"is_active": true,
"email_verified": true,
"last_login_at": "2025-10-14T12:00:00Z",
"created_at": "2025-10-01T10:00:00Z",
"updated_at": "2025-10-14T12:00:00Z"
}
}
Implementation Notes:
- Extract user_id and tenant_id from JWT middleware
- Use
UserRepository::get_by_id() - DO NOT include password_hash in response
โณ PUT /api/v5/users/meโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Update current user profile
Headers: Authorization: Bearer <access_token>
Request Body (partial update supported):
{
"first_name": "Jane",
"last_name": "Smith"
}
Response (200 OK):
{
"success": true,
"data": {
"user_id": "uuid",
"email": "user@example.com",
"first_name": "Jane",
"last_name": "Smith",
"full_name": "Jane Smith",
"updated_at": "2025-10-14T14:05:00Z"
}
}
Implementation Notes:
- Extract user_id and tenant_id from JWT
- Use
UserRepository::update() - Allow updating: first_name, last_name
- DO NOT allow updating: email, role, password (use separate endpoints)
- Update
updated_attimestamp
โณ PUT /api/v5/users/me/passwordโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Change user password
Headers: Authorization: Bearer <access_token>
Request Body:
{
"current_password": "OldP@ssw0rd!",
"new_password": "NewP@ssw0rd!"
}
Response (200 OK):
{
"success": true,
"message": "Password changed successfully"
}
Error Response (401 Unauthorized):
{
"success": false,
"error": {
"code": "INVALID_PASSWORD",
"message": "Current password is incorrect"
}
}
Implementation Notes:
- Extract user_id and tenant_id from JWT
- Get user with
UserRepository::get_by_id() - Verify current_password with Argon2id
- Hash new_password with Argon2id
- Update user with new password_hash
- Invalidate all auth sessions (force re-login on all devices)
- Use
AuthSessionRepository::invalidate_all_for_user()
5. Settings Handlers (3 endpoints)โ
โณ GET /api/v5/settingsโ
Status: โณ TO IMPLEMENT (Priority: P2 - Medium)
Purpose: Get all user settings
Headers: Authorization: Bearer <access_token>
Query Parameters (optional):
category(optional, filter by category): "editor", "theme", "llm", "terminal", "workspace"
Response (200 OK - All settings):
{
"success": true,
"data": {
"editor": {
"theme": "dark",
"font_size": 14,
"line_numbers": true,
"word_wrap": false
},
"llm": {
"default_model": "meta-llama-3.3-70b",
"temperature": 0.7,
"max_tokens": 4096
},
"theme": {
"accent_color": "#007acc",
"sidebar_position": "left"
}
}
}
Response (200 OK - Category filter):
{
"success": true,
"data": {
"editor": {
"theme": "dark",
"font_size": 14,
"line_numbers": true,
"word_wrap": false
}
}
}
Implementation Notes:
- Extract user_id and tenant_id from JWT
- Use
SettingRepository::get_all()or filter by category - Group settings by category in response
- Return empty object for categories with no settings
โณ PUT /api/v5/settings/:category/:keyโ
Status: โณ TO IMPLEMENT (Priority: P2 - Medium)
Purpose: Update or create user setting (upsert)
Headers: Authorization: Bearer <access_token>
Path Parameters:
category: "editor", "theme", "llm", "terminal", "workspace"key: Setting key name
Request Body:
{
"value": "dark"
}
Response (200 OK):
{
"success": true,
"data": {
"category": "editor",
"key": "theme",
"value": "dark",
"updated_at": "2025-10-14T14:10:00Z"
}
}
Implementation Notes:
- Extract user_id and tenant_id from JWT
- Use
SettingRepository::set()(upsert operation) - Value can be any JSON type (string, number, boolean, object, array)
- Update
updated_attimestamp
โณ DELETE /api/v5/settings/:category/:keyโ
Status: โณ TO IMPLEMENT (Priority: P2 - Medium)
Purpose: Delete user setting
Headers: Authorization: Bearer <access_token>
Path Parameters:
category: "editor", "theme", "llm", "terminal", "workspace"key: Setting key name
Response (200 OK):
{
"success": true,
"message": "Setting deleted successfully"
}
Response (404 Not Found):
{
"success": false,
"error": {
"code": "SETTING_NOT_FOUND",
"message": "Setting not found: editor.theme"
}
}
Implementation Notes:
- Extract user_id and tenant_id from JWT
- Use
SettingRepository::delete() - Return 404 if setting doesn't exist
๐ก๏ธ Middleware Componentsโ
1. JWT Authentication Middlewareโ
Status: โ
Already implemented in backend/src/middleware/auth.rs
Purpose: Validate JWT tokens and extract user context
Functionality:
- Parse
Authorization: Bearer <token>header - Validate JWT signature and expiration
- Extract
user_idandtenant_idclaims - Inject into request extensions for handlers
- Return 401 Unauthorized on failure
Exclusions (no auth required):
/api/v5/health/api/v5/ready/api/v5/auth/register/api/v5/auth/login/api/v5/auth/refresh
2. Tenant Isolation Middlewareโ
Status: โณ TO IMPLEMENT (Priority: P0 - Critical)
Purpose: Ensure all FDB operations are tenant-scoped
Functionality:
- Extract
tenant_idfrom JWT (already available from JwtMiddleware) - Inject
tenant_idinto all repository calls automatically - Prevent cross-tenant data access (security critical)
- Log any tenant isolation violations
Implementation:
// Middleware structure
pub struct TenantMiddleware;
impl<S, B> Transform<S, ServiceRequest> for TenantMiddleware
where
S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
B: MessageBody,
{
// Extract tenant_id from JWT
// Inject into request extensions
// Verify all FDB keys are prefixed with /{tenant_id}/
}
Critical: This middleware is essential for multi-tenancy security. Without it, users could potentially access other tenants' data.
3. Rate Limiting Middlewareโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Prevent abuse and ensure fair usage
Rate Limits:
-
Per User:
- 100 requests per minute
- 1,000 requests per hour
- 10,000 requests per day
-
Per Tenant:
- 500 requests per minute
- 5,000 requests per hour
- 50,000 requests per day
-
Per Endpoint (special limits):
/api/v5/auth/login: 5 attempts per 15 minutes (brute force protection)/api/v5/auth/register: 3 attempts per hour (prevent spam)/api/v5/conversations/:id/messages: 60 requests per minute (llm protection)
Implementation:
// Use actix-web-lab or actix-limitation
use actix_limitation::{Limiter, RateLimiter};
use redis::Client as RedisClient;
// Store rate limit state in Redis (or FDB)
pub fn configure_rate_limiter() -> Limiter {
let redis_client = RedisClient::open("redis://127.0.0.1/").unwrap();
Limiter::builder("api")
.limit(100)
.period(Duration::from_secs(60))
.build()
}
Response (429 Too Many Requests):
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 45 seconds.",
"retry_after": 45
}
}
4. Audit Logging Middlewareโ
Status: โณ TO IMPLEMENT (Priority: P1 - High)
Purpose: Log all API requests for compliance (SOC2, GDPR)
Logged Events:
- All authenticated requests
- Auth events (login, logout, token refresh)
- Data mutations (POST, PUT, DELETE)
- Failed authentication attempts
- Rate limit violations
Audit Data Captured:
pub struct AuditLog {
tenant_id: Uuid,
user_id: Uuid,
event_type: AuditEventType,
endpoint: String, // "/api/v5/sessions"
method: String, // "POST"
status_code: u16, // 201
ip_address: Option<String>,
user_agent: Option<String>,
request_body: Option<Value>, // Sanitized (no passwords)
response_time_ms: u64,
created_at: DateTime<Utc>,
}
Implementation:
- Use
AuditRepository::create()after each request - Run asynchronously (don't block response)
- Sanitize sensitive fields (passwords, tokens)
- Handle failures gracefully (log to stderr, don't fail request)
Compliance:
- SOC2: Complete audit trail
- GDPR: User activity tracking for data subject requests
๐จ Frontend Service Integrationโ
1. session-service.tsโ
Status: โณ TO IMPLEMENT
Current Implementation:
// src/services/session-service.ts
export const sessionService = {
create: async (data) => api.post('/sessions', data),
list: async () => api.get('/sessions'),
get: async (id) => api.get(`/sessions/${id}`),
delete: async (id) => api.delete(`/sessions/${id}`)
};
Phase 3 Additions:
export const sessionService = {
// ... existing methods
// New methods for Phase 3
update: async (id: string, data: Partial<workspaceSession>) => {
return api.put(`/sessions/${id}`, data);
},
fork: async (id: string, overrides?: { name?: string; workspace_path?: string }) => {
return api.post(`/sessions/${id}/fork`, overrides);
},
getRelated: async (tags: string[], limit: number = 10) => {
return api.get('/sessions/related', {
params: { tags: tags.join(','), limit }
});
}
};
2. user-service.tsโ
Status: โณ TO IMPLEMENT
New Service (create src/services/user-service.ts):
import api from './api-client';
export interface User {
user_id: string;
tenant_id: string;
email: string;
first_name: string;
last_name: string;
full_name: string;
role: 'Admin' | 'Developer' | 'Manager' | 'Viewer';
is_active: boolean;
email_verified: boolean;
last_login_at: string;
created_at: string;
updated_at: string;
}
export interface UpdateProfileRequest {
first_name?: string;
last_name?: string;
}
export interface ChangePasswordRequest {
current_password: string;
new_password: string;
}
export const userService = {
getMe: async (): Promise<User> => {
const response = await api.get('/users/me');
return response.data.data;
},
updateMe: async (data: UpdateProfileRequest): Promise<User> => {
const response = await api.put('/users/me', data);
return response.data.data;
},
changePassword: async (data: ChangePasswordRequest): Promise<void> => {
await api.put('/users/me/password', data);
}
};
3. llm-service.tsโ
Status: โณ TO IMPLEMENT
Current Implementation (basic LM Studio integration):
// src/services/llm-service.ts
export const llmService = {
chat: async (model: string, messages: Message[]) => {
return fetch('http://localhost:1234/v1/chat/completions', {
method: 'POST',
body: JSON.stringify({ model, messages })
});
}
};
Phase 3 Enhancement (add conversation tracking):
import api from './api-client';
import { Conversation, Message } from '../types';
export const llmService = {
// ... existing chat method
// Conversation management
createConversation: async (data: {
workspace_session_id: string;
title: string;
description?: string;
ai_provider: string;
tags?: string[];
}): Promise<Conversation> => {
const response = await api.post('/conversations', data);
return response.data.data;
},
getConversation: async (id: string): Promise<Conversation> => {
const response = await api.get(`/conversations/${id}`);
return response.data.data;
},
addMessage: async (conversationId: string, data: {
role: 'User' | 'Assistant' | 'System';
content: string;
model?: string;
}): Promise<Message> => {
const response = await api.post(`/conversations/${conversationId}/messages`, data);
return response.data.data;
},
getMessages: async (conversationId: string, offset: number = 0, limit: number = 50): Promise<{
messages: Message[];
total_count: number;
has_more: boolean;
}> => {
const response = await api.get(`/conversations/${conversationId}/messages`, {
params: { offset, limit }
});
return response.data.data;
},
// Enhanced chat with conversation tracking
chatWithTracking: async (
conversationId: string,
model: string,
userMessage: string
): Promise<{ message: Message; llmResponse: string }> => {
// 1. Add user message to conversation
const userMsg = await llmService.addMessage(conversationId, {
role: 'User',
content: userMessage
});
// 2. Call llm
const llmResponse = await llmService.chat(model, [
{ role: 'user', content: userMessage }
]);
const responseText = await llmResponse.json();
const assistantContent = responseText.choices[0].message.content;
// 3. Add assistant response to conversation
const assistantMsg = await llmService.addMessage(conversationId, {
role: 'Assistant',
content: assistantContent,
model
});
return {
message: assistantMsg,
llmResponse: assistantContent
};
}
};
4. file-service.tsโ
Status: โณ TO IMPLEMENT (Phase 4 - File Operations)
Purpose: Manage file metadata (Phase 3 focuses on conversation/session APIs)
Note: File operations will be implemented in Phase 4 alongside WebSocket real-time updates. Phase 3 focuses on REST APIs for sessions, conversations, users, and settings.
5. settings-service.tsโ
Status: โณ TO IMPLEMENT
New Service (create src/services/settings-service.ts):
import api from './api-client';
export interface UserSettings {
editor?: {
theme?: string;
font_size?: number;
line_numbers?: boolean;
word_wrap?: boolean;
};
llm?: {
default_model?: string;
temperature?: number;
max_tokens?: number;
};
theme?: {
accent_color?: string;
sidebar_position?: 'left' | 'right';
};
terminal?: {
shell?: string;
font_size?: number;
};
workspace?: {
auto_save?: boolean;
save_interval?: number;
};
}
export const settingsService = {
getAll: async (): Promise<UserSettings> => {
const response = await api.get('/settings');
return response.data.data;
},
getCategory: async (category: string): Promise<Record<string, any>> => {
const response = await api.get('/settings', {
params: { category }
});
return response.data.data[category];
},
set: async (category: string, key: string, value: any): Promise<void> => {
await api.put(`/settings/${category}/${key}`, { value });
},
delete: async (category: string, key: string): Promise<void> => {
await api.delete(`/settings/${category}/${key}`);
},
// Convenience methods
seteditorTheme: async (theme: string) => {
return settingsService.set('editor', 'theme', theme);
},
setDefaultModel: async (model: string) => {
return settingsService.set('llm', 'default_model', model);
}
};
๐ Implementation Timelineโ
Week 1 - Core API (P0 + P1)โ
Day 1-2: Auth & Middleware (P0)
- Implement POST /api/v5/auth/refresh
- Implement Tenant Isolation Middleware
- Test JWT rotation flow
- Test tenant isolation security
Day 3: Session API (P0)
- Implement PUT /api/v5/sessions/:id
- Test session state updates
- Test partial updates
Day 4-5: Conversations & Users (P1)
- Implement 4 conversation endpoints
- Implement 3 user profile endpoints
- Test conversation + message flow
- Test password change flow
Day 6: Middleware & Sessions (P1)
- Implement POST /api/v5/sessions/:id/fork
- Implement GET /api/v5/sessions/related
- Implement Rate Limiting Middleware
- Implement Audit Logging Middleware
Day 7: Settings & Testing (P2)
- Implement 3 settings endpoints
- Integration testing
- API documentation
๐งช Testing Strategyโ
Unit Tests (per handler)โ
#[cfg(test)]
mod tests {
use super::*;
#[actix_web::test]
async fn test_refresh_token() {
// Test token rotation
}
#[actix_web::test]
async fn test_update_session() {
// Test partial session updates
}
#[actix_web::test]
async fn test_fork_session() {
// Test session forking
}
}
Integration Testsโ
// tests/api_integration_tests.rs
#[actix_web::test]
async fn test_full_conversation_flow() {
// 1. Create conversation
// 2. Add user message
// 3. Add assistant response
// 4. Paginate messages
// 5. Verify counts
}
#[actix_web::test]
async fn test_session_fork_flow() {
// 1. Create parent session
// 2. Update parent state
// 3. Fork to child
// 4. Verify child has parent state
// 5. Update child independently
}
E2E Tests (Postman/curl)โ
# Test auth flow
curl -X POST http://localhost:8080/api/v5/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"pass"}'
# Test session update
curl -X PUT http://localhost:8080/api/v5/sessions/$SESSION_ID \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Updated Session"}'
โ Success Criteriaโ
Technical Requirementsโ
- All 18 endpoints implemented and tested
- 4 middleware components working
- 5 frontend services integrated
- 100% test coverage for new handlers
- API documentation complete
Performance Requirementsโ
- Response time < 100ms (p50)
- Response time < 500ms (p99)
- Rate limiting enforced
- Audit logging doesn't block responses
Security Requirementsโ
- JWT authentication on all protected routes
- Tenant isolation enforced (no cross-tenant access)
- Password changes invalidate all sessions
- Rate limiting prevents brute force attacks
- Audit logs capture all mutations
User Experience Requirementsโ
- Session state persists across page reloads
- Conversation messages paginate smoothly
- User settings sync immediately
- Related sessions discovered accurately
๐ Progress Trackingโ
Phase 3 Checklistโ
Auth Handlers (1/4 complete):
- POST /api/v5/auth/register
- POST /api/v5/auth/login
- POST /api/v5/auth/logout
- POST /api/v5/auth/refresh
Session Handlers (4/7 complete):
- POST /api/v5/sessions
- GET /api/v5/sessions
- GET /api/v5/sessions/:id
- DELETE /api/v5/sessions/:id
- PUT /api/v5/sessions/:id
- POST /api/v5/sessions/:id/fork
- GET /api/v5/sessions/related
Conversation Handlers (0/4 complete):
- POST /api/v5/conversations
- GET /api/v5/conversations/:id
- POST /api/v5/conversations/:id/messages
- GET /api/v5/conversations/:id/messages
User Handlers (0/3 complete):
- GET /api/v5/users/me
- PUT /api/v5/users/me
- PUT /api/v5/users/me/password
Settings Handlers (0/3 complete):
- GET /api/v5/settings
- PUT /api/v5/settings/:category/:key
- DELETE /api/v5/settings/:category/:key
Middleware (1/4 complete):
- JWT Authentication
- Tenant Isolation
- Rate Limiting
- Audit Logging
Frontend Services (0/5 complete):
- session-service.ts (update, fork, related)
- user-service.ts (new)
- llm-service.ts (conversation tracking)
- file-service.ts (Phase 4)
- settings-service.ts (new)
Total Progress: 9/47 items (19.1%) Phase 3 Progress: 9/27 items (33.3%)
๐ฏ Next Stepsโ
- โ Review this plan - Confirm scope and priorities
- โณ Start implementation - Begin with P0 items (auth refresh, tenant isolation)
- โณ Incremental testing - Test each endpoint as it's implemented
- โณ Frontend integration - Update services in parallel with backend
- โณ Documentation - Document APIs as they're completed
Last Updated: 2025-10-14 Status: ๐ PLANNING COMPLETE - READY FOR IMPLEMENTATION Estimated Duration: ~1 week (solo) | 4-5 days (2-person) | 3-4 days (4-person) Blocking Dependencies: None (Phase 1 & 2 complete)