docs(05-01): improve message schema with sender/recipient and optional response
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user