erp-transportistas-backend-v2/src/modules/ai/entities/completion.entity.ts
Adrian Flores Cortes 95c6b58449 feat: Add base modules from erp-core following SIMCO-REUSE directive
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>
2026-01-25 10:10:19 -06:00

93 lines
2.5 KiB
TypeScript

import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
Index,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { AIModel } from './model.entity';
import { AIPrompt } from './prompt.entity';
export type CompletionStatus = 'pending' | 'processing' | 'completed' | 'failed';
@Entity({ name: 'completions', schema: 'ai' })
export class AICompletion {
@PrimaryGeneratedColumn('uuid')
id: string;
@Index()
@Column({ name: 'tenant_id', type: 'uuid' })
tenantId: string;
@Index()
@Column({ name: 'user_id', type: 'uuid', nullable: true })
userId: string;
@Index()
@Column({ name: 'prompt_id', type: 'uuid', nullable: true })
promptId: string;
@Column({ name: 'prompt_code', type: 'varchar', length: 100, nullable: true })
promptCode: string;
@Column({ name: 'model_id', type: 'uuid', nullable: true })
modelId: string;
@Column({ name: 'input_text', type: 'text' })
inputText: string;
@Column({ name: 'input_variables', type: 'jsonb', default: {} })
inputVariables: Record<string, any>;
@Column({ name: 'output_text', type: 'text', nullable: true })
outputText: string;
@Column({ name: 'prompt_tokens', type: 'int', nullable: true })
promptTokens: number;
@Column({ name: 'completion_tokens', type: 'int', nullable: true })
completionTokens: number;
@Column({ name: 'total_tokens', type: 'int', nullable: true })
totalTokens: number;
@Column({ name: 'cost', type: 'decimal', precision: 10, scale: 6, nullable: true })
cost: number;
@Column({ name: 'latency_ms', type: 'int', nullable: true })
latencyMs: number;
@Column({ name: 'finish_reason', type: 'varchar', length: 30, nullable: true })
finishReason: string;
@Column({ name: 'status', type: 'varchar', length: 20, default: 'pending' })
status: CompletionStatus;
@Column({ name: 'error_message', type: 'text', nullable: true })
errorMessage: string;
@Index()
@Column({ name: 'context_type', type: 'varchar', length: 50, nullable: true })
contextType: string;
@Column({ name: 'context_id', type: 'uuid', nullable: true })
contextId: string;
@Column({ name: 'metadata', type: 'jsonb', default: {} })
metadata: Record<string, any>;
@Index()
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
createdAt: Date;
@ManyToOne(() => AIModel, { nullable: true })
@JoinColumn({ name: 'model_id' })
model: AIModel;
@ManyToOne(() => AIPrompt, { nullable: true })
@JoinColumn({ name: 'prompt_id' })
prompt: AIPrompt;
}