Updated signature handling, added booking detail components, introduced a signature management page, updated routing, enabled document downloads, and simplified the profile page.

This commit is contained in:
Marshal
2026-06-17 01:02:09 +00:00
parent e65addc619
commit c76f8648a9
12 changed files with 222 additions and 22 deletions

View File

@@ -1,7 +1,9 @@
import { Injectable } from '@nestjs/common';
import { Readable } from 'stream';
import { DataSource } from 'typeorm';
import { FilesService } from '../files/files.service';
import { FileRecord } from '../files/entities/file.entity';
import { MinioService } from '../minio/minio.service';
import { SignaturesRepository } from './signatures.repository';
import { SavedSignature } from './entities/saved-signature.entity';
@@ -19,6 +21,7 @@ export class SignaturesService {
private readonly signaturesRepository: SignaturesRepository,
private readonly filesService: FilesService,
private readonly minioService: MinioService,
private readonly dataSource: DataSource,
) {}
/** Saved signature for a user, with the image inlined as a data URL (or null). */
@@ -47,18 +50,32 @@ export class SignaturesService {
path: '',
};
const fileRecord = await this.filesService.upsertByCode({
// Capture the previously referenced file so we can remove it only AFTER the
// saved_signatures row is repointed — deleting it first would violate the
// FK constraint (saved_signatures.signature_file_id -> files.id).
const existing = await this.signaturesRepository.findByUserId(input.userId);
const previousFileId = existing?.signatureFileId ?? null;
const fileRecord = await this.filesService.upload({
resourceId: input.userId,
resource: 'saved_signatures',
code: 'signature',
file,
});
return this.signaturesRepository.upsert({
const saved = await this.signaturesRepository.upsert({
userId: input.userId,
signerDisplayName: input.signerDisplayName,
signatureFileId: fileRecord.id,
});
if (previousFileId && previousFileId !== fileRecord.id) {
await this.dataSource
.getRepository(FileRecord)
.delete({ id: previousFileId });
}
return saved;
}
private async inlineImageUrl(