New endpoints under /api/hub/channels/: - create.php: Create channel with type (public/private/direct), auto-add creator as owner - list.php: List channels with filters (type, agent membership, archived, pagination) - get.php: Get channel by ID or Name, includes member list - update.php: Update display name, purpose, archive status (admin/owner only) - delete.php: Hard-delete channel (owner only), FK cascade removes members - members.php: List channel members with agent info - join.php: Join public channels (private requires invite) - leave.php: Leave channel (owners blocked from leaving) Database: Hub_Channels + Hub_ChannelMembers tables with FK cascade. Task #59 (T51-Sub1) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
62 lines
1.6 KiB
PHP
62 lines
1.6 KiB
PHP
<?php
|
|
/**
|
|
* POST /api/hub/channels/join.php
|
|
*
|
|
* Join a channel. Public channels are open to anyone.
|
|
* Private channels require an invite (admin/owner must add via addMember).
|
|
*
|
|
* Body:
|
|
* ChannelID int REQUIRED
|
|
* Agent string REQUIRED agent address joining
|
|
*
|
|
* Response: { OK: true }
|
|
*/
|
|
|
|
require_once __DIR__ . '/../../helpers.php';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'method_not_allowed'], 405);
|
|
}
|
|
|
|
$body = readJsonBody();
|
|
|
|
$channelId = (int) ($body['ChannelID'] ?? 0);
|
|
$agent = trim($body['Agent'] ?? '');
|
|
|
|
if ($channelId <= 0) {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'channel_id_required']);
|
|
}
|
|
if ($agent === '') {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'agent_required']);
|
|
}
|
|
|
|
// Verify channel exists and is not archived
|
|
$channel = queryOne("SELECT * FROM Hub_Channels WHERE ID = ?", [$channelId]);
|
|
if (!$channel) {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'channel_not_found'], 404);
|
|
}
|
|
if ((bool) $channel['IsArchived']) {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'channel_archived']);
|
|
}
|
|
|
|
// Private/direct channels can't be self-joined
|
|
if ($channel['ChannelType'] !== 'public') {
|
|
jsonResponse(['OK' => false, 'ERROR' => 'channel_not_public']);
|
|
}
|
|
|
|
// Check if already a member
|
|
$existing = queryOne(
|
|
"SELECT ID FROM Hub_ChannelMembers WHERE ChannelID = ? AND AgentAddress = ?",
|
|
[$channelId, $agent]
|
|
);
|
|
if ($existing) {
|
|
jsonResponse(['OK' => true, 'Note' => 'already_member']);
|
|
}
|
|
|
|
// Add member
|
|
queryTimed(
|
|
"INSERT INTO Hub_ChannelMembers (ChannelID, AgentAddress, Role) VALUES (?, ?, 'member')",
|
|
[$channelId, $agent]
|
|
);
|
|
|
|
jsonResponse(['OK' => true]);
|