fix: message detail shows only its own images, not everyone's
Build & Deploy (Nix) / build-and-deploy (discord-gateway) (push) Successful in 2m47s
Build & Deploy (Nix) / build-and-deploy (backend) (push) Successful in 3m12s
Build & Deploy (Nix) / build-and-deploy (proxy) (push) Successful in 3m12s
Build & Deploy (Nix) / build-and-deploy (discord-gateway) (push) Successful in 2m47s
Build & Deploy (Nix) / build-and-deploy (backend) (push) Successful in 3m12s
Build & Deploy (Nix) / build-and-deploy (proxy) (push) Successful in 3m12s
useMessageDetail fetch attachments per-channel -> detail view nampilin 10 image terbaru di channel itu (semua orang), bukan image pesan yang diklik. Root cause: getAttachmentsByChannel cuma filter channel_id. - backend: messageQuerySchema + messageId optional; repository tambah eq(message_id) pas messageId ada. Sudah ada index idx_attachments_message. - frontend: getAttachments(channelId, limit, cursor, messageId); useMessageDetail pass id pesan. Verifikasi: backend tsc PASS, frontend tsc PASS + next build PASS. E2E local (tsx + env prod, port 3901): tanpa messageId -> 3 row (termasuk image.png punya message lain); dengan messageId -> tepat 2 row milik pesan itu. psql juga konfirmasi channel-only 3 vs message-filtered 2.
This commit is contained in:
@@ -385,6 +385,12 @@ export class MessagesRepository {
|
|||||||
const limit = query.limit ?? 50;
|
const limit = query.limit ?? 50;
|
||||||
const conditions: SQL[] = [eq(pgAttachmentsTable.channel_id, channelId)];
|
const conditions: SQL[] = [eq(pgAttachmentsTable.channel_id, channelId)];
|
||||||
|
|
||||||
|
// Detail view: narrow to the selected message so we don't show
|
||||||
|
// everyone else's images from the same channel.
|
||||||
|
if (query.messageId) {
|
||||||
|
conditions.push(eq(pgAttachmentsTable.message_id, query.messageId));
|
||||||
|
}
|
||||||
|
|
||||||
if (query.cursor) {
|
if (query.cursor) {
|
||||||
conditions.push(lt(pgAttachmentsTable.created_at, Number(query.cursor)));
|
conditions.push(lt(pgAttachmentsTable.created_at, Number(query.cursor)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ export const messageQuerySchema = z.object({
|
|||||||
limit: z.coerce.number().int().positive().default(50),
|
limit: z.coerce.number().int().positive().default(50),
|
||||||
offset: z.coerce.number().int().nonnegative().default(0),
|
offset: z.coerce.number().int().nonnegative().default(0),
|
||||||
cursor: z.string().optional(),
|
cursor: z.string().optional(),
|
||||||
|
// Filter attachments to a single message (used by the message detail view)
|
||||||
|
messageId: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const messageCreateSchema = z.object({
|
export const messageCreateSchema = z.object({
|
||||||
|
|||||||
@@ -136,7 +136,9 @@ export function useMessageDetail(id: string | null) {
|
|||||||
// can race the detail load and see detail.data === undefined.
|
// can race the detail load and see detail.data === undefined.
|
||||||
const cid = detail.data?.channel_id;
|
const cid = detail.data?.channel_id;
|
||||||
if (!cid) return [];
|
if (!cid) return [];
|
||||||
const res = await messagesApi.getAttachments(cid, 10);
|
// messageId filter: attachment list must show only this message's
|
||||||
|
// images, not the latest images from everyone in the channel.
|
||||||
|
const res = await messagesApi.getAttachments(cid, 10, undefined, id ?? "");
|
||||||
return res.data;
|
return res.data;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -40,10 +40,16 @@ export const messagesApi = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
getAttachments: (channelId: string, limit?: number, cursor?: string) => {
|
getAttachments: (
|
||||||
|
channelId: string,
|
||||||
|
limit?: number,
|
||||||
|
cursor?: string,
|
||||||
|
messageId?: string,
|
||||||
|
) => {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
if (limit) params.set("limit", String(limit));
|
if (limit) params.set("limit", String(limit));
|
||||||
if (cursor) params.set("cursor", cursor);
|
if (cursor) params.set("cursor", cursor);
|
||||||
|
if (messageId) params.set("messageId", messageId);
|
||||||
const qs = params.toString();
|
const qs = params.toString();
|
||||||
return api.get<{ data: AttachmentRecord[]; nextCursor: string | null }>(
|
return api.get<{ data: AttachmentRecord[]; nextCursor: string | null }>(
|
||||||
`/api/messages/${channelId}/attachments${qs ? `?${qs}` : ""}`,
|
`/api/messages/${channelId}/attachments${qs ? `?${qs}` : ""}`,
|
||||||
|
|||||||
Reference in New Issue
Block a user