W n8n attention

This commit is contained in:
alma 2025-05-24 11:54:37 +02:00
parent a6407fc0c9
commit 2c19339a4c
3 changed files with 62 additions and 33 deletions

View File

@ -83,7 +83,7 @@ export async function GET(request: Request, props: { params: Promise<{ missionId
// Add public URLs to mission logo and attachments // Add public URLs to mission logo and attachments
const missionWithUrls = { const missionWithUrls = {
...mission, ...mission,
logoUrl: mission.logo ? `/api/missions/image/${mission.logo.replace('missions/', '')}` : null, logoUrl: mission.logo ? `/api/missions/image/${mission.logo}` : null,
logo: mission.logo, logo: mission.logo,
attachments: mission.attachments.map((attachment: { id: string; filename: string; filePath: string; fileType: string; fileSize: number; createdAt: Date }) => ({ attachments: mission.attachments.map((attachment: { id: string; filename: string; filePath: string; fileType: string; fileSize: number; createdAt: Date }) => ({
...attachment, ...attachment,

View File

@ -3,6 +3,7 @@ import { getServerSession } from 'next-auth';
import { authOptions } from '@/app/api/auth/options'; import { authOptions } from '@/app/api/auth/options';
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3'; import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
import { S3_CONFIG } from '@/lib/s3'; import { S3_CONFIG } from '@/lib/s3';
import { NoSuchKey } from '@aws-sdk/client-s3';
// Initialize S3 client // Initialize S3 client
const s3Client = new S3Client({ const s3Client = new S3Client({
@ -21,48 +22,46 @@ export async function GET(
{ params }: { params: Promise<{ path: string[] }> } { params }: { params: Promise<{ path: string[] }> }
) { ) {
try { try {
// Await the params promise to get the actual path parameter const { path: pathSegments } = await params;
const { path } = await params if (!pathSegments || pathSegments.length === 0) {
// Check if path is provided
if (!path || path.length === 0) {
return new NextResponse('Path is required', { status: 400 }); return new NextResponse('Path is required', { status: 400 });
} }
// Reconstruct the full path from path segments // Reconstruct the full path from path segments
const filePath = path.join('/'); const filePath = pathSegments.join('/');
console.log('Fetching mission image:', filePath); console.log('Fetching mission image:', filePath);
// Create S3 command to get the object // Ensure the path has the missions/ prefix
const minioPath = filePath.startsWith('missions/') ? filePath : `missions/${filePath}`;
console.log('Full Minio path:', minioPath);
const command = new GetObjectCommand({ const command = new GetObjectCommand({
Bucket: S3_CONFIG.bucket, // Use the pages bucket Bucket: process.env.MINIO_BUCKET_NAME || 'missions',
Key: filePath, Key: minioPath,
}); });
// Get the object from S3/Minio try {
const response = await s3Client.send(command); const response = await s3Client.send(command);
if (!response.Body) {
if (!response.Body) { return new NextResponse('File not found', { status: 404 });
console.error('File not found in Minio:', filePath); }
return new NextResponse('File not found', { status: 404 });
// Set appropriate content type and cache control
const contentType = response.ContentType || 'application/octet-stream';
const headers = new Headers();
headers.set('Content-Type', contentType);
headers.set('Cache-Control', 'public, max-age=31536000');
return new NextResponse(response.Body as any, { headers });
} catch (error) {
console.error('Error fetching file from Minio:', error);
if (error instanceof NoSuchKey) {
return new NextResponse('File not found', { status: 404 });
}
return new NextResponse('Internal Server Error', { status: 500 });
} }
// Get the readable web stream directly
const stream = response.Body.transformToWebStream();
// Determine content type
const contentType = response.ContentType || 'application/octet-stream';
// Create and return a new response with the file stream
return new NextResponse(stream as ReadableStream, {
headers: {
'Content-Type': contentType,
'Cache-Control': 'public, max-age=31536000', // Cache for 1 year
},
});
} catch (error) { } catch (error) {
console.error('Error serving mission image:', error); console.error('Error in image serving:', error);
console.error('Error details:', JSON.stringify(error, null, 2));
return new NextResponse('Internal Server Error', { status: 500 }); return new NextResponse('Internal Server Error', { status: 500 });
} }
} }

View File

@ -64,6 +64,14 @@ interface MissionResponse {
penpotProjectId: string | null; penpotProjectId: string | null;
createdAt: Date; createdAt: Date;
updatedAt: Date; updatedAt: Date;
attachments?: Array<{
id: string;
filename: string;
filePath: string;
fileType: string;
fileSize: number;
createdAt: Date;
}>;
} }
// Helper function to check authentication // Helper function to check authentication
@ -123,14 +131,36 @@ export async function GET(request: Request) {
} }
} }
} }
},
attachments: {
select: {
id: true,
filename: true,
filePath: true,
fileType: true,
fileSize: true,
createdAt: true
},
orderBy: { createdAt: 'desc' }
} }
} }
}); });
const totalCount = await prisma.mission.count({ where }); const totalCount = await prisma.mission.count({ where });
// Transform missions to include public URLs
const missionsWithUrls = missions.map(mission => ({
...mission,
logoUrl: mission.logo ? `/api/missions/image/${mission.logo}` : null,
logo: mission.logo,
attachments: mission.attachments?.map(attachment => ({
...attachment,
publicUrl: `/api/missions/image/${attachment.filePath}`
})) || []
}));
return NextResponse.json({ return NextResponse.json({
missions, missions: missionsWithUrls,
pagination: { pagination: {
total: totalCount, total: totalCount,
offset, offset,