docs(05-01): improve message schema with sender/recipient and optional response

This commit is contained in:
Lukas May
2026-01-30 20:30:20 +01:00
parent e5ae103ef1
commit 14f2e472f8

View File

@@ -40,15 +40,26 @@ Output: messages table, MessageRepository port/adapter with full CRUD and tests.
<action>
Add messages table after agents table. Schema:
- id: text primary key
- agentId: text NOT NULL foreign key to agents.id with SET NULL on delete (message persists even if agent deleted)
- type: text enum ['question', 'info', 'error'] NOT NULL default 'question'
- content: text NOT NULL (the question or message text)
- senderType: text enum ['agent', 'user'] NOT NULL (who sent the message)
- senderId: text nullable (agent ID if senderType='agent', null for user)
- recipientType: text enum ['agent', 'user'] NOT NULL (who receives the message)
- recipientId: text nullable (agent ID if recipientType='agent', null for user)
- type: text enum ['question', 'info', 'error', 'response'] NOT NULL default 'info'
- content: text NOT NULL (the message text)
- requiresResponse: integer boolean NOT NULL default 0 (1 = expects reply, 0 = notification only)
- status: text enum ['pending', 'read', 'responded'] NOT NULL default 'pending'
- response: text nullable (user's response when status is 'responded')
- parentMessageId: text nullable foreign key to messages.id (links response to original question)
- createdAt: integer timestamp NOT NULL
- updatedAt: integer timestamp NOT NULL
Add relations: message belongs to agent (nullable after delete).
Sender/recipient foreign keys reference agents.id with SET NULL on delete (messages persist).
Add relations:
- sender agent (optional)
- recipient agent (optional)
- parent message (for threading responses)
- child messages (replies to this message)
Export Message and NewMessage types.
Follow existing patterns: use sqliteTable, relations, InferSelectModel/InferInsertModel.
@@ -69,8 +80,11 @@ Create MessageRepository following TaskRepository pattern exactly:
- MessageRepository interface with:
- create(data: CreateMessageData): Promise<Message>
- findById(id: string): Promise<Message | null>
- findByAgentId(agentId: string): Promise<Message[]>
- findPending(): Promise<Message[]> (status = 'pending')
- findBySender(type: 'agent'|'user', id?: string): Promise<Message[]>
- findByRecipient(type: 'agent'|'user', id?: string): Promise<Message[]>
- findPendingForUser(): Promise<Message[]> (recipientType='user', status='pending')
- findRequiringResponse(): Promise<Message[]> (requiresResponse=true, status='pending')
- findReplies(parentMessageId: string): Promise<Message[]>
- update(id: string, data: UpdateMessageData): Promise<Message>
- delete(id: string): Promise<void>
@@ -82,9 +96,13 @@ Create MessageRepository following TaskRepository pattern exactly:
3. Tests (drizzle/message.test.ts):
- Use createTestDatabase helper
- Test create, findById, findByAgentId, findPending, update, delete
- Test pending filter returns only pending messages
- Test response field update when marking as responded
- Test create with agent→user message (question)
- Test create with agent→user message (notification, requiresResponse=false)
- Test findBySender and findByRecipient
- Test findPendingForUser returns only user-targeted pending messages
- Test findRequiringResponse returns only messages needing response
- Test message threading (parentMessageId linking)
- Test update status flow: pending → read → responded
4. Re-export from index files (same pattern as AgentRepository)
</action>