Commit 3be0edb2 authored by Phạm Quang Bảo's avatar Phạm Quang Bảo

feat: add fillter classes for method get

parent 38e7d8fd
......@@ -3,13 +3,21 @@
"version": "1.0.0",
"description": "",
"author": "PhamQuangBao",
"type": "commonjs",
"main": "./src/index.ts",
"scripts": {
"dev": "tsx watch ./src/index.ts",
"test": "echo \"Error: no test specified\" && exit 1",
"gen:db": "sequelize-auto -h localhost -d challenge_db -u postgres -x 123456 -p 2550 --dialect postgres --lang ts -o ./src/models",
"gen:db": "sequelize-auto -h localhost -d challenge_db -u postgres -x 123456 -p 2550 --dialect postgres --lang ts -o ./src/models --caseProp s --useDefine",
"gen:swagger": "tsx src/scripts/swagger-gen.ts"
},
"imports": {
"#models/*": "./src/models/*",
"#controllers/*": "./src/controllers/*",
"#services/*": "./src/services/*",
"#providers/*": "./src/providers/*",
"#docs/*": "./src/docs/*"
},
"dependencies": {
"express": "^5.2.1",
"express-automatic-routes": "^1.1.0",
......
......@@ -11,11 +11,14 @@ export default (_express: Application) => {
* /api/v1.0/classes:
* get:
* tags: [Classes]
* summary: Lấy danh sách lớp học
* description: Trả về danh sách lớp học.
* parameters:
* - $ref: '#/components/parameters/filters'
* - $ref: '#/components/parameters/sort'
* - $ref: '#/components/parameters/page'
* - $ref: '#/components/parameters/pageSize'
* responses:
* 200:
* description: Trả về danh sách lớp học thành công
* description: Trả về danh sách lớp học thành công
* content:
* application/json:
* schema:
......@@ -25,8 +28,23 @@ export default (_express: Application) => {
*/
get: {
handler: async (req, res) => {
const classes = await classesProvider.getAllClasses();
return res.json(classes);
try {
// 1. Lấy các tham số từ Query String (được Swagger gửi lên)
const { filters, sort, page, pageSize } = req.query;
// 2. Truyền các tham số này vào hàm xử lý
const classes = await classesProvider.getAllClasses({
filters: filters as string,
sort: sort as string,
page: page ? parseInt(page as string) : 1,
pageSize: pageSize ? parseInt(pageSize as string) : 10
});
return res.json(classes);
} catch (error) {
console.error('Error getting classes:', error);
return res.status(500).json({ error: (error as Error).message });
}
}
}
};
......
......@@ -34,6 +34,17 @@
"nullable": true,
"example": "Lớp chuyên toán"
},
"course_id": {
"type": "string",
"format": "uuid",
"nullable": true,
"example": "7c1a4d9c-3a2b-4c58-9df4-8e2c2d9a3c10"
},
"status": {
"type": "string",
"nullable": true,
"example": "active"
},
"created_at": {
"type": "string",
"format": "date-time",
......@@ -55,20 +66,43 @@
"format": "uuid",
"nullable": true,
"example": "2b4f6f8e-19f6-4c5d-93c2-4d7a7c3d1e11"
},
"course_id": {
"type": "string",
"format": "uuid",
"nullable": true,
"example": "7c1a4d9c-3a2b-4c58-9df4-8e2c2d9a3c10"
},
"status": {
"type": "string",
"nullable": true,
"example": "active"
}
}
}
},
"parameters": {
"filters": {
"name": "filters",
"in": "query",
"schema": {
"type": "string"
}
},
"sort": {
"name": "sort",
"in": "query",
"schema": {
"type": "string",
"enum": [
"asc",
"desc"
]
}
},
"page": {
"name": "page",
"in": "query",
"schema": {
"type": "integer"
}
},
"pageSize": {
"name": "pageSize",
"in": "query",
"schema": {
"type": "integer"
}
}
}
},
"paths": {
......@@ -77,8 +111,20 @@
"tags": [
"Classes"
],
"summary": "Lấy danh sách lớp học",
"description": "Trả về danh sách lớp học.",
"parameters": [
{
"$ref": "#/components/parameters/filters"
},
{
"$ref": "#/components/parameters/sort"
},
{
"$ref": "#/components/parameters/page"
},
{
"$ref": "#/components/parameters/pageSize"
}
],
"responses": {
"200": {
"description": "Trả về danh sách lớp học thành công",
......
......@@ -12,13 +12,7 @@ _autoroutes(app, {
log: true
});
const swaggerOptions = {
swaggerOptions: {
url: '/swagger.json',
},
};
app.use('/swagger', swaggerUi.serve, swaggerUi.setup(swaggerFile, swaggerOptions));
app.use('/swagger', swaggerUi.serve, swaggerUi.setup(swaggerFile));
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
......
......@@ -50,7 +50,7 @@ export class classes extends Model<classesAttributes, classesCreationAttributes>
createCourse!: Sequelize.BelongsToCreateAssociationMixin<courses>;
static initModel(sequelize: Sequelize.Sequelize): typeof classes {
return classes.init({
return sequelize.define('classes', {
id: {
type: DataTypes.UUID,
allowNull: false,
......@@ -86,7 +86,6 @@ export class classes extends Model<classesAttributes, classesCreationAttributes>
allowNull: true
}
}, {
sequelize,
tableName: 'classes',
schema: 'public',
timestamps: true,
......@@ -99,6 +98,6 @@ export class classes extends Model<classesAttributes, classesCreationAttributes>
]
},
]
});
}) as typeof classes;
}
}
......@@ -38,7 +38,7 @@ export class courses extends Model<coursesAttributes, coursesCreationAttributes>
countClasses!: Sequelize.HasManyCountAssociationsMixin;
static initModel(sequelize: Sequelize.Sequelize): typeof courses {
return courses.init({
return sequelize.define('courses', {
id: {
type: DataTypes.UUID,
allowNull: false,
......@@ -62,7 +62,6 @@ export class courses extends Model<coursesAttributes, coursesCreationAttributes>
allowNull: true
}
}, {
sequelize,
tableName: 'courses',
schema: 'public',
timestamps: true,
......@@ -75,6 +74,6 @@ export class courses extends Model<coursesAttributes, coursesCreationAttributes>
]
},
]
});
}) as typeof courses;
}
}
......@@ -35,7 +35,7 @@ export class enrollments extends Model<enrollmentsAttributes, enrollmentsCreatio
createUser!: Sequelize.BelongsToCreateAssociationMixin<users>;
static initModel(sequelize: Sequelize.Sequelize): typeof enrollments {
return enrollments.init({
return sequelize.define('enrollments', {
id: {
type: DataTypes.UUID,
allowNull: false,
......@@ -63,10 +63,9 @@ export class enrollments extends Model<enrollmentsAttributes, enrollmentsCreatio
allowNull: true
}
}, {
sequelize,
tableName: 'enrollments',
schema: 'public',
timestamps: true
});
}) as typeof enrollments;
}
}
......@@ -36,7 +36,7 @@ export class roles extends Model<rolesAttributes, rolesCreationAttributes> imple
countUsers!: Sequelize.HasManyCountAssociationsMixin;
static initModel(sequelize: Sequelize.Sequelize): typeof roles {
return roles.init({
return sequelize.define('roles', {
id: {
type: DataTypes.UUID,
allowNull: false,
......@@ -56,7 +56,6 @@ export class roles extends Model<rolesAttributes, rolesCreationAttributes> imple
allowNull: true
}
}, {
sequelize,
tableName: 'roles',
schema: 'public',
timestamps: true,
......@@ -69,6 +68,6 @@ export class roles extends Model<rolesAttributes, rolesCreationAttributes> imple
]
},
]
});
}) as typeof roles;
}
}
......@@ -27,7 +27,7 @@ export class user_auth extends Model<user_authAttributes, user_authCreationAttri
createUser!: Sequelize.BelongsToCreateAssociationMixin<users>;
static initModel(sequelize: Sequelize.Sequelize): typeof user_auth {
return user_auth.init({
return sequelize.define('user_auth', {
id: {
type: DataTypes.UUID,
allowNull: false,
......@@ -47,7 +47,6 @@ export class user_auth extends Model<user_authAttributes, user_authCreationAttri
allowNull: true
}
}, {
sequelize,
tableName: 'user_auth',
schema: 'public',
timestamps: true,
......@@ -60,6 +59,6 @@ export class user_auth extends Model<user_authAttributes, user_authCreationAttri
]
},
]
});
}) as typeof user_auth;
}
}
......@@ -61,7 +61,7 @@ export class users extends Model<usersAttributes, usersCreationAttributes> imple
countUser_auths!: Sequelize.HasManyCountAssociationsMixin;
static initModel(sequelize: Sequelize.Sequelize): typeof users {
return users.init({
return sequelize.define('users', {
id: {
type: DataTypes.UUID,
allowNull: false,
......@@ -97,7 +97,6 @@ export class users extends Model<usersAttributes, usersCreationAttributes> imple
}
}
}, {
sequelize,
tableName: 'users',
schema: 'public',
timestamps: true,
......@@ -110,6 +109,6 @@ export class users extends Model<usersAttributes, usersCreationAttributes> imple
]
},
]
});
}) as typeof users;
}
}
import { models } from '#scripts/database-gen.js';
import { Op } from 'sequelize';
export class ClassesProvider {
async getAllClasses() {
try {
const data = await models.classes.findAll({
attributes: ['id', 'name'],
order: [['id', 'DESC']]
});
async getAllClasses(params: { filters?: string, sort?: string, page?: number, pageSize?: number }) {
const { filters, sort, page = 1, pageSize = 10 } = params;
return data;
} catch (error) {
console.error("Lỗi khi lấy danh sách classes:", error);
throw error;
const offset = (page - 1) * pageSize;
const where: any = {};
if (filters) {
where.name = { [Op.like]: `%${filters}%` };
}
return await models.classes.findAndCountAll({
where,
order: sort ? [['created_at', sort]] : [['created_at', 'DESC']],
limit: pageSize,
offset: offset
});
}
async getClassById(classId: number) {
......
......@@ -6,6 +6,12 @@ const sequelize = new Sequelize('challenge_db', 'postgres', '123456', {
port: 2550,
dialect: 'postgres',
logging: false,
define: {
underscored: true,
timestamps: false,
createdAt: 'created_at',
updatedAt: 'updated_at',
},
});
const models = initModels(sequelize);
......
......@@ -27,6 +27,17 @@ const classSchemas = {
nullable: true,
example: 'Lớp chuyên toán',
},
course_id: {
type: 'string',
format: 'uuid',
nullable: true,
example: '7c1a4d9c-3a2b-4c58-9df4-8e2c2d9a3c10',
},
status: {
type: 'string',
nullable: true,
example: 'active',
},
created_at: {
type: 'string',
format: 'date-time',
......@@ -49,17 +60,6 @@ const classSchemas = {
nullable: true,
example: '2b4f6f8e-19f6-4c5d-93c2-4d7a7c3d1e11',
},
course_id: {
type: 'string',
format: 'uuid',
nullable: true,
example: '7c1a4d9c-3a2b-4c58-9df4-8e2c2d9a3c10',
},
status: {
type: 'string',
nullable: true,
example: 'active',
},
},
},
};
......
......@@ -14,6 +14,28 @@ const swaggerOptions: Options = {
schemas: {
...classSchemas,
},
parameters: {
filters: {
name: 'filters',
in: 'query',
schema: { type: 'string' }
},
sort: {
name: 'sort',
in: 'query',
schema: { type: 'string', enum: ['asc', 'desc'] }
},
page: {
name: 'page',
in: 'query',
schema: { type: 'integer' }
},
pageSize: {
name: 'pageSize',
in: 'query',
schema: { type: 'integer' }
},
}
},
},
......
......@@ -37,9 +37,15 @@
"#models/*": [
"./src/models/*"
],
"#controllers/*": [
"./src/controllers/*"
],
"#interfaces/*": [
"./src/interfaces/*"
],
"#docs/*": [
"./src/docs/*"
],
"#*": [
"./src/*"
]
......
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