feat: add certificate generation system with PDF template and Thai font support

This commit is contained in:
JakkrapartXD 2026-01-30 14:14:00 +07:00
parent c72b76c2a5
commit 9ed2347843
8 changed files with 440 additions and 0 deletions

View file

@ -0,0 +1,61 @@
import { Get, Post, Route, Tags, SuccessResponse, Response, Security, Path, Request } from 'tsoa';
import { ValidationError } from '../middleware/errorHandler';
import { CertificateService } from '../services/certificate.service';
import {
GenerateCertificateResponse,
GetCertificateResponse,
ListMyCertificatesResponse,
} from '../types/certificate.types';
@Route('api/certificates')
@Tags('Certificates')
export class CertificateController {
private certificateService = new CertificateService();
/**
* Certificate
* Get all certificates for the authenticated user
*/
@Get('')
@Security('jwt')
@SuccessResponse('200', 'Certificates retrieved successfully')
@Response('401', 'Invalid or expired token')
public async listMyCertificates(@Request() request: any): Promise<ListMyCertificatesResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) throw new ValidationError('No token provided');
return await this.certificateService.listMyCertificates({ token });
}
/**
* Certificate
* Get certificate for a specific course
* @param courseId - / Course ID
*/
@Get('{courseId}')
@Security('jwt')
@SuccessResponse('200', 'Certificate retrieved successfully')
@Response('401', 'Invalid or expired token')
@Response('404', 'Certificate not found')
public async getCertificate(@Request() request: any, @Path() courseId: number): Promise<GetCertificateResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) throw new ValidationError('No token provided');
return await this.certificateService.getCertificate({ token, course_id: courseId });
}
/**
* Certificate
* Generate certificate for a completed course
* @param courseId - / Course ID
*/
@Post('{courseId}/generate')
@Security('jwt')
@SuccessResponse('201', 'Certificate generated successfully')
@Response('400', 'Course not completed or does not offer certificates')
@Response('401', 'Invalid or expired token')
@Response('404', 'Enrollment not found')
public async generateCertificate(@Request() request: any, @Path() courseId: number): Promise<GenerateCertificateResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) throw new ValidationError('No token provided');
return await this.certificateService.generateCertificate({ token, course_id: courseId });
}
}