58 lines
2.0 KiB
TypeScript
58 lines
2.0 KiB
TypeScript
import { randomUUID } from 'crypto';
|
|
import type { CreateDocumentBody, DocumentRecord, DocumentType, UpdateDocumentBody } from './documents.types';
|
|
import { DocumentsRepository } from '../data/documents.repository';
|
|
import pool from '../../../core/config/database';
|
|
|
|
export class DocumentsService {
|
|
private readonly repo = new DocumentsRepository(pool);
|
|
|
|
async createDocument(userId: string, body: CreateDocumentBody): Promise<DocumentRecord> {
|
|
await this.assertVehicleOwnership(userId, body.vehicleId);
|
|
const id = randomUUID();
|
|
return this.repo.insert({
|
|
id,
|
|
userId,
|
|
vehicleId: body.vehicleId,
|
|
documentType: body.documentType as DocumentType,
|
|
title: body.title,
|
|
notes: body.notes ?? null,
|
|
details: body.details ?? null,
|
|
issuedDate: body.issuedDate ?? null,
|
|
expirationDate: body.expirationDate ?? null,
|
|
emailNotifications: body.emailNotifications ?? false,
|
|
scanForMaintenance: body.scanForMaintenance ?? false,
|
|
});
|
|
}
|
|
|
|
async getDocument(userId: string, id: string): Promise<DocumentRecord | null> {
|
|
return this.repo.findById(id, userId);
|
|
}
|
|
|
|
async listDocuments(userId: string, filters?: { vehicleId?: string; type?: DocumentType; expiresBefore?: string }) {
|
|
return this.repo.listByUser(userId, filters);
|
|
}
|
|
|
|
async updateDocument(userId: string, id: string, patch: UpdateDocumentBody) {
|
|
const existing = await this.repo.findById(id, userId);
|
|
if (!existing) return null;
|
|
if (patch && typeof patch === 'object') {
|
|
return this.repo.updateMetadata(id, userId, patch as any);
|
|
}
|
|
return existing;
|
|
}
|
|
|
|
async deleteDocument(userId: string, id: string): Promise<void> {
|
|
await this.repo.softDelete(id, userId);
|
|
}
|
|
|
|
private async assertVehicleOwnership(userId: string, vehicleId: string) {
|
|
const res = await pool.query('SELECT id FROM vehicles WHERE id = $1 AND user_id = $2', [vehicleId, userId]);
|
|
if (!res.rows[0]) {
|
|
const err: any = new Error('Vehicle not found or not owned by user');
|
|
err.statusCode = 403;
|
|
throw err;
|
|
}
|
|
}
|
|
}
|
|
|