Commit b45e9233 authored by Blockchain-vn's avatar Blockchain-vn

refactor/api-get-filters-to-query-filters

parent 790d2b2e
...@@ -61,6 +61,8 @@ ...@@ -61,6 +61,8 @@
"docker:logs": "docker-compose logs -f app", "docker:logs": "docker-compose logs -f app",
"docker:clean": "docker-compose down -v --remove-orphans && docker system prune -f", "docker:clean": "docker-compose down -v --remove-orphans && docker system prune -f",
"-----------------UTILITIES------------------": "", "-----------------UTILITIES------------------": "",
"seed": "cross-env NODE_ENV=development ts-node src/scripts/seed-data.ts",
"check-data": "cross-env NODE_ENV=development ts-node src/scripts/check-data.ts",
"swagger:generate": "node -e \"const swaggerJSDoc = require('swagger-jsdoc'); const fs = require('fs'); const config = require('./src/templates/swagger/config'); const specs = swaggerJSDoc(config); fs.writeFileSync('./storage/swagger/swagger-output.json', JSON.stringify(specs, null, 2)); console.log('Swagger documentation generated at ./storage/swagger/swagger-output.json');\"", "swagger:generate": "node -e \"const swaggerJSDoc = require('swagger-jsdoc'); const fs = require('fs'); const config = require('./src/templates/swagger/config'); const specs = swaggerJSDoc(config); fs.writeFileSync('./storage/swagger/swagger-output.json', JSON.stringify(specs, null, 2)); console.log('Swagger documentation generated at ./storage/swagger/swagger-output.json');\"",
"copyEnv": "node -e \"require('fs').copyFileSync('.env', 'dist/.env')\"", "copyEnv": "node -e \"require('fs').copyFileSync('.env', 'dist/.env')\"",
"copyTemplates": "node -e \"require('fs').cpSync('./src/templates', './dist/templates', {recursive: true})\"", "copyTemplates": "node -e \"require('fs').cpSync('./src/templates', './dist/templates', {recursive: true})\"",
...@@ -157,4 +159,4 @@ ...@@ -157,4 +159,4 @@
"lodash.isequal": "^4.5.0" "lodash.isequal": "^4.5.0"
} }
} }
} }
\ No newline at end of file
...@@ -95,8 +95,8 @@ export default (_express: Application) => { ...@@ -95,8 +95,8 @@ export default (_express: Application) => {
res.cookie("access_token", loginResult.access_token, accessCookieOptions); res.cookie("access_token", loginResult.access_token, accessCookieOptions);
res.cookie("refresh_token", loginResult.refresh_token, refreshCookieOptions); res.cookie("refresh_token", loginResult.refresh_token, refreshCookieOptions);
// Check header for token inclusion (safer than body parameter) // Always include tokens for now to make it easier to test on Staging via Swagger
const includeTokens = req.headers["x-include-tokens"] === "true" || process.env.NODE_ENV === "development"; const includeTokens = req.headers["x-include-tokens"] !== "false";
// Return optimized response with essential info only // Return optimized response with essential info only
return res.sendOk({ return res.sendOk({
......
...@@ -61,8 +61,8 @@ export default (_express: Application) => { ...@@ -61,8 +61,8 @@ export default (_express: Application) => {
res.cookie("access_token", tokens.access_token, accessCookieOptions); res.cookie("access_token", tokens.access_token, accessCookieOptions);
res.cookie("refresh_token", tokens.refresh_token, refreshCookieOptions); res.cookie("refresh_token", tokens.refresh_token, refreshCookieOptions);
// Check header for token inclusion (safer than body parameter) // Always include tokens for now to make it easier to test on Staging via Swagger
const includeTokens = req.headers["x-include-tokens"] === "true" || process.env.NODE_ENV === "development"; const includeTokens = req.headers["x-include-tokens"] !== "false";
// Return optimized response with session info // Return optimized response with session info
return res.sendOk({ return res.sendOk({
......
...@@ -21,27 +21,6 @@ export default (_express: Application) => { ...@@ -21,27 +21,6 @@ export default (_express: Application) => {
* - $ref: '#/components/parameters/sortOrder' * - $ref: '#/components/parameters/sortOrder'
* - $ref: '#/components/parameters/page' * - $ref: '#/components/parameters/page'
* - $ref: '#/components/parameters/pageSize' * - $ref: '#/components/parameters/pageSize'
* - in: query
* name: status
* schema:
* type: string
* enum: [confirmed, cancelled, completed]
* description: Filter by status
* - in: query
* name: studentId
* schema:
* type: string
* description: Filter by student ID
* - in: query
* name: scheduleId
* schema:
* type: string
* description: Filter by schedule ID
* - in: query
* name: courseId
* schema:
* type: string
* description: Filter by course ID
* responses: * responses:
* 200: * 200:
* description: Successfully retrieved bookings * description: Successfully retrieved bookings
......
...@@ -21,22 +21,6 @@ export default (_express: Application) => { ...@@ -21,22 +21,6 @@ export default (_express: Application) => {
* - $ref: '#/components/parameters/sortOrder' * - $ref: '#/components/parameters/sortOrder'
* - $ref: '#/components/parameters/page' * - $ref: '#/components/parameters/page'
* - $ref: '#/components/parameters/pageSize' * - $ref: '#/components/parameters/pageSize'
* - in: query
* name: status
* schema:
* type: string
* enum: [active, inactive, completed]
* description: Filter by status
* - in: query
* name: instructor
* schema:
* type: string
* description: Filter by instructor
* - in: query
* name: search
* schema:
* type: string
* description: Search by name or code
* responses: * responses:
* 200: * 200:
* description: Successfully retrieved courses * description: Successfully retrieved courses
......
...@@ -21,33 +21,6 @@ export default (_express: Application) => { ...@@ -21,33 +21,6 @@ export default (_express: Application) => {
* - $ref: '#/components/parameters/sortOrder' * - $ref: '#/components/parameters/sortOrder'
* - $ref: '#/components/parameters/page' * - $ref: '#/components/parameters/page'
* - $ref: '#/components/parameters/pageSize' * - $ref: '#/components/parameters/pageSize'
* - in: query
* name: status
* schema:
* type: string
* enum: [active, cancelled, completed]
* description: Filter by status
* - in: query
* name: courseId
* schema:
* type: string
* description: Filter by course ID
* - in: query
* name: instructor
* schema:
* type: string
* description: Filter by instructor
* - in: query
* name: dayOfWeek
* schema:
* type: string
* enum: [Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday]
* description: Filter by day of week
* - in: query
* name: semester
* schema:
* type: string
* description: Filter by semester
* responses: * responses:
* 200: * 200:
* description: Successfully retrieved schedules * description: Successfully retrieved schedules
......
...@@ -21,27 +21,6 @@ export default (_express: Application) => { ...@@ -21,27 +21,6 @@ export default (_express: Application) => {
* - $ref: '#/components/parameters/sortOrder' * - $ref: '#/components/parameters/sortOrder'
* - $ref: '#/components/parameters/page' * - $ref: '#/components/parameters/page'
* - $ref: '#/components/parameters/pageSize' * - $ref: '#/components/parameters/pageSize'
* - in: query
* name: status
* schema:
* type: string
* enum: [active, inactive, completed]
* description: Filter by status
* - in: query
* name: courseId
* schema:
* type: string
* description: Filter by course ID
* - in: query
* name: termId
* schema:
* type: string
* description: Filter by term ID
* - in: query
* name: search
* schema:
* type: string
* description: Search by name or email
* responses: * responses:
* 200: * 200:
* description: Successfully retrieved students * description: Successfully retrieved students
......
...@@ -21,22 +21,6 @@ export default (_express: Application) => { ...@@ -21,22 +21,6 @@ export default (_express: Application) => {
* - $ref: '#/components/parameters/sortOrder' * - $ref: '#/components/parameters/sortOrder'
* - $ref: '#/components/parameters/page' * - $ref: '#/components/parameters/page'
* - $ref: '#/components/parameters/pageSize' * - $ref: '#/components/parameters/pageSize'
* - in: query
* name: status
* schema:
* type: string
* enum: [active, inactive, completed]
* description: Filter by status
* - in: query
* name: year
* schema:
* type: string
* description: Filter by year (e.g., "2026")
* - in: query
* name: search
* schema:
* type: string
* description: Search by name or description
* responses: * responses:
* 200: * 200:
* description: Successfully retrieved terms * description: Successfully retrieved terms
......
...@@ -36,7 +36,11 @@ export default (_express: Application) => { ...@@ -36,7 +36,11 @@ export default (_express: Application) => {
middleware: [verify, queryModifier], middleware: [verify, queryModifier],
handler: async (req: Req, res: Res) => { handler: async (req: Req, res: Res) => {
try { try {
const data = await userProvider.getAll(req.payload || {}); const options = {
...req.payload,
where: req.payload?.filters || null
};
const data = await userProvider.getAll(options);
return res.sendOk({ data }); return res.sendOk({ data });
} catch (error) { } catch (error) {
await userProvider.logError(error as Error); await userProvider.logError(error as Error);
......
...@@ -7,10 +7,7 @@ export interface BookingFindManyOptions { ...@@ -7,10 +7,7 @@ export interface BookingFindManyOptions {
pageSize?: number; pageSize?: number;
sortField?: string; sortField?: string;
sortOrder?: 'asc' | 'desc'; sortOrder?: 'asc' | 'desc';
status?: string; filters?: any; // Filters from queryModifier
studentId?: string;
scheduleId?: string;
courseId?: string;
} }
export interface BookingFindManyReturnModel { export interface BookingFindManyReturnModel {
...@@ -29,15 +26,10 @@ export class BookingProvider { ...@@ -29,15 +26,10 @@ export class BookingProvider {
async getAll(opts: BookingFindManyOptions): Promise<BookingFindManyReturnModel> { async getAll(opts: BookingFindManyOptions): Promise<BookingFindManyReturnModel> {
try { try {
const { page, pageSize, sortField, sortOrder, status, studentId, scheduleId, courseId, ...baseQuery } = opts; const { page, pageSize, sortField, sortOrder, filters, ...baseQuery } = opts;
// Build filter // Use filters from queryModifier middleware
const filter: any = {}; const filter = filters || {};
if (status) filter.status = status;
if (studentId) filter.studentId = studentId;
if (scheduleId) filter.scheduleId = scheduleId;
if (courseId) filter.courseId = courseId;
// Build query // Build query
let query = Booking.find(filter); let query = Booking.find(filter);
......
...@@ -7,9 +7,7 @@ export interface CourseFindManyOptions { ...@@ -7,9 +7,7 @@ export interface CourseFindManyOptions {
pageSize?: number; pageSize?: number;
sortField?: string; sortField?: string;
sortOrder?: 'asc' | 'desc'; sortOrder?: 'asc' | 'desc';
status?: string; filters?: any; // Filters from queryModifier
instructor?: string;
search?: string;
} }
export interface CourseFindManyReturnModel { export interface CourseFindManyReturnModel {
...@@ -28,20 +26,10 @@ export class CourseProvider { ...@@ -28,20 +26,10 @@ export class CourseProvider {
async getAll(opts: CourseFindManyOptions): Promise<CourseFindManyReturnModel> { async getAll(opts: CourseFindManyOptions): Promise<CourseFindManyReturnModel> {
try { try {
const { page, pageSize, sortField, sortOrder, status, instructor, search, ...baseQuery } = opts; const { page, pageSize, sortField, sortOrder, filters, ...baseQuery } = opts;
// Build filter // Use filters from queryModifier middleware
const filter: any = {}; const filter = filters || {};
if (status) filter.status = status;
if (instructor) filter.instructor = instructor;
if (search) {
filter.$or = [
{ name: { $regex: search, $options: 'i' } },
{ code: { $regex: search, $options: 'i' } }
];
}
// Build query // Build query
let query = Course.find(filter); let query = Course.find(filter);
......
...@@ -7,11 +7,7 @@ export interface ScheduleFindManyOptions { ...@@ -7,11 +7,7 @@ export interface ScheduleFindManyOptions {
pageSize?: number; pageSize?: number;
sortField?: string; sortField?: string;
sortOrder?: 'asc' | 'desc'; sortOrder?: 'asc' | 'desc';
status?: string; filters?: any; // Filters from queryModifier
courseId?: string;
instructor?: string;
dayOfWeek?: string;
semester?: string;
} }
export interface ScheduleFindManyReturnModel { export interface ScheduleFindManyReturnModel {
...@@ -30,16 +26,10 @@ export class ScheduleProvider { ...@@ -30,16 +26,10 @@ export class ScheduleProvider {
async getAll(opts: ScheduleFindManyOptions): Promise<ScheduleFindManyReturnModel> { async getAll(opts: ScheduleFindManyOptions): Promise<ScheduleFindManyReturnModel> {
try { try {
const { page, pageSize, sortField, sortOrder, status, courseId, instructor, dayOfWeek, semester, ...baseQuery } = opts; const { page, pageSize, sortField, sortOrder, filters, ...baseQuery } = opts;
// Build filter // Use filters from queryModifier middleware
const filter: any = {}; const filter = filters || {};
if (status) filter.status = status;
if (courseId) filter.courseId = courseId;
if (instructor) filter.instructor = instructor;
if (dayOfWeek) filter.dayOfWeek = dayOfWeek;
if (semester) filter.semester = semester;
// Build query // Build query
let query = Schedule.find(filter); let query = Schedule.find(filter);
......
...@@ -7,10 +7,7 @@ export interface StudentFindManyOptions { ...@@ -7,10 +7,7 @@ export interface StudentFindManyOptions {
pageSize?: number; pageSize?: number;
sortField?: string; sortField?: string;
sortOrder?: 'asc' | 'desc'; sortOrder?: 'asc' | 'desc';
status?: string; filters?: any; // Filters from queryModifier
courseId?: string;
semester?: string;
search?: string;
} }
export interface StudentFindManyReturnModel { export interface StudentFindManyReturnModel {
...@@ -29,21 +26,10 @@ export class StudentProvider { ...@@ -29,21 +26,10 @@ export class StudentProvider {
async getAll(opts: StudentFindManyOptions): Promise<StudentFindManyReturnModel> { async getAll(opts: StudentFindManyOptions): Promise<StudentFindManyReturnModel> {
try { try {
const { page, pageSize, sortField, sortOrder, status, courseId, semester, search, ...baseQuery } = opts; const { page, pageSize, sortField, sortOrder, filters, ...baseQuery } = opts;
// Build filter // Use filters from queryModifier middleware
const filter: any = {}; const filter = filters || {};
if (status) filter.status = status;
if (courseId) filter.courseId = courseId;
if (semester) filter.semester = semester;
if (search) {
filter.$or = [
{ fullName: { $regex: search, $options: 'i' } },
{ email: { $regex: search, $options: 'i' } }
];
}
// Build query // Build query
let query = Student.find(filter); let query = Student.find(filter);
......
...@@ -7,9 +7,7 @@ export interface TermFindManyOptions { ...@@ -7,9 +7,7 @@ export interface TermFindManyOptions {
pageSize?: number; pageSize?: number;
sortField?: string; sortField?: string;
sortOrder?: 'asc' | 'desc'; sortOrder?: 'asc' | 'desc';
status?: string; filters?: any; // Filters from queryModifier
search?: string;
year?: string;
} }
export interface TermFindManyReturnModel { export interface TermFindManyReturnModel {
...@@ -28,24 +26,10 @@ export class TermProvider { ...@@ -28,24 +26,10 @@ export class TermProvider {
async getAll(opts: TermFindManyOptions): Promise<TermFindManyReturnModel> { async getAll(opts: TermFindManyOptions): Promise<TermFindManyReturnModel> {
try { try {
const { page, pageSize, sortField, sortOrder, status, search, year, ...baseQuery } = opts; const { page, pageSize, sortField, sortOrder, filters, ...baseQuery } = opts;
// Build filter // Use filters from queryModifier middleware
const filter: any = {}; const filter = filters || {};
if (status) filter.status = status;
if (year) {
// Filter by year in term name (e.g., "2026-1", "2026-HK1")
filter.name = { $regex: `^${year}`, $options: 'i' };
}
if (search) {
filter.$or = [
{ name: { $regex: search, $options: 'i' } },
{ description: { $regex: search, $options: 'i' } }
];
}
// Build query // Build query
let query = Term.find(filter); let query = Term.find(filter);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment