C1: جدول vehicles (مكافئ CarRegistration عند سيرو) — plate/vin مشفَّران، make/model/year، color+color_hex (لتلوين السيارة في فلاتر)، fuel/owner/ category، is_default، status. سائق قد يملك أكثر من مركبة؛ VehiclesService يضمن افتراضية واحدة دائماً (أول مركبة تلقائياً، حذف الافتراضية يرقّي غيرها). C2: حقول الملف على drivers — gender، national_number (مشفَّر + فهرس أعمى فريد لكل مستأجر، نفس نمط الهاتف)، name_arabic (مشفَّر)، birthdate، address، الرخصة (type/categories/issue/expiry)، rejected_reason. عبر PATCH /drivers/profile. C3: ai_data + user_input (jsonb) على drivers و vehicles — مخرجات Gemini مقابل مدخلات السائق، تُراكَم للمقارنة حقلاً بحقل. C4: vehicle_photo min:2 في كتالوج الوثائق. C5: نوع وثيقة face_liveness (فيديو) — الرفع يقبله بلا قيد mime. قرار: المركبة كيان مستقل لا حقول مسطّحة (سيرو يفصلها بـisDefault). الحقول القديمة على drivers تبقى للتوافق؛ المصدر الجديد vehicles. هجرة: VehiclesAndDriverProfile (جدول vehicles + أعمدة السائق + فهرس فريد جزئي على الرقم الوطني). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
79 lines
2.4 KiB
TypeScript
79 lines
2.4 KiB
TypeScript
import {
|
|
Column,
|
|
CreateDateColumn,
|
|
Entity,
|
|
Index,
|
|
PrimaryGeneratedColumn,
|
|
UpdateDateColumn,
|
|
} from 'typeorm';
|
|
import { EncryptedTransformer } from '../../../common/crypto/crypto.util';
|
|
|
|
export type DocType =
|
|
| 'license' // رخصة القيادة (وجهين)
|
|
| 'national_id' // هوية الأحوال المدنية (وجهين)
|
|
| 'vehicle_registration' // دفتر/بطاقة المركبة (وجهين)
|
|
| 'insurance' // تأمين
|
|
| 'criminal_record' // عدم محكومية (البحث الجنائي)
|
|
| 'selfie' // صورة شخصية
|
|
| 'vehicle_photo' // صورة/صور السيارة
|
|
| 'face_liveness'; // فيديو حيوية الوجه (docs/17 — C5؛ غير السيلفي الثابت)
|
|
export type DocSide = 'front' | 'back' | 'single';
|
|
export type DocStatus = 'pending' | 'approved' | 'rejected';
|
|
|
|
/** وثيقة سائق (صورة + بيانات). الجدول: tripz_driver_documents. */
|
|
@Entity('driver_documents')
|
|
@Index(['tenant_id', 'driver_id'])
|
|
@Index(['tenant_id', 'status'])
|
|
export class DriverDocument {
|
|
@PrimaryGeneratedColumn('uuid')
|
|
id: string;
|
|
|
|
@Column({ type: 'uuid' })
|
|
tenant_id: string;
|
|
|
|
@Column({ type: 'uuid' })
|
|
driver_id: string;
|
|
|
|
@Column()
|
|
type: DocType;
|
|
|
|
@Column({ type: 'varchar', default: 'single' })
|
|
side: DocSide; // front | back | single
|
|
|
|
@Column()
|
|
file_key: string; // مفتاح التخزين (سيرفر التوطين لاحقاً)
|
|
|
|
// رقم الرخصة/الهوية — مشفّر at-rest (AES-256-GCM)
|
|
@Column({ type: 'varchar', nullable: true, transformer: EncryptedTransformer })
|
|
number: string | null;
|
|
|
|
// اسم حامل الوثيقة — مشفّر at-rest
|
|
@Column({ type: 'varchar', nullable: true, transformer: EncryptedTransformer })
|
|
holder_name: string | null;
|
|
|
|
@Column({ type: 'date', nullable: true })
|
|
issue_date: string | null;
|
|
|
|
@Column({ type: 'date', nullable: true })
|
|
expiry_date: string | null;
|
|
|
|
// حقول إضافية يدخلها موظف خدمة العملاء (سلطة إصدار، ملاحظات...)
|
|
@Column({ type: 'jsonb', default: {} })
|
|
extra: Record<string, any>;
|
|
|
|
@Column({ type: 'varchar', default: 'pending' })
|
|
status: DocStatus;
|
|
|
|
@Column({ type: 'varchar', nullable: true })
|
|
review_note: string | null;
|
|
|
|
@Column({ type: 'uuid', nullable: true })
|
|
reviewed_by: string | null;
|
|
|
|
@CreateDateColumn()
|
|
created_at: Date;
|
|
|
|
@UpdateDateColumn()
|
|
updated_at: Date;
|
|
}
|