diff --git a/app/api/missions/[missionId]/files/route.ts b/app/api/missions/[missionId]/files/route.ts index 1314ca9..6064b3f 100644 --- a/app/api/missions/[missionId]/files/route.ts +++ b/app/api/missions/[missionId]/files/route.ts @@ -6,12 +6,13 @@ import { S3Client, ListObjectsV2Command, GetObjectCommand, PutObjectCommand, Del import { Readable } from 'stream'; // S3 Configuration for missions bucket +// Use the same configuration as mission-uploads.ts for consistency const MISSIONS_S3_CONFIG = { - endpoint: (process.env.MINIO_S3_UPLOAD_BUCKET_URL || 'https://dome-api.slm-lab.net').replace(/\/$/, ''), - region: process.env.MINIO_AWS_REGION || 'us-east-1', - bucket: process.env.MINIO_MISSIONS_BUCKET || 'missions', - accessKey: process.env.MINIO_ACCESS_KEY || '', - secretKey: process.env.MINIO_SECRET_KEY || '' + endpoint: 'https://dome-api.slm-lab.net', + region: 'us-east-1', + bucket: 'missions', + accessKey: process.env.MINIO_ACCESS_KEY || '4aBT4CMb7JIMMyUtp4Pl', + secretKey: process.env.MINIO_SECRET_KEY || 'HGn39XhCIlqOjmDVzRK9MED2Fci2rYvDDgbLFElg' }; const missionsS3Client = new S3Client({ @@ -21,7 +22,7 @@ const missionsS3Client = new S3Client({ accessKeyId: MISSIONS_S3_CONFIG.accessKey, secretAccessKey: MISSIONS_S3_CONFIG.secretKey }, - forcePathStyle: true + forcePathStyle: true // Required for MinIO }); // Helper function to check if user has access to mission @@ -71,11 +72,13 @@ export async function GET( const path = searchParams.get('path') || ''; // Subfolder path within mission // Construct prefix for listing - // Note: In MinIO, files are stored without the "missions/" prefix (it's removed during upload) - // So the prefix should be just "{missionId}/" or "{missionId}/{path}/" + // Based on mission-uploads.ts, files are stored in MinIO without the "missions/" prefix + // The filePath in DB is "missions/{missionId}/attachments/{filename}" + // But in MinIO it's stored as "{missionId}/attachments/{filename}" + // So we need to use just "{missionId}/" or "{missionId}/{path}/" as prefix const prefix = path ? `${missionId}/${path}/` : `${missionId}/`; - console.log(`[GET /api/missions/${missionId}/files] Listing with prefix: ${prefix} in bucket: ${MISSIONS_S3_CONFIG.bucket}`); + console.log(`[GET /api/missions/${missionId}/files] Listing with prefix: "${prefix}" in bucket: "${MISSIONS_S3_CONFIG.bucket}"`); const command = new ListObjectsV2Command({ Bucket: MISSIONS_S3_CONFIG.bucket, @@ -83,7 +86,31 @@ export async function GET( Delimiter: '/' }); - const response = await missionsS3Client.send(command); + console.log(`[GET /api/missions/${missionId}/files] S3 command:`, { + bucket: MISSIONS_S3_CONFIG.bucket, + prefix: prefix, + endpoint: MISSIONS_S3_CONFIG.endpoint, + accessKey: MISSIONS_S3_CONFIG.accessKey.substring(0, 4) + '...' + }); + + let response; + try { + response = await missionsS3Client.send(command); + console.log(`[GET /api/missions/${missionId}/files] S3 response success:`, { + commonPrefixes: response.CommonPrefixes?.length || 0, + contents: response.Contents?.length || 0 + }); + } catch (s3Error: any) { + console.error(`[GET /api/missions/${missionId}/files] S3 error:`, { + code: s3Error.Code, + message: s3Error.message, + bucket: MISSIONS_S3_CONFIG.bucket, + prefix: prefix, + endpoint: MISSIONS_S3_CONFIG.endpoint, + fullError: s3Error + }); + throw s3Error; + } // Extract folders (CommonPrefixes) const folders = (response.CommonPrefixes || []).map(commonPrefix => {