214 lines
6.6 KiB
JavaScript
214 lines
6.6 KiB
JavaScript
import { pool } from '../db.js';
|
|
|
|
/**
|
|
* Repository для работы с метаданными файлов пользователей
|
|
*/
|
|
export const userFileRepository = {
|
|
/**
|
|
* Создать запись о файле
|
|
*/
|
|
async create({ userId, s3Key, originalFilename, fileSize, contentType, fileType = 'image', folder = 'images_input', generationUuid = null, generationStepId = null, status = 'uploaded', uploadId = null }) {
|
|
const query = `
|
|
INSERT INTO uno_bff.user_files (user_id, s3_key, original_filename, file_size, content_type, file_type, folder, generation_uuid, generation_step_id, status, upload_id)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
RETURNING id, user_id, s3_key, original_filename, file_size, content_type, file_type, folder, generation_uuid, generation_step_id, status, upload_id, created_at, updated_at
|
|
`;
|
|
const values = [userId, s3Key, originalFilename, fileSize, contentType, fileType, folder, generationUuid, generationStepId, status, uploadId];
|
|
|
|
const result = await pool.query(query, values);
|
|
return result.rows[0];
|
|
},
|
|
|
|
/**
|
|
* Обновить файл
|
|
*/
|
|
async update(fileId, updates) {
|
|
const allowedFields = ['status', 'upload_id', 'file_size', 'updated_at'];
|
|
const setClauses = [];
|
|
const values = [fileId];
|
|
let paramIndex = 2;
|
|
|
|
for (const [key, value] of Object.entries(updates)) {
|
|
if (allowedFields.includes(key)) {
|
|
setClauses.push(`${key} = $${paramIndex}`);
|
|
values.push(value);
|
|
paramIndex++;
|
|
}
|
|
}
|
|
|
|
if (setClauses.length === 0) {
|
|
throw new Error('No valid fields to update');
|
|
}
|
|
|
|
const query = `
|
|
UPDATE uno_bff.user_files
|
|
SET ${setClauses.join(', ')}
|
|
WHERE id = $1
|
|
RETURNING id, user_id, s3_key, original_filename, file_size, content_type, file_type, folder, status, upload_id, created_at, updated_at
|
|
`;
|
|
|
|
const result = await pool.query(query, values);
|
|
return result.rows[0];
|
|
},
|
|
|
|
/**
|
|
* Удалить файл по ID
|
|
*/
|
|
async delete(fileId) {
|
|
const query = `
|
|
DELETE FROM uno_bff.user_files
|
|
WHERE id = $1
|
|
RETURNING id
|
|
`;
|
|
|
|
const result = await pool.query(query, [fileId]);
|
|
return result.rows[0];
|
|
},
|
|
|
|
/**
|
|
* Найти файл по ID и проверить владение
|
|
*/
|
|
async findByIdAndOwner(fileId, userId) {
|
|
const query = `
|
|
SELECT id, user_id, s3_key, original_filename, file_size, content_type, file_type, folder, created_at
|
|
FROM uno_bff.user_files
|
|
WHERE id = $1 AND user_id = $2
|
|
`;
|
|
|
|
const result = await pool.query(query, [fileId, userId]);
|
|
return result.rows[0];
|
|
},
|
|
|
|
/**
|
|
* Найти файл по S3 ключу и проверить владение
|
|
*/
|
|
async findByKeyAndOwner(s3Key, userId) {
|
|
const query = `
|
|
SELECT id, user_id, s3_key, original_filename, file_size, content_type, file_type, folder, created_at
|
|
FROM uno_bff.user_files
|
|
WHERE s3_key = $1 AND user_id = $2
|
|
`;
|
|
|
|
const result = await pool.query(query, [s3Key, userId]);
|
|
return result.rows[0];
|
|
},
|
|
|
|
/**
|
|
* Получить список файлов пользователя
|
|
*/
|
|
async findByUser(userId, options = {}) {
|
|
const {
|
|
fileType = 'image',
|
|
folder = 'images_input',
|
|
limit = 50,
|
|
offset = 0,
|
|
orderBy = 'created_at',
|
|
order = 'DESC',
|
|
} = options;
|
|
|
|
const validOrderColumns = ['created_at', 'original_filename', 'file_size'];
|
|
const validOrders = ['ASC', 'DESC'];
|
|
const safeOrderBy = validOrderColumns.includes(orderBy) ? orderBy : 'created_at';
|
|
const safeOrder = validOrders.includes(order?.toUpperCase()) ? order.toUpperCase() : 'DESC';
|
|
|
|
const query = `
|
|
SELECT id, user_id, s3_key, original_filename, file_size, content_type, file_type, folder, created_at
|
|
FROM uno_bff.user_files
|
|
WHERE user_id = $1
|
|
AND ($2::VARCHAR IS NULL OR file_type = $2)
|
|
AND ($3::VARCHAR IS NULL OR folder = $3)
|
|
ORDER BY ${safeOrderBy} ${safeOrder}
|
|
LIMIT $4 OFFSET $5
|
|
`;
|
|
|
|
const values = [
|
|
userId,
|
|
fileType || null,
|
|
folder || null,
|
|
limit,
|
|
offset,
|
|
];
|
|
|
|
const result = await pool.query(query, values);
|
|
return result.rows;
|
|
},
|
|
|
|
/**
|
|
* Получить общее количество файлов пользователя
|
|
*/
|
|
async countByUser(userId, options = {}) {
|
|
const { fileType = 'image', folder = 'images_input' } = options;
|
|
|
|
const query = `
|
|
SELECT COUNT(*) as total
|
|
FROM uno_bff.user_files
|
|
WHERE user_id = $1
|
|
AND ($2::VARCHAR IS NULL OR file_type = $2)
|
|
AND ($3::VARCHAR IS NULL OR folder = $3)
|
|
`;
|
|
|
|
const values = [userId, fileType || null, folder || null];
|
|
const result = await pool.query(query, values);
|
|
return parseInt(result.rows[0].total, 10);
|
|
},
|
|
|
|
/**
|
|
* Удалить запись о файле (по ID и владельцу)
|
|
*/
|
|
async deleteByIdAndOwner(fileId, userId) {
|
|
const query = `
|
|
DELETE FROM uno_bff.user_files
|
|
WHERE id = $1 AND user_id = $2
|
|
RETURNING s3_key
|
|
`;
|
|
|
|
const result = await pool.query(query, [fileId, userId]);
|
|
return result.rows[0];
|
|
},
|
|
|
|
/**
|
|
* Удалить запись о файле по S3 ключу
|
|
*/
|
|
async deleteByKeyAndOwner(s3Key, userId) {
|
|
const query = `
|
|
DELETE FROM uno_bff.user_files
|
|
WHERE s3_key = $1 AND user_id = $2
|
|
RETURNING s3_key
|
|
`;
|
|
|
|
const result = await pool.query(query, [s3Key, userId]);
|
|
return result.rows[0];
|
|
},
|
|
|
|
/**
|
|
* Получить файлы генерации
|
|
*/
|
|
async findByGeneration(generationUuid, userId) {
|
|
const query = `
|
|
SELECT id, user_id, s3_key, original_filename, file_size, content_type, file_type, folder, generation_uuid, generation_step_id, created_at
|
|
FROM uno_bff.user_files
|
|
WHERE generation_uuid = $1 AND user_id = $2
|
|
ORDER BY created_at ASC
|
|
`;
|
|
|
|
const result = await pool.query(query, [generationUuid, userId]);
|
|
return result.rows;
|
|
},
|
|
|
|
/**
|
|
* Получить файлы шага генерации
|
|
*/
|
|
async findByGenerationStep(generationUuid, stepId, userId) {
|
|
const query = `
|
|
SELECT f.id, f.user_id, f.s3_key, f.original_filename, f.file_size, f.content_type, f.file_type, f.folder, f.generation_uuid, f.generation_step_id, f.created_at
|
|
FROM uno_bff.user_files f
|
|
INNER JOIN uno_bff.generation_steps gs ON f.generation_step_id = gs.id
|
|
WHERE f.generation_uuid = $1 AND gs.step_id = $2 AND f.user_id = $3
|
|
ORDER BY f.created_at ASC
|
|
`;
|
|
|
|
const result = await pool.query(query, [generationUuid, stepId, userId]);
|
|
return result.rows;
|
|
},
|
|
};
|