feat(#88): implement QUERY message type for federation

Implement complete QUERY message protocol for federated queries between
Mosaic Stack instances, building on existing connection infrastructure.

Database Changes:
- Add FederationMessageType enum (QUERY, COMMAND, EVENT)
- Add FederationMessageStatus enum (PENDING, DELIVERED, FAILED, TIMEOUT)
- Add FederationMessage model for tracking all federation messages
- Add workspace and connection relations

Types & DTOs:
- QueryMessage: Signed query request payload
- QueryResponse: Signed query response payload
- QueryMessageDetails: API response type
- SendQueryDto: Client request DTO
- IncomingQueryDto: Validated incoming query DTO

QueryService:
- sendQuery: Send signed query to remote instance via ACTIVE connection
- handleIncomingQuery: Process and validate incoming queries
- processQueryResponse: Handle and verify query responses
- getQueryMessages: List workspace queries with optional status filter
- getQueryMessage: Get single query message details
- Message deduplication via unique messageId
- Signature verification using SignatureService
- Timestamp validation (5-minute window)

QueryController:
- POST /api/v1/federation/query: Send query (authenticated)
- POST /api/v1/federation/incoming/query: Receive query (public, signature-verified)
- GET /api/v1/federation/queries: List queries (authenticated)
- GET /api/v1/federation/queries/🆔 Get query details (authenticated)

Security:
- All messages signed with instance private key
- All responses verified with remote public key
- Timestamp validation prevents replay attacks
- Connection status validation (must be ACTIVE)
- Workspace isolation enforced via RLS

Testing:
- 15 QueryService tests (100% coverage)
- 9 QueryController tests (100% coverage)
- All tests passing with proper mocking
- TypeScript strict mode compliance

Refs #88

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
This commit is contained in:
Jason Woltje
2026-02-03 13:12:12 -06:00
co-authored by Claude Sonnet 4.5
parent 70a6bc82e0
commit 1159ca42a7
10 changed files with 1672 additions and 2 deletions
+10 -1
View File
@@ -10,6 +10,7 @@ import { HttpModule } from "@nestjs/axios";
import { FederationController } from "./federation.controller";
import { FederationAuthController } from "./federation-auth.controller";
import { IdentityLinkingController } from "./identity-linking.controller";
import { QueryController } from "./query.controller";
import { FederationService } from "./federation.service";
import { CryptoService } from "./crypto.service";
import { FederationAuditService } from "./audit.service";
@@ -18,6 +19,7 @@ import { ConnectionService } from "./connection.service";
import { OIDCService } from "./oidc.service";
import { IdentityLinkingService } from "./identity-linking.service";
import { IdentityResolutionService } from "./identity-resolution.service";
import { QueryService } from "./query.service";
import { PrismaModule } from "../prisma/prisma.module";
@Module({
@@ -29,7 +31,12 @@ import { PrismaModule } from "../prisma/prisma.module";
maxRedirects: 5,
}),
],
controllers: [FederationController, FederationAuthController, IdentityLinkingController],
controllers: [
FederationController,
FederationAuthController,
IdentityLinkingController,
QueryController,
],
providers: [
FederationService,
CryptoService,
@@ -39,6 +46,7 @@ import { PrismaModule } from "../prisma/prisma.module";
OIDCService,
IdentityLinkingService,
IdentityResolutionService,
QueryService,
],
exports: [
FederationService,
@@ -48,6 +56,7 @@ import { PrismaModule } from "../prisma/prisma.module";
OIDCService,
IdentityLinkingService,
IdentityResolutionService,
QueryService,
],
})
export class FederationModule {}