https://project.mdnd-it.cc/work_packages/94
This commit is contained in:
2025-08-23 04:25:28 +02:00
parent 725516ad6c
commit 19cfa031d0
25823 changed files with 1095587 additions and 2801760 deletions
@@ -0,0 +1,8 @@
export interface CreateDeckCommand {
name: string;
type: number;
userid: string;
cards: any[];
ctype?: number;
}
//# sourceMappingURL=CreateDeckCommand.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"CreateDeckCommand.d.ts","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/CreateDeckCommand.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=CreateDeckCommand.js.map
@@ -0,0 +1 @@
{"version":3,"file":"CreateDeckCommand.js","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/CreateDeckCommand.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
import { IDeckRepository } from '../../../Domain/IRepository/IDeckRepository';
import { IUserRepository } from '../../../Domain/IRepository/IUserRepository';
import { IOrganizationRepository } from '../../../Domain/IRepository/IOrganizationRepository';
import { CreateDeckCommand } from './CreateDeckCommand';
import { ShortDeckDto } from '../../DTOs/DeckDto';
export declare class CreateDeckCommandHandler {
private readonly deckRepo;
private readonly userRepo;
private readonly orgRepo;
constructor(deckRepo: IDeckRepository, userRepo: IUserRepository, orgRepo: IOrganizationRepository);
execute(cmd: CreateDeckCommand): Promise<ShortDeckDto>;
/**
* Private method to create deck after all validations
*/
private createDeck;
}
//# sourceMappingURL=CreateDeckCommandHandler.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"CreateDeckCommandHandler.d.ts","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/CreateDeckCommandHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,qDAAqD,CAAC;AAC9F,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAOlD,qBAAa,wBAAwB;IAEjC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAFP,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,uBAAuB;IAG7C,OAAO,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAsE5D;;OAEG;YACW,UAAU;CAiCzB"}
@@ -0,0 +1,105 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CreateDeckCommandHandler = void 0;
const DeckAggregate_1 = require("../../../Domain/Deck/DeckAggregate");
const UserAggregate_1 = require("../../../Domain/User/UserAggregate");
const DeckMapper_1 = require("../../DTOs/Mappers/DeckMapper");
const AdminBypassService_1 = require("../../Services/AdminBypassService");
const Logger_1 = require("../../Services/Logger");
class CreateDeckCommandHandler {
constructor(deckRepo, userRepo, orgRepo) {
this.deckRepo = deckRepo;
this.userRepo = userRepo;
this.orgRepo = orgRepo;
}
async execute(cmd) {
try {
// 1. Get user details
const user = await this.userRepo.findById(cmd.userid);
if (!user) {
throw new Error('User not found');
}
// 2. ADMIN BYPASS - Skip all restrictions
if (AdminBypassService_1.AdminBypassService.shouldBypassRestrictions(user.state)) {
AdminBypassService_1.AdminBypassService.logAdminBypass('CREATE_DECK_BYPASS', user.id, 'new-deck', {
deckName: cmd.name,
deckType: cmd.type,
cardCount: cmd.cards.length,
ctype: cmd.ctype
});
return this.createDeck(cmd);
}
// 3. Check deck count limits for regular users
const userDeckCount = await this.deckRepo.countActiveByUserId(cmd.userid);
const maxDecks = user.state === UserAggregate_1.UserState.VERIFIED_PREMIUM ? 12 : 8;
if (userDeckCount >= maxDecks) {
throw new Error(`Deck limit exceeded. Maximum ${maxDecks} decks allowed for your account type.`);
}
// 4. Organizational deck restrictions
if (cmd.ctype === DeckAggregate_1.CType.ORGANIZATION) {
// Only premium users can create organizational decks
if (user.state !== UserAggregate_1.UserState.VERIFIED_PREMIUM) {
throw new Error('Only premium users can create organizational decks.');
}
// User must belong to an organization
if (!user.orgid) {
throw new Error('You must be a member of an organization to create organizational decks.');
}
// Check organization limits
const org = await this.orgRepo.findById(user.orgid);
if (!org) {
throw new Error('Organization not found.');
}
if (org.maxOrganizationalDecks === null) {
throw new Error('Organization deck limit not configured. Contact administrator.');
}
const userOrgDeckCount = await this.deckRepo.countOrganizationalByUserId(cmd.userid);
if (userOrgDeckCount >= org.maxOrganizationalDecks) {
throw new Error(`Organization deck limit exceeded. Maximum ${org.maxOrganizationalDecks} organizational decks allowed.`);
}
}
// 5. Create deck with restrictions passed
return this.createDeck(cmd);
}
catch (error) {
if (error instanceof Error) {
throw error; // Re-throw known errors with original message
}
throw new Error('Failed to create deck');
}
}
/**
* Private method to create deck after all validations
*/
async createDeck(cmd) {
const deck = new DeckAggregate_1.DeckAggregate();
deck.name = cmd.name;
deck.type = cmd.type;
deck.userid = cmd.userid;
deck.cards = cmd.cards;
deck.ctype = cmd.ctype ?? DeckAggregate_1.CType.PUBLIC;
deck.state = DeckAggregate_1.State.ACTIVE;
// Set organization reference for organizational decks
if (cmd.ctype === DeckAggregate_1.CType.ORGANIZATION) {
const user = await this.userRepo.findById(cmd.userid);
if (user?.orgid) {
const org = await this.orgRepo.findById(user.orgid);
if (org) {
deck.organization = org;
}
}
}
const created = await this.deckRepo.create(deck);
(0, Logger_1.logRequest)('Deck created successfully', undefined, undefined, {
deckId: created.id,
userId: cmd.userid,
deckName: cmd.name,
deckType: cmd.type,
ctype: cmd.ctype,
cardCount: cmd.cards.length
});
return DeckMapper_1.DeckMapper.toShortDto(created);
}
}
exports.CreateDeckCommandHandler = CreateDeckCommandHandler;
//# sourceMappingURL=CreateDeckCommandHandler.js.map
@@ -0,0 +1 @@
{"version":3,"file":"CreateDeckCommandHandler.js","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/CreateDeckCommandHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
export interface DeleteDeckCommand {
id: string;
soft?: boolean;
}
//# sourceMappingURL=DeleteDeckCommand.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"DeleteDeckCommand.d.ts","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/DeleteDeckCommand.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB"}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=DeleteDeckCommand.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DeleteDeckCommand.js","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/DeleteDeckCommand.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
import { IDeckRepository } from '../../../Domain/IRepository/IDeckRepository';
import { DeleteDeckCommand } from './DeleteDeckCommand';
export declare class DeleteDeckCommandHandler {
private readonly deckRepo;
constructor(deckRepo: IDeckRepository);
execute(cmd: DeleteDeckCommand): Promise<boolean>;
}
//# sourceMappingURL=DeleteDeckCommandHandler.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"DeleteDeckCommandHandler.d.ts","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/DeleteDeckCommandHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,qBAAa,wBAAwB;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,eAAe;IAEhD,OAAO,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;CAQxD"}
@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeleteDeckCommandHandler = void 0;
class DeleteDeckCommandHandler {
constructor(deckRepo) {
this.deckRepo = deckRepo;
}
async execute(cmd) {
if (cmd.soft) {
await this.deckRepo.softDelete(cmd.id);
}
else {
await this.deckRepo.delete(cmd.id);
}
return true;
}
}
exports.DeleteDeckCommandHandler = DeleteDeckCommandHandler;
//# sourceMappingURL=DeleteDeckCommandHandler.js.map
@@ -0,0 +1 @@
{"version":3,"file":"DeleteDeckCommandHandler.js","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/DeleteDeckCommandHandler.ts"],"names":[],"mappings":";;;AAGA,MAAa,wBAAwB;IACnC,YAA6B,QAAyB;QAAzB,aAAQ,GAAR,QAAQ,CAAiB;IAAG,CAAC;IAE1D,KAAK,CAAC,OAAO,CAAC,GAAsB;QAClC,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAXD,4DAWC"}
@@ -0,0 +1,10 @@
export interface UpdateDeckCommand {
id: string;
name?: string;
type?: number;
userid?: string;
cards?: any[];
ctype?: number;
state?: number;
}
//# sourceMappingURL=UpdateDeckCommand.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"UpdateDeckCommand.d.ts","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/UpdateDeckCommand.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=UpdateDeckCommand.js.map
@@ -0,0 +1 @@
{"version":3,"file":"UpdateDeckCommand.js","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/UpdateDeckCommand.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
import { IDeckRepository } from '../../../Domain/IRepository/IDeckRepository';
import { UpdateDeckCommand } from './UpdateDeckCommand';
import { ShortDeckDto } from '../../DTOs/DeckDto';
export declare class UpdateDeckCommandHandler {
private readonly deckRepo;
constructor(deckRepo: IDeckRepository);
execute(cmd: UpdateDeckCommand): Promise<ShortDeckDto | null>;
}
//# sourceMappingURL=UpdateDeckCommandHandler.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"UpdateDeckCommandHandler.d.ts","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/UpdateDeckCommandHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,qBAAa,wBAAwB;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,eAAe;IAEhD,OAAO,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;CAKpE"}
@@ -0,0 +1,17 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UpdateDeckCommandHandler = void 0;
const DeckMapper_1 = require("../../DTOs/Mappers/DeckMapper");
class UpdateDeckCommandHandler {
constructor(deckRepo) {
this.deckRepo = deckRepo;
}
async execute(cmd) {
const updated = await this.deckRepo.update(cmd.id, { ...cmd });
if (!updated)
return null;
return DeckMapper_1.DeckMapper.toShortDto(updated);
}
}
exports.UpdateDeckCommandHandler = UpdateDeckCommandHandler;
//# sourceMappingURL=UpdateDeckCommandHandler.js.map
@@ -0,0 +1 @@
{"version":3,"file":"UpdateDeckCommandHandler.js","sourceRoot":"","sources":["../../../../src/Application/Deck/commands/UpdateDeckCommandHandler.ts"],"names":[],"mappings":";;;AAGA,8DAA2D;AAE3D,MAAa,wBAAwB;IACnC,YAA6B,QAAyB;QAAzB,aAAQ,GAAR,QAAQ,CAAiB;IAAG,CAAC;IAE1D,KAAK,CAAC,OAAO,CAAC,GAAsB;QAClC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,OAAO,uBAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;CACF;AARD,4DAQC"}