feat(MAI-002): Add Torre, Nivel, Departamento entities for vertical structures
- Add torre.entity.ts for construction.torres table - Add nivel.entity.ts for construction.niveles table - Add departamento.entity.ts for construction.departamentos table - Update etapa.entity.ts with OneToMany Torre relation - Update avance-obra.entity.ts with ManyToOne Lote/Departamento relations - Update entities index.ts with new exports Completes vertical structure entities matching DDL schema. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
598c3215e1
commit
6d84520811
94
src/modules/construction/entities/departamento.entity.ts
Normal file
94
src/modules/construction/entities/departamento.entity.ts
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Departamento Entity
|
||||
* Departamentos/Unidades en torre (vivienda vertical)
|
||||
*
|
||||
* @module Construction
|
||||
* @table construction.departamentos
|
||||
* @ddl schemas/01-construction-schema-ddl.sql
|
||||
*/
|
||||
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
ManyToOne,
|
||||
JoinColumn,
|
||||
Index,
|
||||
} from 'typeorm';
|
||||
import { Nivel } from './nivel.entity';
|
||||
import { Prototipo } from './prototipo.entity';
|
||||
|
||||
@Entity({ schema: 'construction', name: 'departamentos' })
|
||||
@Index(['nivelId', 'code'], { unique: true })
|
||||
@Index(['tenantId'])
|
||||
@Index(['nivelId'])
|
||||
@Index(['status'])
|
||||
export class Departamento {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ name: 'tenant_id', type: 'uuid' })
|
||||
tenantId: string;
|
||||
|
||||
@Column({ name: 'nivel_id', type: 'uuid' })
|
||||
nivelId: string;
|
||||
|
||||
@Column({ name: 'prototipo_id', type: 'uuid', nullable: true })
|
||||
prototipoId: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 30 })
|
||||
code: string;
|
||||
|
||||
@Column({ name: 'unit_number', type: 'varchar', length: 20 })
|
||||
unitNumber: string;
|
||||
|
||||
@Column({ name: 'area_m2', type: 'decimal', precision: 10, scale: 2, nullable: true })
|
||||
areaM2: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 50, default: 'available' })
|
||||
status: string;
|
||||
|
||||
@Column({ name: 'price_base', type: 'decimal', precision: 14, scale: 2, nullable: true })
|
||||
priceBase: number;
|
||||
|
||||
@Column({ name: 'price_final', type: 'decimal', precision: 14, scale: 2, nullable: true })
|
||||
priceFinal: number;
|
||||
|
||||
@Column({ name: 'buyer_id', type: 'uuid', nullable: true })
|
||||
buyerId: string;
|
||||
|
||||
@Column({ name: 'sale_date', type: 'date', nullable: true })
|
||||
saleDate: Date;
|
||||
|
||||
@Column({ name: 'delivery_date', type: 'date', nullable: true })
|
||||
deliveryDate: Date;
|
||||
|
||||
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy: string;
|
||||
|
||||
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz', nullable: true })
|
||||
updatedAt: Date;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy: string;
|
||||
|
||||
@Column({ name: 'deleted_at', type: 'timestamptz', nullable: true })
|
||||
deletedAt: Date;
|
||||
|
||||
@Column({ name: 'deleted_by', type: 'uuid', nullable: true })
|
||||
deletedBy: string;
|
||||
|
||||
// Relations
|
||||
@ManyToOne(() => Nivel, (n) => n.departamentos, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'nivel_id' })
|
||||
nivel: Nivel;
|
||||
|
||||
@ManyToOne(() => Prototipo)
|
||||
@JoinColumn({ name: 'prototipo_id' })
|
||||
prototipo: Prototipo;
|
||||
}
|
||||
@ -18,6 +18,7 @@ import {
|
||||
} from 'typeorm';
|
||||
import { Fraccionamiento } from './fraccionamiento.entity';
|
||||
import { Manzana } from './manzana.entity';
|
||||
import { Torre } from './torre.entity';
|
||||
|
||||
@Entity({ schema: 'construction', name: 'etapas' })
|
||||
@Index(['fraccionamientoId', 'code'], { unique: true })
|
||||
@ -80,4 +81,7 @@ export class Etapa {
|
||||
|
||||
@OneToMany(() => Manzana, (m) => m.etapa)
|
||||
manzanas: Manzana[];
|
||||
|
||||
@OneToMany(() => Torre, (t) => t.etapa)
|
||||
torres: Torre[];
|
||||
}
|
||||
|
||||
@ -9,3 +9,6 @@ export { Etapa } from './etapa.entity';
|
||||
export { Manzana } from './manzana.entity';
|
||||
export { Lote } from './lote.entity';
|
||||
export { Prototipo } from './prototipo.entity';
|
||||
export { Torre } from './torre.entity';
|
||||
export { Nivel } from './nivel.entity';
|
||||
export { Departamento } from './departamento.entity';
|
||||
|
||||
72
src/modules/construction/entities/nivel.entity.ts
Normal file
72
src/modules/construction/entities/nivel.entity.ts
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Nivel Entity
|
||||
* Pisos/Niveles de una torre
|
||||
*
|
||||
* @module Construction
|
||||
* @table construction.niveles
|
||||
* @ddl schemas/01-construction-schema-ddl.sql
|
||||
*/
|
||||
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
JoinColumn,
|
||||
Index,
|
||||
} from 'typeorm';
|
||||
import { Torre } from './torre.entity';
|
||||
import { Departamento } from './departamento.entity';
|
||||
|
||||
@Entity({ schema: 'construction', name: 'niveles' })
|
||||
@Index(['torreId', 'floorNumber'], { unique: true })
|
||||
@Index(['tenantId'])
|
||||
@Index(['torreId'])
|
||||
export class Nivel {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ name: 'tenant_id', type: 'uuid' })
|
||||
tenantId: string;
|
||||
|
||||
@Column({ name: 'torre_id', type: 'uuid' })
|
||||
torreId: string;
|
||||
|
||||
@Column({ name: 'floor_number', type: 'integer' })
|
||||
floorNumber: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||
name: string;
|
||||
|
||||
@Column({ name: 'total_units', type: 'integer', default: 0 })
|
||||
totalUnits: number;
|
||||
|
||||
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy: string;
|
||||
|
||||
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz', nullable: true })
|
||||
updatedAt: Date;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy: string;
|
||||
|
||||
@Column({ name: 'deleted_at', type: 'timestamptz', nullable: true })
|
||||
deletedAt: Date;
|
||||
|
||||
@Column({ name: 'deleted_by', type: 'uuid', nullable: true })
|
||||
deletedBy: string;
|
||||
|
||||
// Relations
|
||||
@ManyToOne(() => Torre, (t) => t.niveles, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'torre_id' })
|
||||
torre: Torre;
|
||||
|
||||
@OneToMany(() => Departamento, (d) => d.nivel)
|
||||
departamentos: Departamento[];
|
||||
}
|
||||
78
src/modules/construction/entities/torre.entity.ts
Normal file
78
src/modules/construction/entities/torre.entity.ts
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Torre Entity
|
||||
* Torres/Edificios verticales dentro de una etapa
|
||||
*
|
||||
* @module Construction
|
||||
* @table construction.torres
|
||||
* @ddl schemas/01-construction-schema-ddl.sql
|
||||
*/
|
||||
|
||||
import {
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
ManyToOne,
|
||||
OneToMany,
|
||||
JoinColumn,
|
||||
Index,
|
||||
} from 'typeorm';
|
||||
import { Etapa } from './etapa.entity';
|
||||
import { Nivel } from './nivel.entity';
|
||||
|
||||
@Entity({ schema: 'construction', name: 'torres' })
|
||||
@Index(['etapaId', 'code'], { unique: true })
|
||||
@Index(['tenantId'])
|
||||
@Index(['etapaId'])
|
||||
export class Torre {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@Column({ name: 'tenant_id', type: 'uuid' })
|
||||
tenantId: string;
|
||||
|
||||
@Column({ name: 'etapa_id', type: 'uuid' })
|
||||
etapaId: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 20 })
|
||||
code: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 100 })
|
||||
name: string;
|
||||
|
||||
@Column({ name: 'total_floors', type: 'integer', default: 1 })
|
||||
totalFloors: number;
|
||||
|
||||
@Column({ name: 'total_units', type: 'integer', default: 0 })
|
||||
totalUnits: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 50, default: 'draft' })
|
||||
status: string;
|
||||
|
||||
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
||||
createdAt: Date;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy: string;
|
||||
|
||||
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz', nullable: true })
|
||||
updatedAt: Date;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy: string;
|
||||
|
||||
@Column({ name: 'deleted_at', type: 'timestamptz', nullable: true })
|
||||
deletedAt: Date;
|
||||
|
||||
@Column({ name: 'deleted_by', type: 'uuid', nullable: true })
|
||||
deletedBy: string;
|
||||
|
||||
// Relations
|
||||
@ManyToOne(() => Etapa, (e) => e.torres, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'etapa_id' })
|
||||
etapa: Etapa;
|
||||
|
||||
@OneToMany(() => Nivel, (n) => n.torre)
|
||||
niveles: Nivel[];
|
||||
}
|
||||
@ -22,6 +22,8 @@ import {
|
||||
import { Tenant } from '../../core/entities/tenant.entity';
|
||||
import { User } from '../../core/entities/user.entity';
|
||||
import { Concepto } from '../../budgets/entities/concepto.entity';
|
||||
import { Lote } from '../../construction/entities/lote.entity';
|
||||
import { Departamento } from '../../construction/entities/departamento.entity';
|
||||
import { FotoAvance } from './foto-avance.entity';
|
||||
|
||||
export type AdvanceStatus = 'pending' | 'captured' | 'reviewed' | 'approved' | 'rejected';
|
||||
@ -122,6 +124,14 @@ export class AvanceObra {
|
||||
@JoinColumn({ name: 'approved_by' })
|
||||
approvedBy: User | null;
|
||||
|
||||
@ManyToOne(() => Lote)
|
||||
@JoinColumn({ name: 'lote_id' })
|
||||
lote: Lote | null;
|
||||
|
||||
@ManyToOne(() => Departamento)
|
||||
@JoinColumn({ name: 'departamento_id' })
|
||||
departamento: Departamento | null;
|
||||
|
||||
@OneToMany(() => FotoAvance, (f) => f.avance)
|
||||
fotos: FotoAvance[];
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user