erp-transportistas-backend-v2/src/modules/auth/entities/trusted-device.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

116 lines
3.1 KiB
TypeScript

import {
Entity,
PrimaryGeneratedColumn,
Column,
CreateDateColumn,
Index,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { User } from './user.entity.js';
export enum TrustLevel {
STANDARD = 'standard',
HIGH = 'high',
TEMPORARY = 'temporary',
}
@Entity({ schema: 'auth', name: 'trusted_devices' })
@Index('idx_trusted_devices_user', ['userId'], { where: 'is_active' })
@Index('idx_trusted_devices_fingerprint', ['deviceFingerprint'])
@Index('idx_trusted_devices_expires', ['trustExpiresAt'], {
where: 'trust_expires_at IS NOT NULL AND is_active',
})
export class TrustedDevice {
@PrimaryGeneratedColumn('uuid')
id: string;
// Relación con usuario
@Column({ type: 'uuid', nullable: false, name: 'user_id' })
userId: string;
// Identificación del dispositivo
@Column({
type: 'varchar',
length: 128,
nullable: false,
name: 'device_fingerprint',
})
deviceFingerprint: string;
@Column({ type: 'varchar', length: 128, nullable: true, name: 'device_name' })
deviceName: string | null;
@Column({ type: 'varchar', length: 32, nullable: true, name: 'device_type' })
deviceType: string | null;
// Información del dispositivo
@Column({ type: 'text', nullable: true, name: 'user_agent' })
userAgent: string | null;
@Column({ type: 'varchar', length: 64, nullable: true, name: 'browser_name' })
browserName: string | null;
@Column({
type: 'varchar',
length: 32,
nullable: true,
name: 'browser_version',
})
browserVersion: string | null;
@Column({ type: 'varchar', length: 64, nullable: true, name: 'os_name' })
osName: string | null;
@Column({ type: 'varchar', length: 32, nullable: true, name: 'os_version' })
osVersion: string | null;
// Ubicación del registro
@Column({ type: 'inet', nullable: false, name: 'registered_ip' })
registeredIp: string;
@Column({ type: 'jsonb', nullable: true, name: 'registered_location' })
registeredLocation: Record<string, any> | null;
// Estado de confianza
@Column({ type: 'boolean', default: true, nullable: false, name: 'is_active' })
isActive: boolean;
@Column({
type: 'enum',
enum: TrustLevel,
default: TrustLevel.STANDARD,
nullable: false,
name: 'trust_level',
})
trustLevel: TrustLevel;
@Column({ type: 'timestamptz', nullable: true, name: 'trust_expires_at' })
trustExpiresAt: Date | null;
// Uso
@Column({ type: 'timestamptz', nullable: false, name: 'last_used_at' })
lastUsedAt: Date;
@Column({ type: 'inet', nullable: true, name: 'last_used_ip' })
lastUsedIp: string | null;
@Column({ type: 'integer', default: 1, nullable: false, name: 'use_count' })
useCount: number;
// Relaciones
@ManyToOne(() => User, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'user_id' })
user: User;
// Auditoría
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
createdAt: Date;
@Column({ type: 'timestamptz', nullable: true, name: 'revoked_at' })
revokedAt: Date | null;
@Column({ type: 'varchar', length: 128, nullable: true, name: 'revoked_reason' })
revokedReason: string | null;
}