import { and, eq } from 'drizzle-orm'; import { NextRequest, NextResponse } from 'next/server'; import { announcements } from '@/db/schema'; import { getAnnouncementByIdForAccess } from '@/features/announcements/server/announcement-data'; import { readStoredAnnouncementAttachment } from '@/lib/announcement-storage'; import { AuthError, requireOrganizationAccess } from '@/lib/auth/session'; import { db } from '@/lib/db'; type Params = { params: Promise<{ id: string }> }; export const runtime = 'nodejs'; export async function GET(_request: NextRequest, { params }: Params) { try { const { organization, session } = await requireOrganizationAccess(); const { id } = await params; const announcementId = Number(id); if (Number.isNaN(announcementId)) { return NextResponse.json({ message: 'Invalid announcement request' }, { status: 400 }); } const announcement = await getAnnouncementByIdForAccess({ id: announcementId, organizationId: organization.id, permissions: session.user.effectivePermissions }); if (!announcement || !announcement.attachmentStorageKey) { return NextResponse.json({ message: 'ไม่พบไฟล์แนบประกาศ' }, { status: 404 }); } const persisted = await db.query.announcements.findFirst({ where: and( eq(announcements.id, announcementId), eq(announcements.organizationId, organization.id) ) }); if (!persisted?.attachmentStorageKey || !persisted.attachmentFileType || !persisted.attachmentFileName) { return NextResponse.json({ message: 'ไม่พบไฟล์แนบประกาศ' }, { status: 404 }); } const file = await readStoredAnnouncementAttachment(persisted.attachmentStorageKey); const disposition = persisted.attachmentFileType === 'application/pdf' || persisted.attachmentFileType.startsWith('image/') ? 'inline' : 'attachment'; return new NextResponse(file, { headers: { 'Content-Type': persisted.attachmentFileType, 'Content-Length': String(persisted.attachmentFileSize ?? file.byteLength), 'Content-Disposition': `${disposition}; filename*=UTF-8''${encodeURIComponent(persisted.attachmentFileName)}`, 'Cache-Control': 'private, no-store' } }); } catch (error) { if (error instanceof AuthError) { return NextResponse.json({ message: error.message }, { status: error.status }); } if ((error as NodeJS.ErrnoException)?.code === 'ENOENT') { return NextResponse.json({ message: 'ไม่พบไฟล์แนบประกาศ' }, { status: 404 }); } return NextResponse.json({ message: 'ไม่สามารถเปิดไฟล์แนบประกาศได้' }, { status: 500 }); } }