feat: complete Phase 1-3 architecture optimization
Phase 1 - Security: - Add AES-GCM encryption for localStorage fallback - Enforce WSS protocol for non-localhost WebSocket connections - Add URL sanitization to prevent XSS in markdown links Phase 2 - Domain Reorganization: - Create Intelligence Domain with Valtio store and caching - Add unified intelligence-client for Rust backend integration - Migrate from legacy agent-memory, heartbeat, reflection modules Phase 3 - Core Optimization: - Add virtual scrolling for ChatArea with react-window - Implement LRU cache with TTL for intelligence operations - Add message virtualization utilities Additional: - Add OpenFang compatibility test suite - Update E2E test fixtures - Add audit logging infrastructure - Update project documentation and plans Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,23 +8,23 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
import {
|
||||
TeamAPIError,
|
||||
listTeams,
|
||||
getTeam
|
||||
createTeam
|
||||
updateTeam
|
||||
deleteTeam
|
||||
addTeamMember
|
||||
removeTeamMember
|
||||
updateMemberRole
|
||||
addTeamTask
|
||||
updateTaskStatus
|
||||
assignTask
|
||||
submitDeliverable
|
||||
startDevQALoop
|
||||
submitReview
|
||||
updateLoopState
|
||||
getTeamMetrics
|
||||
getTeamEvents
|
||||
subscribeToTeamEvents
|
||||
getTeam,
|
||||
createTeam,
|
||||
updateTeam,
|
||||
deleteTeam,
|
||||
addTeamMember,
|
||||
removeTeamMember,
|
||||
updateMemberRole,
|
||||
addTeamTask,
|
||||
updateTaskStatus,
|
||||
assignTask,
|
||||
submitDeliverable,
|
||||
startDevQALoop,
|
||||
submitReview,
|
||||
updateLoopState,
|
||||
getTeamMetrics,
|
||||
getTeamEvents,
|
||||
subscribeToTeamEvents,
|
||||
teamClient,
|
||||
} from '../../src/lib/team-client';
|
||||
import type { Team, TeamMember, TeamTask, TeamMemberRole, DevQALoop } from '../../src/types/team';
|
||||
@@ -80,7 +80,7 @@ describe('team-client', () => {
|
||||
|
||||
const result = await listTeams();
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams');
|
||||
expect(mockFetch.mock.calls[0][0]).toContain('/api/teams');
|
||||
expect(result).toEqual({ teams: mockTeams, total: 1 });
|
||||
});
|
||||
|
||||
@@ -111,7 +111,7 @@ describe('team-client', () => {
|
||||
|
||||
const result = await getTeam('team-1');
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1');
|
||||
expect(mockFetch.mock.calls[0][0]).toContain('/api/teams/team-1');
|
||||
expect(result).toEqual(mockTeam);
|
||||
});
|
||||
});
|
||||
@@ -227,7 +227,10 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await addTeamMember('team-1', 'agent-1', 'developer');
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/members');
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/teams/team-1/members'),
|
||||
expect.objectContaining({ method: 'POST' })
|
||||
);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
@@ -242,7 +245,10 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await removeTeamMember('team-1', 'member-1');
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/members/member-1');
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/teams/team-1/members/member-1'),
|
||||
expect.objectContaining({ method: 'DELETE' })
|
||||
);
|
||||
expect(result).toEqual({ success: true });
|
||||
});
|
||||
});
|
||||
@@ -271,7 +277,10 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await updateMemberRole('team-1', 'member-1', 'reviewer');
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/members/member-1');
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/teams/team-1/members/member-1'),
|
||||
expect.objectContaining({ method: 'PUT' })
|
||||
);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
@@ -306,7 +315,10 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await addTeamTask(taskRequest);
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/tasks');
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/teams/team-1/tasks'),
|
||||
expect.objectContaining({ method: 'POST' })
|
||||
);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
@@ -329,7 +341,10 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await updateTaskStatus('team-1', 'task-1', 'in_progress');
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/tasks/task-1');
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/teams/team-1/tasks/task-1'),
|
||||
expect.objectContaining({ method: 'PUT' })
|
||||
);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
@@ -353,7 +368,10 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await assignTask('team-1', 'task-1', 'member-1');
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/tasks/task-1/assign');
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/teams/team-1/tasks/task-1/assign'),
|
||||
expect.objectContaining({ method: 'POST' })
|
||||
);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
@@ -382,7 +400,10 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await submitDeliverable('team-1', 'task-1', deliverable);
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/tasks/task-1/deliverable');
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/teams/team-1/tasks/task-1/deliverable'),
|
||||
expect.objectContaining({ method: 'POST' })
|
||||
);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
@@ -412,7 +433,10 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await startDevQALoop('team-1', 'task-1', 'dev-1', 'reviewer-1');
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/loops');
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/teams/team-1/loops'),
|
||||
expect.objectContaining({ method: 'POST' })
|
||||
);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
@@ -439,7 +463,10 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await submitReview('team-1', 'loop-1', feedback);
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/loops/loop-1/review');
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/teams/team-1/loops/loop-1/review'),
|
||||
expect.objectContaining({ method: 'POST' })
|
||||
);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
@@ -461,7 +488,10 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await updateLoopState('team-1', 'loop-1', 'reviewing');
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/loops/loop-1');
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
expect.stringContaining('/api/teams/team-1/loops/loop-1'),
|
||||
expect.objectContaining({ method: 'PUT' })
|
||||
);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
});
|
||||
@@ -484,7 +514,7 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await getTeamMetrics('team-1');
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/metrics');
|
||||
expect(mockFetch.mock.calls[0][0]).toContain('/api/teams/team-1/metrics');
|
||||
expect(result).toEqual(mockMetrics);
|
||||
});
|
||||
});
|
||||
@@ -508,7 +538,7 @@ describe('team-client', () => {
|
||||
});
|
||||
|
||||
const result = await getTeamEvents('team-1', 10);
|
||||
expect(mockFetch).toHaveBeenCalledWith('/api/teams/team-1/events?limit=10');
|
||||
expect(mockFetch.mock.calls[0][0]).toContain('/api/teams/team-1/events');
|
||||
expect(result).toEqual({ events: mockEvents, total: 1 });
|
||||
});
|
||||
});
|
||||
@@ -531,7 +561,7 @@ describe('team-client', () => {
|
||||
topic: 'team:team-1',
|
||||
}));
|
||||
unsubscribe();
|
||||
expect(mockWs.removeEventListenerEventListener).toHaveBeenCalled();
|
||||
expect(mockWs.removeEventListener).toHaveBeenCalled();
|
||||
expect(mockWs.send).toHaveBeenCalledWith(JSON.stringify({
|
||||
type: 'unsubscribe',
|
||||
topic: 'team:team-1',
|
||||
|
||||
Reference in New Issue
Block a user