235 lines
6.8 KiB
TypeScript
235 lines
6.8 KiB
TypeScript
/**
|
|
* Utilities for mission-related file paths and uploads
|
|
*/
|
|
|
|
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
|
|
import { logger } from '@/lib/logger';
|
|
|
|
// Initialize S3 client for Minio
|
|
const s3Client = new S3Client({
|
|
region: 'us-east-1',
|
|
endpoint: 'https://dome-api.slm-lab.net',
|
|
credentials: {
|
|
accessKeyId: '4aBT4CMb7JIMMyUtp4Pl',
|
|
secretAccessKey: 'HGn39XhCIlqOjmDVzRK9MED2Fci2rYvDDgbLFElg'
|
|
},
|
|
forcePathStyle: true // Required for MinIO
|
|
});
|
|
|
|
// Generate the mission logo path in Minio
|
|
export function getMissionLogoPath(userId: string, missionId: string, fileExtension: string): string {
|
|
// Use a consistent path structure: missions/{missionId}/logo{extension}
|
|
return `missions/${missionId}/logo${fileExtension}`;
|
|
}
|
|
|
|
// Generate the mission attachment path in Minio
|
|
export function getMissionAttachmentPath(userId: string, missionId: string, filename: string): string {
|
|
// Use a consistent path structure: missions/{missionId}/attachments/{filename}
|
|
return `missions/${missionId}/attachments/${filename}`;
|
|
}
|
|
|
|
// Helper function to ensure a path has the missions/ prefix
|
|
export function ensureMissionsPrefix(path: string): string {
|
|
return path.startsWith('missions/') ? path : `missions/${path}`;
|
|
}
|
|
|
|
// Helper function to construct a public URL for a mission file
|
|
export function getMissionFileUrl(path: string): string {
|
|
const normalizedPath = ensureMissionsPrefix(path);
|
|
return `/api/missions/image/${normalizedPath}`;
|
|
}
|
|
|
|
// Helper function to delete a mission logo
|
|
export async function deleteMissionLogo(missionId: string, logoPath: string): Promise<void> {
|
|
try {
|
|
const { DeleteObjectCommand } = await import('@aws-sdk/client-s3');
|
|
const normalizedPath = ensureMissionsPrefix(logoPath);
|
|
const minioPath = normalizedPath.replace(/^missions\//, ''); // Remove prefix for Minio
|
|
|
|
logger.debug('Deleting mission logo', {
|
|
missionId,
|
|
minioPath
|
|
});
|
|
|
|
const command = new DeleteObjectCommand({
|
|
Bucket: 'missions',
|
|
Key: minioPath,
|
|
});
|
|
|
|
await s3Client.send(command);
|
|
|
|
logger.debug('Mission logo deleted successfully', { minioPath });
|
|
} catch (error) {
|
|
logger.error('Error deleting mission logo', {
|
|
error: error instanceof Error ? error.message : String(error),
|
|
missionId,
|
|
minioPath
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Helper function to delete a mission attachment
|
|
export async function deleteMissionAttachment(filePath: string): Promise<void> {
|
|
try {
|
|
const { DeleteObjectCommand } = await import('@aws-sdk/client-s3');
|
|
const normalizedPath = ensureMissionsPrefix(filePath);
|
|
const minioPath = normalizedPath.replace(/^missions\//, ''); // Remove prefix for Minio
|
|
|
|
logger.debug('Deleting mission attachment', {
|
|
minioPath
|
|
});
|
|
|
|
const command = new DeleteObjectCommand({
|
|
Bucket: 'missions',
|
|
Key: minioPath,
|
|
});
|
|
|
|
await s3Client.send(command);
|
|
|
|
logger.debug('Mission attachment deleted successfully', { minioPath });
|
|
} catch (error) {
|
|
logger.error('Error deleting mission attachment', {
|
|
error: error instanceof Error ? error.message : String(error),
|
|
minioPath
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Upload a mission logo to Minio
|
|
export async function uploadMissionLogo(userId: string, missionId: string, file: File): Promise<{ filePath: string }> {
|
|
try {
|
|
logger.debug('Starting logo upload', {
|
|
missionId,
|
|
fileName: file.name,
|
|
fileSize: file.size,
|
|
fileType: file.type
|
|
});
|
|
|
|
const fileExtension = file.name.substring(file.name.lastIndexOf('.'));
|
|
const filePath = getMissionLogoPath(userId, missionId, fileExtension);
|
|
const minioPath = filePath.replace(/^missions\//, ''); // Remove prefix for Minio
|
|
|
|
// Convert File to Buffer
|
|
const arrayBuffer = await file.arrayBuffer();
|
|
const buffer = Buffer.from(arrayBuffer);
|
|
|
|
logger.debug('Uploading to Minio', {
|
|
bucket: 'missions',
|
|
key: minioPath,
|
|
contentType: file.type
|
|
});
|
|
|
|
await s3Client.send(new PutObjectCommand({
|
|
Bucket: 'missions',
|
|
Key: minioPath,
|
|
Body: buffer,
|
|
ContentType: file.type,
|
|
ACL: 'public-read'
|
|
}));
|
|
|
|
logger.debug('Logo upload successful', {
|
|
filePath,
|
|
minioPath
|
|
});
|
|
|
|
return { filePath };
|
|
} catch (error) {
|
|
logger.error('Error uploading mission logo', {
|
|
error: error instanceof Error ? error.message : String(error),
|
|
missionId,
|
|
fileName: file.name
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Upload a mission attachment to Minio
|
|
export async function uploadMissionAttachment(
|
|
userId: string,
|
|
missionId: string,
|
|
file: File
|
|
): Promise<{
|
|
filename: string;
|
|
filePath: string;
|
|
fileType: string;
|
|
fileSize: number;
|
|
}> {
|
|
try {
|
|
logger.debug('Starting attachment upload', {
|
|
missionId,
|
|
fileName: file.name,
|
|
fileSize: file.size,
|
|
fileType: file.type
|
|
});
|
|
|
|
const filePath = getMissionAttachmentPath(userId, missionId, file.name);
|
|
const minioPath = filePath.replace(/^missions\//, ''); // Remove prefix for Minio
|
|
|
|
// Convert File to Buffer
|
|
const arrayBuffer = await file.arrayBuffer();
|
|
const buffer = Buffer.from(arrayBuffer);
|
|
|
|
logger.debug('Uploading to Minio', {
|
|
bucket: 'missions',
|
|
key: minioPath,
|
|
contentType: file.type
|
|
});
|
|
|
|
await s3Client.send(new PutObjectCommand({
|
|
Bucket: 'missions',
|
|
Key: minioPath,
|
|
Body: buffer,
|
|
ContentType: file.type,
|
|
ACL: 'public-read'
|
|
}));
|
|
|
|
logger.debug('Attachment upload successful', {
|
|
filePath,
|
|
minioPath
|
|
});
|
|
|
|
return {
|
|
filename: file.name,
|
|
filePath,
|
|
fileType: file.type,
|
|
fileSize: file.size
|
|
};
|
|
} catch (error) {
|
|
logger.error('Error uploading mission attachment', {
|
|
error: error instanceof Error ? error.message : String(error),
|
|
missionId,
|
|
fileName: file.name
|
|
});
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Generate a presigned URL for direct upload to Minio (for logo)
|
|
export async function generateMissionLogoUploadUrl(
|
|
userId: string,
|
|
missionId: string,
|
|
fileExtension: string
|
|
): Promise<{ uploadUrl: string; filePath: string }> {
|
|
const filePath = getMissionLogoPath(userId, missionId, fileExtension);
|
|
const minioPath = filePath.replace(/^missions\//, '');
|
|
|
|
// TODO: Implement presigned URL generation
|
|
// This would require additional AWS SDK functionality
|
|
throw new Error('Presigned URL generation not implemented');
|
|
}
|
|
|
|
// Generate a presigned URL for direct upload to Minio (for attachment)
|
|
export async function generateMissionAttachmentUploadUrl(
|
|
userId: string,
|
|
missionId: string,
|
|
filename: string
|
|
): Promise<{ uploadUrl: string; filePath: string }> {
|
|
const filePath = getMissionAttachmentPath(userId, missionId, filename);
|
|
const minioPath = filePath.replace(/^missions\//, '');
|
|
|
|
// TODO: Implement presigned URL generation
|
|
// This would require additional AWS SDK functionality
|
|
throw new Error('Presigned URL generation not implemented');
|
|
}
|