Add initial project files

This commit is contained in:
Igor Martyniuk
2026-09-01 13:03:41 +03:00
parent 22e111bb44
commit 74cb5b6176
1841 changed files with 242819 additions and 30 deletions
+18
View File
@@ -0,0 +1,18 @@
export default [
{
slug: 'role.view',
name: 'Role view',
},
{
slug: 'role.create',
name: 'Role create',
},
{
slug: 'role.update',
name: 'Role update',
},
{
slug: 'role.delete',
name: 'Role delete',
},
]
@@ -0,0 +1,89 @@
import { HttpContext } from '@adonisjs/core/http'
import { addSearchFilter, searchableColumns } from '#services/database_inspector'
import Role from '#base_modules/Role/model/role'
import RolePolicy from '#base_modules/Role/policy/role_policy'
import { createRoleValidator } from '#base_modules/Role/validator/role_create_validator'
import { updateRoleValidator } from '#base_modules/Role/validator/role_update_validator'
import db from '@adonisjs/lucid/services/db'
export default class RoleController {
public async index({ request, response, bouncer }: HttpContext) {
await bouncer.with(RolePolicy).authorize('roleList')
const {
page = 1,
perPage = 10,
search = null,
sortBy = 'id',
sortOrder = 'desc',
} = request.all()
const query = Role.query()
if (search) {
const columns = Role.searchable || (await searchableColumns('admins'))
addSearchFilter(query, columns, search)
}
const result = await query.orderBy(sortBy, sortOrder).paginate(page, perPage)
return response.ok(result)
}
public async store({ request, response, bouncer }: HttpContext) {
await bouncer.with(RolePolicy).authorize('createRole')
const { permissions, ...data } = await createRoleValidator.validate(request.all())
const record = await Role.create(data)
if (record) {
// await record.related('permissions').sync(data.permissions)
await this.updatePermissions(record, permissions)
return response.created({ message: 'Successfully created.' })
}
return response.badRequest({ message: 'Cannot create.' })
}
public async show({ request, response, bouncer }: HttpContext) {
await bouncer.with(RolePolicy).authorize('viewRole')
const { id } = request.params()
if (!id) return response.notFound({ message: 'Not found.' })
const record = await Role.find(id)
if (!record) return response.notFound({ message: 'Not found.' })
const permissions = await db
.from('role_permissions')
.where('role_id', id)
.select(['permission_slug as slug', 'role_id'])
return response.ok({ ...record.serialize(), permissions })
}
public async update({ request, response, bouncer }: HttpContext) {
await bouncer.with(RolePolicy).authorize('updateRole')
const { id } = request.params()
if (!id) return response.notFound({ message: 'Not found.' })
const data = await updateRoleValidator.validate(request.all())
const record = await Role.find(id)
if (!record) return response.notFound({ message: 'Not found.' })
record.name = data.name
await record.save()
await this.updatePermissions(record, data.permissions)
return response.ok({ message: 'Updated.' })
}
public async destroy({ request, response, bouncer }: HttpContext) {
await bouncer.with(RolePolicy).authorize('deleteRole')
const { id } = request.params()
if (!id) return response.notFound({ message: 'Not found.' })
const record = await Role.find(id)
if (!record) return response.notFound({ message: 'Not found.' })
await Role.query().where('id', id).delete()
return response.ok({ message: 'Deleted.' })
}
private async updatePermissions(record: Role, permissions?: string[]) {
await db.from('role_permissions').where('role_id', record.id).delete()
if (!permissions || permissions.length === 0) {
console.log('no permissions to insert')
return
}
const newPermissions = permissions.map((perm) => ({
role_id: record.id,
permission_slug: perm,
}))
await db.table('role_permissions').insert(newPermissions)
console.log('inserted permissions:', newPermissions.length)
}
}
+13
View File
@@ -0,0 +1,13 @@
import { BaseModel, column } from '@adonisjs/lucid/orm'
import { DateTime } from 'luxon'
export default class Role extends BaseModel {
static searchable = {
string: ['name'],
number: ['id'],
}
@column({ isPrimary: true }) declare id: number
@column() declare name: string
@column.dateTime({ columnName: 'created_at' }) declare createdAt: DateTime | null
@column.dateTime({ columnName: 'updated_at' }) declare updatedAt: DateTime | null
}
+36
View File
@@ -0,0 +1,36 @@
import { BasePolicy } from '@adonisjs/bouncer'
import type { AuthorizerResponse } from '@adonisjs/bouncer/types'
import Admins from '#base_modules/Admin/model/admin'
import { getAdminPermissionSlugs } from '#services/permission_service'
export default class RolePolicy extends BasePolicy {
async roleList(user: Admins): Promise<AuthorizerResponse> {
if (!user) return false
const perms = await getAdminPermissionSlugs(user)
return perms.has('role.view')
}
async viewRole(user: Admins): Promise<AuthorizerResponse> {
if (!user) return false
const perms = await getAdminPermissionSlugs(user)
return perms.has('role.view')
}
async createRole(user: Admins): Promise<AuthorizerResponse> {
if (!user) return false
const perms = await getAdminPermissionSlugs(user)
return perms.has('role.create')
}
async updateRole(user: Admins): Promise<AuthorizerResponse> {
if (!user) return false
const perms = await getAdminPermissionSlugs(user)
return perms.has('role.update')
}
async deleteRole(user: Admins): Promise<AuthorizerResponse> {
if (!user) return false
const perms = await getAdminPermissionSlugs(user)
return perms.has('role.delete')
}
}
+6
View File
@@ -0,0 +1,6 @@
import router from '@adonisjs/core/services/router'
import { middleware } from '#start/kernel'
const roleController = () => import('#base_modules/Role/controller/role_controller')
router.resource('/role', roleController).apiOnly().use('*', [middleware.auth()]) //.use(['store', 'update', 'destroy'], [middleware.auth()])
@@ -0,0 +1,9 @@
import vine from '@vinejs/vine'
export const createRoleValidator = vine.compile(
vine.object({
id: vine.number().optional(),
name: vine.string().trim(),
permissions: vine.array(vine.string()),
})
)
@@ -0,0 +1,9 @@
import vine from '@vinejs/vine'
export const updateRoleValidator = vine.compile(
vine.object({
id: vine.number().optional(),
name: vine.string().trim(),
permissions: vine.array(vine.string()),
})
)