Skip to content

Commit

Permalink
feat: implement roles services and controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielmaialva33 committed Nov 26, 2024
1 parent d98ae34 commit 1e04f1e
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 8 deletions.
30 changes: 29 additions & 1 deletion app/modules/role/controllers/roles_controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,32 @@
import { inject } from '@adonisjs/core'
import { HttpContext } from '@adonisjs/core/http'
import app from '@adonisjs/core/services/app'

import ListRolesService from '#modules/role/services/list_roles/list_roles_service'
import SyncRolesService from '#modules/role/services/attach_roles/sync_roles_service'

import { attachRoleValidator } from '#modules/role/validation/roles_validator'

@inject()
export default class RolesController {}
export default class RolesController {
async list({ response }: HttpContext) {
const service = await app.container.make(ListRolesService)

const roles = await service.run()
return response.json(roles)
}

async attach({ request, response, i18n }: HttpContext) {
const data = request.body()
const { user_id: userId, role_ids: roleIds } = await attachRoleValidator.validate(data)

const syncRolesService = await app.container.make(SyncRolesService)
await syncRolesService.run({ userId, roleIds })

return response.json({
message: i18n.t('messages.successfully_attached', {
resource: i18n.t('models.role'),
}),
})
}
}
27 changes: 26 additions & 1 deletion app/modules/role/models/role.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { DateTime } from 'luxon'
import { BaseModel, column } from '@adonisjs/lucid/orm'
import { BaseModel, column, manyToMany } from '@adonisjs/lucid/orm'
import IRole from '#modules/role/interfaces/role_interface'
import type { ManyToMany } from '@adonisjs/lucid/types/relations'

import User from '#modules/user/models/user'

export default class Role extends BaseModel {
static table = 'roles'
Expand All @@ -27,4 +30,26 @@ export default class Role extends BaseModel {

@column.dateTime({ autoCreate: true, autoUpdate: true })
declare updatedAt: DateTime

/**
* ------------------------------------------------------
* Relationships
* ------------------------------------------------------
*/
@manyToMany(() => User, {
pivotTable: 'user_roles',
})
declare users: ManyToMany<typeof User>

/**
* ------------------------------------------------------
* Hooks
* ------------------------------------------------------
*/

/**
* ------------------------------------------------------
* Query Scopes
* ------------------------------------------------------
*/
}
18 changes: 18 additions & 0 deletions app/modules/role/routes/admin_routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import router from '@adonisjs/core/services/router'
import { middleware } from '#start/kernel'
import IRole from '#modules/role/interfaces/role_interface'

const RolesController = () => import('#modules/role/controllers/roles_controller')

router
.group(() => {
router.get('/', [RolesController, 'list']).as('role.list')
router.put('/attach', [RolesController, 'attach']).as('role.attach')
})
.use([
middleware.auth(),
middleware.acl({
role_slugs: [IRole.Slugs.ROOT, IRole.Slugs.ADMIN],
}),
])
.prefix('admin/roles')
1 change: 1 addition & 0 deletions app/modules/role/routes/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '#modules/role/routes/admin_routes'
20 changes: 20 additions & 0 deletions app/modules/role/services/attach_roles/sync_roles_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { inject } from '@adonisjs/core'
import app from '@adonisjs/core/services/app'
import GetUserService from '#modules/user/services/read_user/get_user_service'

type SyncRolesRequest = {
userId: number
roleIds: number[]
}

@inject()
export default class SyncRolesService {
constructor() {}

async run({ userId, roleIds }: SyncRolesRequest) {
const getUserService = await app.container.make(GetUserService)
const user = await getUserService.run(userId)

await user.related('roles').sync(roleIds)
}
}
13 changes: 13 additions & 0 deletions app/modules/role/validation/roles_validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import vine from '@vinejs/vine'

export const attachRoleValidator = vine.compile(
vine.object({
user_id: vine.number(),
role_ids: vine.array(
vine.number().exists(async (db, value) => {
const roles = await db.from('roles').where('id', +value)
return roles.length === value.length
})
),
})
)
2 changes: 1 addition & 1 deletion app/modules/user/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import {
import { withAuthFinder } from '@adonisjs/auth/mixins/lucid'
import { DbAccessTokensProvider } from '@adonisjs/auth/access_tokens'
import * as model from '@adonisjs/lucid/types/model'
import type { ManyToMany } from '@adonisjs/lucid/types/relations'

import Role from '#modules/role/models/role'
import type { ManyToMany } from '@adonisjs/lucid/types/relations'
import IRole from '#modules/role/interfaces/role_interface'

const AuthFinder = withAuthFinder(() => hash.use('argon'), {
Expand Down
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@
"docker": "node ace migration:run && node ace db:seed && node bin/server.js"
},
"imports": {
"#controllers/*": "./app/controllers/*.js",
"#exceptions/*": "./app/exceptions/*.js",
"#models/*": "./app/models/*.js",
"#mails/*": "./app/mails/*.js",
"#services/*": "./app/services/*.js",
"#listeners/*": "./app/listeners/*.js",
Expand Down
1 change: 1 addition & 0 deletions resources/lang/en/messages.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
successfully_deleted: '{resource} successfully deleted.'
successfully_updated: '{resource} successfully updated.'
successfully_created: '{resource} successfully created.'
successfully_attached: '{resource} successfully attached.'
1 change: 1 addition & 0 deletions resources/lang/en/models.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
user: 'User'
role: 'Role'
1 change: 1 addition & 0 deletions resources/lang/pt/messages.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
successfully_deleted: '{resource} deletado com sucesso.'
successfully_updated: '{resource} atualizado com sucesso.'
successfully_created: '{resource} criado com sucesso.'
successfully_attached: '{resource} anexado com sucesso.'
1 change: 1 addition & 0 deletions resources/lang/pt/models.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
user: 'Usuário'
role: 'Função'
6 changes: 3 additions & 3 deletions start/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
*/

import router from '@adonisjs/core/services/router'
import '#modules/health/routes/index'
import '#modules/role/routes/index'
import '#modules/user/routes/index'

router.get('/', async () => {
return { hello: 'world' }
})

import '#modules/health/routes/index'
import '#modules/user/routes/index'

0 comments on commit 1e04f1e

Please sign in to comment.