/** * Repository Interface - Generic repository contract * * @module @erp-suite/core/interfaces */ import { ServiceContext, QueryOptions } from './base-service.interface'; import { PaginatedResult, PaginationOptions } from '../types/pagination.types'; /** * Generic repository interface for data access * * This interface defines the contract for repository implementations, * supporting both TypeORM and raw SQL approaches. * * @template T - Entity type * * @example * ```typescript * export class PartnerRepository implements IRepository { * async findById(ctx: ServiceContext, id: string): Promise { * // Implementation * } * } * ``` */ export interface IRepository { /** * Find entity by ID */ findById( ctx: ServiceContext, id: string, options?: QueryOptions, ): Promise; /** * Find one entity by criteria */ findOne( ctx: ServiceContext, criteria: Partial, options?: QueryOptions, ): Promise; /** * Find all entities with pagination */ findAll( ctx: ServiceContext, filters?: PaginationOptions & Partial, options?: QueryOptions, ): Promise>; /** * Find multiple entities by criteria */ findMany( ctx: ServiceContext, criteria: Partial, options?: QueryOptions, ): Promise; /** * Create new entity */ create(ctx: ServiceContext, data: Partial): Promise; /** * Create multiple entities */ createMany(ctx: ServiceContext, data: Partial[]): Promise; /** * Update existing entity */ update(ctx: ServiceContext, id: string, data: Partial): Promise; /** * Update multiple entities by criteria */ updateMany( ctx: ServiceContext, criteria: Partial, data: Partial, ): Promise; /** * Soft delete entity */ softDelete(ctx: ServiceContext, id: string): Promise; /** * Hard delete entity */ hardDelete(ctx: ServiceContext, id: string): Promise; /** * Delete multiple entities by criteria */ deleteMany(ctx: ServiceContext, criteria: Partial): Promise; /** * Count entities matching criteria */ count( ctx: ServiceContext, criteria?: Partial, options?: QueryOptions, ): Promise; /** * Check if entity exists */ exists( ctx: ServiceContext, id: string, options?: QueryOptions, ): Promise; /** * Execute raw SQL query */ query( ctx: ServiceContext, sql: string, params: unknown[], ): Promise; /** * Execute raw SQL query and return first result */ queryOne( ctx: ServiceContext, sql: string, params: unknown[], ): Promise; } /** * Read-only repository interface * * For repositories that only need read operations (e.g., views, reports) * * @template T - Entity type */ export interface IReadOnlyRepository { findById( ctx: ServiceContext, id: string, options?: QueryOptions, ): Promise; findOne( ctx: ServiceContext, criteria: Partial, options?: QueryOptions, ): Promise; findAll( ctx: ServiceContext, filters?: PaginationOptions & Partial, options?: QueryOptions, ): Promise>; findMany( ctx: ServiceContext, criteria: Partial, options?: QueryOptions, ): Promise; count( ctx: ServiceContext, criteria?: Partial, options?: QueryOptions, ): Promise; exists( ctx: ServiceContext, id: string, options?: QueryOptions, ): Promise; } /** * Write-only repository interface * * For repositories that only need write operations (e.g., event stores) * * @template T - Entity type */ export interface IWriteOnlyRepository { create(ctx: ServiceContext, data: Partial): Promise; createMany(ctx: ServiceContext, data: Partial[]): Promise; update(ctx: ServiceContext, id: string, data: Partial): Promise; updateMany( ctx: ServiceContext, criteria: Partial, data: Partial, ): Promise; softDelete(ctx: ServiceContext, id: string): Promise; hardDelete(ctx: ServiceContext, id: string): Promise; deleteMany(ctx: ServiceContext, criteria: Partial): Promise; } // ============================================================================ // Domain-Specific Repository Interfaces // ============================================================================ /** * User repository interface * * Extends the base repository with user-specific operations * * @example * ```typescript * export class UserRepository implements IUserRepository { * async findByEmail(ctx: ServiceContext, email: string): Promise { * return this.findOne(ctx, { email }); * } * } * ``` */ export interface IUserRepository extends IRepository { /** * Find user by email address */ findByEmail(ctx: ServiceContext, email: string): Promise; /** * Find users by tenant ID */ findByTenantId(ctx: ServiceContext, tenantId: string): Promise; /** * Find active users only */ findActiveUsers( ctx: ServiceContext, filters?: PaginationOptions, ): Promise>; /** * Update last login timestamp */ updateLastLogin(ctx: ServiceContext, userId: string): Promise; /** * Update user password hash */ updatePasswordHash( ctx: ServiceContext, userId: string, passwordHash: string, ): Promise; } /** * Tenant repository interface * * Extends the base repository with tenant-specific operations * * @example * ```typescript * export class TenantRepository implements ITenantRepository { * async findBySlug(ctx: ServiceContext, slug: string): Promise { * return this.findOne(ctx, { slug }); * } * } * ``` */ export interface ITenantRepository extends IRepository { /** * Find tenant by unique slug */ findBySlug(ctx: ServiceContext, slug: string): Promise; /** * Find tenant by domain */ findByDomain(ctx: ServiceContext, domain: string): Promise; /** * Find active tenants only */ findActiveTenants( ctx: ServiceContext, filters?: PaginationOptions, ): Promise>; /** * Update tenant settings */ updateSettings( ctx: ServiceContext, tenantId: string, settings: Record, ): Promise; } /** * Audit log entry type */ export interface AuditLogEntry { id?: string; tenantId: string; userId: string; action: string; entityType: string; entityId: string; changes?: Record; metadata?: Record; ipAddress?: string; userAgent?: string; timestamp: Date; } /** * Audit repository interface * * Specialized repository for audit logging and compliance * * @example * ```typescript * export class AuditRepository implements IAuditRepository { * async logAction(ctx: ServiceContext, entry: AuditLogEntry): Promise { * await this.create(ctx, entry); * } * } * ``` */ export interface IAuditRepository { /** * Log an audit entry */ logAction(ctx: ServiceContext, entry: AuditLogEntry): Promise; /** * Find audit logs by entity */ findByEntity( ctx: ServiceContext, entityType: string, entityId: string, filters?: PaginationOptions, ): Promise>; /** * Find audit logs by user */ findByUser( ctx: ServiceContext, userId: string, filters?: PaginationOptions, ): Promise>; /** * Find audit logs by tenant */ findByTenant( ctx: ServiceContext, tenantId: string, filters?: PaginationOptions, ): Promise>; /** * Find audit logs by action type */ findByAction( ctx: ServiceContext, action: string, filters?: PaginationOptions, ): Promise>; /** * Find audit logs within date range */ findByDateRange( ctx: ServiceContext, startDate: Date, endDate: Date, filters?: PaginationOptions, ): Promise>; } /** * Configuration entry type */ export interface ConfigEntry { id?: string; tenantId?: string; key: string; value: unknown; type: 'string' | 'number' | 'boolean' | 'json'; scope: 'system' | 'tenant' | 'module'; module?: string; description?: string; isEncrypted?: boolean; updatedAt?: Date; } /** * Config repository interface * * Specialized repository for application configuration * * @example * ```typescript * export class ConfigRepository implements IConfigRepository { * async getValue(ctx: ServiceContext, key: string): Promise { * const entry = await this.findByKey(ctx, key); * return entry ? (entry.value as T) : null; * } * } * ``` */ export interface IConfigRepository { /** * Find configuration by key */ findByKey( ctx: ServiceContext, key: string, scope?: 'system' | 'tenant' | 'module', ): Promise; /** * Get typed configuration value */ getValue( ctx: ServiceContext, key: string, defaultValue?: T, ): Promise; /** * Set configuration value */ setValue(ctx: ServiceContext, key: string, value: T): Promise; /** * Find all configurations by scope */ findByScope( ctx: ServiceContext, scope: 'system' | 'tenant' | 'module', filters?: PaginationOptions, ): Promise>; /** * Find all configurations by module */ findByModule( ctx: ServiceContext, module: string, filters?: PaginationOptions, ): Promise>; /** * Find all tenant-specific configurations */ findByTenant( ctx: ServiceContext, tenantId: string, filters?: PaginationOptions, ): Promise>; /** * Delete configuration by key */ deleteByKey(ctx: ServiceContext, key: string): Promise; /** * Bulk update configurations */ bulkUpdate(ctx: ServiceContext, configs: ConfigEntry[]): Promise; }