Phase 0 - Base modules (100% copy): - shared/ (errors, middleware, services, utils, types) - auth, users, tenants (multi-tenancy) - ai, audit, notifications, mcp, payment-terminals - billing-usage, branches, companies, core Phase 1 - Modules to adapt (70-95%): - partners (for shippers/consignees) - inventory (for refacciones) - financial (for transport costing) Phase 2 - Pattern modules (50-70%): - ordenes-transporte (from sales) - gestion-flota (from products) - viajes (from projects) Phase 3 - New transport-specific modules: - tracking (GPS, events, alerts) - tarifas-transporte (pricing, surcharges) - combustible-gastos (fuel, tolls, expenses) - carta-porte (CFDI complement 3.1) Estimated token savings: ~65% (~10,675 lines) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
121 lines
3.3 KiB
TypeScript
121 lines
3.3 KiB
TypeScript
import {
|
|
Entity,
|
|
PrimaryGeneratedColumn,
|
|
Column,
|
|
CreateDateColumn,
|
|
UpdateDateColumn,
|
|
Index,
|
|
Unique,
|
|
} from 'typeorm';
|
|
|
|
export type UsageType = 'chat' | 'completion' | 'embedding' | 'image';
|
|
|
|
@Entity({ name: 'usage_logs', schema: 'ai' })
|
|
export class AIUsageLog {
|
|
@PrimaryGeneratedColumn('uuid')
|
|
id: string;
|
|
|
|
@Index()
|
|
@Column({ name: 'tenant_id', type: 'uuid' })
|
|
tenantId: string;
|
|
|
|
@Column({ name: 'user_id', type: 'uuid', nullable: true })
|
|
userId: string;
|
|
|
|
@Index()
|
|
@Column({ name: 'model_id', type: 'uuid', nullable: true })
|
|
modelId: string;
|
|
|
|
@Column({ name: 'model_name', type: 'varchar', length: 100, nullable: true })
|
|
modelName: string;
|
|
|
|
@Column({ name: 'provider', type: 'varchar', length: 50, nullable: true })
|
|
provider: string;
|
|
|
|
@Column({ name: 'usage_type', type: 'varchar', length: 30 })
|
|
usageType: UsageType;
|
|
|
|
@Column({ name: 'prompt_tokens', type: 'int', default: 0 })
|
|
promptTokens: number;
|
|
|
|
@Column({ name: 'completion_tokens', type: 'int', default: 0 })
|
|
completionTokens: number;
|
|
|
|
@Column({ name: 'total_tokens', type: 'int', default: 0 })
|
|
totalTokens: number;
|
|
|
|
@Column({ name: 'cost', type: 'decimal', precision: 10, scale: 6, default: 0 })
|
|
cost: number;
|
|
|
|
@Column({ name: 'conversation_id', type: 'uuid', nullable: true })
|
|
conversationId: string;
|
|
|
|
@Column({ name: 'completion_id', type: 'uuid', nullable: true })
|
|
completionId: string;
|
|
|
|
@Column({ name: 'request_id', type: 'varchar', length: 255, nullable: true })
|
|
requestId: string;
|
|
|
|
@Index()
|
|
@Column({ name: 'usage_date', type: 'date', default: () => 'CURRENT_DATE' })
|
|
usageDate: Date;
|
|
|
|
@Index()
|
|
@Column({ name: 'usage_month', type: 'varchar', length: 7, nullable: true })
|
|
usageMonth: string;
|
|
|
|
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
|
createdAt: Date;
|
|
}
|
|
|
|
@Entity({ name: 'tenant_quotas', schema: 'ai' })
|
|
@Unique(['tenantId', 'quotaMonth'])
|
|
export class AITenantQuota {
|
|
@PrimaryGeneratedColumn('uuid')
|
|
id: string;
|
|
|
|
@Index()
|
|
@Column({ name: 'tenant_id', type: 'uuid' })
|
|
tenantId: string;
|
|
|
|
@Column({ name: 'monthly_token_limit', type: 'int', nullable: true })
|
|
monthlyTokenLimit: number;
|
|
|
|
@Column({ name: 'monthly_request_limit', type: 'int', nullable: true })
|
|
monthlyRequestLimit: number;
|
|
|
|
@Column({ name: 'monthly_cost_limit', type: 'decimal', precision: 10, scale: 2, nullable: true })
|
|
monthlyCostLimit: number;
|
|
|
|
@Column({ name: 'current_tokens', type: 'int', default: 0 })
|
|
currentTokens: number;
|
|
|
|
@Column({ name: 'current_requests', type: 'int', default: 0 })
|
|
currentRequests: number;
|
|
|
|
@Column({ name: 'current_cost', type: 'decimal', precision: 10, scale: 4, default: 0 })
|
|
currentCost: number;
|
|
|
|
@Index()
|
|
@Column({ name: 'quota_month', type: 'varchar', length: 7 })
|
|
quotaMonth: string;
|
|
|
|
@Column({ name: 'is_exceeded', type: 'boolean', default: false })
|
|
isExceeded: boolean;
|
|
|
|
@Column({ name: 'exceeded_at', type: 'timestamptz', nullable: true })
|
|
exceededAt: Date;
|
|
|
|
@Column({ name: 'alert_threshold_percent', type: 'int', default: 80 })
|
|
alertThresholdPercent: number;
|
|
|
|
@Column({ name: 'alert_sent_at', type: 'timestamptz', nullable: true })
|
|
alertSentAt: Date;
|
|
|
|
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
|
createdAt: Date;
|
|
|
|
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
|
|
updatedAt: Date;
|
|
}
|