W n8n attention
This commit is contained in:
parent
a6407fc0c9
commit
2c19339a4c
@ -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,
|
||||||
|
|||||||
@ -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 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user