Implements all 5 phases of Foundary Studio backend:
Phase 1: Chat Persistence (8 API endpoints)
- Conversations and messages with proper cascading deletes
- PostgreSQL schema with auto-update triggers
- Full CRUD operations with structured logging
Phase 2: Blueprint Entity (5 API endpoints)
- JSONB spec storage with GIN indexes
- Flexible structured data for project specifications
- Version-controlled blueprint management
Phase 3: Architect Service (3 API endpoints)
- Conversational AI orchestration with Claude
- Multi-turn dialogue with context building
- Blueprint spec extraction from conversations
Phase 4: Work Queue Integration
- Verified existing endpoint compatibility
Phase 5: Structured Questions (6 API endpoints)
- Four question types: text, choice, multichoice, yesno
- Answer validation with proper constraints
- Conversation-linked Q&A flow
Architecture:
- Textbook hexagonal architecture (domain → port → adapter → service → handler)
- Zero external dependencies in domain layer
- Consistent error handling with proper wrapping
- Auth scopes on all routes (projects:read, projects:execute)
- Structured logging with operation context and duration tracking
- NULL-safe DTO converters throughout
Database:
- 3 new migrations (019, 020, 021)
- UUIDs for all primary keys
- Proper foreign key constraints with ON DELETE CASCADE
- Optimized indexes including partial index for unanswered questions
- Auto-update triggers for timestamps
OpenAPI Documentation:
- Complete API documentation under 'Foundary' tag
- 22 new endpoints documented with examples
- Request/response schemas for all operations
Logging Improvements:
- Added operation field to all service logs
- Added duration_ms tracking for performance monitoring
- Log response_length instead of full response content
- Consistent use of logging field constants
- Execute-then-log pattern for delete operations
Files: 32 changed, 2800+ lines added
- 7 domain models
- 3 database migrations
- 3 port interfaces
- 3 postgres adapters
- 4 services (conversation, blueprint, question, architect)
- 4 handlers with DTOs
- OpenAPI documentation
- Integration in main.go
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
96 lines
3.3 KiB
Go
96 lines
3.3 KiB
Go
package domain
|
|
|
|
import "errors"
|
|
|
|
// Domain errors - these are business-level errors that should be translated
|
|
// to appropriate HTTP status codes or gRPC error codes by the presentation layer.
|
|
var (
|
|
// Generic errors
|
|
ErrNotFound = errors.New("not found")
|
|
|
|
// Project errors
|
|
ErrProjectNotFound = errors.New("project not found")
|
|
ErrProjectNotRunning = errors.New("project is not running")
|
|
ErrInvalidProjectName = errors.New("invalid project name")
|
|
|
|
// Template errors
|
|
ErrTemplateNotFound = errors.New("template not found")
|
|
|
|
// Command errors
|
|
ErrCommandNotFound = errors.New("command not found")
|
|
ErrCommandTimeout = errors.New("command timed out")
|
|
ErrCommandCancelled = errors.New("command was cancelled")
|
|
ErrLimitExceeded = errors.New("concurrent command limit exceeded")
|
|
ErrInvalidCommand = errors.New("invalid command")
|
|
ErrCommandSanitization = errors.New("command failed sanitization")
|
|
|
|
// Agent errors
|
|
ErrInvalidAgentProvider = errors.New("invalid agent provider")
|
|
ErrPromptRequired = errors.New("prompt is required")
|
|
ErrInvalidTimeout = errors.New("timeout cannot be negative")
|
|
|
|
// Credential errors
|
|
ErrCredentialNotFound = errors.New("credential not found")
|
|
|
|
// Work queue errors
|
|
ErrWorkTaskNotFound = errors.New("work task not found")
|
|
|
|
// Worker pool errors
|
|
ErrWorkerNotFound = errors.New("worker not found")
|
|
ErrWorkerIDRequired = errors.New("worker ID is required")
|
|
ErrWorkerHostnameRequired = errors.New("worker hostname is required")
|
|
|
|
// Build errors
|
|
ErrBuildNotFound = errors.New("build not found")
|
|
|
|
// API Key errors
|
|
ErrKeyNotFound = errors.New("api key not found")
|
|
ErrKeyRevoked = errors.New("api key has been revoked")
|
|
ErrKeyExpired = errors.New("api key has expired")
|
|
ErrKeyInvalid = errors.New("invalid api key format")
|
|
|
|
// Authorization errors
|
|
ErrUnauthorized = errors.New("unauthorized")
|
|
ErrForbidden = errors.New("forbidden")
|
|
ErrInsufficientScope = errors.New("insufficient scope")
|
|
ErrIPNotAllowed = errors.New("ip address not allowed")
|
|
|
|
// Rate limiting errors
|
|
ErrRateLimited = errors.New("rate limit exceeded")
|
|
|
|
// Webhook errors
|
|
ErrWebhookNotFound = errors.New("webhook not found")
|
|
ErrInvalidWebhook = errors.New("invalid webhook configuration")
|
|
|
|
// Domain errors
|
|
ErrDuplicateDomain = errors.New("domain already exists")
|
|
ErrDomainNotFound = errors.New("domain not found")
|
|
|
|
// Component errors
|
|
ErrInvalidComponentName = errors.New("invalid component name")
|
|
ErrInvalidComponentType = errors.New("invalid component type")
|
|
ErrDuplicateComponent = errors.New("component already exists")
|
|
ErrComponentNotFound = errors.New("component not found")
|
|
|
|
// Audit errors
|
|
ErrAuditNotFound = errors.New("audit log entry not found")
|
|
|
|
// Operation errors
|
|
ErrOperationNotFound = errors.New("operation not found")
|
|
|
|
// Conversation errors
|
|
ErrConversationNotFound = errors.New("conversation not found")
|
|
ErrMessageNotFound = errors.New("message not found")
|
|
|
|
// Blueprint errors
|
|
ErrBlueprintNotFound = errors.New("blueprint not found")
|
|
|
|
// Question errors
|
|
ErrQuestionNotFound = errors.New("question not found")
|
|
|
|
// Infrastructure errors (should typically be wrapped)
|
|
ErrDatabaseConnection = errors.New("database connection error")
|
|
ErrKubernetesError = errors.New("kubernetes error")
|
|
ErrRegistryUnavailable = errors.New("container registry unavailable")
|
|
)
|