/** * @horux/database * * Database package for Horux Strategy - CFO Digital para Empresas Mexicanas * * Provides: * - PostgreSQL connection pool with multi-tenant support * - Tenant schema management (create, delete, suspend) * - Migration utilities * - Type definitions for database entities */ // Import types used in this file import type { TenantStatus, TenantSettings } from './tenant.js'; // Connection management export { DatabaseConnection, TenantDatabase, getDatabase, createDatabase, createTenantDatabase, type DatabaseConfig, type TenantContext, type QueryOptions, type Pool, type PoolClient, type QueryResult, type QueryResultRow, } from './connection.js'; // Tenant management export { createTenantSchema, deleteTenantSchema, suspendTenant, reactivateTenant, getTenant, getTenantBySlug, listTenants, updateTenantSettings, validateTenantAccess, getSchemaName, createTenantContext, type CreateTenantOptions, type TenantSettings, type TenantInfo, type TenantStatus, } from './tenant.js'; // Migration utilities (for programmatic use) export { runMigrations, printStatus as getMigrationStatus, rollbackLast as rollbackMigration, ensureDatabase, loadMigrationFiles, getExecutedMigrations, ensureMigrationsTable, type MigrationFile, type MigrationRecord, } from './migrate.js'; // Seed data exports export { PLANS, SYSTEM_SETTINGS, } from './seed.js'; // ============================================================================ // Type Definitions for Database Entities // ============================================================================ // User roles export type UserRole = 'super_admin' | 'owner' | 'admin' | 'manager' | 'analyst' | 'viewer'; // Subscription status export type SubscriptionStatus = 'active' | 'trial' | 'past_due' | 'cancelled' | 'suspended' | 'expired'; // Job status export type JobStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'; // Transaction types export type TransactionType = 'income' | 'expense' | 'transfer' | 'adjustment'; export type TransactionStatus = 'pending' | 'confirmed' | 'reconciled' | 'voided'; // CFDI types export type CfdiStatus = 'active' | 'cancelled' | 'pending_cancellation'; export type CfdiType = 'I' | 'E' | 'T' | 'N' | 'P'; // Ingreso, Egreso, Traslado, Nomina, Pago // Contact types export type ContactType = 'customer' | 'supplier' | 'both' | 'employee'; // Category types export type CategoryType = 'income' | 'expense' | 'cost' | 'other'; // Account types export type AccountType = 'asset' | 'liability' | 'equity' | 'revenue' | 'expense'; // Alert severity export type AlertSeverity = 'info' | 'warning' | 'critical'; // Report status export type ReportStatus = 'draft' | 'generating' | 'completed' | 'failed' | 'archived'; // ============================================================================ // Entity Interfaces // ============================================================================ /** * Plan entity */ export interface Plan { id: string; name: string; description: string | null; priceMonthly: number; priceYearly: number; maxUsers: number; maxCfdisMonthly: number; maxStorageMb: number; maxApiCallsDaily: number; maxReportsMonthly: number; features: Record; hasSatSync: boolean; hasBankSync: boolean; hasAiInsights: boolean; hasCustomReports: boolean; hasApiAccess: boolean; hasWhiteLabel: boolean; hasPrioritySupport: boolean; hasDedicatedAccountManager: boolean; dataRetentionMonths: number; displayOrder: number; isActive: boolean; isPopular: boolean; createdAt: Date; updatedAt: Date; } /** * User entity */ export interface User { id: string; email: string; firstName: string | null; lastName: string | null; phone: string | null; avatarUrl: string | null; defaultRole: UserRole; isActive: boolean; isEmailVerified: boolean; emailVerifiedAt: Date | null; twoFactorEnabled: boolean; preferences: Record; timezone: string; locale: string; lastLoginAt: Date | null; lastLoginIp: string | null; createdAt: Date; updatedAt: Date; } /** * Tenant entity */ export interface Tenant { id: string; name: string; slug: string; schemaName: string; rfc: string | null; razonSocial: string | null; email: string | null; phone: string | null; ownerId: string; planId: string; status: TenantStatus; settings: TenantSettings; createdAt: Date; updatedAt: Date; } /** * Subscription entity */ export interface Subscription { id: string; tenantId: string; planId: string; status: SubscriptionStatus; billingCycle: 'monthly' | 'yearly'; trialEndsAt: Date | null; currentPeriodStart: Date; currentPeriodEnd: Date; cancelledAt: Date | null; cancelAtPeriodEnd: boolean; paymentProcessor: string | null; externalSubscriptionId: string | null; externalCustomerId: string | null; priceCents: number; currency: string; usageCfdisCurrent: number; usageStorageMbCurrent: number; usageApiCallsCurrent: number; usageResetAt: Date | null; createdAt: Date; updatedAt: Date; } /** * User session entity */ export interface UserSession { id: string; userId: string; tenantId: string | null; userAgent: string | null; ipAddress: string | null; deviceType: string | null; deviceName: string | null; locationCity: string | null; locationCountry: string | null; isActive: boolean; expiresAt: Date; refreshExpiresAt: Date | null; lastActivityAt: Date; createdAt: Date; revokedAt: Date | null; } /** * Background job entity */ export interface BackgroundJob { id: string; tenantId: string | null; userId: string | null; jobType: string; jobName: string | null; queue: string; priority: number; payload: Record; status: JobStatus; progress: number; result: Record | null; errorMessage: string | null; errorStack: string | null; attempts: number; maxAttempts: number; scheduledAt: Date; startedAt: Date | null; completedAt: Date | null; timeoutSeconds: number; createdAt: Date; updatedAt: Date; } /** * API key entity */ export interface ApiKey { id: string; tenantId: string; name: string; description: string | null; keyPrefix: string; scopes: string[]; allowedIps: string[] | null; allowedOrigins: string[] | null; rateLimitPerMinute: number; rateLimitPerDay: number; lastUsedAt: Date | null; usageCount: number; isActive: boolean; expiresAt: Date | null; createdBy: string | null; createdAt: Date; updatedAt: Date; revokedAt: Date | null; revokedBy: string | null; } /** * Audit log entry entity */ export interface AuditLogEntry { id: string; tenantId: string | null; userId: string | null; action: string; entityType: string; entityId: string | null; oldValues: Record | null; newValues: Record | null; details: Record | null; ipAddress: string | null; userAgent: string | null; requestId: string | null; createdAt: Date; } // ============================================================================ // Tenant Schema Entity Interfaces // ============================================================================ /** * SAT credentials entity (tenant schema) */ export interface SatCredentials { id: string; rfc: string; cerSerialNumber: string | null; cerIssuedAt: Date | null; cerExpiresAt: Date | null; cerIssuer: string | null; isActive: boolean; isValid: boolean; lastValidatedAt: Date | null; validationError: string | null; syncEnabled: boolean; syncFrequencyHours: number; lastSyncAt: Date | null; lastSyncStatus: string | null; lastSyncError: string | null; createdBy: string; createdAt: Date; updatedAt: Date; } /** * CFDI entity (tenant schema) */ export interface Cfdi { id: string; uuidFiscal: string; serie: string | null; folio: string | null; tipoComprobante: CfdiType; status: CfdiStatus; fechaEmision: Date; fechaTimbrado: Date | null; fechaCancelacion: Date | null; emisorRfc: string; emisorNombre: string; emisorRegimenFiscal: string; receptorRfc: string; receptorNombre: string; receptorRegimenFiscal: string | null; receptorDomicilioFiscal: string | null; receptorUsoCfdi: string; subtotal: number; descuento: number; total: number; totalImpuestosTrasladados: number; totalImpuestosRetenidos: number; iva16: number; iva8: number; iva0: number; ivaExento: number; isrRetenido: number; ivaRetenido: number; moneda: string; tipoCambio: number; formaPago: string | null; metodoPago: string | null; condicionesPago: string | null; cfdiRelacionados: Record | null; tipoRelacion: string | null; conceptos: Record[]; isEmitted: boolean; categoryId: string | null; contactId: string | null; isReconciled: boolean; reconciledAt: Date | null; reconciledBy: string | null; aiCategorySuggestion: string | null; aiConfidenceScore: number | null; source: string; createdAt: Date; updatedAt: Date; } /** * Transaction entity (tenant schema) */ export interface Transaction { id: string; type: TransactionType; status: TransactionStatus; amount: number; currency: string; exchangeRate: number; amountMxn: number; transactionDate: Date; valueDate: Date | null; recordedAt: Date; description: string | null; reference: string | null; notes: string | null; categoryId: string | null; accountId: string | null; contactId: string | null; cfdiId: string | null; bankTransactionId: string | null; bankAccountId: string | null; bankDescription: string | null; isRecurring: boolean; recurringPattern: Record | null; parentTransactionId: string | null; attachments: Record[] | null; tags: string[] | null; isReconciled: boolean; reconciledAt: Date | null; reconciledBy: string | null; requiresApproval: boolean; approvedAt: Date | null; approvedBy: string | null; aiCategoryId: string | null; aiConfidence: number | null; aiNotes: string | null; createdBy: string | null; createdAt: Date; updatedAt: Date; voidedAt: Date | null; voidedBy: string | null; voidReason: string | null; } /** * Contact entity (tenant schema) */ export interface Contact { id: string; type: ContactType; name: string; tradeName: string | null; rfc: string | null; regimenFiscal: string | null; usoCfdiDefault: string | null; email: string | null; phone: string | null; mobile: string | null; website: string | null; addressStreet: string | null; addressInterior: string | null; addressExterior: string | null; addressNeighborhood: string | null; addressCity: string | null; addressMunicipality: string | null; addressState: string | null; addressZip: string | null; addressCountry: string; bankName: string | null; bankAccount: string | null; bankClabe: string | null; creditDays: number; creditLimit: number; balanceReceivable: number; balancePayable: number; category: string | null; tags: string[] | null; isActive: boolean; notes: string | null; createdBy: string | null; createdAt: Date; updatedAt: Date; } /** * Category entity (tenant schema) */ export interface Category { id: string; code: string; name: string; description: string | null; type: CategoryType; parentId: string | null; level: number; path: string | null; satKey: string | null; budgetMonthly: number | null; budgetYearly: number | null; color: string | null; icon: string | null; displayOrder: number; isActive: boolean; isSystem: boolean; createdAt: Date; updatedAt: Date; } /** * Account entity (tenant schema) */ export interface Account { id: string; code: string; name: string; description: string | null; type: AccountType; parentId: string | null; level: number; path: string | null; satCode: string | null; satNature: 'D' | 'A' | null; balanceDebit: number; balanceCredit: number; balanceCurrent: number; isActive: boolean; isSystem: boolean; allowsMovements: boolean; displayOrder: number; createdAt: Date; updatedAt: Date; } /** * Alert entity (tenant schema) */ export interface Alert { id: string; type: string; title: string; message: string; severity: AlertSeverity; entityType: string | null; entityId: string | null; thresholdType: string | null; thresholdValue: number | null; currentValue: number | null; actionUrl: string | null; actionLabel: string | null; actionData: Record | null; isRead: boolean; isDismissed: boolean; readAt: Date | null; dismissedAt: Date | null; dismissedBy: string | null; isRecurring: boolean; lastTriggeredAt: Date | null; triggerCount: number; autoResolved: boolean; resolvedAt: Date | null; resolvedBy: string | null; resolutionNotes: string | null; createdAt: Date; expiresAt: Date | null; } /** * Report entity (tenant schema) */ export interface Report { id: string; type: string; name: string; description: string | null; periodStart: Date; periodEnd: Date; comparisonPeriodStart: Date | null; comparisonPeriodEnd: Date | null; status: ReportStatus; parameters: Record | null; data: Record | null; fileUrl: string | null; fileFormat: string | null; isScheduled: boolean; scheduleCron: string | null; nextScheduledAt: Date | null; lastGeneratedAt: Date | null; isShared: boolean; sharedWith: string[] | null; shareToken: string | null; shareExpiresAt: Date | null; generatedBy: string | null; createdAt: Date; updatedAt: Date; } /** * Metric cache entry entity (tenant schema) */ export interface MetricCache { id: string; metricKey: string; periodType: 'daily' | 'weekly' | 'monthly' | 'yearly'; periodStart: Date; periodEnd: Date; dimensionType: string | null; dimensionId: string | null; valueNumeric: number | null; valueJson: Record | null; previousValue: number | null; changePercent: number | null; changeAbsolute: number | null; computedAt: Date; validUntil: Date | null; isStale: boolean; } /** * Setting entity (tenant schema) */ export interface Setting { key: string; value: string; valueType: 'string' | 'integer' | 'boolean' | 'json'; category: string; label: string | null; description: string | null; isSensitive: boolean; createdAt: Date; updatedAt: Date; } /** * Bank account entity (tenant schema) */ export interface BankAccount { id: string; bankName: string; bankCode: string | null; accountNumber: string | null; clabe: string | null; accountType: string | null; alias: string | null; currency: string; balanceAvailable: number | null; balanceCurrent: number | null; balanceUpdatedAt: Date | null; connectionProvider: string | null; connectionId: string | null; connectionStatus: string | null; lastSyncAt: Date | null; lastSyncError: string | null; accountId: string | null; isActive: boolean; createdAt: Date; updatedAt: Date; } /** * Budget item entity (tenant schema) */ export interface BudgetItem { id: string; year: number; month: number; categoryId: string | null; accountId: string | null; amountBudgeted: number; amountActual: number; amountVariance: number; notes: string | null; isLocked: boolean; createdBy: string | null; createdAt: Date; updatedAt: Date; } /** * Attachment entity (tenant schema) */ export interface Attachment { id: string; entityType: string; entityId: string; fileName: string; fileType: string | null; fileSize: number | null; fileUrl: string; storageProvider: string; storagePath: string | null; uploadedBy: string | null; createdAt: Date; }