chore: import DH V2 D5.6.4 production baseline
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum AreaOrganizationRole {
|
||||
OPERATOR='OPERATOR', TECHNICAL_OPERATOR='TECHNICAL_OPERATOR', CONCESSIONAIRE='CONCESSIONAIRE', PERMIT_HOLDER='PERMIT_HOLDER', PARTICIPANT='PARTICIPANT', OTHER='OTHER'
|
||||
}
|
||||
|
||||
@Entity({ name: 'area_company_relations' })
|
||||
@Index('idx_area_company_relations_area_id', ['areaId'])
|
||||
@Index('idx_area_company_relations_company_id', ['companyId'])
|
||||
@Index('idx_area_company_relations_valid_until', ['validUntil'])
|
||||
export class AreaCompanyRelation extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'area_id', type: 'uuid' })
|
||||
areaId!: string;
|
||||
|
||||
@Column({ name: 'company_id', type: 'uuid' })
|
||||
companyId!: string;
|
||||
|
||||
@Column({ name:'relation_role', type:'enum', enum:AreaOrganizationRole, enumName:'area_organization_role', default:AreaOrganizationRole.OPERATOR })
|
||||
relationRole!: AreaOrganizationRole;
|
||||
|
||||
@Column({ name:'participation_percent', type:'numeric', precision:7, scale:4, nullable:true })
|
||||
participationPercent!: string|null;
|
||||
|
||||
@Column({ name:'legal_instrument', type:'varchar', length:240, nullable:true })
|
||||
legalInstrument!: string|null;
|
||||
|
||||
@Column({ name:'source_document_id', type:'uuid', nullable:true })
|
||||
sourceDocumentId!: string|null;
|
||||
|
||||
@Column({ name: 'valid_from', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
validFrom!: Date;
|
||||
|
||||
@Column({ name: 'valid_until', type: 'timestamptz', nullable: true })
|
||||
validUntil!: Date | null;
|
||||
|
||||
@Column({ name: 'start_reason', type: 'text' })
|
||||
startReason!: string;
|
||||
|
||||
@Column({ name: 'end_reason', type: 'text', nullable: true })
|
||||
endReason!: string | null;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'ended_by', type: 'uuid', nullable: true })
|
||||
endedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'; import { TimestampedEntity } from './timestamped.entity';
|
||||
export enum AreaLegalRightOrganizationRole { HOLDER='HOLDER', PARTICIPANT='PARTICIPANT', OPERATOR='OPERATOR', OTHER='OTHER' }
|
||||
@Entity({name:'area_legal_right_organizations'}) @Index('idx_area_legal_right_org_right_id',['rightId']) @Index('idx_area_legal_right_org_organization_id',['organizationId']) @Index('idx_area_legal_right_org_valid_until',['validUntil'])
|
||||
export class AreaLegalRightOrganization extends TimestampedEntity { @PrimaryGeneratedColumn('uuid') id!:string; @Column({name:'right_id',type:'uuid'}) rightId!:string; @Column({name:'organization_id',type:'uuid'}) organizationId!:string; @Column({type:'enum',enum:AreaLegalRightOrganizationRole,enumName:'area_legal_right_organization_role'}) role!:AreaLegalRightOrganizationRole; @Column({name:'participation_percent',type:'numeric',precision:7,scale:4,nullable:true}) participationPercent!:string|null; @Column({name:'valid_from',type:'date',default:()=> 'CURRENT_DATE'}) validFrom!:string; @Column({name:'valid_until',type:'date',nullable:true}) validUntil!:string|null; @Column({type:'text',nullable:true}) notes!:string|null; @Column({name:'end_reason',type:'text',nullable:true}) endReason!:string|null; @Column({name:'created_by',type:'uuid',nullable:true}) createdBy!:string|null; @Column({name:'ended_by',type:'uuid',nullable:true}) endedBy!:string|null; }
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'; import { TimestampedEntity } from './timestamped.entity';
|
||||
export enum AreaLegalRightType { EXPLOITATION_CONCESSION='EXPLOITATION_CONCESSION', EXPLORATION_PERMIT='EXPLORATION_PERMIT', TRANSPORT_CONCESSION='TRANSPORT_CONCESSION', OTHER='OTHER' }
|
||||
export enum AreaLegalRightStatus { ACTIVE='ACTIVE', EXPIRED='EXPIRED', REVOKED='REVOKED', PENDING='PENDING' }
|
||||
@Entity({name:'area_legal_rights'}) @Index('idx_area_legal_rights_area_id',['areaId']) @Index('idx_area_legal_rights_valid_until',['validUntil'])
|
||||
export class AreaLegalRight extends TimestampedEntity { @PrimaryGeneratedColumn('uuid') id!:string; @Column({name:'area_id',type:'uuid'}) areaId!:string; @Column({name:'right_type',type:'enum',enum:AreaLegalRightType,enumName:'area_legal_right_type'}) rightType!:AreaLegalRightType; @Column({type:'varchar',length:260}) name!:string; @Column({name:'instrument_number',type:'varchar',length:180,nullable:true}) instrumentNumber!:string|null; @Column({name:'valid_from',type:'date',nullable:true}) validFrom!:string|null; @Column({name:'valid_until',type:'date',nullable:true}) validUntil!:string|null; @Column({type:'enum',enum:AreaLegalRightStatus,enumName:'area_legal_right_status',default:AreaLegalRightStatus.ACTIVE}) status!:AreaLegalRightStatus; @Column({name:'source_document_id',type:'uuid',nullable:true}) sourceDocumentId!:string|null; @Column({type:'text',nullable:true}) notes!:string|null; @Column({name:'created_by',type:'uuid',nullable:true}) createdBy!:string|null; @Column({name:'updated_by',type:'uuid',nullable:true}) updatedBy!:string|null; }
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum AssetAttributeDataType {
|
||||
TEXT = 'TEXT',
|
||||
NUMBER = 'NUMBER',
|
||||
BOOLEAN = 'BOOLEAN',
|
||||
DATE = 'DATE',
|
||||
DATETIME = 'DATETIME',
|
||||
SELECT = 'SELECT',
|
||||
}
|
||||
|
||||
@Entity({ name: 'asset_attribute_definitions' })
|
||||
@Index('idx_asset_attribute_definitions_type', ['assetTypeId', 'sortOrder'])
|
||||
@Index('idx_asset_attribute_definitions_active', ['isActive'])
|
||||
export class AssetAttributeDefinition extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'asset_type_id', type: 'uuid' })
|
||||
assetTypeId!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 80 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 160 })
|
||||
name!: string;
|
||||
|
||||
@Column({
|
||||
name: 'data_type',
|
||||
type: 'enum',
|
||||
enum: AssetAttributeDataType,
|
||||
enumName: 'asset_attribute_data_type',
|
||||
})
|
||||
dataType!: AssetAttributeDataType;
|
||||
|
||||
@Column({ name: 'is_required', type: 'boolean', default: false })
|
||||
isRequired!: boolean;
|
||||
|
||||
@Column({ name: 'is_active', type: 'boolean', default: true })
|
||||
isActive!: boolean;
|
||||
|
||||
@Column({ type: 'varchar', length: 40, nullable: true })
|
||||
unit!: string | null;
|
||||
|
||||
@Column({ type: 'jsonb', nullable: true })
|
||||
options!: string[] | null;
|
||||
|
||||
@Column({ name: 'sort_order', type: 'integer', default: 0 })
|
||||
sortOrder!: number;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||
|
||||
@Entity({ name: 'asset_attribute_values' })
|
||||
export class AssetAttributeValue {
|
||||
@PrimaryColumn({ name: 'asset_id', type: 'uuid' })
|
||||
assetId!: string;
|
||||
|
||||
@PrimaryColumn({ name: 'definition_id', type: 'uuid' })
|
||||
definitionId!: string;
|
||||
|
||||
@Column({ type: 'jsonb' })
|
||||
value!: unknown;
|
||||
|
||||
@Column({ name: 'updated_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
updatedAt!: Date;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'; import { TimestampedEntity } from './timestamped.entity';
|
||||
@Entity({name:'asset_external_identifiers'}) @Index('idx_asset_external_identifiers_asset_id',['assetId']) @Index('idx_asset_external_identifiers_namespace',['namespace'])
|
||||
export class AssetExternalIdentifier extends TimestampedEntity { @PrimaryGeneratedColumn('uuid') id!:string; @Column({name:'asset_id',type:'uuid'}) assetId!:string; @Column({type:'varchar',length:80}) namespace!:string; @Column({type:'varchar',length:180}) value!:string; @Column({name:'valid_from',type:'timestamptz',default:()=> 'CURRENT_TIMESTAMP'}) validFrom!:Date; @Column({name:'valid_until',type:'timestamptz',nullable:true}) validUntil!:Date|null; @Column({name:'source_document_id',type:'uuid',nullable:true}) sourceDocumentId!:string|null; @Column({type:'text',nullable:true}) notes!:string|null; @Column({name:'end_reason',type:'text',nullable:true}) endReason!:string|null; @Column({name:'created_by',type:'uuid',nullable:true}) createdBy!:string|null; @Column({name:'ended_by',type:'uuid',nullable:true}) endedBy!:string|null; }
|
||||
@@ -0,0 +1,58 @@
|
||||
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
||||
|
||||
export enum AssetGeometryType {
|
||||
POINT = 'POINT',
|
||||
LINESTRING = 'LINESTRING',
|
||||
POLYGON = 'POLYGON',
|
||||
}
|
||||
|
||||
export enum AssetGeometrySource {
|
||||
WEB = 'WEB',
|
||||
ANDROID = 'ANDROID',
|
||||
IMPORT = 'IMPORT',
|
||||
SURVEY = 'SURVEY',
|
||||
}
|
||||
|
||||
@Entity({ name: 'asset_geometries' })
|
||||
@Index('idx_asset_geometries_geometry', ['geometry'], { spatial: true })
|
||||
@Index('idx_asset_geometries_type', ['geometryType'])
|
||||
export class AssetGeometry {
|
||||
@PrimaryColumn({ name: 'asset_id', type: 'uuid' })
|
||||
assetId!: string;
|
||||
|
||||
@Column({
|
||||
type: 'geometry',
|
||||
spatialFeatureType: 'Geometry',
|
||||
srid: 4326,
|
||||
})
|
||||
geometry!: { type: AssetGeometryType; coordinates: unknown };
|
||||
|
||||
@Column({ name: 'geometry_type', type: 'varchar', length: 20 })
|
||||
geometryType!: AssetGeometryType;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: AssetGeometrySource,
|
||||
enumName: 'asset_geometry_source',
|
||||
default: AssetGeometrySource.WEB,
|
||||
})
|
||||
source!: AssetGeometrySource;
|
||||
|
||||
@Column({ name: 'accuracy_m', type: 'numeric', precision: 12, scale: 3, nullable: true })
|
||||
accuracyM!: string | null;
|
||||
|
||||
@Column({ name: 'captured_at', type: 'timestamptz', nullable: true })
|
||||
capturedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'device_label', type: 'varchar', length: 255, nullable: true })
|
||||
deviceLabel!: string | null;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
|
||||
@Column({ name: 'updated_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
updatedAt!: Date;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
export enum AssetMediaKind {
|
||||
PHOTO = 'PHOTO',
|
||||
DOCUMENT = 'DOCUMENT',
|
||||
}
|
||||
|
||||
export enum AssetMediaSource {
|
||||
WEB = 'WEB',
|
||||
ANDROID = 'ANDROID',
|
||||
IMPORT = 'IMPORT',
|
||||
}
|
||||
|
||||
@Entity({ name: 'asset_media' })
|
||||
@Index('idx_asset_media_asset_created', ['assetId', 'createdAt'])
|
||||
@Index('idx_asset_media_sha256', ['sha256'])
|
||||
@Index('idx_asset_media_active', ['assetId', 'deletedAt'])
|
||||
export class AssetMedia {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'asset_id', type: 'uuid' })
|
||||
assetId!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 20 })
|
||||
kind!: AssetMediaKind;
|
||||
|
||||
@Column({ name: 'original_name', type: 'varchar', length: 255 })
|
||||
originalName!: string;
|
||||
|
||||
@Column({ name: 'stored_name', type: 'varchar', length: 80 })
|
||||
storedName!: string;
|
||||
|
||||
@Column({ name: 'mime_type', type: 'varchar', length: 100 })
|
||||
mimeType!: string;
|
||||
|
||||
@Column({ name: 'size_bytes', type: 'bigint' })
|
||||
sizeBytes!: string;
|
||||
|
||||
@Column({ type: 'char', length: 64 })
|
||||
sha256!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||
title!: string | null;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
description!: string | null;
|
||||
|
||||
@Column({ name: 'captured_at', type: 'timestamptz', nullable: true })
|
||||
capturedAt!: Date | null;
|
||||
|
||||
@Column({ type: 'numeric', precision: 9, scale: 6, nullable: true })
|
||||
latitude!: string | null;
|
||||
|
||||
@Column({ type: 'numeric', precision: 9, scale: 6, nullable: true })
|
||||
longitude!: string | null;
|
||||
|
||||
@Column({ name: 'accuracy_m', type: 'numeric', precision: 12, scale: 3, nullable: true })
|
||||
accuracyM!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 20 })
|
||||
source!: AssetMediaSource;
|
||||
|
||||
@Column({ name: 'uploaded_by', type: 'uuid', nullable: true })
|
||||
uploadedBy!: string | null;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
|
||||
@Column({ name: 'updated_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
updatedAt!: Date;
|
||||
|
||||
@Column({ name: 'deleted_at', type: 'timestamptz', nullable: true })
|
||||
deletedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'deleted_by', type: 'uuid', nullable: true })
|
||||
deletedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'; import { TimestampedEntity } from './timestamped.entity';
|
||||
export enum AssetSourceDocumentRelationType { SOURCE='SOURCE', MENTIONS='MENTIONS', VALIDATES='VALIDATES', SUPERSEDES='SUPERSEDES', OTHER='OTHER' }
|
||||
@Entity({name:'asset_source_documents'}) @Index('idx_asset_source_documents_asset_id',['assetId']) @Index('idx_asset_source_documents_document_id',['documentId'])
|
||||
export class AssetSourceDocument extends TimestampedEntity { @PrimaryGeneratedColumn('uuid') id!:string; @Column({name:'asset_id',type:'uuid'}) assetId!:string; @Column({name:'document_id',type:'uuid'}) documentId!:string; @Column({name:'relation_type',type:'enum',enum:AssetSourceDocumentRelationType,enumName:'asset_source_document_relation_type',default:AssetSourceDocumentRelationType.SOURCE}) relationType!:AssetSourceDocumentRelationType; @Column({type:'text',nullable:true}) notes!:string|null; @Column({name:'created_by',type:'uuid',nullable:true}) createdBy!:string|null; }
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||
|
||||
@Entity({ name: 'asset_type_parent_rules' })
|
||||
export class AssetTypeParentRule {
|
||||
@PrimaryColumn({ name: 'child_type_id', type: 'uuid' })
|
||||
childTypeId!: string;
|
||||
|
||||
@PrimaryColumn({ name: 'parent_type_id', type: 'uuid' })
|
||||
parentTypeId!: string;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum AssetTypeOperationalRole {
|
||||
GENERIC = 'GENERIC',
|
||||
AREA = 'AREA',
|
||||
COMPANY = 'COMPANY',
|
||||
}
|
||||
|
||||
@Entity({ name: 'asset_types' })
|
||||
@Index('idx_asset_types_is_active', ['isActive'])
|
||||
export class AssetType extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 80 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 160 })
|
||||
name!: string;
|
||||
|
||||
@Column({ type: 'text', default: '' })
|
||||
description!: string;
|
||||
|
||||
@Column({ name: 'can_be_root', type: 'boolean', default: false })
|
||||
canBeRoot!: boolean;
|
||||
|
||||
@Column({ name: 'is_active', type: 'boolean', default: true })
|
||||
isActive!: boolean;
|
||||
|
||||
@Column({
|
||||
name: 'operational_role',
|
||||
type: 'enum',
|
||||
enum: AssetTypeOperationalRole,
|
||||
enumName: 'asset_type_operational_role',
|
||||
default: AssetTypeOperationalRole.GENERIC,
|
||||
})
|
||||
operationalRole!: AssetTypeOperationalRole;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
export enum AssetVersionChangeType {
|
||||
BASELINE = 'BASELINE',
|
||||
CREATED = 'CREATED',
|
||||
UPDATED = 'UPDATED',
|
||||
CONTEXT_CHANGED = 'CONTEXT_CHANGED',
|
||||
STATUS_CHANGED = 'STATUS_CHANGED',
|
||||
OPERATIONAL_STATUS_CHANGED = 'OPERATIONAL_STATUS_CHANGED',
|
||||
REGISTRY_UPDATED = 'REGISTRY_UPDATED',
|
||||
GEOMETRY_UPDATED = 'GEOMETRY_UPDATED',
|
||||
GEOMETRY_REMOVED = 'GEOMETRY_REMOVED',
|
||||
MEDIA_UPLOADED = 'MEDIA_UPLOADED',
|
||||
MEDIA_UPDATED = 'MEDIA_UPDATED',
|
||||
MEDIA_REMOVED = 'MEDIA_REMOVED',
|
||||
PROVENANCE_BASELINE = 'PROVENANCE_BASELINE',
|
||||
PROVENANCE_UPDATED = 'PROVENANCE_UPDATED',
|
||||
PROVENANCE_VERIFIED = 'PROVENANCE_VERIFIED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'asset_versions' })
|
||||
@Index('idx_asset_versions_asset_number', ['assetId', 'versionNumber'], {
|
||||
unique: true,
|
||||
})
|
||||
@Index('idx_asset_versions_occurred_at', ['occurredAt'])
|
||||
@Index('idx_asset_versions_change_type', ['changeType'])
|
||||
export class AssetVersion {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'asset_id', type: 'uuid' })
|
||||
assetId!: string;
|
||||
|
||||
@Column({ name: 'version_number', type: 'integer' })
|
||||
versionNumber!: number;
|
||||
|
||||
@Column({ name: 'change_type', type: 'varchar', length: 32 })
|
||||
changeType!: AssetVersionChangeType;
|
||||
|
||||
@Column({ name: 'changed_fields', type: 'text', array: true, default: () => "'{}'" })
|
||||
changedFields!: string[];
|
||||
|
||||
@Column({ type: 'jsonb' })
|
||||
snapshot!: Record<string, unknown>;
|
||||
|
||||
@Column({ name: 'occurred_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
occurredAt!: Date;
|
||||
|
||||
@Column({ name: 'actor_user_id', type: 'uuid', nullable: true })
|
||||
actorUserId!: string | null;
|
||||
|
||||
@Column({ name: 'actor_username', type: 'varchar', length: 80, nullable: true })
|
||||
actorUsername!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 32 })
|
||||
source!: string;
|
||||
|
||||
@Column({ name: 'request_id', type: 'varchar', length: 128, nullable: true })
|
||||
requestId!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum AssetInformationStatus {
|
||||
DRAFT = 'DRAFT',
|
||||
PENDING_SURVEY = 'PENDING_SURVEY',
|
||||
SURVEYED = 'SURVEYED',
|
||||
VALIDATED = 'VALIDATED',
|
||||
OBSERVED = 'OBSERVED',
|
||||
OUTDATED = 'OUTDATED',
|
||||
INACTIVE = 'INACTIVE',
|
||||
}
|
||||
|
||||
export enum AssetOperationalStatus {
|
||||
UNKNOWN = 'UNKNOWN',
|
||||
IN_SERVICE = 'IN_SERVICE',
|
||||
TEMPORARILY_OUT_OF_SERVICE = 'TEMPORARILY_OUT_OF_SERVICE',
|
||||
OUT_OF_SERVICE = 'OUT_OF_SERVICE',
|
||||
DECOMMISSIONED = 'DECOMMISSIONED',
|
||||
ABANDONED = 'ABANDONED',
|
||||
}
|
||||
|
||||
export enum AssetDataOrigin {
|
||||
MANUAL = 'MANUAL',
|
||||
FIELD_SURVEY = 'FIELD_SURVEY',
|
||||
PROVIDED_DOCUMENT = 'PROVIDED_DOCUMENT',
|
||||
IMPORT = 'IMPORT',
|
||||
SYSTEM = 'SYSTEM',
|
||||
}
|
||||
|
||||
@Entity({ name: 'assets' })
|
||||
@Index('idx_assets_type_id', ['assetTypeId'])
|
||||
@Index('idx_assets_parent_id', ['parentId'])
|
||||
@Index('idx_assets_operational_area_id', ['operationalAreaId'])
|
||||
@Index('idx_assets_operator_company_id', ['operatorCompanyId'])
|
||||
@Index('idx_assets_information_status', ['informationStatus'])
|
||||
@Index('idx_assets_operational_status', ['operationalStatus'])
|
||||
@Index('idx_assets_data_origin', ['dataOrigin'])
|
||||
@Index('idx_assets_provenance_verified_at', ['provenanceVerifiedAt'])
|
||||
export class Asset extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'asset_type_id', type: 'uuid' })
|
||||
assetTypeId!: string;
|
||||
|
||||
@Column({ name: 'parent_id', type: 'uuid', nullable: true })
|
||||
parentId!: string | null;
|
||||
|
||||
@Column({ name: 'operational_area_id', type: 'uuid', nullable: true })
|
||||
operationalAreaId!: string | null;
|
||||
|
||||
@Column({ name: 'operator_company_id', type: 'uuid', nullable: true })
|
||||
operatorCompanyId!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 120 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 200 })
|
||||
name!: string;
|
||||
|
||||
@Column({ name: 'common_name', type: 'varchar', length: 200, nullable: true })
|
||||
commonName!: string | null;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
description!: string | null;
|
||||
|
||||
@Column({
|
||||
name: 'information_status',
|
||||
type: 'enum',
|
||||
enum: AssetInformationStatus,
|
||||
enumName: 'asset_information_status',
|
||||
default: AssetInformationStatus.DRAFT,
|
||||
})
|
||||
informationStatus!: AssetInformationStatus;
|
||||
|
||||
@Column({ name: 'operational_status', type: 'enum', enum: AssetOperationalStatus, enumName: 'asset_operational_status', default: AssetOperationalStatus.UNKNOWN })
|
||||
operationalStatus!: AssetOperationalStatus;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
|
||||
@Column({ name: 'current_version', type: 'integer', default: 0 })
|
||||
currentVersion!: number;
|
||||
|
||||
@Column({ name: 'data_origin', type: 'varchar', length: 32, default: AssetDataOrigin.MANUAL })
|
||||
dataOrigin!: AssetDataOrigin;
|
||||
|
||||
@Column({ name: 'source_name', type: 'varchar', length: 160, nullable: true })
|
||||
sourceName!: string | null;
|
||||
|
||||
@Column({ name: 'source_reference', type: 'varchar', length: 255, nullable: true })
|
||||
sourceReference!: string | null;
|
||||
|
||||
@Column({ name: 'source_observed_at', type: 'timestamptz', nullable: true })
|
||||
sourceObservedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'source_notes', type: 'text', nullable: true })
|
||||
sourceNotes!: string | null;
|
||||
|
||||
@Column({ name: 'provenance_verified_at', type: 'timestamptz', nullable: true })
|
||||
provenanceVerifiedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'provenance_verified_by', type: 'uuid', nullable: true })
|
||||
provenanceVerifiedBy!: string | null;
|
||||
|
||||
@Column({ name: 'provenance_updated_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
provenanceUpdatedAt!: Date;
|
||||
|
||||
@Column({ name: 'provenance_updated_by', type: 'uuid', nullable: true })
|
||||
provenanceUpdatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
export enum AuditSource {
|
||||
WEB = 'WEB',
|
||||
ANDROID = 'ANDROID',
|
||||
SYSTEM = 'SYSTEM',
|
||||
IMPORT = 'IMPORT',
|
||||
}
|
||||
|
||||
export enum AuditAction {
|
||||
AUTH_LOGIN_SUCCESS = 'AUTH_LOGIN_SUCCESS',
|
||||
AUTH_LOGIN_FAILED = 'AUTH_LOGIN_FAILED',
|
||||
AUTH_LOGOUT = 'AUTH_LOGOUT',
|
||||
AUTH_REFRESH = 'AUTH_REFRESH',
|
||||
AUTH_REFRESH_REUSE_DETECTED = 'AUTH_REFRESH_REUSE_DETECTED',
|
||||
AUTH_PASSWORD_CHANGED = 'AUTH_PASSWORD_CHANGED',
|
||||
SYSTEM_BOOTSTRAP_ADMIN_CREATED = 'SYSTEM_BOOTSTRAP_ADMIN_CREATED',
|
||||
USER_CREATED = 'USER_CREATED',
|
||||
USER_UPDATED = 'USER_UPDATED',
|
||||
USER_PASSWORD_RESET = 'USER_PASSWORD_RESET',
|
||||
USER_STATUS_CHANGED = 'USER_STATUS_CHANGED',
|
||||
USER_ROLES_CHANGED = 'USER_ROLES_CHANGED',
|
||||
ROLE_CREATED = 'ROLE_CREATED',
|
||||
ROLE_UPDATED = 'ROLE_UPDATED',
|
||||
ROLE_PERMISSIONS_CHANGED = 'ROLE_PERMISSIONS_CHANGED',
|
||||
ASSET_TYPE_CREATED = 'ASSET_TYPE_CREATED',
|
||||
ASSET_TYPE_UPDATED = 'ASSET_TYPE_UPDATED',
|
||||
ASSET_MASTER_BOOTSTRAPPED = 'ASSET_MASTER_BOOTSTRAPPED',
|
||||
ASSET_ATTRIBUTE_CREATED = 'ASSET_ATTRIBUTE_CREATED',
|
||||
ASSET_ATTRIBUTE_UPDATED = 'ASSET_ATTRIBUTE_UPDATED',
|
||||
ASSET_CREATED = 'ASSET_CREATED',
|
||||
ASSET_FIELD_DISCOVERY_CREATED = 'ASSET_FIELD_DISCOVERY_CREATED',
|
||||
ASSET_FIELD_DISCOVERY_APPROVED = 'ASSET_FIELD_DISCOVERY_APPROVED',
|
||||
ASSET_FIELD_DISCOVERY_MATCHED = 'ASSET_FIELD_DISCOVERY_MATCHED',
|
||||
ASSET_FIELD_DISCOVERY_REJECTED = 'ASSET_FIELD_DISCOVERY_REJECTED',
|
||||
ASSET_UPDATED = 'ASSET_UPDATED',
|
||||
ASSET_CONTEXT_CHANGED = 'ASSET_CONTEXT_CHANGED',
|
||||
ASSET_INFORMATION_STATUS_CHANGED = 'ASSET_INFORMATION_STATUS_CHANGED',
|
||||
ASSET_OPERATIONAL_STATUS_CHANGED = 'ASSET_OPERATIONAL_STATUS_CHANGED',
|
||||
ASSET_REGISTRY_UPDATED = 'ASSET_REGISTRY_UPDATED',
|
||||
ASSET_IMPORT_BATCH_ANALYZED = 'ASSET_IMPORT_BATCH_ANALYZED',
|
||||
ASSET_IMPORT_BATCH_RECONCILED = 'ASSET_IMPORT_BATCH_RECONCILED',
|
||||
ASSET_IMPORT_PLAN_GENERATED = 'ASSET_IMPORT_PLAN_GENERATED',
|
||||
ASSET_IMPORT_PLAN_ITEM_RESOLVED = 'ASSET_IMPORT_PLAN_ITEM_RESOLVED',
|
||||
ASSET_IMPORT_PLAN_APPLIED = 'ASSET_IMPORT_PLAN_APPLIED',
|
||||
ASSET_IMPORT_PLAN_ROLLED_BACK = 'ASSET_IMPORT_PLAN_ROLLED_BACK',
|
||||
ASSET_IMPORT_BATCH_CANCELLED = 'ASSET_IMPORT_BATCH_CANCELLED',
|
||||
SOURCE_DOCUMENT_CREATED = 'SOURCE_DOCUMENT_CREATED',
|
||||
AREA_LEGAL_RIGHT_CREATED = 'AREA_LEGAL_RIGHT_CREATED',
|
||||
AREA_LEGAL_RIGHT_UPDATED = 'AREA_LEGAL_RIGHT_UPDATED',
|
||||
AREA_LEGAL_RIGHT_ORGANIZATION_ENDED = 'AREA_LEGAL_RIGHT_ORGANIZATION_ENDED',
|
||||
ASSET_GEOMETRY_UPDATED = 'ASSET_GEOMETRY_UPDATED',
|
||||
ASSET_GEOMETRY_REMOVED = 'ASSET_GEOMETRY_REMOVED',
|
||||
ASSET_MEDIA_UPLOADED = 'ASSET_MEDIA_UPLOADED',
|
||||
ASSET_MEDIA_UPDATED = 'ASSET_MEDIA_UPDATED',
|
||||
ASSET_MEDIA_REMOVED = 'ASSET_MEDIA_REMOVED',
|
||||
ASSET_PROVENANCE_UPDATED = 'ASSET_PROVENANCE_UPDATED',
|
||||
ASSET_PROVENANCE_VERIFIED = 'ASSET_PROVENANCE_VERIFIED',
|
||||
ASSET_AREA_COMPANY_RELATION_CREATED = 'ASSET_AREA_COMPANY_RELATION_CREATED',
|
||||
ASSET_AREA_COMPANY_RELATION_ENDED = 'ASSET_AREA_COMPANY_RELATION_ENDED',
|
||||
SURVEY_CAMPAIGN_CREATED = 'SURVEY_CAMPAIGN_CREATED',
|
||||
SURVEY_CAMPAIGN_UPDATED = 'SURVEY_CAMPAIGN_UPDATED',
|
||||
SURVEY_CAMPAIGN_STATUS_CHANGED = 'SURVEY_CAMPAIGN_STATUS_CHANGED',
|
||||
SURVEY_TARGET_ADDED = 'SURVEY_TARGET_ADDED',
|
||||
SURVEY_TARGET_UPDATED = 'SURVEY_TARGET_UPDATED',
|
||||
SURVEY_TARGET_ASSIGNED = 'SURVEY_TARGET_ASSIGNED',
|
||||
SURVEY_TARGET_STATUS_CHANGED = 'SURVEY_TARGET_STATUS_CHANGED',
|
||||
SURVEY_REPORT_SAVED = 'SURVEY_REPORT_SAVED',
|
||||
SURVEY_REPORT_SUBMITTED = 'SURVEY_REPORT_SUBMITTED',
|
||||
SURVEY_REPORT_APPROVED = 'SURVEY_REPORT_APPROVED',
|
||||
SURVEY_REPORT_REJECTED = 'SURVEY_REPORT_REJECTED',
|
||||
INSPECTION_VISIT_CREATED = 'INSPECTION_VISIT_CREATED',
|
||||
INSPECTION_VISIT_UPDATED = 'INSPECTION_VISIT_UPDATED',
|
||||
INSPECTION_VISIT_STATUS_CHANGED = 'INSPECTION_VISIT_STATUS_CHANGED',
|
||||
INSPECTION_VISIT_ASSETS_UPDATED = 'INSPECTION_VISIT_ASSETS_UPDATED',
|
||||
INSPECTION_VISIT_TEAM_UPDATED = 'INSPECTION_VISIT_TEAM_UPDATED',
|
||||
INSPECTION_VISIT_CHECKLIST_GENERATED = 'INSPECTION_VISIT_CHECKLIST_GENERATED',
|
||||
INSPECTION_VISIT_ASSET_EXCLUDED = 'INSPECTION_VISIT_ASSET_EXCLUDED',
|
||||
INSPECTION_VISIT_ASSET_REINCLUDED = 'INSPECTION_VISIT_ASSET_REINCLUDED',
|
||||
INSPECTION_VISIT_STARTED = 'INSPECTION_VISIT_STARTED',
|
||||
INSPECTION_ACT_CREATED = 'INSPECTION_ACT_CREATED',
|
||||
INSPECTION_ACT_UPDATED = 'INSPECTION_ACT_UPDATED',
|
||||
INSPECTION_ACT_CANCELLED = 'INSPECTION_ACT_CANCELLED',
|
||||
INSPECTION_ACT_RESPONSIBLE_UPDATED = 'INSPECTION_ACT_RESPONSIBLE_UPDATED',
|
||||
INSPECTION_ACT_READY = 'INSPECTION_ACT_READY',
|
||||
INSPECTION_ACT_REOPENED = 'INSPECTION_ACT_REOPENED',
|
||||
INSPECTION_ACT_SIGNATURE_RECORDED = 'INSPECTION_ACT_SIGNATURE_RECORDED',
|
||||
INSPECTION_ACT_COMPANY_OUTCOME_RECORDED = 'INSPECTION_ACT_COMPANY_OUTCOME_RECORDED',
|
||||
INSPECTION_ACT_CLOSED = 'INSPECTION_ACT_CLOSED',
|
||||
INSPECTION_REPORT_GENERATED = 'INSPECTION_REPORT_GENERATED',
|
||||
INSPECTION_REPORT_REVISION_ADDED = 'INSPECTION_REPORT_REVISION_ADDED',
|
||||
INSPECTION_REPORT_APPROVED = 'INSPECTION_REPORT_APPROVED',
|
||||
INSPECTION_REPORT_SIGNED = 'INSPECTION_REPORT_SIGNED',
|
||||
DOCUMENT_DELIVERY_SETTINGS_UPDATED = 'DOCUMENT_DELIVERY_SETTINGS_UPDATED',
|
||||
DOCUMENT_DELIVERY_RETRY_REQUESTED = 'DOCUMENT_DELIVERY_RETRY_REQUESTED',
|
||||
DOCUMENT_DELIVERY_SENT = 'DOCUMENT_DELIVERY_SENT',
|
||||
INSPECTION_VERIFICATION_PLANNED = 'INSPECTION_VERIFICATION_PLANNED',
|
||||
INSPECTION_VERIFICATION_RESULT_RECORDED = 'INSPECTION_VERIFICATION_RESULT_RECORDED',
|
||||
INSPECTION_FINDING_CREATED = 'INSPECTION_FINDING_CREATED',
|
||||
INSPECTION_FINDING_UPDATED = 'INSPECTION_FINDING_UPDATED',
|
||||
INSPECTION_FINDING_FOLLOW_UP_UPDATED = 'INSPECTION_FINDING_FOLLOW_UP_UPDATED',
|
||||
INSPECTION_FINDING_CLOSED = 'INSPECTION_FINDING_CLOSED',
|
||||
INSPECTION_FINDING_EVIDENCE_UPLOADED = 'INSPECTION_FINDING_EVIDENCE_UPLOADED',
|
||||
INSPECTION_FINDING_COMMUNICATION_CREATED = 'INSPECTION_FINDING_COMMUNICATION_CREATED',
|
||||
FINDING_CATEGORY_CREATED = 'FINDING_CATEGORY_CREATED',
|
||||
FINDING_CATEGORY_UPDATED = 'FINDING_CATEGORY_UPDATED',
|
||||
FINDING_CATALOG_ITEM_CREATED = 'FINDING_CATALOG_ITEM_CREATED',
|
||||
FINDING_CATALOG_ITEM_UPDATED = 'FINDING_CATALOG_ITEM_UPDATED',
|
||||
FINDING_CATALOG_TYPE_APPLICABILITY_UPDATED = 'FINDING_CATALOG_TYPE_APPLICABILITY_UPDATED',
|
||||
FINDING_CATALOG_ASSET_SELECTION_UPDATED = 'FINDING_CATALOG_ASSET_SELECTION_UPDATED',
|
||||
FINDING_CATALOG_PROPOSAL_MATCHED = 'FINDING_CATALOG_PROPOSAL_MATCHED',
|
||||
FINDING_CATALOG_PROPOSAL_REJECTED = 'FINDING_CATALOG_PROPOSAL_REJECTED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'audit_events' })
|
||||
@Index('idx_audit_events_occurred_at', ['occurredAt'])
|
||||
@Index('idx_audit_events_actor_user_id', ['actorUserId'])
|
||||
@Index('idx_audit_events_action', ['action'])
|
||||
@Index('idx_audit_events_entity', ['entityType', 'entityId'])
|
||||
@Index('idx_audit_events_request_id', ['requestId'])
|
||||
export class AuditEvent {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'occurred_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
occurredAt!: Date;
|
||||
|
||||
@Column({ name: 'actor_user_id', type: 'uuid', nullable: true })
|
||||
actorUserId!: string | null;
|
||||
|
||||
@Column({ name: 'actor_username', type: 'varchar', length: 80, nullable: true })
|
||||
actorUsername!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 100 })
|
||||
action!: string;
|
||||
|
||||
@Column({ name: 'entity_type', type: 'varchar', length: 100, nullable: true })
|
||||
entityType!: string | null;
|
||||
|
||||
@Column({ name: 'entity_id', type: 'varchar', length: 255, nullable: true })
|
||||
entityId!: string | null;
|
||||
|
||||
@Column({ name: 'request_id', type: 'varchar', length: 128, nullable: true })
|
||||
requestId!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 32 })
|
||||
source!: AuditSource;
|
||||
|
||||
@Column({ type: 'inet', nullable: true })
|
||||
ip!: string | null;
|
||||
|
||||
@Column({ name: 'user_agent', type: 'text', nullable: true })
|
||||
userAgent!: string | null;
|
||||
|
||||
@Column({ name: 'before_data', type: 'jsonb', nullable: true })
|
||||
beforeData!: Record<string, unknown> | null;
|
||||
|
||||
@Column({ name: 'after_data', type: 'jsonb', nullable: true })
|
||||
afterData!: Record<string, unknown> | null;
|
||||
|
||||
@Column({ type: 'jsonb', nullable: true })
|
||||
metadata!: Record<string, unknown> | null;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
} from 'typeorm';
|
||||
import { User } from './user.entity';
|
||||
|
||||
@Entity({ name: 'auth_sessions' })
|
||||
@Index('idx_auth_sessions_user_id', ['userId'])
|
||||
@Index('idx_auth_sessions_expires_at', ['expiresAt'])
|
||||
@Index('idx_auth_sessions_revoked_at', ['revokedAt'])
|
||||
@Index('idx_auth_sessions_replaced_by_session_id', ['replacedBySessionId'])
|
||||
export class AuthSession {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'user_id', type: 'uuid' })
|
||||
userId!: string;
|
||||
|
||||
@Column({ name: 'refresh_token_hash', type: 'text', select: false })
|
||||
refreshTokenHash!: string;
|
||||
|
||||
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
||||
createdAt!: Date;
|
||||
|
||||
@Column({ name: 'expires_at', type: 'timestamptz' })
|
||||
expiresAt!: Date;
|
||||
|
||||
@Column({ name: 'last_used_at', type: 'timestamptz' })
|
||||
lastUsedAt!: Date;
|
||||
|
||||
@Column({ name: 'revoked_at', type: 'timestamptz', nullable: true })
|
||||
revokedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'replaced_by_session_id', type: 'uuid', nullable: true })
|
||||
replacedBySessionId!: string | null;
|
||||
|
||||
@Column({ type: 'inet', nullable: true })
|
||||
ip!: string | null;
|
||||
|
||||
@Column({ name: 'user_agent', type: 'text', nullable: true })
|
||||
userAgent!: string | null;
|
||||
|
||||
@Column({ name: 'device_label', type: 'text', nullable: true })
|
||||
deviceLabel!: string | null;
|
||||
|
||||
@ManyToOne(() => User, { onDelete: 'RESTRICT' })
|
||||
@JoinColumn({ name: 'user_id' })
|
||||
user!: User;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Column, Entity, PrimaryColumn, UpdateDateColumn } from 'typeorm';
|
||||
|
||||
export enum DocumentSequenceType {
|
||||
ACT = 'ACT',
|
||||
REPORT = 'REPORT',
|
||||
}
|
||||
|
||||
@Entity({ name: 'document_annual_sequences' })
|
||||
export class DocumentAnnualSequence {
|
||||
@PrimaryColumn({ name: 'document_type', type: 'varchar', length: 20 })
|
||||
documentType!: DocumentSequenceType;
|
||||
|
||||
@PrimaryColumn({ type: 'integer' })
|
||||
year!: number;
|
||||
|
||||
@Column({ name: 'last_number', type: 'integer', default: 0 })
|
||||
lastNumber!: number;
|
||||
|
||||
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
|
||||
updatedAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
@Entity({ name: 'finding_catalog_asset_overrides' })
|
||||
@Index('uq_finding_catalog_asset_overrides_pair', ['assetId', 'catalogItemId'], { unique: true })
|
||||
@Index('idx_finding_catalog_asset_overrides_asset', ['assetId'])
|
||||
export class FindingCatalogAssetOverride extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'asset_id', type: 'uuid' })
|
||||
assetId!: string;
|
||||
|
||||
@Column({ name: 'catalog_item_id', type: 'uuid' })
|
||||
catalogItemId!: string;
|
||||
|
||||
@Column({ name: 'is_enabled', type: 'boolean' })
|
||||
isEnabled!: boolean;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
reason!: string;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
@Entity({ name: 'finding_catalog_asset_type_profiles' })
|
||||
@Index('idx_finding_catalog_asset_type_profiles_updated', ['updatedAt'])
|
||||
export class FindingCatalogAssetTypeProfile extends TimestampedEntity {
|
||||
@PrimaryColumn({ name: 'asset_type_id', type: 'uuid' })
|
||||
assetTypeId!: string;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
reason!: string;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
@Entity({ name: 'finding_catalog_item_asset_types' })
|
||||
@Index('uq_finding_catalog_item_asset_types_pair', ['catalogItemId', 'assetTypeId'], { unique: true })
|
||||
@Index('idx_finding_catalog_item_asset_types_type', ['assetTypeId', 'catalogItemId'])
|
||||
export class FindingCatalogItemAssetType extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'catalog_item_id', type: 'uuid' })
|
||||
catalogItemId!: string;
|
||||
|
||||
@Column({ name: 'asset_type_id', type: 'uuid' })
|
||||
assetTypeId!: string;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
@Entity({ name: 'finding_catalog_items' })
|
||||
@Index('uq_finding_catalog_items_code', ['code'], { unique: true })
|
||||
@Index('uq_finding_catalog_items_source', ['categoryId', 'sourceNumber'], { unique: true })
|
||||
@Index('idx_finding_catalog_items_active', ['categoryId', 'isActive'])
|
||||
export class FindingCatalogItem extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'category_id', type: 'uuid' })
|
||||
categoryId!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 120 })
|
||||
code!: string;
|
||||
|
||||
@Column({ name: 'source_number', type: 'integer' })
|
||||
sourceNumber!: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 500 })
|
||||
title!: string;
|
||||
|
||||
@Column({ name: 'legal_basis', type: 'text', nullable: true })
|
||||
legalBasis!: string | null;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
glossary!: string | null;
|
||||
|
||||
@Column({ name: 'import_note', type: 'text', nullable: true })
|
||||
importNote!: string | null;
|
||||
|
||||
@Column({ name: 'suggested_severity', type: 'smallint', nullable: true })
|
||||
suggestedSeverity!: number | null;
|
||||
|
||||
@Column({ type: 'integer', default: 1 })
|
||||
revision!: number;
|
||||
|
||||
@Column({ name: 'is_active', type: 'boolean', default: true })
|
||||
isActive!: boolean;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum FindingCatalogProposalStatus {
|
||||
PENDING = 'PENDING',
|
||||
MATCHED = 'MATCHED',
|
||||
REJECTED = 'REJECTED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'finding_catalog_proposals' })
|
||||
@Index('uq_finding_catalog_proposals_finding', ['findingId'], { unique: true })
|
||||
@Index('idx_finding_catalog_proposals_status', ['status', 'createdAt'])
|
||||
@Index('idx_finding_catalog_proposals_asset_type', ['assetTypeId', 'status'])
|
||||
export class FindingCatalogProposal extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'finding_id', type: 'uuid' })
|
||||
findingId!: string;
|
||||
|
||||
@Column({ name: 'asset_id', type: 'uuid' })
|
||||
assetId!: string;
|
||||
|
||||
@Column({ name: 'asset_type_id', type: 'uuid' })
|
||||
assetTypeId!: string;
|
||||
|
||||
@Column({ name: 'proposed_title', type: 'varchar', length: 500 })
|
||||
proposedTitle!: string;
|
||||
|
||||
@Column({ name: 'proposed_legal_basis', type: 'text', nullable: true })
|
||||
proposedLegalBasis!: string | null;
|
||||
|
||||
@Column({ name: 'proposed_severity', type: 'smallint', nullable: true })
|
||||
proposedSeverity!: number | null;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
description!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 20, default: FindingCatalogProposalStatus.PENDING })
|
||||
status!: FindingCatalogProposalStatus;
|
||||
|
||||
@Column({ name: 'resolved_catalog_item_id', type: 'uuid', nullable: true })
|
||||
resolvedCatalogItemId!: string | null;
|
||||
|
||||
@Column({ name: 'office_notes', type: 'text', nullable: true })
|
||||
officeNotes!: string | null;
|
||||
|
||||
@Column({ name: 'reviewed_by', type: 'uuid', nullable: true })
|
||||
reviewedBy!: string | null;
|
||||
|
||||
@Column({ name: 'reviewed_at', type: 'timestamptz', nullable: true })
|
||||
reviewedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
@Entity({ name: 'finding_categories' })
|
||||
@Index('uq_finding_categories_code', ['code'], { unique: true })
|
||||
@Index('idx_finding_categories_active_order', ['isActive', 'sortOrder'])
|
||||
export class FindingCategory extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 80 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 200 })
|
||||
name!: string;
|
||||
|
||||
@Column({ name: 'sort_order', type: 'integer', default: 0 })
|
||||
sortOrder!: number;
|
||||
|
||||
@Column({ name: 'is_active', type: 'boolean', default: true })
|
||||
isActive!: boolean;
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
export { AuditAction, AuditEvent, AuditSource } from './audit-event.entity';
|
||||
export { AuthSession } from './auth-session.entity';
|
||||
export { Permission } from './permission.entity';
|
||||
export { RolePermission } from './role-permission.entity';
|
||||
export { Role } from './role.entity';
|
||||
export { UserRole } from './user-role.entity';
|
||||
export { User, UserStatus } from './user.entity';
|
||||
export { Asset, AssetDataOrigin, AssetInformationStatus, AssetOperationalStatus } from './asset.entity';
|
||||
export {
|
||||
AssetVersion,
|
||||
AssetVersionChangeType,
|
||||
} from './asset-version.entity';
|
||||
export {
|
||||
AssetAttributeDataType,
|
||||
AssetAttributeDefinition,
|
||||
} from './asset-attribute-definition.entity';
|
||||
export { AssetAttributeValue } from './asset-attribute-value.entity';
|
||||
export { AreaCompanyRelation, AreaOrganizationRole } from './area-company-relation.entity';
|
||||
export { OrganizationProfile, OrganizationKind } from './organization-profile.entity';
|
||||
export { OrganizationMembership, OrganizationMembershipRole } from './organization-membership.entity';
|
||||
export { SourceDocument, SourceDocumentType } from './source-document.entity';
|
||||
export { AssetSourceDocument, AssetSourceDocumentRelationType } from './asset-source-document.entity';
|
||||
export { AssetExternalIdentifier } from './asset-external-identifier.entity';
|
||||
export { AreaLegalRight, AreaLegalRightType, AreaLegalRightStatus } from './area-legal-right.entity';
|
||||
export { AreaLegalRightOrganization, AreaLegalRightOrganizationRole } from './area-legal-right-organization.entity';
|
||||
export { AssetTypeParentRule } from './asset-type-parent-rule.entity';
|
||||
export { AssetType, AssetTypeOperationalRole } from './asset-type.entity';
|
||||
export {
|
||||
AssetGeometry,
|
||||
AssetGeometrySource,
|
||||
AssetGeometryType,
|
||||
} from './asset-geometry.entity';
|
||||
export {
|
||||
AssetMedia,
|
||||
AssetMediaKind,
|
||||
AssetMediaSource,
|
||||
} from './asset-media.entity';
|
||||
export {
|
||||
SurveyCampaign,
|
||||
SurveyCampaignStatus,
|
||||
} from './survey-campaign.entity';
|
||||
export {
|
||||
SurveyCampaignTarget,
|
||||
SurveyTargetStatus,
|
||||
} from './survey-campaign-target.entity';
|
||||
export {
|
||||
SurveyReportOutcome,
|
||||
SurveyReportStatus,
|
||||
SurveyTargetReport,
|
||||
} from './survey-target-report.entity';
|
||||
export { SurveyTargetReportMedia } from './survey-target-report-media.entity';
|
||||
export {
|
||||
SurveyReportVersionEvent,
|
||||
SurveyTargetReportVersion,
|
||||
} from './survey-target-report-version.entity';
|
||||
export {
|
||||
InspectionVisit,
|
||||
InspectionVisitStatus,
|
||||
} from './inspection-visit.entity';
|
||||
export { InspectionVisitAsset, InspectionVisitAssetPlanningSource } from './inspection-visit-asset.entity';
|
||||
export { InspectionVisitMember } from './inspection-visit-member.entity';
|
||||
export {
|
||||
DocumentAnnualSequence,
|
||||
DocumentSequenceType,
|
||||
} from './document-annual-sequence.entity';
|
||||
export {
|
||||
InspectionAct,
|
||||
InspectionActStatus,
|
||||
} from './inspection-act.entity';
|
||||
export { InspectionActAsset } from './inspection-act-asset.entity';
|
||||
export {
|
||||
InspectionReport,
|
||||
InspectionReportPdfStatus,
|
||||
InspectionReportReviewStatus,
|
||||
InspectionReportStatus,
|
||||
InspectionReportWordStatus,
|
||||
} from './inspection-report.entity';
|
||||
export {
|
||||
InspectionActVersion,
|
||||
InspectionActVersionEvent,
|
||||
} from './inspection-act-version.entity';
|
||||
export {
|
||||
InspectionActResponsible,
|
||||
InspectionResponsibleAttendanceStatus,
|
||||
InspectionResponsibleDocumentType,
|
||||
} from './inspection-act-responsible.entity';
|
||||
export {
|
||||
InspectionActClosure,
|
||||
InspectionActUploadMode,
|
||||
} from './inspection-act-closure.entity';
|
||||
export {
|
||||
InspectionActSignature,
|
||||
InspectionActSignatureSource,
|
||||
InspectionActSignatureStatus,
|
||||
InspectionActSignerType,
|
||||
} from './inspection-act-signature.entity';
|
||||
export { FindingCategory } from './finding-category.entity';
|
||||
export { FindingCatalogItem } from './finding-catalog-item.entity';
|
||||
export { FindingCatalogItemAssetType } from './finding-catalog-item-asset-type.entity';
|
||||
export { FindingCatalogAssetTypeProfile } from './finding-catalog-asset-type-profile.entity';
|
||||
export { FindingCatalogAssetOverride } from './finding-catalog-asset-override.entity';
|
||||
export { FindingCatalogProposal, FindingCatalogProposalStatus } from './finding-catalog-proposal.entity';
|
||||
export {
|
||||
InspectionFinding,
|
||||
InspectionFindingResponseDueBasis,
|
||||
InspectionFindingStatus,
|
||||
} from './inspection-finding.entity';
|
||||
export {
|
||||
InspectionFindingVersion,
|
||||
InspectionFindingVersionEvent,
|
||||
} from './inspection-finding-version.entity';
|
||||
export {
|
||||
InspectionCommunicationChannel,
|
||||
InspectionCommunicationDirection,
|
||||
InspectionCommunicationType,
|
||||
InspectionFindingCommunication,
|
||||
} from './inspection-finding-communication.entity';
|
||||
export {
|
||||
InspectionEvidenceKind,
|
||||
InspectionEvidencePurpose,
|
||||
InspectionEvidenceSource,
|
||||
InspectionFindingEvidence,
|
||||
} from './inspection-finding-evidence.entity';
|
||||
export {
|
||||
InspectionFindingVerificationVisit,
|
||||
InspectionVerificationOutcome,
|
||||
} from './inspection-finding-verification-visit.entity';
|
||||
export {
|
||||
InspectionFindingVerificationEvent,
|
||||
InspectionFindingVerificationEventType,
|
||||
} from './inspection-finding-verification-event.entity';
|
||||
|
||||
import { AuditEvent } from './audit-event.entity';
|
||||
import { AuthSession } from './auth-session.entity';
|
||||
import { Permission } from './permission.entity';
|
||||
import { RolePermission } from './role-permission.entity';
|
||||
import { Role } from './role.entity';
|
||||
import { UserRole } from './user-role.entity';
|
||||
import { User } from './user.entity';
|
||||
import { Asset } from './asset.entity';
|
||||
import { AssetAttributeDefinition } from './asset-attribute-definition.entity';
|
||||
import { AssetAttributeValue } from './asset-attribute-value.entity';
|
||||
import { AssetTypeParentRule } from './asset-type-parent-rule.entity';
|
||||
import { AssetType } from './asset-type.entity';
|
||||
import { AreaCompanyRelation } from './area-company-relation.entity';
|
||||
import { OrganizationProfile } from './organization-profile.entity';
|
||||
import { OrganizationMembership } from './organization-membership.entity';
|
||||
import { SourceDocument } from './source-document.entity';
|
||||
import { AssetSourceDocument } from './asset-source-document.entity';
|
||||
import { AssetExternalIdentifier } from './asset-external-identifier.entity';
|
||||
import { AreaLegalRight } from './area-legal-right.entity';
|
||||
import { AreaLegalRightOrganization } from './area-legal-right-organization.entity';
|
||||
import { AssetGeometry } from './asset-geometry.entity';
|
||||
import { AssetVersion } from './asset-version.entity';
|
||||
import { AssetMedia } from './asset-media.entity';
|
||||
import { SurveyCampaign } from './survey-campaign.entity';
|
||||
import { SurveyCampaignTarget } from './survey-campaign-target.entity';
|
||||
import { SurveyTargetReport } from './survey-target-report.entity';
|
||||
import { SurveyTargetReportMedia } from './survey-target-report-media.entity';
|
||||
import { SurveyTargetReportVersion } from './survey-target-report-version.entity';
|
||||
import { InspectionVisit } from './inspection-visit.entity';
|
||||
import { InspectionVisitAsset } from './inspection-visit-asset.entity';
|
||||
import { InspectionVisitMember } from './inspection-visit-member.entity';
|
||||
import { DocumentAnnualSequence } from './document-annual-sequence.entity';
|
||||
import { InspectionAct } from './inspection-act.entity';
|
||||
import { InspectionActAsset } from './inspection-act-asset.entity';
|
||||
import { InspectionReport } from './inspection-report.entity';
|
||||
import { InspectionActVersion } from './inspection-act-version.entity';
|
||||
import { InspectionActResponsible } from './inspection-act-responsible.entity';
|
||||
import { InspectionActClosure } from './inspection-act-closure.entity';
|
||||
import { InspectionActSignature } from './inspection-act-signature.entity';
|
||||
import { FindingCategory } from './finding-category.entity';
|
||||
import { FindingCatalogItem } from './finding-catalog-item.entity';
|
||||
import { FindingCatalogItemAssetType } from './finding-catalog-item-asset-type.entity';
|
||||
import { FindingCatalogAssetTypeProfile } from './finding-catalog-asset-type-profile.entity';
|
||||
import { FindingCatalogAssetOverride } from './finding-catalog-asset-override.entity';
|
||||
import { FindingCatalogProposal } from './finding-catalog-proposal.entity';
|
||||
import { InspectionFinding } from './inspection-finding.entity';
|
||||
import { InspectionFindingVersion } from './inspection-finding-version.entity';
|
||||
import { InspectionFindingCommunication } from './inspection-finding-communication.entity';
|
||||
import { InspectionFindingEvidence } from './inspection-finding-evidence.entity';
|
||||
import { InspectionFindingVerificationVisit } from './inspection-finding-verification-visit.entity';
|
||||
import { InspectionFindingVerificationEvent } from './inspection-finding-verification-event.entity';
|
||||
|
||||
export const PHASE_A_ENTITIES = [
|
||||
User,
|
||||
Role,
|
||||
Permission,
|
||||
UserRole,
|
||||
RolePermission,
|
||||
AuthSession,
|
||||
AuditEvent,
|
||||
AssetType,
|
||||
AssetTypeParentRule,
|
||||
AssetAttributeDefinition,
|
||||
Asset,
|
||||
AssetAttributeValue,
|
||||
AreaCompanyRelation,
|
||||
OrganizationProfile,
|
||||
OrganizationMembership,
|
||||
SourceDocument,
|
||||
AssetSourceDocument,
|
||||
AssetExternalIdentifier,
|
||||
AreaLegalRight,
|
||||
AreaLegalRightOrganization,
|
||||
AssetGeometry,
|
||||
AssetVersion,
|
||||
AssetMedia,
|
||||
SurveyCampaign,
|
||||
SurveyCampaignTarget,
|
||||
SurveyTargetReport,
|
||||
SurveyTargetReportMedia,
|
||||
SurveyTargetReportVersion,
|
||||
InspectionVisit,
|
||||
InspectionVisitAsset,
|
||||
InspectionVisitMember,
|
||||
DocumentAnnualSequence,
|
||||
InspectionAct,
|
||||
InspectionActAsset,
|
||||
InspectionReport,
|
||||
InspectionActVersion,
|
||||
InspectionActResponsible,
|
||||
InspectionActClosure,
|
||||
InspectionActSignature,
|
||||
FindingCategory,
|
||||
FindingCatalogItem,
|
||||
FindingCatalogItemAssetType,
|
||||
FindingCatalogAssetTypeProfile,
|
||||
FindingCatalogAssetOverride,
|
||||
FindingCatalogProposal,
|
||||
InspectionFinding,
|
||||
InspectionFindingVersion,
|
||||
InspectionFindingCommunication,
|
||||
InspectionFindingEvidence,
|
||||
InspectionFindingVerificationVisit,
|
||||
InspectionFindingVerificationEvent,
|
||||
];
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
@Entity({ name: 'inspection_act_assets' })
|
||||
@Index('idx_inspection_act_assets_asset_id', ['assetId'])
|
||||
@Index('idx_inspection_act_assets_included', ['actId', 'included'])
|
||||
export class InspectionActAsset extends TimestampedEntity {
|
||||
@PrimaryColumn({ name: 'act_id', type: 'uuid' })
|
||||
actId!: string;
|
||||
|
||||
@PrimaryColumn({ name: 'asset_id', type: 'uuid' })
|
||||
assetId!: string;
|
||||
|
||||
@Column({ type: 'boolean', default: true })
|
||||
included!: boolean;
|
||||
|
||||
@Column({ name: 'added_by', type: 'uuid', nullable: true })
|
||||
addedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||
|
||||
export enum InspectionActUploadMode {
|
||||
IMMEDIATE = 'IMMEDIATE',
|
||||
DEFERRED = 'DEFERRED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_act_closures' })
|
||||
export class InspectionActClosure {
|
||||
@PrimaryColumn({ name: 'act_id', type: 'uuid' })
|
||||
actId!: string;
|
||||
|
||||
@Column({ name: 'schema_version', type: 'varchar', length: 40 })
|
||||
schemaVersion!: string;
|
||||
|
||||
@Column({ name: 'prepared_snapshot', type: 'jsonb' })
|
||||
preparedSnapshot!: Record<string, unknown>;
|
||||
|
||||
@Column({ name: 'prepared_sha256', type: 'char', length: 64 })
|
||||
preparedSha256!: string;
|
||||
|
||||
@Column({ name: 'prepared_at', type: 'timestamptz' })
|
||||
preparedAt!: Date;
|
||||
|
||||
@Column({ name: 'prepared_by', type: 'uuid' })
|
||||
preparedBy!: string;
|
||||
|
||||
@Column({ name: 'final_snapshot', type: 'jsonb', nullable: true })
|
||||
finalSnapshot!: Record<string, unknown> | null;
|
||||
|
||||
@Column({ name: 'final_sha256', type: 'char', length: 64, nullable: true })
|
||||
finalSha256!: string | null;
|
||||
|
||||
@Column({ name: 'device_closed_at', type: 'timestamptz', nullable: true })
|
||||
deviceClosedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'server_closed_at', type: 'timestamptz', nullable: true })
|
||||
serverClosedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'upload_mode', type: 'varchar', length: 20, nullable: true })
|
||||
uploadMode!: InspectionActUploadMode | null;
|
||||
|
||||
@Column({ name: 'closed_by', type: 'uuid', nullable: true })
|
||||
closedBy!: string | null;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
|
||||
@Column({ name: 'updated_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
updatedAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||
|
||||
export enum InspectionResponsibleAttendanceStatus {
|
||||
PRESENT = 'PRESENT',
|
||||
ABSENT = 'ABSENT',
|
||||
}
|
||||
|
||||
export enum InspectionResponsibleDocumentType {
|
||||
DNI = 'DNI',
|
||||
CUIL = 'CUIL',
|
||||
PASSPORT = 'PASSPORT',
|
||||
OTHER = 'OTHER',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_act_responsibles' })
|
||||
export class InspectionActResponsible {
|
||||
@PrimaryColumn({ name: 'act_id', type: 'uuid' })
|
||||
actId!: string;
|
||||
|
||||
@Column({ name: 'attendance_status', type: 'varchar', length: 20 })
|
||||
attendanceStatus!: InspectionResponsibleAttendanceStatus;
|
||||
|
||||
@Column({ name: 'full_name', type: 'varchar', length: 200, nullable: true })
|
||||
fullName!: string | null;
|
||||
|
||||
@Column({ name: 'document_type', type: 'varchar', length: 20, nullable: true })
|
||||
documentType!: InspectionResponsibleDocumentType | null;
|
||||
|
||||
@Column({ name: 'document_number', type: 'varchar', length: 40, nullable: true })
|
||||
documentNumber!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||
position!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 320, nullable: true })
|
||||
email!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 50, nullable: true })
|
||||
phone!: string | null;
|
||||
|
||||
@Column({ name: 'absence_reason', type: 'text', nullable: true })
|
||||
absenceReason!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
|
||||
@Column({ name: 'updated_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
updatedAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { InspectionResponsibleDocumentType } from './inspection-act-responsible.entity';
|
||||
|
||||
export enum InspectionActSignerType {
|
||||
INSPECTOR = 'INSPECTOR',
|
||||
COMPANY_RESPONSIBLE = 'COMPANY_RESPONSIBLE',
|
||||
}
|
||||
|
||||
export enum InspectionActSignatureStatus {
|
||||
SIGNED = 'SIGNED',
|
||||
REFUSED = 'REFUSED',
|
||||
ABSENT = 'ABSENT',
|
||||
}
|
||||
|
||||
export enum InspectionActSignatureSource {
|
||||
WEB = 'WEB',
|
||||
ANDROID = 'ANDROID',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_act_signatures' })
|
||||
@Index('idx_inspection_act_signatures_act_created', ['actId', 'createdAt'])
|
||||
@Index('idx_inspection_act_signatures_sha256', ['signaturePayloadSha256'])
|
||||
export class InspectionActSignature {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'act_id', type: 'uuid' })
|
||||
actId!: string;
|
||||
|
||||
@Column({ name: 'signer_type', type: 'varchar', length: 32 })
|
||||
signerType!: InspectionActSignerType;
|
||||
|
||||
@Column({ name: 'signer_user_id', type: 'uuid', nullable: true })
|
||||
signerUserId!: string | null;
|
||||
|
||||
@Column({ name: 'signer_name', type: 'varchar', length: 200 })
|
||||
signerName!: string;
|
||||
|
||||
@Column({ name: 'document_type', type: 'varchar', length: 20, nullable: true })
|
||||
documentType!: InspectionResponsibleDocumentType | null;
|
||||
|
||||
@Column({ name: 'document_number', type: 'varchar', length: 40, nullable: true })
|
||||
documentNumber!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||
position!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 20 })
|
||||
status!: InspectionActSignatureStatus;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
reason!: string | null;
|
||||
|
||||
@Column({ name: 'original_name', type: 'varchar', length: 255, nullable: true })
|
||||
originalName!: string | null;
|
||||
|
||||
@Column({ name: 'stored_name', type: 'varchar', length: 80, nullable: true })
|
||||
storedName!: string | null;
|
||||
|
||||
@Column({ name: 'mime_type', type: 'varchar', length: 100, nullable: true })
|
||||
mimeType!: string | null;
|
||||
|
||||
@Column({ name: 'size_bytes', type: 'bigint', nullable: true })
|
||||
sizeBytes!: number | null;
|
||||
|
||||
@Column({ name: 'image_sha256', type: 'char', length: 64, nullable: true })
|
||||
imageSha256!: string | null;
|
||||
|
||||
@Column({ name: 'consent_text', type: 'text', nullable: true })
|
||||
consentText!: string | null;
|
||||
|
||||
@Column({ name: 'consent_version', type: 'varchar', length: 20, nullable: true })
|
||||
consentVersion!: string | null;
|
||||
|
||||
@Column({ name: 'consent_accepted_at', type: 'timestamptz', nullable: true })
|
||||
consentAcceptedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'client_signed_at', type: 'timestamptz', nullable: true })
|
||||
clientSignedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'signed_at', type: 'timestamptz', nullable: true })
|
||||
signedAt!: Date | null;
|
||||
|
||||
@Column({ type: 'numeric', precision: 9, scale: 6, nullable: true })
|
||||
latitude!: number | null;
|
||||
|
||||
@Column({ type: 'numeric', precision: 9, scale: 6, nullable: true })
|
||||
longitude!: number | null;
|
||||
|
||||
@Column({ name: 'accuracy_m', type: 'numeric', precision: 12, scale: 3, nullable: true })
|
||||
accuracyM!: number | null;
|
||||
|
||||
@Column({ name: 'device_label', type: 'varchar', length: 200, nullable: true })
|
||||
deviceLabel!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 20 })
|
||||
source!: InspectionActSignatureSource;
|
||||
|
||||
@Column({ name: 'prepared_sha256', type: 'char', length: 64 })
|
||||
preparedSha256!: string;
|
||||
|
||||
@Column({ name: 'signature_payload_sha256', type: 'char', length: 64 })
|
||||
signaturePayloadSha256!: string;
|
||||
|
||||
@Column({ name: 'uploaded_by', type: 'uuid' })
|
||||
uploadedBy!: string;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
export enum InspectionActVersionEvent {
|
||||
CREATED = 'CREATED',
|
||||
UPDATED = 'UPDATED',
|
||||
READY = 'READY',
|
||||
REOPENED = 'REOPENED',
|
||||
CLOSED = 'CLOSED',
|
||||
CANCELLED = 'CANCELLED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_act_versions' })
|
||||
@Index('uq_inspection_act_versions_number', ['actId', 'versionNumber'], { unique: true })
|
||||
@Index('idx_inspection_act_versions_created_at', ['createdAt'])
|
||||
export class InspectionActVersion {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'act_id', type: 'uuid' })
|
||||
actId!: string;
|
||||
|
||||
@Column({ name: 'version_number', type: 'integer' })
|
||||
versionNumber!: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 24 })
|
||||
event!: InspectionActVersionEvent;
|
||||
|
||||
@Column({ type: 'jsonb' })
|
||||
snapshot!: Record<string, unknown>;
|
||||
|
||||
@Column({ name: 'actor_user_id', type: 'uuid', nullable: true })
|
||||
actorUserId!: string | null;
|
||||
|
||||
@Column({ name: 'actor_username', type: 'varchar', length: 80, nullable: true })
|
||||
actorUsername!: string | null;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum InspectionActStatus {
|
||||
DRAFT = 'DRAFT',
|
||||
READY = 'READY',
|
||||
CLOSED = 'CLOSED',
|
||||
CANCELLED = 'CANCELLED',
|
||||
RECTIFIED = 'RECTIFIED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_acts' })
|
||||
@Index('uq_inspection_acts_visit', ['visitId'], { unique: true })
|
||||
@Index('uq_inspection_acts_year_number', ['actYear', 'actNumber'], { unique: true })
|
||||
@Index('uq_inspection_acts_code', ['code'], { unique: true })
|
||||
@Index('idx_inspection_acts_visit_status', ['visitId', 'status'])
|
||||
@Index('idx_inspection_acts_occurred_at', ['occurredAt'])
|
||||
@Index('idx_inspection_acts_created_by', ['createdBy'])
|
||||
export class InspectionAct extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'visit_id', type: 'uuid' })
|
||||
visitId!: string;
|
||||
|
||||
@Column({ name: 'act_year', type: 'integer' })
|
||||
actYear!: number;
|
||||
|
||||
@Column({ name: 'act_number', type: 'integer' })
|
||||
actNumber!: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 24 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 24, default: InspectionActStatus.DRAFT })
|
||||
status!: InspectionActStatus;
|
||||
|
||||
@Column({ name: 'occurred_at', type: 'timestamptz' })
|
||||
occurredAt!: Date;
|
||||
|
||||
@Column({ type: 'varchar', length: 200 })
|
||||
title!: string;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
summary!: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
observations!: string | null;
|
||||
|
||||
@Column({ name: 'current_version', type: 'integer', default: 0 })
|
||||
currentVersion!: number;
|
||||
|
||||
@Column({ name: 'cancellation_reason', type: 'text', nullable: true })
|
||||
cancellationReason!: string | null;
|
||||
|
||||
@Column({ name: 'closed_at', type: 'timestamptz', nullable: true })
|
||||
closedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'closed_by', type: 'uuid', nullable: true })
|
||||
closedBy!: string | null;
|
||||
|
||||
@Column({ name: 'closure_sha256', type: 'char', length: 64, nullable: true })
|
||||
closureSha256!: string | null;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
export enum InspectionCommunicationDirection {
|
||||
INBOUND = 'INBOUND',
|
||||
OUTBOUND = 'OUTBOUND',
|
||||
INTERNAL = 'INTERNAL',
|
||||
}
|
||||
|
||||
export enum InspectionCommunicationChannel {
|
||||
EMAIL = 'EMAIL',
|
||||
IN_PERSON = 'IN_PERSON',
|
||||
PHONE = 'PHONE',
|
||||
LETTER = 'LETTER',
|
||||
SYSTEM = 'SYSTEM',
|
||||
OTHER = 'OTHER',
|
||||
}
|
||||
|
||||
export enum InspectionCommunicationType {
|
||||
COMPANY_RESPONSE = 'COMPANY_RESPONSE',
|
||||
AUTHORITY_NOTICE = 'AUTHORITY_NOTICE',
|
||||
FOLLOW_UP = 'FOLLOW_UP',
|
||||
OTHER = 'OTHER',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_finding_communications' })
|
||||
@Index('uq_inspection_finding_communications_id_finding', ['id', 'findingId'], { unique: true })
|
||||
@Index('idx_inspection_finding_communications_timeline', ['findingId', 'occurredAt'])
|
||||
export class InspectionFindingCommunication {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'finding_id', type: 'uuid' })
|
||||
findingId!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 20 })
|
||||
direction!: InspectionCommunicationDirection;
|
||||
|
||||
@Column({ type: 'varchar', length: 20 })
|
||||
channel!: InspectionCommunicationChannel;
|
||||
|
||||
@Column({ type: 'varchar', length: 32 })
|
||||
type!: InspectionCommunicationType;
|
||||
|
||||
@Column({ name: 'occurred_at', type: 'timestamptz' })
|
||||
occurredAt!: Date;
|
||||
|
||||
@Column({ type: 'varchar', length: 250 })
|
||||
subject!: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
details!: string | null;
|
||||
|
||||
@Column({ name: 'contact_name', type: 'varchar', length: 200, nullable: true })
|
||||
contactName!: string | null;
|
||||
|
||||
@Column({ name: 'contact_email', type: 'varchar', length: 320, nullable: true })
|
||||
contactEmail!: string | null;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
export enum InspectionEvidenceKind {
|
||||
PHOTO = 'PHOTO',
|
||||
DOCUMENT = 'DOCUMENT',
|
||||
}
|
||||
|
||||
export enum InspectionEvidencePurpose {
|
||||
OBSERVATION = 'OBSERVATION',
|
||||
VERIFICATION = 'VERIFICATION',
|
||||
COMPANY_RESPONSE = 'COMPANY_RESPONSE',
|
||||
COMMUNICATION_ATTACHMENT = 'COMMUNICATION_ATTACHMENT',
|
||||
OTHER_DOCUMENT = 'OTHER_DOCUMENT',
|
||||
}
|
||||
|
||||
export enum InspectionEvidenceSource {
|
||||
WEB = 'WEB',
|
||||
ANDROID = 'ANDROID',
|
||||
IMPORT = 'IMPORT',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_finding_evidence' })
|
||||
@Index('idx_inspection_finding_evidence_finding_created', ['findingId', 'createdAt'])
|
||||
@Index('idx_inspection_finding_evidence_sha256', ['sha256'])
|
||||
@Index('idx_inspection_finding_evidence_communication', ['communicationId'])
|
||||
export class InspectionFindingEvidence {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'finding_id', type: 'uuid' })
|
||||
findingId!: string;
|
||||
|
||||
@Column({ name: 'communication_id', type: 'uuid', nullable: true })
|
||||
communicationId!: string | null;
|
||||
|
||||
@Column({ name: 'verification_visit_id', type: 'uuid', nullable: true })
|
||||
verificationVisitId!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 20 })
|
||||
kind!: InspectionEvidenceKind;
|
||||
|
||||
@Column({ type: 'varchar', length: 40 })
|
||||
purpose!: InspectionEvidencePurpose;
|
||||
|
||||
@Column({ name: 'original_name', type: 'varchar', length: 255 })
|
||||
originalName!: string;
|
||||
|
||||
@Column({ name: 'stored_name', type: 'varchar', length: 80 })
|
||||
storedName!: string;
|
||||
|
||||
@Column({ name: 'mime_type', type: 'varchar', length: 100 })
|
||||
mimeType!: string;
|
||||
|
||||
@Column({ name: 'size_bytes', type: 'bigint' })
|
||||
sizeBytes!: string;
|
||||
|
||||
@Column({ type: 'char', length: 64 })
|
||||
sha256!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 200, nullable: true })
|
||||
title!: string | null;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
description!: string | null;
|
||||
|
||||
@Column({ name: 'captured_at', type: 'timestamptz', nullable: true })
|
||||
capturedAt!: Date | null;
|
||||
|
||||
@Column({ type: 'numeric', precision: 9, scale: 6, nullable: true })
|
||||
latitude!: string | null;
|
||||
|
||||
@Column({ type: 'numeric', precision: 9, scale: 6, nullable: true })
|
||||
longitude!: string | null;
|
||||
|
||||
@Column({ name: 'accuracy_m', type: 'numeric', precision: 12, scale: 3, nullable: true })
|
||||
accuracyM!: string | null;
|
||||
|
||||
@Column({ name: 'device_label', type: 'varchar', length: 200, nullable: true })
|
||||
deviceLabel!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 20 })
|
||||
source!: InspectionEvidenceSource;
|
||||
|
||||
@Column({ name: 'uploaded_by', type: 'uuid', nullable: true })
|
||||
uploadedBy!: string | null;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { InspectionVerificationOutcome } from './inspection-finding-verification-visit.entity';
|
||||
|
||||
export enum InspectionFindingVerificationEventType {
|
||||
CONTROL_DATE_DEFINED = 'CONTROL_DATE_DEFINED',
|
||||
CONTROL_DATE_CHANGED = 'CONTROL_DATE_CHANGED',
|
||||
CONTROL_DATE_CLEARED = 'CONTROL_DATE_CLEARED',
|
||||
VISIT_PLANNED = 'VISIT_PLANNED',
|
||||
RESULT_RECORDED = 'RESULT_RECORDED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_finding_verification_events' })
|
||||
@Index('idx_inspection_finding_verification_events_finding', ['findingId', 'occurredAt'])
|
||||
@Index('idx_inspection_finding_verification_events_visit', ['verificationVisitId'])
|
||||
export class InspectionFindingVerificationEvent {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'finding_id', type: 'uuid' })
|
||||
findingId!: string;
|
||||
|
||||
@Column({ name: 'verification_visit_id', type: 'uuid', nullable: true })
|
||||
verificationVisitId!: string | null;
|
||||
|
||||
@Column({ name: 'event_type', type: 'varchar', length: 40 })
|
||||
eventType!: InspectionFindingVerificationEventType;
|
||||
|
||||
@Column({ name: 'occurred_at', type: 'timestamptz' })
|
||||
occurredAt!: Date;
|
||||
|
||||
@Column({ name: 'target_control_on', type: 'date', nullable: true })
|
||||
targetControlOn!: string | null;
|
||||
|
||||
@Column({ name: 'previous_control_on', type: 'date', nullable: true })
|
||||
previousControlOn!: string | null;
|
||||
|
||||
@Column({ name: 'next_control_on', type: 'date', nullable: true })
|
||||
nextControlOn!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 24, nullable: true })
|
||||
outcome!: InspectionVerificationOutcome | null;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
notes!: string | null;
|
||||
|
||||
@Column({ name: 'actor_user_id', type: 'uuid', nullable: true })
|
||||
actorUserId!: string | null;
|
||||
|
||||
@Column({ name: 'actor_username', type: 'varchar', length: 80, nullable: true })
|
||||
actorUsername!: string | null;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum InspectionVerificationOutcome {
|
||||
RESOLVED = 'RESOLVED',
|
||||
NOT_RESOLVED = 'NOT_RESOLVED',
|
||||
REQUIRES_NEW_DATE = 'REQUIRES_NEW_DATE',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_finding_verification_visits' })
|
||||
@Index('uq_inspection_finding_verification_visit', ['findingId', 'visitId'], { unique: true })
|
||||
@Index('idx_inspection_finding_verification_finding', ['findingId'])
|
||||
@Index('idx_inspection_finding_verification_visit', ['visitId'])
|
||||
export class InspectionFindingVerificationVisit extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'finding_id', type: 'uuid' })
|
||||
findingId!: string;
|
||||
|
||||
@Column({ name: 'visit_id', type: 'uuid' })
|
||||
visitId!: string;
|
||||
|
||||
@Column({ name: 'linked_by', type: 'uuid', nullable: true })
|
||||
linkedBy!: string | null;
|
||||
|
||||
@Column({ name: 'target_control_on', type: 'date', nullable: true })
|
||||
targetControlOn!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 24, nullable: true })
|
||||
outcome!: InspectionVerificationOutcome | null;
|
||||
|
||||
@Column({ name: 'result_notes', type: 'text', nullable: true })
|
||||
resultNotes!: string | null;
|
||||
|
||||
@Column({ name: 'verified_at', type: 'timestamptz', nullable: true })
|
||||
verifiedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'result_recorded_at', type: 'timestamptz', nullable: true })
|
||||
resultRecordedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'result_recorded_by', type: 'uuid', nullable: true })
|
||||
resultRecordedBy!: string | null;
|
||||
|
||||
@Column({ name: 'rescheduled_control_on', type: 'date', nullable: true })
|
||||
rescheduledControlOn!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
export enum InspectionFindingVersionEvent {
|
||||
CREATED = 'CREATED',
|
||||
UPDATED = 'UPDATED',
|
||||
FOLLOW_UP_UPDATED = 'FOLLOW_UP_UPDATED',
|
||||
VERIFICATION_RECORDED = 'VERIFICATION_RECORDED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_finding_versions' })
|
||||
@Index('uq_inspection_finding_versions_number', ['findingId', 'versionNumber'], { unique: true })
|
||||
@Index('idx_inspection_finding_versions_created_at', ['createdAt'])
|
||||
export class InspectionFindingVersion {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'finding_id', type: 'uuid' })
|
||||
findingId!: string;
|
||||
|
||||
@Column({ name: 'version_number', type: 'integer' })
|
||||
versionNumber!: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 32 })
|
||||
event!: InspectionFindingVersionEvent;
|
||||
|
||||
@Column({ type: 'jsonb' })
|
||||
snapshot!: Record<string, unknown>;
|
||||
|
||||
@Column({ name: 'actor_user_id', type: 'uuid', nullable: true })
|
||||
actorUserId!: string | null;
|
||||
|
||||
@Column({ name: 'actor_username', type: 'varchar', length: 80, nullable: true })
|
||||
actorUsername!: string | null;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum InspectionFindingResponseDueBasis {
|
||||
FINDING_DATE = 'FINDING_DATE',
|
||||
REPORT_NOTIFICATION = 'REPORT_NOTIFICATION',
|
||||
}
|
||||
|
||||
export enum InspectionFindingStatus {
|
||||
OPEN = 'OPEN',
|
||||
CLOSED = 'CLOSED',
|
||||
VOIDED = 'VOIDED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_findings' })
|
||||
@Index('uq_inspection_findings_number', ['actId', 'findingNumber'], { unique: true })
|
||||
@Index('uq_inspection_findings_code', ['code'], { unique: true })
|
||||
@Index('idx_inspection_findings_status_control', ['status', 'nextControlOn'])
|
||||
@Index('idx_inspection_findings_asset_status', ['assetId', 'status'])
|
||||
@Index('idx_inspection_findings_catalog_item', ['catalogItemId'])
|
||||
export class InspectionFinding extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'act_id', type: 'uuid' })
|
||||
actId!: string;
|
||||
|
||||
@Column({ name: 'asset_id', type: 'uuid' })
|
||||
assetId!: string;
|
||||
|
||||
@Column({ name: 'catalog_item_id', type: 'uuid', nullable: true })
|
||||
catalogItemId!: string | null;
|
||||
|
||||
@Column({ name: 'finding_number', type: 'integer' })
|
||||
findingNumber!: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 40 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 20, default: InspectionFindingStatus.OPEN })
|
||||
status!: InspectionFindingStatus;
|
||||
|
||||
@Column({ type: 'varchar', length: 500 })
|
||||
title!: string;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
description!: string;
|
||||
|
||||
@Column({ name: 'legal_basis', type: 'text', nullable: true })
|
||||
legalBasis!: string | null;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
glossary!: string | null;
|
||||
|
||||
@Column({ name: 'catalog_revision', type: 'integer', nullable: true })
|
||||
catalogRevision!: number | null;
|
||||
|
||||
@Column({ name: 'suggested_severity', type: 'smallint', nullable: true })
|
||||
suggestedSeverity!: number | null;
|
||||
|
||||
@Column({ type: 'smallint', nullable: true })
|
||||
severity!: number | null;
|
||||
|
||||
@Column({ name: 'correction_due_on', type: 'date', nullable: true })
|
||||
correctionDueOn!: string | null;
|
||||
|
||||
@Column({ name: 'response_due_basis', type: 'varchar', length: 32, nullable: true })
|
||||
responseDueBasis!: InspectionFindingResponseDueBasis | null;
|
||||
|
||||
@Column({ name: 'response_due_days', type: 'integer', nullable: true })
|
||||
responseDueDays!: number | null;
|
||||
|
||||
@Column({ name: 'response_due_base_on', type: 'date', nullable: true })
|
||||
responseDueBaseOn!: string | null;
|
||||
|
||||
@Column({ name: 'report_notified_on', type: 'date', nullable: true })
|
||||
reportNotifiedOn!: string | null;
|
||||
|
||||
@Column({ name: 'company_response', type: 'text', nullable: true })
|
||||
companyResponse!: string | null;
|
||||
|
||||
@Column({ name: 'company_response_received_on', type: 'date', nullable: true })
|
||||
companyResponseReceivedOn!: string | null;
|
||||
|
||||
@Column({ name: 'company_committed_correction_on', type: 'date', nullable: true })
|
||||
companyCommittedCorrectionOn!: string | null;
|
||||
|
||||
@Column({ name: 'next_control_on', type: 'date', nullable: true })
|
||||
nextControlOn!: string | null;
|
||||
|
||||
@Column({ name: 'current_version', type: 'integer', default: 0 })
|
||||
currentVersion!: number;
|
||||
|
||||
@Column({ name: 'closed_at', type: 'timestamptz', nullable: true })
|
||||
closedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'closed_by', type: 'uuid', nullable: true })
|
||||
closedBy!: string | null;
|
||||
|
||||
@Column({ name: 'closure_notes', type: 'text', nullable: true })
|
||||
closureNotes!: string | null;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum InspectionReportStatus {
|
||||
FROZEN = 'FROZEN',
|
||||
CANCELLED = 'CANCELLED',
|
||||
}
|
||||
|
||||
export enum InspectionReportPdfStatus {
|
||||
PENDING = 'PENDING',
|
||||
READY = 'READY',
|
||||
FAILED = 'FAILED',
|
||||
}
|
||||
|
||||
export enum InspectionReportWordStatus {
|
||||
PENDING = 'PENDING',
|
||||
READY = 'READY',
|
||||
FAILED = 'FAILED',
|
||||
}
|
||||
|
||||
export enum InspectionReportReviewStatus {
|
||||
PENDING_REVIEW = 'PENDING_REVIEW',
|
||||
APPROVED = 'APPROVED',
|
||||
SIGNED = 'SIGNED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_reports' })
|
||||
@Index('uq_inspection_reports_visit', ['visitId'], { unique: true })
|
||||
@Index('uq_inspection_reports_act', ['actId'], { unique: true })
|
||||
@Index('uq_inspection_reports_year_number', ['reportYear', 'reportNumber'], { unique: true })
|
||||
@Index('uq_inspection_reports_code', ['code'], { unique: true })
|
||||
@Index('idx_inspection_reports_generated_at', ['generatedAt'])
|
||||
@Index('idx_inspection_reports_status', ['status', 'pdfStatus'])
|
||||
export class InspectionReport extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'visit_id', type: 'uuid' })
|
||||
visitId!: string;
|
||||
|
||||
@Column({ name: 'act_id', type: 'uuid' })
|
||||
actId!: string;
|
||||
|
||||
@Column({ name: 'report_year', type: 'integer' })
|
||||
reportYear!: number;
|
||||
|
||||
@Column({ name: 'report_number', type: 'integer' })
|
||||
reportNumber!: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 24 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 24, default: InspectionReportStatus.FROZEN })
|
||||
status!: InspectionReportStatus;
|
||||
|
||||
@Column({ name: 'pdf_status', type: 'varchar', length: 24, default: InspectionReportPdfStatus.PENDING })
|
||||
pdfStatus!: InspectionReportPdfStatus;
|
||||
|
||||
@Column({ name: 'word_status', type: 'varchar', length: 24, default: InspectionReportWordStatus.PENDING })
|
||||
wordStatus!: InspectionReportWordStatus;
|
||||
|
||||
@Column({ name: 'word_original_name', type: 'varchar', length: 255, nullable: true })
|
||||
wordOriginalName!: string | null;
|
||||
|
||||
@Column({ name: 'word_stored_name', type: 'varchar', length: 255, nullable: true })
|
||||
wordStoredName!: string | null;
|
||||
|
||||
@Column({ name: 'word_mime_type', type: 'varchar', length: 120, nullable: true })
|
||||
wordMimeType!: string | null;
|
||||
|
||||
@Column({ name: 'word_size_bytes', type: 'integer', nullable: true })
|
||||
wordSizeBytes!: number | null;
|
||||
|
||||
@Column({ name: 'word_sha256', type: 'char', length: 64, nullable: true })
|
||||
wordSha256!: string | null;
|
||||
|
||||
@Column({ name: 'word_generated_at', type: 'timestamptz', nullable: true })
|
||||
wordGeneratedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'word_error', type: 'varchar', length: 500, nullable: true })
|
||||
wordError!: string | null;
|
||||
|
||||
@Column({ name: 'review_status', type: 'varchar', length: 32, default: InspectionReportReviewStatus.PENDING_REVIEW })
|
||||
reviewStatus!: InspectionReportReviewStatus;
|
||||
|
||||
@Column({ name: 'current_revision_number', type: 'integer', default: 0 })
|
||||
currentRevisionNumber!: number;
|
||||
|
||||
@Column({ name: 'approved_revision_id', type: 'uuid', nullable: true })
|
||||
approvedRevisionId!: string | null;
|
||||
|
||||
@Column({ name: 'approved_by', type: 'uuid', nullable: true })
|
||||
approvedBy!: string | null;
|
||||
|
||||
@Column({ name: 'approved_at', type: 'timestamptz', nullable: true })
|
||||
approvedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'review_note', type: 'varchar', length: 1000, nullable: true })
|
||||
reviewNote!: string | null;
|
||||
|
||||
@Column({ name: 'signed_at', type: 'timestamptz', nullable: true })
|
||||
signedAt!: Date | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 220 })
|
||||
title!: string;
|
||||
|
||||
@Column({ name: 'act_version', type: 'integer' })
|
||||
actVersion!: number;
|
||||
|
||||
@Column({ name: 'act_closure_sha256', type: 'char', length: 64 })
|
||||
actClosureSha256!: string;
|
||||
|
||||
@Column({ name: 'frozen_sha256', type: 'char', length: 64 })
|
||||
frozenSha256!: string;
|
||||
|
||||
@Column({ name: 'frozen_snapshot', type: 'jsonb' })
|
||||
frozenSnapshot!: Record<string, unknown>;
|
||||
|
||||
@Column({ name: 'generated_at', type: 'timestamptz' })
|
||||
generatedAt!: Date;
|
||||
|
||||
@Column({ name: 'generated_by', type: 'uuid' })
|
||||
generatedBy!: string;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum InspectionVisitAssetPlanningSource {
|
||||
LEGACY = 'LEGACY',
|
||||
AUTOMATIC = 'AUTOMATIC',
|
||||
PREVENTIVE = 'PREVENTIVE',
|
||||
VERIFICATION = 'VERIFICATION',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_visit_assets' })
|
||||
@Index('idx_inspection_visit_assets_asset_id', ['assetId'])
|
||||
@Index('idx_inspection_visit_assets_included', ['visitId', 'included'])
|
||||
export class InspectionVisitAsset extends TimestampedEntity {
|
||||
@PrimaryColumn({ name: 'visit_id', type: 'uuid' })
|
||||
visitId!: string;
|
||||
|
||||
@PrimaryColumn({ name: 'asset_id', type: 'uuid' })
|
||||
assetId!: string;
|
||||
|
||||
@Column({ type: 'boolean', default: true })
|
||||
included!: boolean;
|
||||
|
||||
@Column({ name: 'planning_source', type: 'varchar', length: 24, default: InspectionVisitAssetPlanningSource.LEGACY })
|
||||
planningSource!: InspectionVisitAssetPlanningSource;
|
||||
|
||||
@Column({ name: 'exclusion_reason', type: 'text', nullable: true })
|
||||
exclusionReason!: string | null;
|
||||
|
||||
@Column({ name: 'excluded_by', type: 'uuid', nullable: true })
|
||||
excludedBy!: string | null;
|
||||
|
||||
@Column({ name: 'excluded_at', type: 'timestamptz', nullable: true })
|
||||
excludedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'added_by', type: 'uuid', nullable: true })
|
||||
addedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
@Entity({ name: 'inspection_visit_members' })
|
||||
@Index('idx_inspection_visit_members_user_id', ['userId'])
|
||||
@Index('idx_inspection_visit_members_included', ['visitId', 'included'])
|
||||
export class InspectionVisitMember extends TimestampedEntity {
|
||||
@PrimaryColumn({ name: 'visit_id', type: 'uuid' })
|
||||
visitId!: string;
|
||||
|
||||
@PrimaryColumn({ name: 'user_id', type: 'uuid' })
|
||||
userId!: string;
|
||||
|
||||
@Column({ type: 'boolean', default: true })
|
||||
included!: boolean;
|
||||
|
||||
@Column({ name: 'assigned_by', type: 'uuid', nullable: true })
|
||||
assignedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum InspectionVisitStatus {
|
||||
DRAFT = 'DRAFT',
|
||||
PLANNED = 'PLANNED',
|
||||
IN_PROGRESS = 'IN_PROGRESS',
|
||||
CLOSED = 'CLOSED',
|
||||
CANCELLED = 'CANCELLED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'inspection_visits' })
|
||||
@Index('uq_inspection_visits_code', ['code'], { unique: true })
|
||||
@Index('idx_inspection_visits_status', ['status'])
|
||||
@Index('idx_inspection_visits_scope_asset_id', ['scopeAssetId'])
|
||||
@Index('idx_inspection_visits_lead_inspector_user_id', ['leadInspectorUserId'])
|
||||
@Index('idx_inspection_visits_planned_dates', ['plannedStartAt', 'plannedEndAt'])
|
||||
@Index('idx_inspection_visits_operational_context', ['operationalAreaId', 'operatorCompanyId'])
|
||||
export class InspectionVisit extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 80 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 200 })
|
||||
title!: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
objective!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 24, default: InspectionVisitStatus.DRAFT })
|
||||
status!: InspectionVisitStatus;
|
||||
|
||||
@Column({ name: 'scope_asset_id', type: 'uuid', nullable: true })
|
||||
scopeAssetId!: string | null;
|
||||
|
||||
@Column({ name: 'operational_area_id', type: 'uuid', nullable: true })
|
||||
operationalAreaId!: string | null;
|
||||
|
||||
@Column({ name: 'operator_company_id', type: 'uuid', nullable: true })
|
||||
operatorCompanyId!: string | null;
|
||||
|
||||
@Column({ name: 'lead_inspector_user_id', type: 'uuid', nullable: true })
|
||||
leadInspectorUserId!: string | null;
|
||||
|
||||
@Column({ name: 'planned_start_at', type: 'timestamptz', nullable: true })
|
||||
plannedStartAt!: Date | null;
|
||||
|
||||
@Column({ name: 'planned_end_at', type: 'timestamptz', nullable: true })
|
||||
plannedEndAt!: Date | null;
|
||||
|
||||
@Column({ name: 'actual_started_at', type: 'timestamptz', nullable: true })
|
||||
actualStartedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'actual_closed_at', type: 'timestamptz', nullable: true })
|
||||
actualClosedAt!: Date | null;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
instructions!: string | null;
|
||||
|
||||
@Column({ name: 'cancellation_reason', type: 'text', nullable: true })
|
||||
cancellationReason!: string | null;
|
||||
|
||||
@Column({ name: 'checklist_generation', type: 'integer', default: 0 })
|
||||
checklistGeneration!: number;
|
||||
|
||||
@Column({ name: 'checklist_generated_at', type: 'timestamptz', nullable: true })
|
||||
checklistGeneratedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
export enum OrganizationMembershipRole { MEMBER='MEMBER', LEAD_MEMBER='LEAD_MEMBER', OTHER='OTHER' }
|
||||
@Entity({name:'organization_memberships'})
|
||||
@Index('idx_organization_memberships_parent_id',['parentOrganizationId'])
|
||||
@Index('idx_organization_memberships_member_id',['memberOrganizationId'])
|
||||
@Index('idx_organization_memberships_valid_until',['validUntil'])
|
||||
export class OrganizationMembership extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid') id!:string;
|
||||
@Column({name:'parent_organization_id',type:'uuid'}) parentOrganizationId!:string;
|
||||
@Column({name:'member_organization_id',type:'uuid'}) memberOrganizationId!:string;
|
||||
@Column({type:'enum',enum:OrganizationMembershipRole,enumName:'organization_membership_role'}) role!:OrganizationMembershipRole;
|
||||
@Column({name:'participation_percent',type:'numeric',precision:7,scale:4,nullable:true}) participationPercent!:string|null;
|
||||
@Column({name:'valid_from',type:'date',default:()=> 'CURRENT_DATE'}) validFrom!:string;
|
||||
@Column({name:'valid_until',type:'date',nullable:true}) validUntil!:string|null;
|
||||
@Column({name:'source_document_id',type:'uuid',nullable:true}) sourceDocumentId!:string|null;
|
||||
@Column({type:'text',nullable:true}) notes!:string|null;
|
||||
@Column({name:'end_reason',type:'text',nullable:true}) endReason!:string|null;
|
||||
@Column({name:'created_by',type:'uuid',nullable:true}) createdBy!:string|null;
|
||||
@Column({name:'ended_by',type:'uuid',nullable:true}) endedBy!:string|null;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Column, Entity, PrimaryColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
export enum OrganizationKind { COMPANY='COMPANY', UTE='UTE', PUBLIC_ENTITY='PUBLIC_ENTITY', OTHER='OTHER' }
|
||||
@Entity({ name: 'organization_profiles' })
|
||||
export class OrganizationProfile extends TimestampedEntity {
|
||||
@PrimaryColumn({ name:'asset_id', type:'uuid' }) assetId!: string;
|
||||
@Column({ name:'organization_kind', type:'enum', enum:OrganizationKind, enumName:'organization_kind', default:OrganizationKind.COMPANY }) organizationKind!: OrganizationKind;
|
||||
@Column({ name:'legal_name', type:'varchar', length:240, nullable:true }) legalName!: string|null;
|
||||
@Column({ name:'tax_id', type:'varchar', length:32, nullable:true }) taxId!: string|null;
|
||||
@Column({ name:'notification_email', type:'varchar', length:320, nullable:true }) notificationEmail!: string|null;
|
||||
@Column({ type:'text', nullable:true }) notes!: string|null;
|
||||
@Column({ name:'updated_by', type:'uuid', nullable:true }) updatedBy!: string|null;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
@Entity({ name: 'permissions' })
|
||||
export class Permission {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 120 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
description!: string;
|
||||
|
||||
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Entity, Index, JoinColumn, ManyToOne, PrimaryColumn } from 'typeorm';
|
||||
import { Permission } from './permission.entity';
|
||||
import { Role } from './role.entity';
|
||||
|
||||
@Entity({ name: 'role_permissions' })
|
||||
@Index('idx_role_permissions_permission_id', ['permissionId'])
|
||||
export class RolePermission {
|
||||
@PrimaryColumn({ name: 'role_id', type: 'uuid' })
|
||||
roleId!: string;
|
||||
|
||||
@PrimaryColumn({ name: 'permission_id', type: 'uuid' })
|
||||
permissionId!: string;
|
||||
|
||||
@ManyToOne(() => Role, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'role_id' })
|
||||
role!: Role;
|
||||
|
||||
@ManyToOne(() => Permission, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'permission_id' })
|
||||
permission!: Permission;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
@Entity({ name: 'roles' })
|
||||
export class Role extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 80 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 120 })
|
||||
name!: string;
|
||||
|
||||
@Column({ type: 'text' })
|
||||
description!: string;
|
||||
|
||||
@Column({ name: 'is_system', type: 'boolean', default: false })
|
||||
isSystem!: boolean;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
export enum SourceDocumentType { NOTE='NOTE', TECHNICAL_REPORT='TECHNICAL_REPORT', INSPECTION_ACT='INSPECTION_ACT', INVENTORY='INVENTORY', RESOLUTION='RESOLUTION', DECREE='DECREE', CONTRACT='CONTRACT', SPREADSHEET='SPREADSHEET', OTHER='OTHER' }
|
||||
@Entity({name:'source_documents'})
|
||||
@Index('idx_source_documents_number',['documentNumber']) @Index('idx_source_documents_document_date',['documentDate'])
|
||||
export class SourceDocument extends TimestampedEntity { @PrimaryGeneratedColumn('uuid') id!:string; @Column({name:'document_type',type:'enum',enum:SourceDocumentType,enumName:'source_document_type'}) documentType!:SourceDocumentType; @Column({name:'document_number',type:'varchar',length:160,nullable:true}) documentNumber!:string|null; @Column({type:'varchar',length:300}) title!:string; @Column({type:'varchar',length:240,nullable:true}) issuer!:string|null; @Column({name:'document_date',type:'date',nullable:true}) documentDate!:string|null; @Column({name:'external_reference',type:'varchar',length:500,nullable:true}) externalReference!:string|null; @Column({type:'text',nullable:true}) notes!:string|null; @Column({name:'created_by',type:'uuid',nullable:true}) createdBy!:string|null; @Column({name:'updated_by',type:'uuid',nullable:true}) updatedBy!:string|null; }
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum SurveyTargetStatus {
|
||||
PENDING = 'PENDING',
|
||||
IN_PROGRESS = 'IN_PROGRESS',
|
||||
SUBMITTED = 'SUBMITTED',
|
||||
COMPLETED = 'COMPLETED',
|
||||
SKIPPED = 'SKIPPED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'survey_campaign_targets' })
|
||||
@Index('uq_survey_campaign_targets_campaign_asset', ['campaignId', 'assetId'], { unique: true })
|
||||
@Index('idx_survey_campaign_targets_campaign_status', ['campaignId', 'status'])
|
||||
@Index('idx_survey_campaign_targets_asset_id', ['assetId'])
|
||||
@Index('idx_survey_campaign_targets_assigned_user_id', ['assignedUserId'])
|
||||
export class SurveyCampaignTarget extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'campaign_id', type: 'uuid' })
|
||||
campaignId!: string;
|
||||
|
||||
@Column({ name: 'asset_id', type: 'uuid' })
|
||||
assetId!: string;
|
||||
|
||||
@Column({ name: 'assigned_user_id', type: 'uuid', nullable: true })
|
||||
assignedUserId!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 24, default: SurveyTargetStatus.PENDING })
|
||||
status!: SurveyTargetStatus;
|
||||
|
||||
@Column({ name: 'due_at', type: 'timestamptz', nullable: true })
|
||||
dueAt!: Date | null;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
instructions!: string | null;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum SurveyCampaignStatus {
|
||||
DRAFT = 'DRAFT',
|
||||
PLANNED = 'PLANNED',
|
||||
IN_PROGRESS = 'IN_PROGRESS',
|
||||
COMPLETED = 'COMPLETED',
|
||||
CANCELLED = 'CANCELLED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'survey_campaigns' })
|
||||
@Index('uq_survey_campaigns_code', ['code'], { unique: true })
|
||||
@Index('idx_survey_campaigns_status', ['status'])
|
||||
@Index('idx_survey_campaigns_scope_asset_id', ['scopeAssetId'])
|
||||
@Index('idx_survey_campaigns_coordinator_user_id', ['coordinatorUserId'])
|
||||
@Index('idx_survey_campaigns_planned_dates', ['plannedStartAt', 'plannedEndAt'])
|
||||
export class SurveyCampaign extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 80 })
|
||||
code!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 200 })
|
||||
name!: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
description!: string | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 24, default: SurveyCampaignStatus.DRAFT })
|
||||
status!: SurveyCampaignStatus;
|
||||
|
||||
@Column({ name: 'planned_start_at', type: 'timestamptz', nullable: true })
|
||||
plannedStartAt!: Date | null;
|
||||
|
||||
@Column({ name: 'planned_end_at', type: 'timestamptz', nullable: true })
|
||||
plannedEndAt!: Date | null;
|
||||
|
||||
@Column({ name: 'scope_asset_id', type: 'uuid', nullable: true })
|
||||
scopeAssetId!: string | null;
|
||||
|
||||
@Column({ name: 'coordinator_user_id', type: 'uuid', nullable: true })
|
||||
coordinatorUserId!: string | null;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
@Entity({ name: 'survey_target_report_media' })
|
||||
@Index('idx_survey_target_report_media_media_id', ['mediaId'])
|
||||
@Index('idx_survey_target_report_media_included', ['reportId', 'included'])
|
||||
export class SurveyTargetReportMedia extends TimestampedEntity {
|
||||
@PrimaryColumn({ name: 'report_id', type: 'uuid' })
|
||||
reportId!: string;
|
||||
|
||||
@PrimaryColumn({ name: 'media_id', type: 'uuid' })
|
||||
mediaId!: string;
|
||||
|
||||
@Column({ type: 'boolean', default: true })
|
||||
included!: boolean;
|
||||
|
||||
@Column({ name: 'added_by', type: 'uuid', nullable: true })
|
||||
addedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
export enum SurveyReportVersionEvent {
|
||||
SUBMITTED = 'SUBMITTED',
|
||||
APPROVED = 'APPROVED',
|
||||
REJECTED = 'REJECTED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'survey_target_report_versions' })
|
||||
@Index('uq_survey_target_report_versions_number', ['reportId', 'versionNumber'], { unique: true })
|
||||
@Index('idx_survey_target_report_versions_created_at', ['createdAt'])
|
||||
export class SurveyTargetReportVersion {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'report_id', type: 'uuid' })
|
||||
reportId!: string;
|
||||
|
||||
@Column({ name: 'version_number', type: 'integer' })
|
||||
versionNumber!: number;
|
||||
|
||||
@Column({ type: 'varchar', length: 24 })
|
||||
event!: SurveyReportVersionEvent;
|
||||
|
||||
@Column({ type: 'jsonb' })
|
||||
snapshot!: Record<string, unknown>;
|
||||
|
||||
@Column({ name: 'actor_user_id', type: 'uuid', nullable: true })
|
||||
actorUserId!: string | null;
|
||||
|
||||
@Column({ name: 'actor_username', type: 'varchar', length: 80, nullable: true })
|
||||
actorUsername!: string | null;
|
||||
|
||||
@Column({ name: 'created_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
createdAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum SurveyReportOutcome {
|
||||
CONFIRMED = 'CONFIRMED',
|
||||
CHANGES_RECORDED = 'CHANGES_RECORDED',
|
||||
NOT_LOCATED = 'NOT_LOCATED',
|
||||
}
|
||||
|
||||
export enum SurveyReportStatus {
|
||||
DRAFT = 'DRAFT',
|
||||
SUBMITTED = 'SUBMITTED',
|
||||
APPROVED = 'APPROVED',
|
||||
REJECTED = 'REJECTED',
|
||||
}
|
||||
|
||||
@Entity({ name: 'survey_target_reports' })
|
||||
@Index('uq_survey_target_reports_target_id', ['targetId'], { unique: true })
|
||||
@Index('idx_survey_target_reports_status', ['status'])
|
||||
@Index('idx_survey_target_reports_submitted_by', ['submittedBy'])
|
||||
@Index('idx_survey_target_reports_reviewed_by', ['reviewedBy'])
|
||||
export class SurveyTargetReport extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ name: 'target_id', type: 'uuid' })
|
||||
targetId!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 32, nullable: true })
|
||||
outcome!: SurveyReportOutcome | null;
|
||||
|
||||
@Column({ type: 'varchar', length: 24, default: SurveyReportStatus.DRAFT })
|
||||
status!: SurveyReportStatus;
|
||||
|
||||
@Column({ name: 'observed_at', type: 'timestamptz', nullable: true })
|
||||
observedAt!: Date | null;
|
||||
|
||||
@Column({ type: 'numeric', precision: 9, scale: 6, nullable: true })
|
||||
latitude!: string | null;
|
||||
|
||||
@Column({ type: 'numeric', precision: 9, scale: 6, nullable: true })
|
||||
longitude!: string | null;
|
||||
|
||||
@Column({ name: 'accuracy_m', type: 'numeric', precision: 12, scale: 3, nullable: true })
|
||||
accuracyM!: string | null;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
notes!: string | null;
|
||||
|
||||
@Column({ name: 'asset_version_at_submission', type: 'integer', nullable: true })
|
||||
assetVersionAtSubmission!: number | null;
|
||||
|
||||
@Column({ name: 'submitted_at', type: 'timestamptz', nullable: true })
|
||||
submittedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'submitted_by', type: 'uuid', nullable: true })
|
||||
submittedBy!: string | null;
|
||||
|
||||
@Column({ name: 'reviewed_at', type: 'timestamptz', nullable: true })
|
||||
reviewedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'reviewed_by', type: 'uuid', nullable: true })
|
||||
reviewedBy!: string | null;
|
||||
|
||||
@Column({ name: 'review_notes', type: 'text', nullable: true })
|
||||
reviewNotes!: string | null;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { CreateDateColumn, UpdateDateColumn } from 'typeorm';
|
||||
|
||||
export abstract class TimestampedEntity {
|
||||
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
|
||||
createdAt!: Date;
|
||||
|
||||
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
|
||||
updatedAt!: Date;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import {
|
||||
Column,
|
||||
Entity,
|
||||
Index,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryColumn,
|
||||
} from 'typeorm';
|
||||
import { Role } from './role.entity';
|
||||
import { User } from './user.entity';
|
||||
|
||||
@Entity({ name: 'user_roles' })
|
||||
@Index('idx_user_roles_user_id', ['userId'])
|
||||
@Index('idx_user_roles_role_id', ['roleId'])
|
||||
export class UserRole {
|
||||
@PrimaryColumn({ name: 'user_id', type: 'uuid' })
|
||||
userId!: string;
|
||||
|
||||
@PrimaryColumn({ name: 'role_id', type: 'uuid' })
|
||||
roleId!: string;
|
||||
|
||||
@Column({ name: 'assigned_at', type: 'timestamptz', default: () => 'CURRENT_TIMESTAMP' })
|
||||
assignedAt!: Date;
|
||||
|
||||
@Column({ name: 'assigned_by', type: 'uuid', nullable: true })
|
||||
assignedBy!: string | null;
|
||||
|
||||
@ManyToOne(() => User, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'user_id' })
|
||||
user!: User;
|
||||
|
||||
@ManyToOne(() => Role, { onDelete: 'RESTRICT' })
|
||||
@JoinColumn({ name: 'role_id' })
|
||||
role!: Role;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { TimestampedEntity } from './timestamped.entity';
|
||||
|
||||
export enum UserStatus {
|
||||
ACTIVE = 'ACTIVE',
|
||||
INACTIVE = 'INACTIVE',
|
||||
}
|
||||
|
||||
@Entity({ name: 'users' })
|
||||
@Index('idx_users_status', ['status'])
|
||||
@Index('idx_users_locked_until', ['lockedUntil'])
|
||||
export class User extends TimestampedEntity {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 80 })
|
||||
username!: string;
|
||||
|
||||
@Column({ type: 'varchar', length: 320, nullable: true })
|
||||
email!: string | null;
|
||||
|
||||
@Column({ name: 'password_hash', type: 'text', select: false })
|
||||
passwordHash!: string;
|
||||
|
||||
@Column({ name: 'first_name', type: 'varchar', length: 120 })
|
||||
firstName!: string;
|
||||
|
||||
@Column({ name: 'last_name', type: 'varchar', length: 120 })
|
||||
lastName!: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: UserStatus,
|
||||
enumName: 'user_status',
|
||||
default: UserStatus.ACTIVE,
|
||||
})
|
||||
status!: UserStatus;
|
||||
|
||||
@Column({ name: 'must_change_password', type: 'boolean', default: true })
|
||||
mustChangePassword!: boolean;
|
||||
|
||||
@Column({ name: 'failed_login_attempts', type: 'integer', default: 0 })
|
||||
failedLoginAttempts!: number;
|
||||
|
||||
@Column({ name: 'locked_until', type: 'timestamptz', nullable: true })
|
||||
lockedUntil!: Date | null;
|
||||
|
||||
@Column({ name: 'last_login_at', type: 'timestamptz', nullable: true })
|
||||
lastLoginAt!: Date | null;
|
||||
|
||||
@Column({ name: 'password_changed_at', type: 'timestamptz', nullable: true })
|
||||
passwordChangedAt!: Date | null;
|
||||
|
||||
@Column({ name: 'created_by', type: 'uuid', nullable: true })
|
||||
createdBy!: string | null;
|
||||
|
||||
@Column({ name: 'updated_by', type: 'uuid', nullable: true })
|
||||
updatedBy!: string | null;
|
||||
}
|
||||
Reference in New Issue
Block a user