diff --git a/app/Controllers/Http/Api/v1/CategoriesController.ts b/app/Controllers/Http/Api/v1/CategoriesController.ts index 7d778f5..7173ada 100644 --- a/app/Controllers/Http/Api/v1/CategoriesController.ts +++ b/app/Controllers/Http/Api/v1/CategoriesController.ts @@ -7,9 +7,10 @@ import { Exception, inject, Ioc } from '@adonisjs/core/build/standalone'; import CategoryService from 'App/Services/CategoryService'; /** - * Validatoes + * Validators */ import CreateCategoryValidator from 'App/Validators/Category/CreateCategoryValidator'; +import UpdateCategoryValidator from 'App/Validators/Category/UpdateCategoryValidator'; import BaseController from '../../BaseController'; @@ -78,6 +79,21 @@ export default class CategoriesController extends BaseController { return this.sendResponse(ctx, result.data, result.message, result.status); } + + /** + * Update category by id + * PATCH /categories/:id + */ + public async update(ctx: HttpContextContract) { + const payload = await ctx.request.validate(UpdateCategoryValidator); + const result = await this.categoryService.updateCategory(ctx.params.id, payload); + + if (!result.success && result.error) { + throw new Exception(result.message, result.status, result.error.code); + } + + return this.sendResponse(ctx, result.data, result.message, result.status); + } } new Ioc().make(CategoriesController); diff --git a/app/Models/Category.ts b/app/Models/Category.ts index ee832c8..2f7a4fb 100644 --- a/app/Models/Category.ts +++ b/app/Models/Category.ts @@ -24,10 +24,10 @@ export default class Category extends BaseModel { }) public color: BelongsTo; - @column.dateTime({ autoCreate: true, serializeAs: null }) + @column.dateTime({ autoCreate: true }) public createdAt: DateTime; - @column.dateTime({ autoCreate: true, autoUpdate: true, serializeAs: null }) + @column.dateTime({ autoCreate: true, autoUpdate: true }) public updatedAt: DateTime; /** diff --git a/app/Repositories/CategoryRepository.ts b/app/Repositories/CategoryRepository.ts index fe2c83a..2361e76 100644 --- a/app/Repositories/CategoryRepository.ts +++ b/app/Repositories/CategoryRepository.ts @@ -7,6 +7,7 @@ import Category from 'App/Models/Category'; * Validators */ import CreateCategoryValidator from 'App/Validators/Category/CreateCategoryValidator'; +import UpdateCategoryValidator from 'App/Validators/Category/UpdateCategoryValidator'; export default class CategoryRepository { private Category: typeof Category; @@ -67,4 +68,27 @@ export default class CategoryRepository { return null; } + + /** + * + * @param id Category id + * @param data + * @returns + */ + public async update(id: string | number, data: UpdateCategoryValidator['schema']['props']): Promise { + const category = await this.Category.query().where('id', id).first(); + + if (category) { + await category + .merge({ + title: data.title, + description: data.description, + }) + .save(); + + return category; + } + + return null; + } } diff --git a/app/Services/CategoryService.ts b/app/Services/CategoryService.ts index 3b2454b..bb72edd 100644 --- a/app/Services/CategoryService.ts +++ b/app/Services/CategoryService.ts @@ -15,6 +15,7 @@ import CategoryRepository from 'App/Repositories/CategoryRepository'; * Validators */ import CreateCategoryValidator from 'App/Validators/Category/CreateCategoryValidator'; +import UpdateCategoryValidator from 'App/Validators/Category/UpdateCategoryValidator'; @inject() export default class CategoryService { @@ -114,6 +115,38 @@ export default class CategoryService { data, }; } + + /** + * Update category + * + * @param id Category id + * @returns Updated category + */ + public async updateCategory( + id: string | number, + data: UpdateCategoryValidator['schema']['props'] + ): Promise { + const category = await this.categoryRepository.update(id, data); + + if (!category) { + return { + success: false, + status: HttpStatusEnum.NOT_FOUND, + message: 'Category not found.', + data: {}, + error: { + code: 'E_NOT_FOUND', + }, + }; + } + + return { + success: true, + status: HttpStatusEnum.OK, + message: 'Category updated.', + data, + }; + } } new Ioc().make(CategoryService); diff --git a/app/Validators/Category/CreateCategoryValidator.ts b/app/Validators/Category/CreateCategoryValidator.ts index 1895f46..3281ea1 100644 --- a/app/Validators/Category/CreateCategoryValidator.ts +++ b/app/Validators/Category/CreateCategoryValidator.ts @@ -6,7 +6,7 @@ export default class CreateCategoryValidator { public schema = schema.create({ title: schema.string(), - description: schema.string(), + description: schema.string.optional(), }); public messages = {}; diff --git a/app/Validators/Category/UpdateCategoryValidator.ts b/app/Validators/Category/UpdateCategoryValidator.ts new file mode 100644 index 0000000..fbfb94b --- /dev/null +++ b/app/Validators/Category/UpdateCategoryValidator.ts @@ -0,0 +1,13 @@ +import { schema } from '@ioc:Adonis/Core/Validator'; +import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; + +export default class UpdateCategoryValidator { + constructor(protected ctx: HttpContextContract) {} + + public schema = schema.create({ + title: schema.string.optional(), + description: schema.string.optional(), + }); + + public messages = {}; +} diff --git a/routes/apis/v1/categories.ts b/routes/apis/v1/categories.ts index 1a31707..7e021fc 100644 --- a/routes/apis/v1/categories.ts +++ b/routes/apis/v1/categories.ts @@ -5,4 +5,5 @@ Route.group(() => { Route.get('/:id', 'Api/v1/CategoriesController.show').middleware('role:admin,teacher,student').as('categories.show'); Route.post('/', 'Api/v1/CategoriesController.create').middleware('role:admin,teacher').as('categories.create'); Route.delete('/:id', 'Api/v1/CategoriesController.delete').middleware('role:admin,teacher').as('categories.delete'); + Route.patch('/:id', 'Api/v1/CategoriesController.update').middleware('role:admin,teacher').as('categories.update'); }).prefix('categories');