Files
SerpentRace/SerpentRace_Backend/dist/Infrastructure/Repository/DeckRepository.js
T

264 lines
13 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeckRepository = void 0;
const typeorm_1 = require("typeorm");
const ormconfig_1 = require("../ormconfig");
const DeckAggregate_1 = require("../../Domain/Deck/DeckAggregate");
const Logger_1 = require("../../Application/Services/Logger");
const AdminBypassService_1 = require("../../Application/Services/AdminBypassService");
class DeckRepository {
constructor() {
this.repo = ormconfig_1.AppDataSource.getRepository(DeckAggregate_1.DeckAggregate);
}
async create(deck) {
return this.repo.save(deck);
}
async findByPage(from, to) {
const startTime = performance.now();
try {
const limit = to - from + 1;
const offset = from;
// Get total count for pagination
const totalCount = await this.repo.count({
where: { state: (0, typeorm_1.Not)(DeckAggregate_1.State.SOFT_DELETE) }
});
// Get paginated results
const decks = await this.repo.find({
where: { state: (0, typeorm_1.Not)(DeckAggregate_1.State.SOFT_DELETE) },
order: { updatedate: 'DESC' },
take: limit,
skip: offset
});
const endTime = performance.now();
(0, Logger_1.logDatabase)('Deck page query completed', `executionTime: ${Math.round(endTime - startTime)}ms, found: ${decks.length}, total: ${totalCount}, from: ${from}, to: ${to}`);
return { decks, totalCount };
}
catch (error) {
const endTime = performance.now();
(0, Logger_1.logDatabase)('Deck page query failed', `executionTime: ${Math.round(endTime - startTime)}ms, from: ${from}, to: ${to}`);
(0, Logger_1.logError)('DeckRepository.findByPage error', error instanceof Error ? error : new Error(String(error)));
throw new Error('Failed to get decks page from database');
}
}
async findByPageIncludingDeleted(from, to) {
const startTime = performance.now();
try {
const limit = to - from + 1;
const offset = from;
// Get total count for pagination
const totalCount = await this.repo.count();
// Get paginated results
const decks = await this.repo.find({
order: { updatedate: 'DESC' },
take: limit,
skip: offset
});
const endTime = performance.now();
(0, Logger_1.logDatabase)('Deck page query completed (including deleted)', `executionTime: ${Math.round(endTime - startTime)}ms, found: ${decks.length}, total: ${totalCount}, from: ${from}, to: ${to}`);
return { decks, totalCount };
}
catch (error) {
const endTime = performance.now();
(0, Logger_1.logDatabase)('Deck page query failed (including deleted)', `executionTime: ${Math.round(endTime - startTime)}ms, from: ${from}, to: ${to}`);
(0, Logger_1.logError)('DeckRepository.findByPageIncludingDeleted error', error instanceof Error ? error : new Error(String(error)));
throw new Error('Failed to get decks page from database');
}
}
async findById(id) {
return this.repo.findOne({
where: {
id,
state: (0, typeorm_1.Not)(DeckAggregate_1.State.SOFT_DELETE)
}
});
}
async findByIdIncludingDeleted(id) {
return this.repo.findOneBy({ id });
}
async update(id, update) {
await this.repo.update(id, update);
return this.findById(id);
}
async delete(id) {
return this.repo.delete(id);
}
async softDelete(id) {
await this.repo.update(id, { state: DeckAggregate_1.State.SOFT_DELETE });
return this.findById(id);
}
async search(query, limit = 20, offset = 0) {
const startTime = performance.now();
try {
const searchPattern = `%${query.toLowerCase()}%`;
const queryBuilder = this.repo.createQueryBuilder('deck')
.where('deck.state != :softDelete', { softDelete: DeckAggregate_1.State.SOFT_DELETE })
.andWhere('LOWER(deck.name) LIKE :pattern', { pattern: searchPattern });
const totalCount = await queryBuilder.getCount();
const decks = await queryBuilder
.orderBy('deck.name', 'ASC')
.limit(limit)
.offset(offset)
.getMany();
const endTime = performance.now();
(0, Logger_1.logDatabase)('Deck search completed', `executionTime: ${Math.round(endTime - startTime)}ms, found: ${decks.length}, total: ${totalCount}, searchTerm: "${query}", limit: ${limit}, offset: ${offset}`);
return { decks, totalCount };
}
catch (error) {
const endTime = performance.now();
(0, Logger_1.logDatabase)('Deck search failed', `executionTime: ${Math.round(endTime - startTime)}ms, searchTerm: "${query}"`);
(0, Logger_1.logError)('DeckRepository.search error', error instanceof Error ? error : new Error(String(error)));
throw new Error('Failed to search decks in database');
}
}
async searchIncludingDeleted(query, limit = 20, offset = 0) {
const startTime = performance.now();
try {
const searchPattern = `%${query.toLowerCase()}%`;
const queryBuilder = this.repo.createQueryBuilder('deck')
.where('LOWER(deck.name) LIKE :pattern', { pattern: searchPattern });
const totalCount = await queryBuilder.getCount();
const decks = await queryBuilder
.orderBy('deck.name', 'ASC')
.limit(limit)
.offset(offset)
.getMany();
const endTime = performance.now();
(0, Logger_1.logDatabase)('Deck search completed (including deleted)', `executionTime: ${Math.round(endTime - startTime)}ms, found: ${decks.length}, total: ${totalCount}, searchTerm: "${query}", limit: ${limit}, offset: ${offset}`);
return { decks, totalCount };
}
catch (error) {
const endTime = performance.now();
(0, Logger_1.logDatabase)('Deck search failed (including deleted)', `executionTime: ${Math.round(endTime - startTime)}ms, searchTerm: "${query}"`);
(0, Logger_1.logError)('DeckRepository.searchIncludingDeleted error', error instanceof Error ? error : new Error(String(error)));
throw new Error('Failed to search all decks in database');
}
}
/**
* Count active (non-soft-deleted) decks for a specific user
* @param userId - User ID to count decks for
* @returns Number of active decks
*/
async countActiveByUserId(userId) {
const startTime = performance.now();
try {
const count = await this.repo.count({
where: {
userid: userId,
state: (0, typeorm_1.Not)(DeckAggregate_1.State.SOFT_DELETE)
}
});
const endTime = performance.now();
(0, Logger_1.logDatabase)('User active deck count completed', `executionTime: ${Math.round(endTime - startTime)}ms, userId: ${userId}, count: ${count}`);
return count;
}
catch (error) {
const endTime = performance.now();
(0, Logger_1.logDatabase)('User active deck count failed', `executionTime: ${Math.round(endTime - startTime)}ms, userId: ${userId}`);
(0, Logger_1.logError)('DeckRepository.countActiveByUserId error', error instanceof Error ? error : new Error(String(error)));
throw new Error('Failed to count active decks for user');
}
}
/**
* Count organizational decks for a specific user
* @param userId - User ID to count organizational decks for
* @returns Number of organizational decks
*/
async countOrganizationalByUserId(userId) {
const startTime = performance.now();
try {
const count = await this.repo.count({
where: {
userid: userId,
ctype: DeckAggregate_1.CType.ORGANIZATION,
state: (0, typeorm_1.Not)(DeckAggregate_1.State.SOFT_DELETE)
}
});
const endTime = performance.now();
(0, Logger_1.logDatabase)('User organizational deck count completed', `executionTime: ${Math.round(endTime - startTime)}ms, userId: ${userId}, count: ${count}`);
return count;
}
catch (error) {
const endTime = performance.now();
(0, Logger_1.logDatabase)('User organizational deck count failed', `executionTime: ${Math.round(endTime - startTime)}ms, userId: ${userId}`);
(0, Logger_1.logError)('DeckRepository.countOrganizationalByUserId error', error instanceof Error ? error : new Error(String(error)));
throw new Error('Failed to count organizational decks for user');
}
}
/**
* Find decks with filtering based on user permissions and mandatory pagination
* @param userId - User ID for filtering
* @param userOrgId - User's organization ID (if any)
* @param isAdmin - Whether user is admin (bypasses filtering)
* @param from - Start index for pagination (default: 0)
* @param to - End index for pagination (default: 49)
* @returns Paginated filtered list of decks with total count
*/
async findFilteredDecks(userId, userOrgId, isAdmin, from = 0, to = 49) {
const startTime = performance.now();
try {
// Validate pagination parameters
if (from < 0 || to < from) {
throw new Error('Invalid pagination parameters');
}
const limit = to - from + 1;
if (limit > 100) {
throw new Error('Page size too large. Maximum 100 records per request');
}
const skip = from;
const take = limit;
// Admin gets ALL decks with pagination
if (isAdmin) {
AdminBypassService_1.AdminBypassService.logAdminBypass('FIND_FILTERED_DECKS_BYPASS', userId, 'all-decks-filtered', {
bypassType: 'admin-all-decks-filtered',
userOrgId,
from,
to,
operation: 'read'
});
const [decks, totalCount] = await this.repo.findAndCount({
where: { state: (0, typeorm_1.Not)(DeckAggregate_1.State.SOFT_DELETE) },
relations: ['organization'],
order: { creationdate: 'DESC' },
skip,
take
});
const endTime = performance.now();
(0, Logger_1.logDatabase)('Admin filtered deck query completed', `executionTime: ${Math.round(endTime - startTime)}ms, userId: ${userId}, found: ${decks.length}, totalCount: ${totalCount}, isAdmin: true`);
return { decks, totalCount };
}
// Regular user complex filtering
const queryBuilder = this.repo.createQueryBuilder('deck')
.leftJoinAndSelect('deck.organization', 'org')
.where('deck.state != :deletedState', { deletedState: DeckAggregate_1.State.SOFT_DELETE });
queryBuilder.andWhere('(' +
// User's private decks
'(deck.userid = :userId AND deck.ctype = :privateType) OR ' +
// All public decks
'(deck.ctype = :publicType)' +
// Organization decks from same org (if user has org)
(userOrgId ? ' OR (deck.ctype = :orgType AND org.id = :orgId)' : '') +
')', {
userId,
privateType: DeckAggregate_1.CType.PRIVATE,
publicType: DeckAggregate_1.CType.PUBLIC,
...(userOrgId && { orgType: DeckAggregate_1.CType.ORGANIZATION, orgId: userOrgId })
});
queryBuilder
.orderBy('deck.creationdate', 'DESC')
.skip(skip)
.take(take);
const [decks, totalCount] = await queryBuilder.getManyAndCount();
const endTime = performance.now();
(0, Logger_1.logDatabase)('User filtered deck query completed', `executionTime: ${Math.round(endTime - startTime)}ms, userId: ${userId}, userOrgId: ${userOrgId}, found: ${decks.length}, totalCount: ${totalCount}, isAdmin: false`);
return { decks, totalCount };
}
catch (error) {
const endTime = performance.now();
(0, Logger_1.logDatabase)('Filtered deck query failed', `executionTime: ${Math.round(endTime - startTime)}ms, userId: ${userId}, isAdmin: ${isAdmin}`);
(0, Logger_1.logError)('DeckRepository.findFilteredDecks error', error instanceof Error ? error : new Error(String(error)));
throw new Error('Failed to find filtered decks');
}
}
}
exports.DeckRepository = DeckRepository;
//# sourceMappingURL=DeckRepository.js.map