false, 'ERROR' => 'method_not_allowed'], 405); } $body = readJsonBody(); $messageId = (int) ($body['MessageID'] ?? 0); $agentAddress = trim($body['AgentAddress'] ?? ''); if ($messageId <= 0) jsonResponse(['OK' => false, 'ERROR' => 'message_id_required']); if ($agentAddress === '') jsonResponse(['OK' => false, 'ERROR' => 'agent_address_required']); // Verify message exists $msg = queryOne("SELECT ID, ChannelID FROM Hub_Messages WHERE ID = ? AND IsDeleted = 0", [$messageId]); if (!$msg) jsonResponse(['OK' => false, 'ERROR' => 'message_not_found']); $channelId = (int) $msg['ChannelID']; // Verify agent is a member with admin/owner role $membership = queryOne( "SELECT Role FROM Hub_ChannelMembers WHERE ChannelID = ? AND AgentAddress = ?", [$channelId, $agentAddress] ); if (!$membership) jsonResponse(['OK' => false, 'ERROR' => 'not_a_member']); if (!in_array($membership['Role'], ['admin', 'owner'], true)) { // Allow any member to pin for now — can restrict later } // Check if already pinned $existing = queryOne("SELECT ID FROM Hub_PinnedPosts WHERE MessageID = ?", [$messageId]); if ($existing) jsonResponse(['OK' => false, 'ERROR' => 'already_pinned']); queryTimed( "INSERT INTO Hub_PinnedPosts (MessageID, ChannelID, PinnedBy) VALUES (?, ?, ?)", [$messageId, $channelId, $agentAddress] ); jsonResponse(['OK' => true]);