fix(together): add member auth to GET endpoints, remove comment_count JOIN
This commit is contained in:
parent
8f41c4736f
commit
1eb94565d5
58
server.js
58
server.js
|
|
@ -2481,9 +2481,17 @@ ${excerpt}
|
|||
}
|
||||
});
|
||||
|
||||
// GET /together/members/:groupId — メンバー一覧
|
||||
// GET /together/members/:groupId — メンバー一覧 ?u=username
|
||||
r.get('/together/members/:groupId', async (req, res) => {
|
||||
const username = req.query.u;
|
||||
if (!username) return res.status(400).json({ error: 'u (username) は必須です' });
|
||||
try {
|
||||
const memberCheck = await pool.query(
|
||||
'SELECT 1 FROM together_members WHERE group_id=$1 AND username=$2',
|
||||
[req.params.groupId, username]
|
||||
);
|
||||
if (memberCheck.rows.length === 0) return res.status(403).json({ error: 'グループのメンバーではありません' });
|
||||
|
||||
const result = await pool.query(
|
||||
'SELECT username, joined_at FROM together_members WHERE group_id=$1 ORDER BY joined_at',
|
||||
[req.params.groupId]
|
||||
|
|
@ -2546,12 +2554,20 @@ ${excerpt}
|
|||
}
|
||||
});
|
||||
|
||||
// GET /together/feed/:groupId — フィード(リアクション・コメント数付き)
|
||||
// ?limit=N&cursor=<ISO timestamp> でカーソルページネーション対応
|
||||
// GET /together/feed/:groupId — フィード(リアクション付き)
|
||||
// ?u=username&limit=N&cursor=<ISO timestamp>
|
||||
r.get('/together/feed/:groupId', async (req, res) => {
|
||||
const username = req.query.u;
|
||||
if (!username) return res.status(400).json({ error: 'u (username) は必須です' });
|
||||
try {
|
||||
const memberCheck = await pool.query(
|
||||
'SELECT 1 FROM together_members WHERE group_id=$1 AND username=$2',
|
||||
[req.params.groupId, username]
|
||||
);
|
||||
if (memberCheck.rows.length === 0) return res.status(403).json({ error: 'グループのメンバーではありません' });
|
||||
|
||||
const limit = Math.min(parseInt(req.query.limit) || 20, 50);
|
||||
const cursor = req.query.cursor; // shared_at の ISO タイムスタンプ
|
||||
const cursor = req.query.cursor;
|
||||
const params = [req.params.groupId];
|
||||
let cursorClause = '';
|
||||
if (cursor) {
|
||||
|
|
@ -2564,11 +2580,9 @@ ${excerpt}
|
|||
COALESCE(
|
||||
json_agg(DISTINCT jsonb_build_object('username', r.username, 'type', r.type))
|
||||
FILTER (WHERE r.username IS NOT NULL), '[]'
|
||||
) AS reactions,
|
||||
COUNT(DISTINCT c.id)::int AS comment_count
|
||||
) AS reactions
|
||||
FROM together_shares s
|
||||
LEFT JOIN together_reactions r ON r.share_id = s.id
|
||||
LEFT JOIN together_comments c ON c.share_id = s.id
|
||||
WHERE s.group_id = $1 ${cursorClause}
|
||||
GROUP BY s.id
|
||||
ORDER BY s.shared_at DESC
|
||||
|
|
@ -2585,9 +2599,17 @@ ${excerpt}
|
|||
}
|
||||
});
|
||||
|
||||
// GET /together/article/:shareId — アーカイブ本文取得
|
||||
// GET /together/article/:shareId — アーカイブ本文取得 ?u=username
|
||||
r.get('/together/article/:shareId', async (req, res) => {
|
||||
const username = req.query.u;
|
||||
if (!username) return res.status(400).json({ error: 'u (username) は必須です' });
|
||||
try {
|
||||
const memberCheck = await pool.query(
|
||||
'SELECT 1 FROM together_members m JOIN together_shares s ON s.group_id=m.group_id WHERE s.id=$1 AND m.username=$2',
|
||||
[req.params.shareId, username]
|
||||
);
|
||||
if (memberCheck.rows.length === 0) return res.status(403).json({ error: 'グループのメンバーではありません' });
|
||||
|
||||
const result = await pool.query(
|
||||
'SELECT id, title, url, full_content, summary, archive_status, shared_at FROM together_shares WHERE id=$1',
|
||||
[req.params.shareId]
|
||||
|
|
@ -2635,9 +2657,17 @@ ${excerpt}
|
|||
}
|
||||
});
|
||||
|
||||
// GET /together/comments/:shareId — コメント一覧
|
||||
// GET /together/comments/:shareId — コメント一覧 ?u=username
|
||||
r.get('/together/comments/:shareId', async (req, res) => {
|
||||
const username = req.query.u;
|
||||
if (!username) return res.status(400).json({ error: 'u (username) は必須です' });
|
||||
try {
|
||||
const memberCheck = await pool.query(
|
||||
'SELECT 1 FROM together_members m JOIN together_shares s ON s.group_id=m.group_id WHERE s.id=$1 AND m.username=$2',
|
||||
[req.params.shareId, username]
|
||||
);
|
||||
if (memberCheck.rows.length === 0) return res.status(403).json({ error: 'グループのメンバーではありません' });
|
||||
|
||||
const result = await pool.query(
|
||||
'SELECT * FROM together_comments WHERE share_id=$1 ORDER BY created_at',
|
||||
[req.params.shareId]
|
||||
|
|
@ -2673,9 +2703,15 @@ ${excerpt}
|
|||
}
|
||||
});
|
||||
|
||||
// GET /together/search/:groupId — キーワード / タグ検索
|
||||
// GET /together/search/:groupId — キーワード / タグ検索 ?u=username
|
||||
r.get('/together/search/:groupId', async (req, res) => {
|
||||
const { q = '', tag = '' } = req.query;
|
||||
const { q = '', tag = '', u: username = '' } = req.query;
|
||||
if (!username) return res.status(400).json({ error: 'u (username) は必須です' });
|
||||
const memberOk = await pool.query(
|
||||
'SELECT 1 FROM together_members WHERE group_id=$1 AND username=$2',
|
||||
[req.params.groupId, username]
|
||||
).then(r => r.rows.length > 0).catch(() => false);
|
||||
if (!memberOk) return res.status(403).json({ error: 'グループのメンバーではありません' });
|
||||
if (!q && !tag) return res.status(400).json({ error: 'q または tag が必要です' });
|
||||
try {
|
||||
const keyword = q ? `%${q}%` : '';
|
||||
|
|
|
|||
Loading…
Reference in New Issue