initial commit

This commit is contained in:
root
2026-05-13 14:20:41 +00:00
commit 6e178d2012
6022 changed files with 399872 additions and 0 deletions
+213
View File
@@ -0,0 +1,213 @@
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;
},
};