- doc types with side (front/back/single): license, national_id, vehicle_registration (both sides), criminal_record, selfie, vehicle_photo - fields: side, holder_name(encrypted), issue_date, extra jsonb; REQUIRED_DOCS checklist + /requirements - CS/admin: POST /admin/drivers/:id/documents (upload for driver), list, review auto-approves when complete - face-match endpoint stub (Gemini/Face provider later) - DB pool extra.max=30 (raises concurrency ceiling); migration DocumentsFields Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
105 lines
3.5 KiB
TypeScript
105 lines
3.5 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Get,
|
|
Param,
|
|
Patch,
|
|
Post,
|
|
UploadedFile,
|
|
UseGuards,
|
|
UseInterceptors,
|
|
} from '@nestjs/common';
|
|
import { FileInterceptor } from '@nestjs/platform-express';
|
|
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
|
import { DocumentsService } from './documents.service';
|
|
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
|
|
import { RolesGuard } from '../auth/guards/roles.guard';
|
|
import { Roles } from '../auth/decorators/roles.decorator';
|
|
import { CurrentUser, AuthUser } from '../auth/decorators/current-user.decorator';
|
|
|
|
@ApiTags('documents')
|
|
@ApiBearerAuth()
|
|
@Controller()
|
|
export class DocumentsController {
|
|
constructor(private readonly documents: DocumentsService) {}
|
|
|
|
// ===== السائق نفسه =====
|
|
@UseGuards(JwtAuthGuard)
|
|
@Post('drivers/documents')
|
|
@UseInterceptors(FileInterceptor('file'))
|
|
upload(@CurrentUser() user: AuthUser, @UploadedFile() file: any, @Body() body: any) {
|
|
return this.documents.uploadSelf(user.tenantId, user.userId, file, body);
|
|
}
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
@Get('drivers/documents/mine')
|
|
mine(@CurrentUser() user: AuthUser) {
|
|
return this.documents.listMine(user.tenantId, user.userId);
|
|
}
|
|
|
|
// قائمة الوثائق المطلوبة وحالتها للسائق الحالي
|
|
@UseGuards(JwtAuthGuard)
|
|
@Get('drivers/documents/requirements')
|
|
async myRequirements(@CurrentUser() user: AuthUser) {
|
|
const list = await this.documents.listMine(user.tenantId, user.userId);
|
|
const driverId = list[0]?.driver_id;
|
|
return driverId
|
|
? this.documents.requirements(user.tenantId, driverId)
|
|
: this.documents.requirements(user.tenantId, '00000000-0000-0000-0000-000000000000');
|
|
}
|
|
|
|
// ===== خدمة العملاء / الأدمن =====
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles('admin', 'dispatcher')
|
|
@Post('admin/drivers/:driverId/documents')
|
|
@UseInterceptors(FileInterceptor('file'))
|
|
uploadForDriver(
|
|
@Param('driverId') driverId: string,
|
|
@CurrentUser() user: AuthUser,
|
|
@UploadedFile() file: any,
|
|
@Body() body: any,
|
|
) {
|
|
return this.documents.uploadForDriver(user.tenantId, driverId, file, body);
|
|
}
|
|
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles('admin', 'dispatcher')
|
|
@Get('admin/drivers/:driverId/documents')
|
|
driverDocs(@Param('driverId') driverId: string, @CurrentUser() user: AuthUser) {
|
|
return this.documents.listByDriver(user.tenantId, driverId);
|
|
}
|
|
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles('admin', 'dispatcher')
|
|
@Get('admin/drivers/:driverId/documents/requirements')
|
|
driverRequirements(@Param('driverId') driverId: string, @CurrentUser() user: AuthUser) {
|
|
return this.documents.requirements(user.tenantId, driverId);
|
|
}
|
|
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles('admin', 'dispatcher')
|
|
@Get('admin/documents/pending')
|
|
pending(@CurrentUser() user: AuthUser) {
|
|
return this.documents.pending(user.tenantId);
|
|
}
|
|
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles('admin', 'dispatcher')
|
|
@Patch('admin/documents/:id/review')
|
|
review(
|
|
@CurrentUser() user: AuthUser,
|
|
@Param('id') id: string,
|
|
@Body('status') status: 'approved' | 'rejected',
|
|
@Body('note') note: string,
|
|
) {
|
|
return this.documents.review(user.tenantId, id, user.userId, status, note);
|
|
}
|
|
|
|
@UseGuards(JwtAuthGuard, RolesGuard)
|
|
@Roles('admin', 'dispatcher')
|
|
@Post('admin/drivers/:driverId/face-match')
|
|
faceMatch(@Param('driverId') driverId: string, @CurrentUser() user: AuthUser) {
|
|
return this.documents.faceMatch(user.tenantId, driverId);
|
|
}
|
|
}
|