Backend Complete: Interface Refactoring & Service Container Enhancements
Repository Interface Optimization: - Created IBaseRepository.ts and IPaginatedRepository.ts - Refactored all 7 repository interfaces to extend base interfaces - Eliminated ~200 lines of redundant code (70% reduction) - Improved type safety and maintainability Dependency Injection Improvements: - Added EmailService and GameTokenService to DIContainer - Updated CreateUserCommandHandler constructor for DI - Updated RequestPasswordResetCommandHandler constructor for DI - Enhanced testability and service consistency Environment Configuration: - Created comprehensive .env.example with 40+ variables - Organized into 12 logical sections (Database, Security, Email, etc.) - Added security guidelines and best practices - Documented all backend environment requirements Documentation: - Added comprehensive codebase review - Created refactoring summary report - Added frontend implementation guide Impact: Improved code quality, reduced maintenance overhead, enhanced developer experience
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
export interface CreateChatDto {
|
||||
users: string[];
|
||||
messages: import('../../Domain/Chat/ChatAggregate').Message[];
|
||||
state?: number;
|
||||
}
|
||||
|
||||
export interface UpdateChatDto {
|
||||
id: string;
|
||||
users?: string[];
|
||||
messages?: import('../../Domain/Chat/ChatAggregate').Message[];
|
||||
state?: number;
|
||||
}
|
||||
|
||||
export interface ShortChatDto {
|
||||
id: string;
|
||||
userCount: number;
|
||||
state: number;
|
||||
}
|
||||
|
||||
export interface DetailChatDto {
|
||||
id: string;
|
||||
users: string[];
|
||||
messages: import('../../Domain/Chat/ChatAggregate').Message[];
|
||||
updateDate: Date;
|
||||
state: number;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { ContactType } from '../../Domain/Contact/ContactAggregate';
|
||||
|
||||
export interface CreateContactDto {
|
||||
name: string;
|
||||
email: string;
|
||||
userid?: string;
|
||||
type: ContactType;
|
||||
txt: string;
|
||||
}
|
||||
|
||||
export interface UpdateContactDto {
|
||||
id: string;
|
||||
adminResponse?: string;
|
||||
state?: number;
|
||||
respondedBy?: string;
|
||||
}
|
||||
|
||||
export interface ShortContactDto {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
type: ContactType;
|
||||
createDate: Date;
|
||||
state: number;
|
||||
}
|
||||
|
||||
export interface DetailContactDto {
|
||||
id: string;
|
||||
name: string;
|
||||
email: string;
|
||||
userid: string | null;
|
||||
type: ContactType;
|
||||
txt: string;
|
||||
state: number;
|
||||
createDate: Date;
|
||||
updateDate: Date;
|
||||
adminResponse: string | null;
|
||||
responseDate: Date | null;
|
||||
respondedBy: string | null;
|
||||
}
|
||||
|
||||
export interface ContactPageDto {
|
||||
contacts: ShortContactDto[];
|
||||
totalCount: number;
|
||||
from: number;
|
||||
to: number;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
export interface CreateDeckDto {
|
||||
name: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface UpdateDeckDto {
|
||||
id: string;
|
||||
name?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface ShortDeckDto {
|
||||
id: string;
|
||||
name: string;
|
||||
type: number;
|
||||
playedNumber: number;
|
||||
ctype: number;
|
||||
}
|
||||
|
||||
export interface DetailDeckDto {
|
||||
id: string;
|
||||
name: string;
|
||||
type: number;
|
||||
userid: string;
|
||||
creationdate: Date;
|
||||
cards: any[];
|
||||
playedNumber: number;
|
||||
ctype: number;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import * as DeckAggregate from "../../Domain/Deck/DeckAggregate";
|
||||
|
||||
export interface GameStartDto {
|
||||
gameid: string;
|
||||
maxplayers: number;
|
||||
logintype: number;
|
||||
gamecode: string;
|
||||
deck: gamedeck[];
|
||||
}
|
||||
|
||||
enum decktype {
|
||||
JOCKER = 0,
|
||||
LUCK = 1,
|
||||
QUEST = 2
|
||||
}
|
||||
|
||||
export interface cards {
|
||||
cardid: string;
|
||||
question?: string;
|
||||
answer?: string;
|
||||
consequence?: DeckAggregate.Consequence | null;
|
||||
played?: boolean;
|
||||
playerid?: string;
|
||||
}
|
||||
|
||||
export interface gamedeck {
|
||||
deckid: string;
|
||||
decktype: decktype;
|
||||
cards: cards[];
|
||||
}
|
||||
|
||||
export interface GameDataDto {
|
||||
id: string;
|
||||
gamecode: string;
|
||||
maxplayers: number;
|
||||
logintype: number;
|
||||
gamedecks: gamedeck[];
|
||||
players: string[];
|
||||
started: boolean;
|
||||
finished: boolean;
|
||||
winner?: string;
|
||||
currentplayer?: string;
|
||||
createdate: Date;
|
||||
startdate?: Date;
|
||||
enddate?: Date;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
export abstract class BaseMapper<TEntity, TShortDto, TDetailDto> {
|
||||
abstract toShortDto(entity: TEntity): TShortDto;
|
||||
abstract toDetailDto(entity: TEntity): TDetailDto;
|
||||
|
||||
toShortDtoList(entities: TEntity[]): TShortDto[] {
|
||||
return entities.map(entity => this.toShortDto(entity));
|
||||
}
|
||||
|
||||
toDetailDtoList(entities: TEntity[]): TDetailDto[] {
|
||||
return entities.map(entity => this.toDetailDto(entity));
|
||||
}
|
||||
|
||||
static toShortDtoListStatic<T, TDto>(
|
||||
entities: T[],
|
||||
mapperFn: (entity: T) => TDto
|
||||
): TDto[] {
|
||||
return entities.map(mapperFn);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { ChatAggregate } from '../../../Domain/Chat/ChatAggregate';
|
||||
import { ShortChatDto, DetailChatDto } from '../ChatDto';
|
||||
|
||||
export class ChatMapper {
|
||||
static toShortDto(chat: ChatAggregate): ShortChatDto {
|
||||
return {
|
||||
id: chat.id,
|
||||
userCount: chat.users?.length ?? 0,
|
||||
state: chat.state,
|
||||
};
|
||||
}
|
||||
|
||||
static toDetailDto(chat: ChatAggregate): DetailChatDto {
|
||||
return {
|
||||
id: chat.id,
|
||||
users: chat.users ?? [],
|
||||
messages: chat.messages,
|
||||
updateDate: chat.updateDate,
|
||||
state: chat.state,
|
||||
};
|
||||
}
|
||||
|
||||
static toShortDtoList(chats: ChatAggregate[]): ShortChatDto[] {
|
||||
return chats.map(this.toShortDto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { ContactAggregate } from '../../../Domain/Contact/ContactAggregate';
|
||||
import { CreateContactDto, UpdateContactDto, ShortContactDto, DetailContactDto } from '../ContactDto';
|
||||
|
||||
export class ContactMapper {
|
||||
static toShortDto(contact: ContactAggregate): ShortContactDto {
|
||||
return {
|
||||
id: contact.id,
|
||||
name: contact.name,
|
||||
email: contact.email,
|
||||
type: contact.type,
|
||||
createDate: contact.createDate,
|
||||
state: contact.state,
|
||||
};
|
||||
}
|
||||
|
||||
static toDetailDto(contact: ContactAggregate): DetailContactDto {
|
||||
return {
|
||||
id: contact.id,
|
||||
name: contact.name,
|
||||
email: contact.email,
|
||||
userid: contact.userid,
|
||||
type: contact.type,
|
||||
txt: contact.txt,
|
||||
state: contact.state,
|
||||
createDate: contact.createDate,
|
||||
updateDate: contact.updateDate,
|
||||
adminResponse: contact.adminResponse,
|
||||
responseDate: contact.responseDate,
|
||||
respondedBy: contact.respondedBy,
|
||||
};
|
||||
}
|
||||
|
||||
static toShortDtoList(contacts: ContactAggregate[]): ShortContactDto[] {
|
||||
return contacts.map(this.toShortDto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { DeckAggregate } from '../../../Domain/Deck/DeckAggregate';
|
||||
import { CreateDeckDto, UpdateDeckDto, ShortDeckDto, DetailDeckDto } from '../DeckDto';
|
||||
|
||||
export class DeckMapper {
|
||||
static toShortDto(deck: DeckAggregate): ShortDeckDto {
|
||||
return {
|
||||
id: deck.id,
|
||||
name: deck.name,
|
||||
type: deck.type,
|
||||
playedNumber: deck.playedNumber,
|
||||
ctype: deck.ctype,
|
||||
};
|
||||
}
|
||||
|
||||
static toDetailDto(deck: DeckAggregate): DetailDeckDto {
|
||||
return {
|
||||
id: deck.id,
|
||||
name: deck.name,
|
||||
type: deck.type,
|
||||
userid: deck.userid,
|
||||
creationdate: deck.creationdate,
|
||||
cards: deck.cards,
|
||||
playedNumber: deck.playedNumber,
|
||||
ctype: deck.ctype,
|
||||
};
|
||||
}
|
||||
|
||||
static toShortDtoList(decks: DeckAggregate[]): ShortDeckDto[] {
|
||||
return decks.map(this.toShortDto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { OrganizationAggregate } from '../../../Domain/Organization/OrganizationAggregate';
|
||||
import { CreateOrganizationDto, UpdateOrganizationDto, ShortOrganizationDto, DetailOrganizationDto } from '../OrganizationDto';
|
||||
|
||||
export class OrganizationMapper {
|
||||
static toShortDto(org: OrganizationAggregate): ShortOrganizationDto {
|
||||
return {
|
||||
id: org.id,
|
||||
name: org.name,
|
||||
state: org.state,
|
||||
userinorg: org.userinorg,
|
||||
maxOrganizationalDecks: org.maxOrganizationalDecks,
|
||||
};
|
||||
}
|
||||
|
||||
static toDetailDto(org: OrganizationAggregate): DetailOrganizationDto {
|
||||
return {
|
||||
id: org.id,
|
||||
name: org.name,
|
||||
contactfname: org.contactfname,
|
||||
contactlname: org.contactlname,
|
||||
contactphone: org.contactphone,
|
||||
contactemail: org.contactemail,
|
||||
state: org.state,
|
||||
regdate: org.regdate,
|
||||
updatedate: org.updatedate,
|
||||
url: org.url,
|
||||
userinorg: org.userinorg,
|
||||
maxOrganizationalDecks: org.maxOrganizationalDecks,
|
||||
users: org.users?.map(u => u.id) ?? [],
|
||||
};
|
||||
}
|
||||
|
||||
static toShortDtoList(orgs: OrganizationAggregate[]): ShortOrganizationDto[] {
|
||||
return orgs.map(this.toShortDto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { UserAggregate, UserState } from '../../../Domain/User/UserAggregate';
|
||||
import { CreateUserDto, UpdateUserDto, ShortUserDto, DetailUserDto } from '../UserDto';
|
||||
import { BaseMapper } from './BaseMapper';
|
||||
|
||||
export class UserMapper {
|
||||
static toShortDto(user: UserAggregate): ShortUserDto {
|
||||
return {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
state: user.state,
|
||||
authLevel: (user.state === UserState.ADMIN ? 1 : 0) as 0 | 1,
|
||||
};
|
||||
}
|
||||
|
||||
static toDetailDto(user: UserAggregate): DetailUserDto {
|
||||
return {
|
||||
id: user.id,
|
||||
orgid: user.orgid,
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
fname: user.fname,
|
||||
lname: user.lname,
|
||||
code: user.token,
|
||||
phone: user.phone,
|
||||
state: user.state,
|
||||
};
|
||||
}
|
||||
|
||||
static toShortDtoList(users: UserAggregate[]): ShortUserDto[] {
|
||||
return BaseMapper.toShortDtoListStatic(users, UserMapper.toShortDto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
export interface CreateOrganizationDto {
|
||||
name: string;
|
||||
description?: string;
|
||||
maxOrganizationalDecks?: number | null;
|
||||
}
|
||||
|
||||
export interface UpdateOrganizationDto {
|
||||
id: string;
|
||||
name?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface ShortOrganizationDto {
|
||||
id: string;
|
||||
name: string;
|
||||
state: number;
|
||||
userinorg: number;
|
||||
maxOrganizationalDecks?: number | null;
|
||||
}
|
||||
|
||||
export interface DetailOrganizationDto {
|
||||
id: string;
|
||||
name: string;
|
||||
contactfname: string;
|
||||
contactlname: string;
|
||||
contactphone: string;
|
||||
contactemail: string;
|
||||
state: number;
|
||||
regdate: Date;
|
||||
updatedate: Date;
|
||||
url: string | null;
|
||||
userinorg: number;
|
||||
maxOrganizationalDecks: number | null;
|
||||
users: string[];
|
||||
}
|
||||
|
||||
export interface OrganizationLoginUrlDto {
|
||||
organizationId: string;
|
||||
organizationName: string;
|
||||
loginUrl: string;
|
||||
}
|
||||
|
||||
export interface OrganizationAuthCallbackDto {
|
||||
organizationId: string;
|
||||
userId: string;
|
||||
status: 'ok' | 'not_ok';
|
||||
authToken?: string;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface SearchQuery {
|
||||
query: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}
|
||||
|
||||
export interface SearchResult<T> {
|
||||
results: T[];
|
||||
totalCount: number;
|
||||
hasMore: boolean;
|
||||
searchQuery: string;
|
||||
searchType: 'users' | 'organizations' | 'decks';
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
export interface CreateUserDto {
|
||||
username: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface UpdateUserDto {
|
||||
id: string;
|
||||
username?: string;
|
||||
email?: string;
|
||||
}
|
||||
|
||||
export interface ShortUserDto {
|
||||
id: string;
|
||||
username: string;
|
||||
state: number;
|
||||
authLevel: 0 | 1;
|
||||
}
|
||||
|
||||
export interface DetailUserDto {
|
||||
id: string;
|
||||
orgid: string | null;
|
||||
username: string;
|
||||
email: string;
|
||||
fname: string;
|
||||
lname: string;
|
||||
code: string | null;
|
||||
phone: string | null;
|
||||
state: number;
|
||||
}
|
||||
Reference in New Issue
Block a user