import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, OneToMany, } from 'typeorm'; import { Exclude } from 'class-transformer'; import { UserRole } from '../../common/enums'; import { Application } from '../../applications/entities/application.entity'; @Entity('users') export class User { @PrimaryGeneratedColumn('uuid') id: string; // Phone is the login identifier (required at registration). Email is an // optional contact field only — it is never used to authenticate. // Both are unique; Postgres treats NULLs as distinct, so accounts missing // either coexist freely. // NOTE: nullable string columns MUST declare an explicit `type` — TypeScript // reflects the `string | null` union as `Object`, which TypeORM rejects with // DataTypeNotSupportedError and crashes the backend at metadata build. @Column({ type: 'varchar', unique: true, nullable: true }) phone: string | null; // canonical E.164, e.g. +989121234567 @Column({ type: 'varchar', unique: true, nullable: true }) email: string | null; @Column({ default: false }) phoneVerified: boolean; /** Bcrypt hash — never serialized into API responses. */ @Exclude({ toPlainOnly: true }) @Column() password: string; @Column() firstName: string; @Column() lastName: string; @Column({ type: 'enum', enum: UserRole, default: UserRole.USER }) role: UserRole; @Column({ default: true }) isActive: boolean; @Column({ nullable: true }) namespace: string; // K8s namespace assigned to user @OneToMany(() => Application, (app: Application) => app.user) applications: Application[]; @CreateDateColumn() createdAt: Date; @UpdateDateColumn() updatedAt: Date; }