feat(#84): implement instance identity model for federation
Implemented the foundation of federation architecture with instance identity and connection management: Database Schema: - Added Instance model for instance identity with keypair generation - Added FederationConnection model for workspace-scoped connections - Added FederationConnectionStatus enum (PENDING, ACTIVE, SUSPENDED, DISCONNECTED) Service Layer: - FederationService with instance identity management - RSA 2048-bit keypair generation for signing - Public identity endpoint (excludes private key) - Keypair regeneration capability API Endpoints: - GET /api/v1/federation/instance - Returns public instance identity - POST /api/v1/federation/instance/regenerate-keys - Admin keypair regeneration Tests: - 11 tests passing (7 service, 4 controller) - 100% statement coverage, 100% function coverage - Follows TDD principles (Red-Green-Refactor) Configuration: - Added INSTANCE_NAME and INSTANCE_URL environment variables - Integrated FederationModule into AppModule Refs #84 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -166,6 +166,13 @@ enum JobStepStatus {
|
||||
SKIPPED
|
||||
}
|
||||
|
||||
enum FederationConnectionStatus {
|
||||
PENDING
|
||||
ACTIVE
|
||||
SUSPENDED
|
||||
DISCONNECTED
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// MODELS
|
||||
// ============================================
|
||||
@@ -226,28 +233,29 @@ model Workspace {
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
|
||||
// Relations
|
||||
owner User @relation("WorkspaceOwner", fields: [ownerId], references: [id], onDelete: Cascade)
|
||||
members WorkspaceMember[]
|
||||
teams Team[]
|
||||
tasks Task[]
|
||||
events Event[]
|
||||
projects Project[]
|
||||
activityLogs ActivityLog[]
|
||||
memoryEmbeddings MemoryEmbedding[]
|
||||
domains Domain[]
|
||||
ideas Idea[]
|
||||
relationships Relationship[]
|
||||
agents Agent[]
|
||||
agentSessions AgentSession[]
|
||||
agentTasks AgentTask[]
|
||||
userLayouts UserLayout[]
|
||||
knowledgeEntries KnowledgeEntry[]
|
||||
knowledgeTags KnowledgeTag[]
|
||||
cronSchedules CronSchedule[]
|
||||
personalities Personality[]
|
||||
llmSettings WorkspaceLlmSettings?
|
||||
qualityGates QualityGate[]
|
||||
runnerJobs RunnerJob[]
|
||||
owner User @relation("WorkspaceOwner", fields: [ownerId], references: [id], onDelete: Cascade)
|
||||
members WorkspaceMember[]
|
||||
teams Team[]
|
||||
tasks Task[]
|
||||
events Event[]
|
||||
projects Project[]
|
||||
activityLogs ActivityLog[]
|
||||
memoryEmbeddings MemoryEmbedding[]
|
||||
domains Domain[]
|
||||
ideas Idea[]
|
||||
relationships Relationship[]
|
||||
agents Agent[]
|
||||
agentSessions AgentSession[]
|
||||
agentTasks AgentTask[]
|
||||
userLayouts UserLayout[]
|
||||
knowledgeEntries KnowledgeEntry[]
|
||||
knowledgeTags KnowledgeTag[]
|
||||
cronSchedules CronSchedule[]
|
||||
personalities Personality[]
|
||||
llmSettings WorkspaceLlmSettings?
|
||||
qualityGates QualityGate[]
|
||||
runnerJobs RunnerJob[]
|
||||
federationConnections FederationConnection[]
|
||||
|
||||
@@index([ownerId])
|
||||
@@map("workspaces")
|
||||
@@ -1217,3 +1225,58 @@ model JobEvent {
|
||||
@@index([jobId, timestamp])
|
||||
@@map("job_events")
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// FEDERATION MODULE
|
||||
// ============================================
|
||||
|
||||
model Instance {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
instanceId String @unique @map("instance_id") // Unique identifier for federation
|
||||
name String
|
||||
url String
|
||||
publicKey String @map("public_key") @db.Text
|
||||
privateKey String @map("private_key") @db.Text // Encrypted private key
|
||||
|
||||
// Capabilities and metadata
|
||||
capabilities Json @default("{}")
|
||||
metadata Json @default("{}")
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
|
||||
@@map("instances")
|
||||
}
|
||||
|
||||
model FederationConnection {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
workspaceId String @map("workspace_id") @db.Uuid
|
||||
|
||||
// Remote instance details
|
||||
remoteInstanceId String @map("remote_instance_id")
|
||||
remoteUrl String @map("remote_url")
|
||||
remotePublicKey String @map("remote_public_key") @db.Text
|
||||
remoteCapabilities Json @default("{}") @map("remote_capabilities")
|
||||
|
||||
// Connection status
|
||||
status FederationConnectionStatus @default(PENDING)
|
||||
|
||||
// Metadata
|
||||
metadata Json @default("{}")
|
||||
|
||||
// Timestamps
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
connectedAt DateTime? @map("connected_at") @db.Timestamptz
|
||||
disconnectedAt DateTime? @map("disconnected_at") @db.Timestamptz
|
||||
|
||||
// Relations
|
||||
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([workspaceId, remoteInstanceId])
|
||||
@@index([workspaceId])
|
||||
@@index([workspaceId, status])
|
||||
@@index([remoteInstanceId])
|
||||
@@map("federation_connections")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user