erp-transportistas-backend-v2/src/modules/ai/entities/prompt.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

111 lines
3.1 KiB
TypeScript

import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
UpdateDateColumn,
Index,
ManyToOne,
JoinColumn,
Unique,
} from 'typeorm';
import { AIModel } from './model.entity';
export type PromptCategory = 'assistant' | 'analysis' | 'generation' | 'extraction';
@Entity({ name: 'prompts', schema: 'ai' })
@Unique(['tenantId', 'code', 'version'])
export class AIPrompt {
@PrimaryGeneratedColumn('uuid')
id: string;
@Index()
@Column({ name: 'tenant_id', type: 'uuid', nullable: true })
tenantId: string;
@Index()
@Column({ name: 'code', type: 'varchar', length: 100 })
code: string;
@Column({ name: 'name', type: 'varchar', length: 200 })
name: string;
@Column({ name: 'description', type: 'text', nullable: true })
description: string;
@Index()
@Column({ name: 'category', type: 'varchar', length: 50, nullable: true })
category: PromptCategory;
@Column({ name: 'system_prompt', type: 'text', nullable: true })
systemPrompt: string;
@Column({ name: 'user_prompt_template', type: 'text' })
userPromptTemplate: string;
@Column({ name: 'model_id', type: 'uuid', nullable: true })
modelId: string;
@Column({ name: 'temperature', type: 'decimal', precision: 3, scale: 2, default: 0.7 })
temperature: number;
@Column({ name: 'max_tokens', type: 'int', nullable: true })
maxTokens: number;
@Column({ name: 'top_p', type: 'decimal', precision: 3, scale: 2, nullable: true })
topP: number;
@Column({ name: 'frequency_penalty', type: 'decimal', precision: 3, scale: 2, nullable: true })
frequencyPenalty: number;
@Column({ name: 'presence_penalty', type: 'decimal', precision: 3, scale: 2, nullable: true })
presencePenalty: number;
@Column({ name: 'required_variables', type: 'text', array: true, default: [] })
requiredVariables: string[];
@Column({ name: 'variable_schema', type: 'jsonb', default: {} })
variableSchema: Record<string, any>;
@Column({ name: 'functions', type: 'jsonb', default: [] })
functions: Record<string, any>[];
@Column({ name: 'version', type: 'int', default: 1 })
version: number;
@Column({ name: 'is_latest', type: 'boolean', default: true })
isLatest: boolean;
@Column({ name: 'parent_version_id', type: 'uuid', nullable: true })
parentVersionId: string;
@Index()
@Column({ name: 'is_active', type: 'boolean', default: true })
isActive: boolean;
@Column({ name: 'is_system', type: 'boolean', default: false })
isSystem: boolean;
@Column({ name: 'usage_count', type: 'int', default: 0 })
usageCount: number;
@Column({ name: 'avg_tokens_used', type: 'int', nullable: true })
avgTokensUsed: number;
@Column({ name: 'avg_latency_ms', type: 'int', nullable: true })
avgLatencyMs: number;
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
updatedAt: Date;
@Column({ name: 'created_by', type: 'uuid', nullable: true })
createdBy: string;
@ManyToOne(() => AIModel, { onDelete: 'SET NULL' })
@JoinColumn({ name: 'model_id' })
model: AIModel;
}