1+ import { PrismaClient } from '@prisma/client' ;
2+ import { Request , Response } from 'express' ;
3+ import { CertificateSearchService } from '../../search/CertificateSearchService.js' ;
4+ import { CourseSearchService } from '../../search/CourseSearchService.js' ;
5+ import { FilterParser } from '../../search/FilterParser.js' ;
6+ import { SearchOptions } from '../../search/SearchService.js' ;
7+ import { StudentSearchService } from '../../search/StudentSearchService.js' ;
8+ import logger from '../../utils/logger.js' ;
9+
10+ export class SearchController {
11+ private prisma : PrismaClient ;
12+ private courseSearchService : CourseSearchService ;
13+ private studentSearchService : StudentSearchService ;
14+ private certificateSearchService : CertificateSearchService ;
15+ private filterParser : FilterParser ;
16+
17+ constructor ( prisma : PrismaClient ) {
18+ this . prisma = prisma ;
19+ this . courseSearchService = new CourseSearchService ( prisma ) ;
20+ this . studentSearchService = new StudentSearchService ( prisma ) ;
21+ this . certificateSearchService = new CertificateSearchService ( prisma ) ;
22+ this . filterParser = new FilterParser ( ) ;
23+ }
24+
25+ private parseSearchOptions ( req : Request ) : SearchOptions {
26+ const { query, page, limit, cursor, sort } = req . query ;
27+
28+ // Parse filters from query string
29+ const filters = this . filterParser . parseQueryStringFilters ( req . url . split ( '?' ) [ 1 ] || '' ) ;
30+
31+ return {
32+ query : query as string ,
33+ filters,
34+ sort : sort as string ,
35+ page : page ? parseInt ( page as string ) : undefined ,
36+ limit : limit ? parseInt ( limit as string ) : undefined ,
37+ cursor : cursor as string ,
38+ } ;
39+ }
40+
41+ async searchCourses ( req : Request , res : Response ) {
42+ try {
43+ const options = this . parseSearchOptions ( req ) ;
44+ const result = await this . courseSearchService . search ( options ) ;
45+
46+ res . json ( result ) ;
47+ } catch ( error ) {
48+ logger . error ( 'Course search error:' , error ) ;
49+ res . status ( 400 ) . json ( {
50+ error : 'Invalid search parameters' ,
51+ message : error instanceof Error ? error . message : 'Unknown error' ,
52+ } ) ;
53+ }
54+ }
55+
56+ async searchStudents ( req : Request , res : Response ) {
57+ try {
58+ const options = this . parseSearchOptions ( req ) ;
59+ const result = await this . studentSearchService . search ( options ) ;
60+
61+ res . json ( result ) ;
62+ } catch ( error ) {
63+ logger . error ( 'Student search error:' , error ) ;
64+ res . status ( 400 ) . json ( {
65+ error : 'Invalid search parameters' ,
66+ message : error instanceof Error ? error . message : 'Unknown error' ,
67+ } ) ;
68+ }
69+ }
70+
71+ async searchCertificates ( req : Request , res : Response ) {
72+ try {
73+ const options = this . parseSearchOptions ( req ) ;
74+ const result = await this . certificateSearchService . search ( options ) ;
75+
76+ res . json ( result ) ;
77+ } catch ( error ) {
78+ logger . error ( 'Certificate search error:' , error ) ;
79+ res . status ( 400 ) . json ( {
80+ error : 'Invalid search parameters' ,
81+ message : error instanceof Error ? error . message : 'Unknown error' ,
82+ } ) ;
83+ }
84+ }
85+
86+ async searchAll ( req : Request , res : Response ) {
87+ try {
88+ const options = this . parseSearchOptions ( req ) ;
89+
90+ // Execute all searches in parallel
91+ const [ courses , students , certificates ] = await Promise . all ( [
92+ this . courseSearchService . search ( { ...options , limit : 5 } ) , // Limit results for global search
93+ this . studentSearchService . search ( { ...options , limit : 5 } ) ,
94+ this . certificateSearchService . search ( { ...options , limit : 5 } ) ,
95+ ] ) ;
96+
97+ res . json ( {
98+ courses : courses . data ,
99+ students : students . data ,
100+ certificates : certificates . data ,
101+ metadata : {
102+ query : options . query ,
103+ filters : options . filters ,
104+ totalResults : courses . metadata . totalResults + students . metadata . totalResults + certificates . metadata . totalResults ,
105+ } ,
106+ } ) ;
107+ } catch ( error ) {
108+ logger . error ( 'Global search error:' , error ) ;
109+ res . status ( 400 ) . json ( {
110+ error : 'Invalid search parameters' ,
111+ message : error instanceof Error ? error . message : 'Unknown error' ,
112+ } ) ;
113+ }
114+ }
115+ }
0 commit comments