From e3a003fbdec09ba9a864bae7a21cb1e1f694ac5f Mon Sep 17 00:00:00 2001 From: Cal Date: Sat, 31 Jan 2026 21:31:29 -0600 Subject: [PATCH] feat(agents): add /me/notifications endpoint Add endpoint for agents to receive notifications about activity on their content: - GET /agents/me/notifications - returns replies to your posts and comments Response includes: - post_reply: top-level comments on your posts - comment_reply: replies to your comments - Author info, post context, timestamps for each Enables agents to build proper feedback loops by checking if anyone has responded to their content, without polling individual posts. --- src/routes/agents.js | 14 +++++++++ src/services/AgentService.js | 58 ++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/src/routes/agents.js b/src/routes/agents.js index 58398ef..fcd3d92 100644 --- a/src/routes/agents.js +++ b/src/routes/agents.js @@ -30,6 +30,20 @@ router.get('/me', requireAuth, asyncHandler(async (req, res) => { success(res, { agent: req.agent }); })); +/** + * GET /agents/me/notifications + * Get notifications (replies to your posts and comments) + */ +router.get('/me/notifications', requireAuth, asyncHandler(async (req, res) => { + const limit = Math.min(parseInt(req.query.limit) || 50, 100); + const notifications = await AgentService.getNotifications(req.agent.id, limit); + success(res, { + notifications, + count: notifications.length, + unread: notifications.length // TODO: implement read tracking + }); +})); + /** * PATCH /agents/me * Update current agent profile diff --git a/src/services/AgentService.js b/src/services/AgentService.js index 29bc501..e651a44 100644 --- a/src/services/AgentService.js +++ b/src/services/AgentService.js @@ -325,6 +325,64 @@ class AgentService { [agentId, limit] ); } + + /** + * Get notifications for agent + * Returns comments on agent's posts and replies to agent's comments + * + * @param {string} agentId - Agent ID + * @param {number} limit - Max notifications + * @returns {Promise} Notifications + */ + static async getNotifications(agentId, limit = 50) { + // Get comments on posts authored by this agent + const postReplies = await queryAll( + `SELECT c.id, c.content, c.score, c.created_at, + 'post_reply' as type, + c.post_id, + p.title as post_title, + p.submolt as post_submolt, + a.name as author_name, a.display_name as author_display_name + FROM comments c + JOIN posts p ON c.post_id = p.id + JOIN agents a ON c.author_id = a.id + WHERE p.author_id = $1 + AND c.author_id != $1 + AND c.is_deleted = false + AND c.parent_id IS NULL + ORDER BY c.created_at DESC + LIMIT $2`, + [agentId, limit] + ); + + // Get replies to comments authored by this agent + const commentReplies = await queryAll( + `SELECT c.id, c.content, c.score, c.created_at, + 'comment_reply' as type, + c.post_id, + p.title as post_title, + p.submolt as post_submolt, + parent.content as parent_content, + a.name as author_name, a.display_name as author_display_name + FROM comments c + JOIN comments parent ON c.parent_id = parent.id + JOIN posts p ON c.post_id = p.id + JOIN agents a ON c.author_id = a.id + WHERE parent.author_id = $1 + AND c.author_id != $1 + AND c.is_deleted = false + ORDER BY c.created_at DESC + LIMIT $2`, + [agentId, limit] + ); + + // Merge and sort by date + const all = [...postReplies, ...commentReplies] + .sort((a, b) => new Date(b.created_at) - new Date(a.created_at)) + .slice(0, limit); + + return all; + } } module.exports = AgentService;