Skip to main content

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โ€‹

CategoryEndpointsAlready DoneTo AddPriority
Auth43 (login, register, logout)1 (refresh)P0 - Critical
Sessions74 (create, get, list, delete)3 (update, fork, related)P0 - Critical
Conversations404 (all)P1 - High
Users303 (all)P1 - High
Settings303 (all)P2 - Medium
Health22 (health, ready)0โœ… Complete
Total23914-

๐Ÿ“‹ 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_at and last_accessed_at timestamps
  • 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_id to 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 model field
  • 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_at timestamp

โณ 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_at timestamp

โณ 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_id and tenant_id claims
  • 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_id from JWT (already available from JwtMiddleware)
  • Inject tenant_id into 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โ€‹

  1. โœ… Review this plan - Confirm scope and priorities
  2. โณ Start implementation - Begin with P0 items (auth refresh, tenant isolation)
  3. โณ Incremental testing - Test each endpoint as it's implemented
  4. โณ Frontend integration - Update services in parallel with backend
  5. โณ 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)