From 9ed8943d24ecca0423e9be20923487c6011b08d0 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Mon, 13 Apr 2026 13:50:59 +0200 Subject: [PATCH 01/39] Added members controller and seeder + factories --- app/controllers/members_controller.ts | 59 ++++++++++++ app/models/member.ts | 2 +- database/factories/members_factory.ts | 13 +++ database/factories/user_factory.ts | 12 +++ database/schema.ts | 127 ++++++-------------------- database/seeders/member_seeder.ts | 8 ++ start/routes.ts | 7 +- 7 files changed, 129 insertions(+), 99 deletions(-) create mode 100644 app/controllers/members_controller.ts create mode 100644 database/factories/members_factory.ts create mode 100644 database/factories/user_factory.ts create mode 100644 database/seeders/member_seeder.ts diff --git a/app/controllers/members_controller.ts b/app/controllers/members_controller.ts new file mode 100644 index 0000000..2f96d43 --- /dev/null +++ b/app/controllers/members_controller.ts @@ -0,0 +1,59 @@ +import type { HttpContext } from '@adonisjs/core/http' +import Member from '#models/member' + +export default class MembersController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + return Member.query().preload('user').preload('role') + // return Member.all() + } + + /** + * Display form to create a new record + */ + async create({}: HttpContext) { + return Member.create({ + firstName: 'John', + lastName: 'Doe', + }) + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) {} + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + return Member.query().where('id', params.id).preload('user').preload('role').firstOrFail() + // return Member.findOrFail(params.id) + } + + /** + * Edit individual record + */ + async edit({ params }: HttpContext) {} + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const member = await Member.findOrFail(params.id) // We get our member by id + const { firstName, lastName } = request.all() // We transfer the new data from the request to constants + member.firstName = firstName // Assigning the data + member.lastName = lastName // Assigning the data + await member.save() // We save the member to the database + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const member = await Member.findOrFail(params.id) // Get the user by id + await member.delete() + } +} \ No newline at end of file diff --git a/app/models/member.ts b/app/models/member.ts index 61f5c9a..d7147f8 100644 --- a/app/models/member.ts +++ b/app/models/member.ts @@ -10,7 +10,7 @@ import Restock from '#models/restock' import Role from '#models/role' export default class Member extends MemberSchema { - @belongsTo(() => User) + @belongsTo(() => User, { foreignKey: 'id' }) declare user: BelongsTo @hasMany(() => Order) diff --git a/database/factories/members_factory.ts b/database/factories/members_factory.ts new file mode 100644 index 0000000..e3eafbd --- /dev/null +++ b/database/factories/members_factory.ts @@ -0,0 +1,13 @@ +import factory from '@adonisjs/lucid/factories' +import Members from '#models/member' +import { UserFactory } from '#database/factories/user_factory' + +export const MembersFactory = factory + .define(Members, async ({ faker }) => { + return { + firstName: faker.person.firstName(), + lastName: faker.person.lastName(), + } + }) + .relation('user', () => UserFactory) + .build() \ No newline at end of file diff --git a/database/factories/user_factory.ts b/database/factories/user_factory.ts new file mode 100644 index 0000000..21bcc6d --- /dev/null +++ b/database/factories/user_factory.ts @@ -0,0 +1,12 @@ +import factory from '@adonisjs/lucid/factories' +import User from '#models/user' + +export const UserFactory = factory + .define(User, async ({ faker }) => { + return { + email: faker.internet.email(), + password: faker.internet.password(), + casId: faker.string.uuid(), + } as any + }) + .build() \ No newline at end of file diff --git a/database/schema.ts b/database/schema.ts index 688c00c..a94fa91 100644 --- a/database/schema.ts +++ b/database/schema.ts @@ -8,18 +8,7 @@ import { BaseModel, column } from '@adonisjs/lucid/orm' import { DateTime } from 'luxon' export class AuthAccessTokenSchema extends BaseModel { - static $columns = [ - 'abilities', - 'createdAt', - 'expiresAt', - 'hash', - 'id', - 'lastUsedAt', - 'name', - 'tokenableId', - 'type', - 'updatedAt', - ] as const + static $columns = ['abilities', 'createdAt', 'expiresAt', 'hash', 'id', 'lastUsedAt', 'name', 'tokenableId', 'type', 'updatedAt'] as const $columns = AuthAccessTokenSchema.$columns @column() declare abilities: string @@ -89,15 +78,7 @@ export class EventProductSchema extends BaseModel { } export class EventSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'date', - 'description', - 'id', - 'name', - 'status', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'date', 'description', 'id', 'name', 'status', 'updatedAt'] as const $columns = EventSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -116,15 +97,7 @@ export class EventSchema extends BaseModel { } export class FastPassSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'description', - 'duration', - 'id', - 'label', - 'price', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'description', 'duration', 'id', 'label', 'price', 'updatedAt'] as const $columns = FastPassSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime @@ -160,13 +133,15 @@ export class FurnitureSchema extends BaseModel { } export class GoodSupplierSchema extends BaseModel { - static $columns = ['createdAt', 'goodId', 'supplierId', 'updatedAt'] as const + static $columns = ['createdAt', 'goodId', 'price', 'supplierId', 'updatedAt'] as const $columns = GoodSupplierSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @column() declare goodId: number @column() + declare price: string + @column() declare supplierId: number @column.dateTime({ autoCreate: true, autoUpdate: true }) declare updatedAt: DateTime | null @@ -207,17 +182,7 @@ export class JobSchema extends BaseModel { } export class LogSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'id', - 'ip', - 'level', - 'message', - 'meta', - 'method', - 'url', - 'userId', - ] as const + static $columns = ['createdAt', 'id', 'ip', 'level', 'message', 'meta', 'method', 'url', 'userId'] as const $columns = LogSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -313,15 +278,7 @@ export class OrderProductSchema extends BaseModel { } export class OrderSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'eventId', - 'id', - 'memberId', - 'status', - 'transactionId', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'eventId', 'id', 'memberId', 'status', 'transactionId', 'updatedAt'] as const $columns = OrderSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -351,14 +308,7 @@ export class PermissionSchema extends BaseModel { } export class PreOrderItemSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'preOrderId', - 'productId', - 'quantity', - 'receivedQuantity', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'preOrderId', 'productId', 'quantity', 'receivedQuantity', 'updatedAt'] as const $columns = PreOrderItemSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -390,33 +340,37 @@ export class PreOrderSchema extends BaseModel { } export class ProductFurnitureSchema extends BaseModel { - static $columns = ['furnitureId', 'productId'] as const + static $columns = ['createdAt', 'furnitureId', 'productId', 'quantity', 'updatedAt'] as const $columns = ProductFurnitureSchema.$columns + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime @column() declare furnitureId: number @column({ isPrimary: true }) declare productId: number + @column() + declare quantity: number + @column.dateTime({ autoCreate: true, autoUpdate: true }) + declare updatedAt: DateTime | null } export class ProductGoodSchema extends BaseModel { - static $columns = ['goodId', 'productId'] as const + static $columns = ['createdAt', 'goodId', 'productId', 'quantity', 'updatedAt'] as const $columns = ProductGoodSchema.$columns + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime @column() declare goodId: number @column({ isPrimary: true }) declare productId: number + @column() + declare quantity: number + @column.dateTime({ autoCreate: true, autoUpdate: true }) + declare updatedAt: DateTime | null } export class ProductSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'description', - 'id', - 'isVegetarian', - 'name', - 'recipe', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'description', 'id', 'isVegetarian', 'name', 'recipe', 'updatedAt'] as const $columns = ProductSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -435,14 +389,7 @@ export class ProductSchema extends BaseModel { } export class RestockSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'id', - 'memberId', - 'supplierId', - 'totalPrice', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'id', 'memberId', 'supplierId', 'totalPrice', 'updatedAt'] as const $columns = RestockSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -483,16 +430,7 @@ export class RolesPermissionSchema extends BaseModel { } export class StockBatchSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'expirationDate', - 'goodId', - 'id', - 'label', - 'quantity', - 'restockId', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'expirationDate', 'goodId', 'id', 'label', 'quantity', 'restockId', 'updatedAt'] as const $columns = StockBatchSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -513,14 +451,7 @@ export class StockBatchSchema extends BaseModel { } export class StockMovementSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'goodId', - 'id', - 'movementType', - 'quantity', - 'stockBatchId', - ] as const + static $columns = ['createdAt', 'goodId', 'id', 'movementType', 'quantity', 'stockBatchId'] as const $columns = StockMovementSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -580,8 +511,10 @@ export class TransactionSchema extends BaseModel { } export class UserSchema extends BaseModel { - static $columns = ['createdAt', 'email', 'id', 'password', 'updatedAt'] as const + static $columns = ['casId', 'createdAt', 'email', 'id', 'password', 'updatedAt'] as const $columns = UserSchema.$columns + @column() + declare casId: string @column.dateTime({ autoCreate: true }) declare createdAt: DateTime @column() diff --git a/database/seeders/member_seeder.ts b/database/seeders/member_seeder.ts new file mode 100644 index 0000000..96299ae --- /dev/null +++ b/database/seeders/member_seeder.ts @@ -0,0 +1,8 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { MembersFactory } from '#database/factories/members_factory' + +export default class MemberSeeder extends BaseSeeder { + async run() { + await MembersFactory.with('user').createMany(10) + } +} \ No newline at end of file diff --git a/start/routes.ts b/start/routes.ts index 720a100..b129614 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -8,9 +8,14 @@ */ import router from '@adonisjs/core/services/router' +import MembersController from '#controllers/members_controller' router.get('/', () => { return { hello: 'world' } }) -router.group(() => {}).prefix('/v1') +router.group(() => { }).prefix('/v1') + +router.group(() => { + router.resource('members', MembersController).apiOnly() +}).prefix('/v1') \ No newline at end of file From 12ead8778920badb081e9cdf12389cfce5f46bb6 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Mon, 13 Apr 2026 14:04:21 +0200 Subject: [PATCH 02/39] Corrected lint and typecheck --- app/controllers/members_controller.ts | 8 ++++---- start/routes.ts | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/controllers/members_controller.ts b/app/controllers/members_controller.ts index 2f96d43..ca05b35 100644 --- a/app/controllers/members_controller.ts +++ b/app/controllers/members_controller.ts @@ -5,7 +5,7 @@ export default class MembersController { /** * Display a list of resource */ - async index({}: HttpContext) { + async index({ }: HttpContext) { return Member.query().preload('user').preload('role') // return Member.all() } @@ -13,7 +13,7 @@ export default class MembersController { /** * Display form to create a new record */ - async create({}: HttpContext) { + async create({ }: HttpContext) { return Member.create({ firstName: 'John', lastName: 'Doe', @@ -23,7 +23,7 @@ export default class MembersController { /** * Handle form submission for the create action */ - async store({ request }: HttpContext) {} + // async store({ request }: HttpContext) {} /** * Show individual record @@ -36,7 +36,7 @@ export default class MembersController { /** * Edit individual record */ - async edit({ params }: HttpContext) {} + // async edit({ params }: HttpContext) { } /** * Handle form submission for the edit action diff --git a/start/routes.ts b/start/routes.ts index b129614..a97a2aa 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -8,7 +8,6 @@ */ import router from '@adonisjs/core/services/router' -import MembersController from '#controllers/members_controller' router.get('/', () => { return { hello: 'world' } @@ -17,5 +16,5 @@ router.get('/', () => { router.group(() => { }).prefix('/v1') router.group(() => { - router.resource('members', MembersController).apiOnly() + router.resource('members', () => import('#controllers/members_controller')).apiOnly() }).prefix('/v1') \ No newline at end of file From 105b54f1c459c0c2f5a67eb18ca1ec276311cabe Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Mon, 13 Apr 2026 14:14:20 +0200 Subject: [PATCH 03/39] Ran prettier --write for the files --- app/controllers/members_controller.ts | 3 +- database/factories/members_factory.ts | 2 +- database/factories/user_factory.ts | 2 +- database/schema.ts | 103 +++++++++++++++++++++++--- database/seeders/member_seeder.ts | 2 +- start/routes.ts | 10 ++- 6 files changed, 103 insertions(+), 19 deletions(-) diff --git a/app/controllers/members_controller.ts b/app/controllers/members_controller.ts index ca05b35..15abba2 100644 --- a/app/controllers/members_controller.ts +++ b/app/controllers/members_controller.ts @@ -4,8 +4,7 @@ import Member from '#models/member' export default class MembersController { /** * Display a list of resource - */ - async index({ }: HttpContext) { + async index({}: HttpContext) { return Member.query().preload('user').preload('role') // return Member.all() } diff --git a/database/factories/members_factory.ts b/database/factories/members_factory.ts index e3eafbd..bbb0f4e 100644 --- a/database/factories/members_factory.ts +++ b/database/factories/members_factory.ts @@ -10,4 +10,4 @@ export const MembersFactory = factory } }) .relation('user', () => UserFactory) - .build() \ No newline at end of file + .build() diff --git a/database/factories/user_factory.ts b/database/factories/user_factory.ts index 21bcc6d..69f90c0 100644 --- a/database/factories/user_factory.ts +++ b/database/factories/user_factory.ts @@ -9,4 +9,4 @@ export const UserFactory = factory casId: faker.string.uuid(), } as any }) - .build() \ No newline at end of file + .build() diff --git a/database/schema.ts b/database/schema.ts index a94fa91..d0a5e46 100644 --- a/database/schema.ts +++ b/database/schema.ts @@ -8,7 +8,18 @@ import { BaseModel, column } from '@adonisjs/lucid/orm' import { DateTime } from 'luxon' export class AuthAccessTokenSchema extends BaseModel { - static $columns = ['abilities', 'createdAt', 'expiresAt', 'hash', 'id', 'lastUsedAt', 'name', 'tokenableId', 'type', 'updatedAt'] as const + static $columns = [ + 'abilities', + 'createdAt', + 'expiresAt', + 'hash', + 'id', + 'lastUsedAt', + 'name', + 'tokenableId', + 'type', + 'updatedAt', + ] as const $columns = AuthAccessTokenSchema.$columns @column() declare abilities: string @@ -78,7 +89,15 @@ export class EventProductSchema extends BaseModel { } export class EventSchema extends BaseModel { - static $columns = ['createdAt', 'date', 'description', 'id', 'name', 'status', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'date', + 'description', + 'id', + 'name', + 'status', + 'updatedAt', + ] as const $columns = EventSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -97,7 +116,15 @@ export class EventSchema extends BaseModel { } export class FastPassSchema extends BaseModel { - static $columns = ['createdAt', 'description', 'duration', 'id', 'label', 'price', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'description', + 'duration', + 'id', + 'label', + 'price', + 'updatedAt', + ] as const $columns = FastPassSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime @@ -182,7 +209,17 @@ export class JobSchema extends BaseModel { } export class LogSchema extends BaseModel { - static $columns = ['createdAt', 'id', 'ip', 'level', 'message', 'meta', 'method', 'url', 'userId'] as const + static $columns = [ + 'createdAt', + 'id', + 'ip', + 'level', + 'message', + 'meta', + 'method', + 'url', + 'userId', + ] as const $columns = LogSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -278,7 +315,15 @@ export class OrderProductSchema extends BaseModel { } export class OrderSchema extends BaseModel { - static $columns = ['createdAt', 'eventId', 'id', 'memberId', 'status', 'transactionId', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'eventId', + 'id', + 'memberId', + 'status', + 'transactionId', + 'updatedAt', + ] as const $columns = OrderSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -308,7 +353,14 @@ export class PermissionSchema extends BaseModel { } export class PreOrderItemSchema extends BaseModel { - static $columns = ['createdAt', 'preOrderId', 'productId', 'quantity', 'receivedQuantity', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'preOrderId', + 'productId', + 'quantity', + 'receivedQuantity', + 'updatedAt', + ] as const $columns = PreOrderItemSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -370,7 +422,15 @@ export class ProductGoodSchema extends BaseModel { } export class ProductSchema extends BaseModel { - static $columns = ['createdAt', 'description', 'id', 'isVegetarian', 'name', 'recipe', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'description', + 'id', + 'isVegetarian', + 'name', + 'recipe', + 'updatedAt', + ] as const $columns = ProductSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -389,7 +449,14 @@ export class ProductSchema extends BaseModel { } export class RestockSchema extends BaseModel { - static $columns = ['createdAt', 'id', 'memberId', 'supplierId', 'totalPrice', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'id', + 'memberId', + 'supplierId', + 'totalPrice', + 'updatedAt', + ] as const $columns = RestockSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -430,7 +497,16 @@ export class RolesPermissionSchema extends BaseModel { } export class StockBatchSchema extends BaseModel { - static $columns = ['createdAt', 'expirationDate', 'goodId', 'id', 'label', 'quantity', 'restockId', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'expirationDate', + 'goodId', + 'id', + 'label', + 'quantity', + 'restockId', + 'updatedAt', + ] as const $columns = StockBatchSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -451,7 +527,14 @@ export class StockBatchSchema extends BaseModel { } export class StockMovementSchema extends BaseModel { - static $columns = ['createdAt', 'goodId', 'id', 'movementType', 'quantity', 'stockBatchId'] as const + static $columns = [ + 'createdAt', + 'goodId', + 'id', + 'movementType', + 'quantity', + 'stockBatchId', + ] as const $columns = StockMovementSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null diff --git a/database/seeders/member_seeder.ts b/database/seeders/member_seeder.ts index 96299ae..bc77f7e 100644 --- a/database/seeders/member_seeder.ts +++ b/database/seeders/member_seeder.ts @@ -5,4 +5,4 @@ export default class MemberSeeder extends BaseSeeder { async run() { await MembersFactory.with('user').createMany(10) } -} \ No newline at end of file +} diff --git a/start/routes.ts b/start/routes.ts index a97a2aa..ce210e0 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -13,8 +13,10 @@ router.get('/', () => { return { hello: 'world' } }) -router.group(() => { }).prefix('/v1') +router.group(() => {}).prefix('/v1') -router.group(() => { - router.resource('members', () => import('#controllers/members_controller')).apiOnly() -}).prefix('/v1') \ No newline at end of file +router + .group(() => { + router.resource('members', () => import('#controllers/members_controller')).apiOnly() + }) + .prefix('/v1') From 84c4069936b4d677e84de4718fac5bca44ce3ca0 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Mon, 13 Apr 2026 14:17:18 +0200 Subject: [PATCH 04/39] Prettier members_controller.ts --- app/controllers/members_controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/members_controller.ts b/app/controllers/members_controller.ts index 15abba2..81256b8 100644 --- a/app/controllers/members_controller.ts +++ b/app/controllers/members_controller.ts @@ -12,7 +12,7 @@ export default class MembersController { /** * Display form to create a new record */ - async create({ }: HttpContext) { + async create({}: HttpContext) { return Member.create({ firstName: 'John', lastName: 'Doe', @@ -55,4 +55,4 @@ export default class MembersController { const member = await Member.findOrFail(params.id) // Get the user by id await member.delete() } -} \ No newline at end of file +} From 7934ef2dc96f32ce0743c1f67dbc300908841b56 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Tue, 14 Apr 2026 15:38:49 +0200 Subject: [PATCH 05/39] feat(categories): add controller --- app/controllers/categories_controller.ts | 44 ++++++++++++++++++++++++ database/factories/category_factory.ts | 10 ++++++ database/seeders/category_seeder.ts | 9 +++++ start/routes.ts | 7 +++- 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 app/controllers/categories_controller.ts create mode 100644 database/factories/category_factory.ts create mode 100644 database/seeders/category_seeder.ts diff --git a/app/controllers/categories_controller.ts b/app/controllers/categories_controller.ts new file mode 100644 index 0000000..46963da --- /dev/null +++ b/app/controllers/categories_controller.ts @@ -0,0 +1,44 @@ +import type { HttpContext } from '@adonisjs/core/http' +import Category from '#models/category' + +export default class CategoriesController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + return Category.all() + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const data = request.all() + return Category.create(data) + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + return Category.findOrFail(params.id) + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const category = await Category.findOrFail(params.id) + const data = request.all() + category.merge(data) + return category.save() + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const category = await Category.findOrFail(params.id) + return category.delete() + } +} \ No newline at end of file diff --git a/database/factories/category_factory.ts b/database/factories/category_factory.ts new file mode 100644 index 0000000..21d78d6 --- /dev/null +++ b/database/factories/category_factory.ts @@ -0,0 +1,10 @@ +import factory from '@adonisjs/lucid/factories' +import Category from '#models/category' + +export const CategoryFactory = factory + .define(Category, async ({ faker }) => { + return { + name: faker.commerce.department(), + } + }) + .build() \ No newline at end of file diff --git a/database/seeders/category_seeder.ts b/database/seeders/category_seeder.ts new file mode 100644 index 0000000..818b0a5 --- /dev/null +++ b/database/seeders/category_seeder.ts @@ -0,0 +1,9 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { CategoryFactory } from '#database/factories/category_factory' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + await CategoryFactory.createMany(10) + } +} \ No newline at end of file diff --git a/start/routes.ts b/start/routes.ts index ce210e0..7c7b23c 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -17,6 +17,11 @@ router.group(() => {}).prefix('/v1') router .group(() => { - router.resource('members', () => import('#controllers/members_controller')).apiOnly() + router.resource('members', () => import('#controllers/members_controller')).apiOnly(), + router.resource('categories', () => import('#controllers/categories_controller')).apiOnly() }) .prefix('/v1') + +router.get('/test', async () => { + return { message: 'ok' } +}) \ No newline at end of file From 2b1ab425d2478657901745a63add455d77eb0bba Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Tue, 14 Apr 2026 16:01:30 +0200 Subject: [PATCH 06/39] Runned prettier --- app/controllers/categories_controller.ts | 2 +- database/factories/category_factory.ts | 2 +- database/seeders/category_seeder.ts | 2 +- start/routes.ts | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/controllers/categories_controller.ts b/app/controllers/categories_controller.ts index 46963da..dd94e08 100644 --- a/app/controllers/categories_controller.ts +++ b/app/controllers/categories_controller.ts @@ -41,4 +41,4 @@ export default class CategoriesController { const category = await Category.findOrFail(params.id) return category.delete() } -} \ No newline at end of file +} diff --git a/database/factories/category_factory.ts b/database/factories/category_factory.ts index 21d78d6..e0f1e4d 100644 --- a/database/factories/category_factory.ts +++ b/database/factories/category_factory.ts @@ -7,4 +7,4 @@ export const CategoryFactory = factory name: faker.commerce.department(), } }) - .build() \ No newline at end of file + .build() diff --git a/database/seeders/category_seeder.ts b/database/seeders/category_seeder.ts index 818b0a5..9a75876 100644 --- a/database/seeders/category_seeder.ts +++ b/database/seeders/category_seeder.ts @@ -6,4 +6,4 @@ export default class extends BaseSeeder { // Write your database queries inside the run method await CategoryFactory.createMany(10) } -} \ No newline at end of file +} diff --git a/start/routes.ts b/start/routes.ts index 7c7b23c..927b6ee 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -17,11 +17,11 @@ router.group(() => {}).prefix('/v1') router .group(() => { - router.resource('members', () => import('#controllers/members_controller')).apiOnly(), - router.resource('categories', () => import('#controllers/categories_controller')).apiOnly() + ;(router.resource('members', () => import('#controllers/members_controller')).apiOnly(), + router.resource('categories', () => import('#controllers/categories_controller')).apiOnly()) }) .prefix('/v1') router.get('/test', async () => { return { message: 'ok' } -}) \ No newline at end of file +}) From a83d788b1172b11b063aa50955767e0a27c1c8e8 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Tue, 14 Apr 2026 16:12:13 +0200 Subject: [PATCH 07/39] Added furniture controller --- app/controllers/furnitures_controller.ts | 44 ++++++++++++++++++++++++ database/factories/furniture_factory.ts | 12 +++++++ database/seeders/furniture_seeder.ts | 9 +++++ start/routes.ts | 3 +- 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 app/controllers/furnitures_controller.ts create mode 100644 database/factories/furniture_factory.ts create mode 100644 database/seeders/furniture_seeder.ts diff --git a/app/controllers/furnitures_controller.ts b/app/controllers/furnitures_controller.ts new file mode 100644 index 0000000..76a68c6 --- /dev/null +++ b/app/controllers/furnitures_controller.ts @@ -0,0 +1,44 @@ +import type { HttpContext } from '@adonisjs/core/http' +import Furniture from '#models/furniture' + +export default class FurnituresController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + return Furniture.all() + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { name, quantity, price } = request.all() + return Furniture.create({ name, quantity, price }) + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + return Furniture.findOrFail(params.id) + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const furniture = await Furniture.findOrFail(params.id) + const { name, quantity, price } = request.all() + furniture.merge({ name, quantity, price }) + return furniture.save() + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const furniture = await Furniture.findOrFail(params.id) + return furniture.delete() + } +} diff --git a/database/factories/furniture_factory.ts b/database/factories/furniture_factory.ts new file mode 100644 index 0000000..7636c13 --- /dev/null +++ b/database/factories/furniture_factory.ts @@ -0,0 +1,12 @@ +import factory from '@adonisjs/lucid/factories' +import Furniture from '#models/furniture' + +export const FurnitureFactory = factory + .define(Furniture, async ({ faker }) => { + return { + name: faker.commerce.productName(), + quantity: faker.number.int({ min: 1, max: 100 }), + price: faker.commerce.price(), + } + }) + .build() diff --git a/database/seeders/furniture_seeder.ts b/database/seeders/furniture_seeder.ts new file mode 100644 index 0000000..d5777a5 --- /dev/null +++ b/database/seeders/furniture_seeder.ts @@ -0,0 +1,9 @@ +import { FurnitureFactory } from '#database/factories/furniture_factory' +import { BaseSeeder } from '@adonisjs/lucid/seeders' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + await FurnitureFactory.createMany(10) + } +} diff --git a/start/routes.ts b/start/routes.ts index 927b6ee..9827236 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -18,7 +18,8 @@ router.group(() => {}).prefix('/v1') router .group(() => { ;(router.resource('members', () => import('#controllers/members_controller')).apiOnly(), - router.resource('categories', () => import('#controllers/categories_controller')).apiOnly()) + router.resource('categories', () => import('#controllers/categories_controller')).apiOnly(), + router.resource('furnitures', () => import('#controllers/furnitures_controller')).apiOnly()) }) .prefix('/v1') From 480229e1ffc526da2ff09e1a73e0947dc2f89e7a Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Tue, 14 Apr 2026 16:39:45 +0200 Subject: [PATCH 08/39] Added Products and relation to furniture --- app/controllers/products_controller.ts | 54 ++++++++++++++++++++ database/factories/product_factory.ts | 13 +++++ database/seeders/product_furniture_seeder.ts | 18 +++++++ database/seeders/product_seeder.ts | 9 ++++ start/routes.ts | 3 +- 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 app/controllers/products_controller.ts create mode 100644 database/factories/product_factory.ts create mode 100644 database/seeders/product_furniture_seeder.ts create mode 100644 database/seeders/product_seeder.ts diff --git a/app/controllers/products_controller.ts b/app/controllers/products_controller.ts new file mode 100644 index 0000000..39a03f0 --- /dev/null +++ b/app/controllers/products_controller.ts @@ -0,0 +1,54 @@ +import type { HttpContext } from '@adonisjs/core/http' +import Product from '#models/product' + +export default class ProductsController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + return Product.query().preload('furnitures') + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { name, isVegetarian, description, recipe } = request.all() + const product = new Product() + product.name = name + product.isVegetarian = isVegetarian + product.description = description + product.recipe = recipe + await product.save() + return product + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + return await Product.query().preload('furnitures').where('id', params.id).firstOrFail() + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const product = await Product.query().preload('furnitures').where('id', params.id).firstOrFail() // We get our product by id + const { name, isVegetarian, description, recipe } = request.all() // We transfer the new data from the request to constants + product.name = name // Assigning the data + product.isVegetarian = isVegetarian // Assigning the data + product.description = description // Assigning the data + product.recipe = recipe // Assigning the data + await product.save() // We save the product to the database + return product + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const product = await Product.query().preload('furnitures').where('id', params.id).firstOrFail() // Get the product by id + await product.delete() + } +} \ No newline at end of file diff --git a/database/factories/product_factory.ts b/database/factories/product_factory.ts new file mode 100644 index 0000000..de87885 --- /dev/null +++ b/database/factories/product_factory.ts @@ -0,0 +1,13 @@ +import factory from '@adonisjs/lucid/factories' +import Product from '#models/product' + +export const ProductFactory = factory + .define(Product, async ({ faker }) => { + return { + name: faker.commerce.productName(), + isVegetarian: faker.datatype.boolean(), + description: faker.commerce.productDescription(), + recipe: faker.lorem.paragraph(), + } + }) + .build() \ No newline at end of file diff --git a/database/seeders/product_furniture_seeder.ts b/database/seeders/product_furniture_seeder.ts new file mode 100644 index 0000000..d838173 --- /dev/null +++ b/database/seeders/product_furniture_seeder.ts @@ -0,0 +1,18 @@ +import Furniture from '#models/furniture' +import Product from '#models/product' +import { BaseSeeder } from '@adonisjs/lucid/seeders' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method. + const products = await Product.all() + const funrnitures = await Furniture.all() + + for (const product of products) { + await product.related('furnitures').sync({ + [funrnitures[0].id]: { quantity: 2 }, + [funrnitures[1].id]: { quantity: 5 }, + }) + } + } +} \ No newline at end of file diff --git a/database/seeders/product_seeder.ts b/database/seeders/product_seeder.ts new file mode 100644 index 0000000..7ee3467 --- /dev/null +++ b/database/seeders/product_seeder.ts @@ -0,0 +1,9 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { ProductFactory } from '#database/factories/product_factory' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + await ProductFactory.createMany(10) + } +} \ No newline at end of file diff --git a/start/routes.ts b/start/routes.ts index 9827236..00420a7 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -19,7 +19,8 @@ router .group(() => { ;(router.resource('members', () => import('#controllers/members_controller')).apiOnly(), router.resource('categories', () => import('#controllers/categories_controller')).apiOnly(), - router.resource('furnitures', () => import('#controllers/furnitures_controller')).apiOnly()) + router.resource('furnitures', () => import('#controllers/furnitures_controller')).apiOnly(), + router.resource('products', () => import('#controllers/products_controller')).apiOnly()) }) .prefix('/v1') From f650ed4dd599925d5ddcb58b5dc385ba3b0c890f Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Tue, 14 Apr 2026 17:01:45 +0200 Subject: [PATCH 09/39] Added goods (not product associated) --- app/controllers/goods_controller.ts | 53 +++++++++++++++++++++++++ database/factories/good_factory.ts | 12 ++++++ database/seeders/good_seeder.ts | 9 +++++ database/seeders/product_good_seeder.ts | 22 ++++++++++ start/routes.ts | 3 +- 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 app/controllers/goods_controller.ts create mode 100644 database/factories/good_factory.ts create mode 100644 database/seeders/good_seeder.ts create mode 100644 database/seeders/product_good_seeder.ts diff --git a/app/controllers/goods_controller.ts b/app/controllers/goods_controller.ts new file mode 100644 index 0000000..cad9b3c --- /dev/null +++ b/app/controllers/goods_controller.ts @@ -0,0 +1,53 @@ +import type { HttpContext } from '@adonisjs/core/http' +import Good from '#models/good' + +export default class GoodsController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + //return Good.query().preload('products').preload('category').preload('suppliers') + return Good.query().preload('products') + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { name, unit, brand } = request.all() + const good = new Good() + good.name = name + good.unit = unit + good.brand = brand + await good.save() + return good + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + return await Good.query().preload('products').where('id', params.id).firstOrFail() + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const good = await Good.query().preload('products').where('id', params.id).firstOrFail() // We get our good by id + const { name, unit, brand } = request.all() + good.name = name + good.unit = unit + good.brand = brand + await good.save() + return good + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const good = await Good.query().preload('products').where('id', params.id).firstOrFail() + await good.delete() + } +} \ No newline at end of file diff --git a/database/factories/good_factory.ts b/database/factories/good_factory.ts new file mode 100644 index 0000000..d304112 --- /dev/null +++ b/database/factories/good_factory.ts @@ -0,0 +1,12 @@ +import factory from '@adonisjs/lucid/factories' +import Good from '#models/good' + +export const GoodFactory = factory + .define(Good, async ({ faker }) => { + return { + name: faker.commerce.productName(), + unit: faker.helpers.arrayElement(['pcs', 'kg', 'liter']), + brand: faker.company.name(), + } + }) + .build() \ No newline at end of file diff --git a/database/seeders/good_seeder.ts b/database/seeders/good_seeder.ts new file mode 100644 index 0000000..5a3940a --- /dev/null +++ b/database/seeders/good_seeder.ts @@ -0,0 +1,9 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { GoodFactory } from '#database/factories/good_factory' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + await GoodFactory.createMany(20) + } +} \ No newline at end of file diff --git a/database/seeders/product_good_seeder.ts b/database/seeders/product_good_seeder.ts new file mode 100644 index 0000000..6fca055 --- /dev/null +++ b/database/seeders/product_good_seeder.ts @@ -0,0 +1,22 @@ +import Good from '#models/good' +import Product from '#models/product' +import { BaseSeeder } from '@adonisjs/lucid/seeders' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + const products = await Product.all() + const goods = await Good.all() + + if (goods.length < 2) { + throw new Error('Not enough goods in database') + } + + for (const product of products) { + await product.related('goods').sync({ + [goods[0].id]: { quantity: 2 }, + [goods[1].id]: { quantity: 5 }, + }) + } + } +} \ No newline at end of file diff --git a/start/routes.ts b/start/routes.ts index 00420a7..01e3072 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -20,7 +20,8 @@ router ;(router.resource('members', () => import('#controllers/members_controller')).apiOnly(), router.resource('categories', () => import('#controllers/categories_controller')).apiOnly(), router.resource('furnitures', () => import('#controllers/furnitures_controller')).apiOnly(), - router.resource('products', () => import('#controllers/products_controller')).apiOnly()) + router.resource('products', () => import('#controllers/products_controller')).apiOnly(), + router.resource('goods', () => import('#controllers/goods_controller')).apiOnly()) }) .prefix('/v1') From 4685b480c1e26a72b1cd418bc349af13449b26f7 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 09:11:18 +0200 Subject: [PATCH 10/39] Fixed category_id problem beeing null --- database/factories/good_factory.ts | 3 + database/schema.ts | 103 +++--------------------- database/seeders/category_seeder.ts | 4 +- database/seeders/good_seeder.ts | 16 +++- database/seeders/product_good_seeder.ts | 2 +- 5 files changed, 29 insertions(+), 99 deletions(-) diff --git a/database/factories/good_factory.ts b/database/factories/good_factory.ts index d304112..6d820f4 100644 --- a/database/factories/good_factory.ts +++ b/database/factories/good_factory.ts @@ -1,5 +1,6 @@ import factory from '@adonisjs/lucid/factories' import Good from '#models/good' +import { CategoryFactory } from './category_factory.ts' export const GoodFactory = factory .define(Good, async ({ faker }) => { @@ -7,6 +8,8 @@ export const GoodFactory = factory name: faker.commerce.productName(), unit: faker.helpers.arrayElement(['pcs', 'kg', 'liter']), brand: faker.company.name(), + categoryId: null, // Will be set by relation } }) + .relation('category', () => CategoryFactory) .build() \ No newline at end of file diff --git a/database/schema.ts b/database/schema.ts index d0a5e46..a94fa91 100644 --- a/database/schema.ts +++ b/database/schema.ts @@ -8,18 +8,7 @@ import { BaseModel, column } from '@adonisjs/lucid/orm' import { DateTime } from 'luxon' export class AuthAccessTokenSchema extends BaseModel { - static $columns = [ - 'abilities', - 'createdAt', - 'expiresAt', - 'hash', - 'id', - 'lastUsedAt', - 'name', - 'tokenableId', - 'type', - 'updatedAt', - ] as const + static $columns = ['abilities', 'createdAt', 'expiresAt', 'hash', 'id', 'lastUsedAt', 'name', 'tokenableId', 'type', 'updatedAt'] as const $columns = AuthAccessTokenSchema.$columns @column() declare abilities: string @@ -89,15 +78,7 @@ export class EventProductSchema extends BaseModel { } export class EventSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'date', - 'description', - 'id', - 'name', - 'status', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'date', 'description', 'id', 'name', 'status', 'updatedAt'] as const $columns = EventSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -116,15 +97,7 @@ export class EventSchema extends BaseModel { } export class FastPassSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'description', - 'duration', - 'id', - 'label', - 'price', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'description', 'duration', 'id', 'label', 'price', 'updatedAt'] as const $columns = FastPassSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime @@ -209,17 +182,7 @@ export class JobSchema extends BaseModel { } export class LogSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'id', - 'ip', - 'level', - 'message', - 'meta', - 'method', - 'url', - 'userId', - ] as const + static $columns = ['createdAt', 'id', 'ip', 'level', 'message', 'meta', 'method', 'url', 'userId'] as const $columns = LogSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -315,15 +278,7 @@ export class OrderProductSchema extends BaseModel { } export class OrderSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'eventId', - 'id', - 'memberId', - 'status', - 'transactionId', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'eventId', 'id', 'memberId', 'status', 'transactionId', 'updatedAt'] as const $columns = OrderSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -353,14 +308,7 @@ export class PermissionSchema extends BaseModel { } export class PreOrderItemSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'preOrderId', - 'productId', - 'quantity', - 'receivedQuantity', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'preOrderId', 'productId', 'quantity', 'receivedQuantity', 'updatedAt'] as const $columns = PreOrderItemSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -422,15 +370,7 @@ export class ProductGoodSchema extends BaseModel { } export class ProductSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'description', - 'id', - 'isVegetarian', - 'name', - 'recipe', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'description', 'id', 'isVegetarian', 'name', 'recipe', 'updatedAt'] as const $columns = ProductSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -449,14 +389,7 @@ export class ProductSchema extends BaseModel { } export class RestockSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'id', - 'memberId', - 'supplierId', - 'totalPrice', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'id', 'memberId', 'supplierId', 'totalPrice', 'updatedAt'] as const $columns = RestockSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -497,16 +430,7 @@ export class RolesPermissionSchema extends BaseModel { } export class StockBatchSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'expirationDate', - 'goodId', - 'id', - 'label', - 'quantity', - 'restockId', - 'updatedAt', - ] as const + static $columns = ['createdAt', 'expirationDate', 'goodId', 'id', 'label', 'quantity', 'restockId', 'updatedAt'] as const $columns = StockBatchSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -527,14 +451,7 @@ export class StockBatchSchema extends BaseModel { } export class StockMovementSchema extends BaseModel { - static $columns = [ - 'createdAt', - 'goodId', - 'id', - 'movementType', - 'quantity', - 'stockBatchId', - ] as const + static $columns = ['createdAt', 'goodId', 'id', 'movementType', 'quantity', 'stockBatchId'] as const $columns = StockMovementSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null diff --git a/database/seeders/category_seeder.ts b/database/seeders/category_seeder.ts index 9a75876..b654f73 100644 --- a/database/seeders/category_seeder.ts +++ b/database/seeders/category_seeder.ts @@ -1,9 +1,9 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' -import { CategoryFactory } from '#database/factories/category_factory' +// import { CategoryFactory } from '#database/factories/category_factory' export default class extends BaseSeeder { async run() { // Write your database queries inside the run method - await CategoryFactory.createMany(10) + // await CategoryFactory.createMany(10) } } diff --git a/database/seeders/good_seeder.ts b/database/seeders/good_seeder.ts index 5a3940a..9b320f6 100644 --- a/database/seeders/good_seeder.ts +++ b/database/seeders/good_seeder.ts @@ -1,9 +1,19 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' import { GoodFactory } from '#database/factories/good_factory' +import { CategoryFactory } from '#database/factories/category_factory' export default class extends BaseSeeder { - async run() { - // Write your database queries inside the run method - await GoodFactory.createMany(20) + public async run () { + // 1. Créer des catégories + const categories = await CategoryFactory.createMany(3) + + // 2. Créer des goods liés aux catégories + await GoodFactory + .merge( + Array.from({ length: 10 }, (_, index) => ({ + categoryId: categories[index % categories.length].id, + })) + ) + .createMany(10) } } \ No newline at end of file diff --git a/database/seeders/product_good_seeder.ts b/database/seeders/product_good_seeder.ts index 6fca055..492e12d 100644 --- a/database/seeders/product_good_seeder.ts +++ b/database/seeders/product_good_seeder.ts @@ -5,8 +5,8 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' export default class extends BaseSeeder { async run() { // Write your database queries inside the run method - const products = await Product.all() const goods = await Good.all() + const products = await Product.all() if (goods.length < 2) { throw new Error('Not enough goods in database') From 43805838ed21425baeef9028f8240545d3ade13c Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 10:00:28 +0200 Subject: [PATCH 11/39] Fixed 0n relationships between goods, products and furnitures --- app/controllers/goods_controller.ts | 16 ++++++++------ app/controllers/products_controller.ts | 8 +++---- database/seeders/main_seeder.ts | 29 +++++++++++++++++++++++++ database/seeders/product_good_seeder.ts | 29 ++++++++++++++++++++----- 4 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 database/seeders/main_seeder.ts diff --git a/app/controllers/goods_controller.ts b/app/controllers/goods_controller.ts index cad9b3c..8937cf8 100644 --- a/app/controllers/goods_controller.ts +++ b/app/controllers/goods_controller.ts @@ -5,20 +5,21 @@ export default class GoodsController { /** * Display a list of resource */ - async index({}: HttpContext) { + async index({ }: HttpContext) { //return Good.query().preload('products').preload('category').preload('suppliers') - return Good.query().preload('products') + return Good.query().preload('products').preload('category') } /** * Handle form submission for the create action */ async store({ request }: HttpContext) { - const { name, unit, brand } = request.all() + const { name, unit, brand, category_id } = request.all() const good = new Good() good.name = name good.unit = unit good.brand = brand + good.categoryId = category_id await good.save() return good } @@ -27,18 +28,19 @@ export default class GoodsController { * Show individual record */ async show({ params }: HttpContext) { - return await Good.query().preload('products').where('id', params.id).firstOrFail() + return await Good.query().preload('products').preload('category').where('id', params.id).firstOrFail() } /** * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const good = await Good.query().preload('products').where('id', params.id).firstOrFail() // We get our good by id - const { name, unit, brand } = request.all() + const good = await Good.query().preload('products').preload('category').where('id', params.id).firstOrFail() // We get our good by id + const { name, unit, brand, category_id } = request.all() good.name = name good.unit = unit good.brand = brand + good.categoryId = category_id await good.save() return good } @@ -47,7 +49,7 @@ export default class GoodsController { * Delete record */ async destroy({ params }: HttpContext) { - const good = await Good.query().preload('products').where('id', params.id).firstOrFail() + const good = await Good.query().preload('products').preload('category').where('id', params.id).firstOrFail() await good.delete() } } \ No newline at end of file diff --git a/app/controllers/products_controller.ts b/app/controllers/products_controller.ts index 39a03f0..dc4f5f7 100644 --- a/app/controllers/products_controller.ts +++ b/app/controllers/products_controller.ts @@ -6,7 +6,7 @@ export default class ProductsController { * Display a list of resource */ async index({}: HttpContext) { - return Product.query().preload('furnitures') + return Product.query().preload('furnitures').preload('goods') } /** @@ -27,14 +27,14 @@ export default class ProductsController { * Show individual record */ async show({ params }: HttpContext) { - return await Product.query().preload('furnitures').where('id', params.id).firstOrFail() + return await Product.query().preload('furnitures').preload('goods').where('id', params.id).firstOrFail() } /** * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const product = await Product.query().preload('furnitures').where('id', params.id).firstOrFail() // We get our product by id + const product = await Product.query().preload('furnitures').preload('goods').where('id', params.id).firstOrFail() // We get our product by id const { name, isVegetarian, description, recipe } = request.all() // We transfer the new data from the request to constants product.name = name // Assigning the data product.isVegetarian = isVegetarian // Assigning the data @@ -48,7 +48,7 @@ export default class ProductsController { * Delete record */ async destroy({ params }: HttpContext) { - const product = await Product.query().preload('furnitures').where('id', params.id).firstOrFail() // Get the product by id + const product = await Product.query().preload('furnitures').preload('goods').where('id', params.id).firstOrFail() // Get the product by id await product.delete() } } \ No newline at end of file diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts new file mode 100644 index 0000000..33c678f --- /dev/null +++ b/database/seeders/main_seeder.ts @@ -0,0 +1,29 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import CategorySeeder from './category_seeder.js' +import GoodSeeder from './good_seeder.js' +import FurnitureSeeder from './furniture_seeder.js' +import ProductSeeder from './product_seeder.js' +import ProductGoodSeeder from './product_good_seeder.js' +import ProductFurnitureSeeder from './product_furniture_seeder.js' + +export default class extends BaseSeeder { + private async runSeeder(Seeder: typeof BaseSeeder) { + await new Seeder(this.client).run() + } + + public async run() { + // 1. D'abord les catégories + await this.runSeeder(CategorySeeder) + + // 2. Ensuite goods et furnitures (qui dépendent des catégories) + await this.runSeeder(GoodSeeder) + await this.runSeeder(FurnitureSeeder) + + // 3. Ensuite products + await this.runSeeder(ProductSeeder) + + // 4. Enfin les relations many-to-many + await this.runSeeder(ProductGoodSeeder) + await this.runSeeder(ProductFurnitureSeeder) + } +} \ No newline at end of file diff --git a/database/seeders/product_good_seeder.ts b/database/seeders/product_good_seeder.ts index 492e12d..9361050 100644 --- a/database/seeders/product_good_seeder.ts +++ b/database/seeders/product_good_seeder.ts @@ -4,19 +4,36 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' export default class extends BaseSeeder { async run() { - // Write your database queries inside the run method const goods = await Good.all() const products = await Product.all() + console.log(`Found ${goods.length} goods and ${products.length} products`) + if (goods.length < 2) { - throw new Error('Not enough goods in database') + throw new Error('Not enough goods in database. Run good_seeder first!') + } + + if (products.length === 0) { + throw new Error('Not enough products in database. Run product_seeder first!') } + // Pour chaque product, attacher plusieurs goods avec des quantités for (const product of products) { - await product.related('goods').sync({ - [goods[0].id]: { quantity: 2 }, - [goods[1].id]: { quantity: 5 }, - }) + // Sélectionner 2-3 goods aléatoires pour chaque product + const randomGoodsCount = Math.floor(Math.random() * 2) + 2 // 2 ou 3 goods + const selectedGoods = goods + .sort(() => 0.5 - Math.random()) // Mélanger + .slice(0, randomGoodsCount) + + const pivotData: Record = {} + + for (const good of selectedGoods) { + pivotData[good.id] = { + quantity: Math.floor(Math.random() * 10) + 1 // quantité entre 1 et 10 + } + } + + await product.related('goods').sync(pivotData) } } } \ No newline at end of file From a386e6163df56420251b957457ed0bbde9070270 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 10:03:34 +0200 Subject: [PATCH 12/39] Fixed linter naming --- app/controllers/goods_controller.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/goods_controller.ts b/app/controllers/goods_controller.ts index 8937cf8..7a72262 100644 --- a/app/controllers/goods_controller.ts +++ b/app/controllers/goods_controller.ts @@ -14,12 +14,12 @@ export default class GoodsController { * Handle form submission for the create action */ async store({ request }: HttpContext) { - const { name, unit, brand, category_id } = request.all() + const { name, unit, brand, categoryId } = request.all() const good = new Good() good.name = name good.unit = unit good.brand = brand - good.categoryId = category_id + good.categoryId = categoryId await good.save() return good } @@ -36,11 +36,11 @@ export default class GoodsController { */ async update({ params, request }: HttpContext) { const good = await Good.query().preload('products').preload('category').where('id', params.id).firstOrFail() // We get our good by id - const { name, unit, brand, category_id } = request.all() + const { name, unit, brand, categoryId } = request.all() good.name = name good.unit = unit good.brand = brand - good.categoryId = category_id + good.categoryId = categoryId await good.save() return good } From 9cf1495f9ede568830bdf9574f0888206376290e Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 10:42:35 +0200 Subject: [PATCH 13/39] Added basic supplier CRUD --- app/controllers/suppliers_controller.ts | 49 +++++++++++++++++++++++++ database/factories/supplier_factory.ts | 10 +++++ database/seeders/supplier_seeder.ts | 9 +++++ start/routes.ts | 3 +- 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 app/controllers/suppliers_controller.ts create mode 100644 database/factories/supplier_factory.ts create mode 100644 database/seeders/supplier_seeder.ts diff --git a/app/controllers/suppliers_controller.ts b/app/controllers/suppliers_controller.ts new file mode 100644 index 0000000..1e04205 --- /dev/null +++ b/app/controllers/suppliers_controller.ts @@ -0,0 +1,49 @@ +import type { HttpContext } from '@adonisjs/core/http' +import Supplier from '#models/supplier' +import { configProvider } from '@adonisjs/core' + +export default class SuppliersController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + return Supplier.query().preload('goods').preload('restocks') + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { name } = request.all() + const supplier = new Supplier() + supplier.name = name + await supplier.save() + return supplier + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + return await Supplier.query().preload('goods').preload('restocks').where('id', params.id).firstOrFail() + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const supplier = await Supplier.query().preload('goods').preload('restocks').where('id', params.id).firstOrFail() // We get our supplier by id + const { name } = request.all() // We transfer the new data from the request to constants + supplier.name = name // Assigning the data + await supplier.save() // We save the supplier to the database + return supplier + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const supplier = await Supplier.query().preload('goods').preload('restocks').where('id', params.id).firstOrFail() // Get the supplier by id + await supplier.delete() + } +} \ No newline at end of file diff --git a/database/factories/supplier_factory.ts b/database/factories/supplier_factory.ts new file mode 100644 index 0000000..01c31d8 --- /dev/null +++ b/database/factories/supplier_factory.ts @@ -0,0 +1,10 @@ +import factory from '@adonisjs/lucid/factories' +import Supplier from '#models/supplier' + +export const SupplierFactory = factory + .define(Supplier, async ({ faker }) => { + return { + name: faker.company.name(), + } + }) + .build() \ No newline at end of file diff --git a/database/seeders/supplier_seeder.ts b/database/seeders/supplier_seeder.ts new file mode 100644 index 0000000..33c7ba6 --- /dev/null +++ b/database/seeders/supplier_seeder.ts @@ -0,0 +1,9 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { SupplierFactory } from '#database/factories/supplier_factory' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + await SupplierFactory.createMany(10) + } +} \ No newline at end of file diff --git a/start/routes.ts b/start/routes.ts index 01e3072..b2afc69 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -21,7 +21,8 @@ router router.resource('categories', () => import('#controllers/categories_controller')).apiOnly(), router.resource('furnitures', () => import('#controllers/furnitures_controller')).apiOnly(), router.resource('products', () => import('#controllers/products_controller')).apiOnly(), - router.resource('goods', () => import('#controllers/goods_controller')).apiOnly()) + router.resource('goods', () => import('#controllers/goods_controller')).apiOnly(), + router.resource('suppliers', () => import('#controllers/suppliers_controller')).apiOnly()) }) .prefix('/v1') From 5a2f23271920a620dc00f4ae53a99be203b2845c Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 10:52:58 +0200 Subject: [PATCH 14/39] Added relation between good and supplier --- database/seeders/good_supplier_seeder.ts | 40 ++++++++++++++++++++++++ database/seeders/main_seeder.ts | 12 ++++--- 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 database/seeders/good_supplier_seeder.ts diff --git a/database/seeders/good_supplier_seeder.ts b/database/seeders/good_supplier_seeder.ts new file mode 100644 index 0000000..758267c --- /dev/null +++ b/database/seeders/good_supplier_seeder.ts @@ -0,0 +1,40 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import Good from '#models/good' +import Supplier from '#models/supplier' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + const goods = await Good.all() + const suppliers = await Supplier.all() + + console.log(`Found ${goods.length} goods and ${suppliers.length} suppliers`) + + if (goods.length < 2) { + throw new Error('Not enough goods in database. Run good_seeder first!') + } + + if (suppliers.length === 0) { + throw new Error('Not enough suppliers in database. Run supplier_seeder first!') + } + + // Pour chaque supplier, attacher plusieurs goods avec des quantités + for (const supplier of suppliers) { + // Sélectionner 2-3 goods aléatoires pour chaque supplier + const randomGoodsCount = Math.floor(Math.random() * 2) + 2 // 2 ou 3 goods + const selectedGoods = goods + .sort(() => 0.5 - Math.random()) // Mélanger + .slice(0, randomGoodsCount) + + const pivotData: Record = {} + + for (const good of selectedGoods) { + pivotData[good.id] = { + price: Math.floor(Math.random() * 1000) + 10 // prix entre 10 et 1000 + } + } + + await supplier.related('goods').sync(pivotData) + } + } +} \ No newline at end of file diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index 33c678f..12e86b1 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -5,6 +5,8 @@ import FurnitureSeeder from './furniture_seeder.js' import ProductSeeder from './product_seeder.js' import ProductGoodSeeder from './product_good_seeder.js' import ProductFurnitureSeeder from './product_furniture_seeder.js' +import SupplierSeeder from './supplier_seeder.js' +import GoodSupplierSeeder from './good_supplier_seeder.js' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { @@ -12,18 +14,20 @@ export default class extends BaseSeeder { } public async run() { - // 1. D'abord les catégories + // 1. Seeders seuls await this.runSeeder(CategorySeeder) - // 2. Ensuite goods et furnitures (qui dépendent des catégories) + // 2. Seeders dépendants await this.runSeeder(GoodSeeder) await this.runSeeder(FurnitureSeeder) + await this.runSeeder(SupplierSeeder) - // 3. Ensuite products + // 3. Seeders dépendants des seeders précédents await this.runSeeder(ProductSeeder) - // 4. Enfin les relations many-to-many + // 4. Seeders dépendants des seeders précédents await this.runSeeder(ProductGoodSeeder) await this.runSeeder(ProductFurnitureSeeder) + await this.runSeeder(GoodSupplierSeeder) } } \ No newline at end of file From 99615eed95bebc6754cf94b5d4cd6985d37de8f1 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 11:00:06 +0200 Subject: [PATCH 15/39] Fixed relation between good and supplier --- app/controllers/goods_controller.ts | 9 ++++----- database/seeders/good_supplier_seeder.ts | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/controllers/goods_controller.ts b/app/controllers/goods_controller.ts index 7a72262..7355cd4 100644 --- a/app/controllers/goods_controller.ts +++ b/app/controllers/goods_controller.ts @@ -6,8 +6,7 @@ export default class GoodsController { * Display a list of resource */ async index({ }: HttpContext) { - //return Good.query().preload('products').preload('category').preload('suppliers') - return Good.query().preload('products').preload('category') + return Good.query().preload('products').preload('category').preload('suppliers') } /** @@ -28,14 +27,14 @@ export default class GoodsController { * Show individual record */ async show({ params }: HttpContext) { - return await Good.query().preload('products').preload('category').where('id', params.id).firstOrFail() + return await Good.query().preload('products').preload('category').preload('suppliers').where('id', params.id).firstOrFail() } /** * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const good = await Good.query().preload('products').preload('category').where('id', params.id).firstOrFail() // We get our good by id + const good = await Good.query().preload('products').preload('category').preload('suppliers').where('id', params.id).firstOrFail() // We get our good by id const { name, unit, brand, categoryId } = request.all() good.name = name good.unit = unit @@ -49,7 +48,7 @@ export default class GoodsController { * Delete record */ async destroy({ params }: HttpContext) { - const good = await Good.query().preload('products').preload('category').where('id', params.id).firstOrFail() + const good = await Good.query().preload('products').preload('category').preload('suppliers').where('id', params.id).firstOrFail() await good.delete() } } \ No newline at end of file diff --git a/database/seeders/good_supplier_seeder.ts b/database/seeders/good_supplier_seeder.ts index 758267c..730e70c 100644 --- a/database/seeders/good_supplier_seeder.ts +++ b/database/seeders/good_supplier_seeder.ts @@ -18,7 +18,7 @@ export default class extends BaseSeeder { throw new Error('Not enough suppliers in database. Run supplier_seeder first!') } - // Pour chaque supplier, attacher plusieurs goods avec des quantités + // Pour chaque supplier, attacher plusieurs goods avec des prices for (const supplier of suppliers) { // Sélectionner 2-3 goods aléatoires pour chaque supplier const randomGoodsCount = Math.floor(Math.random() * 2) + 2 // 2 ou 3 goods From 8c57d3126d1e79bcbbd062ddf46feba02bc3a822 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 11:11:44 +0200 Subject: [PATCH 16/39] Added restock --- app/controllers/suppliers_controller.ts | 1 - database/seeders/supplier_seeder.ts | 14 +++++++++++++- start/routes.ts | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/controllers/suppliers_controller.ts b/app/controllers/suppliers_controller.ts index 1e04205..bc3dcde 100644 --- a/app/controllers/suppliers_controller.ts +++ b/app/controllers/suppliers_controller.ts @@ -1,6 +1,5 @@ import type { HttpContext } from '@adonisjs/core/http' import Supplier from '#models/supplier' -import { configProvider } from '@adonisjs/core' export default class SuppliersController { /** diff --git a/database/seeders/supplier_seeder.ts b/database/seeders/supplier_seeder.ts index 33c7ba6..0c9994a 100644 --- a/database/seeders/supplier_seeder.ts +++ b/database/seeders/supplier_seeder.ts @@ -1,9 +1,21 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' import { SupplierFactory } from '#database/factories/supplier_factory' +import { RestockFactory } from '#database/factories/restock_factory' +import { MembersFactory } from '#database/factories/members_factory' export default class extends BaseSeeder { async run() { // Write your database queries inside the run method - await SupplierFactory.createMany(10) + const suppliers = await SupplierFactory.createMany(5) + const members = await MembersFactory.createMany(5) + + await RestockFactory + .merge( + Array.from({ length: 10 }, (_, index) => ({ + supplierId: suppliers[index % suppliers.length].id, + memberId: members[index % members.length].id, + })) + ) + .createMany(10) } } \ No newline at end of file diff --git a/start/routes.ts b/start/routes.ts index b2afc69..7e9fc30 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -22,7 +22,8 @@ router router.resource('furnitures', () => import('#controllers/furnitures_controller')).apiOnly(), router.resource('products', () => import('#controllers/products_controller')).apiOnly(), router.resource('goods', () => import('#controllers/goods_controller')).apiOnly(), - router.resource('suppliers', () => import('#controllers/suppliers_controller')).apiOnly()) + router.resource('suppliers', () => import('#controllers/suppliers_controller')).apiOnly(), + router.resource('restocks', () => import('#controllers/restocks_controller')).apiOnly()) }) .prefix('/v1') From bc93ee038c16686e39ab052224081086afe9dec6 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 11:11:56 +0200 Subject: [PATCH 17/39] Added restock files --- app/controllers/restocks_controller.ts | 54 ++++++++++++++++++++++++++ database/factories/restock_factory.ts | 16 ++++++++ database/seeders/restock_seeder.ts | 7 ++++ 3 files changed, 77 insertions(+) create mode 100644 app/controllers/restocks_controller.ts create mode 100644 database/factories/restock_factory.ts create mode 100644 database/seeders/restock_seeder.ts diff --git a/app/controllers/restocks_controller.ts b/app/controllers/restocks_controller.ts new file mode 100644 index 0000000..e48281d --- /dev/null +++ b/app/controllers/restocks_controller.ts @@ -0,0 +1,54 @@ +import type { HttpContext } from '@adonisjs/core/http' +import Restock from '#models/restock' + +export default class RestocksController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + const restocks = await Restock.query().preload('member').preload('supplier').preload('stockBatches') + return restocks + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { memberId, supplierId, totalPrice } = request.all() + const restock = new Restock() + restock.memberId = memberId + restock.supplierId = supplierId + restock.totalPrice = totalPrice + await restock.save() + return restock + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + const restock = await Restock.query().preload('member').preload('supplier').preload('stockBatches').where('id', params.id).firstOrFail() + return restock + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const restock = await Restock.query().preload('member').preload('supplier').preload('stockBatches').where('id', params.id).firstOrFail() + const { memberId, supplierId, totalPrice } = request.all() + restock.memberId = memberId + restock.supplierId = supplierId + restock.totalPrice = totalPrice + await restock.save() + return restock + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const restock = await Restock.query().preload('member').preload('supplier').preload('stockBatches').where('id', params.id).firstOrFail() + await restock.delete() + } +} \ No newline at end of file diff --git a/database/factories/restock_factory.ts b/database/factories/restock_factory.ts new file mode 100644 index 0000000..dc6bdbf --- /dev/null +++ b/database/factories/restock_factory.ts @@ -0,0 +1,16 @@ +import factory from '@adonisjs/lucid/factories' +import Restock from '#models/restock' +import { SupplierFactory } from './supplier_factory.ts' +import { MembersFactory } from './members_factory.ts' + +export const RestockFactory = factory + .define(Restock, async ({ faker }) => { + return { + totalPrice: faker.commerce.price(), + memberId: null, // Will be set by relation + supplierId: null, // Will be set by relation + } + }) + .relation('member', () => MembersFactory) + .relation('supplier', () => SupplierFactory) + .build() \ No newline at end of file diff --git a/database/seeders/restock_seeder.ts b/database/seeders/restock_seeder.ts new file mode 100644 index 0000000..c1f7c79 --- /dev/null +++ b/database/seeders/restock_seeder.ts @@ -0,0 +1,7 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + } +} \ No newline at end of file From b71f34fd6e9bb8f7abc1723f4d7c952797755e7f Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 14:51:04 +0200 Subject: [PATCH 18/39] Fixed member - user relationship --- app/controllers/members_controller.ts | 54 +++++++++---------- app/models/member.ts | 2 + app/models/user.ts | 2 +- database/factories/members_factory.ts | 12 +++++ database/factories/user_factory.ts | 2 +- .../1761885935168_create_users_table.ts | 2 +- .../1773828511747_create_members_table.ts | 10 +++- database/seeders/main_seeder.ts | 6 ++- database/seeders/restock_seeder.ts | 14 +++++ database/seeders/supplier_seeder.ts | 14 +---- 10 files changed, 71 insertions(+), 47 deletions(-) diff --git a/app/controllers/members_controller.ts b/app/controllers/members_controller.ts index 81256b8..dced5b4 100644 --- a/app/controllers/members_controller.ts +++ b/app/controllers/members_controller.ts @@ -4,55 +4,55 @@ import Member from '#models/member' export default class MembersController { /** * Display a list of resource - async index({}: HttpContext) { - return Member.query().preload('user').preload('role') - // return Member.all() - } - - /** - * Display form to create a new record */ - async create({}: HttpContext) { - return Member.create({ - firstName: 'John', - lastName: 'Doe', - }) + async index({}: HttpContext) { + const members = await Member.query() + return members } /** * Handle form submission for the create action */ - // async store({ request }: HttpContext) {} + async store({ request }: HttpContext) { + const { firstName, lastName } = request.all() + const member = new Member() + member.firstName = firstName + member.lastName = lastName + await member.save() + return member + } /** * Show individual record */ async show({ params }: HttpContext) { - return Member.query().where('id', params.id).preload('user').preload('role').firstOrFail() - // return Member.findOrFail(params.id) + const member = await Member.find(params.id) + return member } - /** - * Edit individual record - */ - // async edit({ params }: HttpContext) { } - /** * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const member = await Member.findOrFail(params.id) // We get our member by id - const { firstName, lastName } = request.all() // We transfer the new data from the request to constants - member.firstName = firstName // Assigning the data - member.lastName = lastName // Assigning the data - await member.save() // We save the member to the database + const member = await Member.find(params.id) + if (!member) { + throw new Error('Member not found') + } + const { firstName, lastName } = request.all() + member.firstName = firstName + member.lastName = lastName + await member.save() + return member } /** * Delete record */ async destroy({ params }: HttpContext) { - const member = await Member.findOrFail(params.id) // Get the user by id + const member = await Member.find(params.id) + if (!member) { + throw new Error('Member not found') + } await member.delete() } -} +} \ No newline at end of file diff --git a/app/models/member.ts b/app/models/member.ts index d7147f8..99c86d2 100644 --- a/app/models/member.ts +++ b/app/models/member.ts @@ -10,6 +10,8 @@ import Restock from '#models/restock' import Role from '#models/role' export default class Member extends MemberSchema { + public static selfAssignPrimaryKey = true + @belongsTo(() => User, { foreignKey: 'id' }) declare user: BelongsTo diff --git a/app/models/user.ts b/app/models/user.ts index f47980f..0b6a72c 100644 --- a/app/models/user.ts +++ b/app/models/user.ts @@ -22,7 +22,7 @@ export default class User extends compose(UserSchema, withAuthFinder(hash)) { }) declare fastPasses: ManyToMany - @hasOne(() => Member) + @hasOne(() => Member, { foreignKey: 'id', localKey: 'id' }) declare member: HasOne @hasMany(() => PreOrder) diff --git a/database/factories/members_factory.ts b/database/factories/members_factory.ts index bbb0f4e..16a1ab1 100644 --- a/database/factories/members_factory.ts +++ b/database/factories/members_factory.ts @@ -9,5 +9,17 @@ export const MembersFactory = factory lastName: faker.person.lastName(), } }) + .before('create', async (builder, member, ctx) => { + const requestedBelongsTo = (builder as any).withBelongsToRelations as undefined | Array<{ name: string }> + const willCreateUserViaRelation = requestedBelongsTo?.some((relation) => relation.name === 'user') + + if (willCreateUserViaRelation) { + return + } + + const user = await UserFactory.useCtx(ctx).create() + member.id = user.id + member.$setRelated('user', user) + }) .relation('user', () => UserFactory) .build() diff --git a/database/factories/user_factory.ts b/database/factories/user_factory.ts index 69f90c0..862f56f 100644 --- a/database/factories/user_factory.ts +++ b/database/factories/user_factory.ts @@ -7,6 +7,6 @@ export const UserFactory = factory email: faker.internet.email(), password: faker.internet.password(), casId: faker.string.uuid(), - } as any + } }) .build() diff --git a/database/migrations/1761885935168_create_users_table.ts b/database/migrations/1761885935168_create_users_table.ts index 93770f5..2f8d0e0 100644 --- a/database/migrations/1761885935168_create_users_table.ts +++ b/database/migrations/1761885935168_create_users_table.ts @@ -5,7 +5,7 @@ export default class extends BaseSchema { async up() { this.schema.createTable(this.tableName, (table) => { - table.increments('id').notNullable() + table.increments('id') table.string('cas_id').unique().notNullable() table.string('email', 254).notNullable().unique() table.string('password').notNullable() diff --git a/database/migrations/1773828511747_create_members_table.ts b/database/migrations/1773828511747_create_members_table.ts index 10da26b..e87ac14 100644 --- a/database/migrations/1773828511747_create_members_table.ts +++ b/database/migrations/1773828511747_create_members_table.ts @@ -5,7 +5,13 @@ export default class extends BaseSchema { async up() { this.schema.createTable(this.tableName, (table) => { - table.integer('id').references('id').inTable('users').onDelete('CASCADE').primary() + table + .integer('id') + .primary() + .notNullable() + .references('id') + .inTable('users') + .onDelete('CASCADE') table.string('first_name').notNullable() table.string('last_name').notNullable() @@ -20,4 +26,4 @@ export default class extends BaseSchema { async down() { this.schema.dropTable(this.tableName) } -} +} \ No newline at end of file diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index 12e86b1..6aad418 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -1,5 +1,4 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' -import CategorySeeder from './category_seeder.js' import GoodSeeder from './good_seeder.js' import FurnitureSeeder from './furniture_seeder.js' import ProductSeeder from './product_seeder.js' @@ -7,6 +6,8 @@ import ProductGoodSeeder from './product_good_seeder.js' import ProductFurnitureSeeder from './product_furniture_seeder.js' import SupplierSeeder from './supplier_seeder.js' import GoodSupplierSeeder from './good_supplier_seeder.js' +import MemberSeeder from './member_seeder.ts' +import RestockSeeder from './restock_seeder.ts' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { @@ -15,15 +16,16 @@ export default class extends BaseSeeder { public async run() { // 1. Seeders seuls - await this.runSeeder(CategorySeeder) // 2. Seeders dépendants + await this.runSeeder(MemberSeeder) await this.runSeeder(GoodSeeder) await this.runSeeder(FurnitureSeeder) await this.runSeeder(SupplierSeeder) // 3. Seeders dépendants des seeders précédents await this.runSeeder(ProductSeeder) + await this.runSeeder(RestockSeeder) // 4. Seeders dépendants des seeders précédents await this.runSeeder(ProductGoodSeeder) diff --git a/database/seeders/restock_seeder.ts b/database/seeders/restock_seeder.ts index c1f7c79..1e29050 100644 --- a/database/seeders/restock_seeder.ts +++ b/database/seeders/restock_seeder.ts @@ -1,7 +1,21 @@ +import { SupplierFactory } from '#database/factories/supplier_factory' import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { RestockFactory } from '#database/factories/restock_factory' +import { MembersFactory } from '#database/factories/members_factory' export default class extends BaseSeeder { async run() { // Write your database queries inside the run method + const suppliers = await SupplierFactory.createMany(5) + const members = await MembersFactory.createMany(5) + + await RestockFactory + .merge( + Array.from({ length: 10 }, (_, index) => ({ + supplierId: suppliers[index % suppliers.length].id, + memberId: members[index % members.length].id, + })) + ) + .createMany(10) } } \ No newline at end of file diff --git a/database/seeders/supplier_seeder.ts b/database/seeders/supplier_seeder.ts index 0c9994a..33c7ba6 100644 --- a/database/seeders/supplier_seeder.ts +++ b/database/seeders/supplier_seeder.ts @@ -1,21 +1,9 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' import { SupplierFactory } from '#database/factories/supplier_factory' -import { RestockFactory } from '#database/factories/restock_factory' -import { MembersFactory } from '#database/factories/members_factory' export default class extends BaseSeeder { async run() { // Write your database queries inside the run method - const suppliers = await SupplierFactory.createMany(5) - const members = await MembersFactory.createMany(5) - - await RestockFactory - .merge( - Array.from({ length: 10 }, (_, index) => ({ - supplierId: suppliers[index % suppliers.length].id, - memberId: members[index % members.length].id, - })) - ) - .createMany(10) + await SupplierFactory.createMany(10) } } \ No newline at end of file From a6ad878145b29d1f026eb7782771f5b4ac4271b6 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 16:00:40 +0200 Subject: [PATCH 19/39] Added stock-movement and stock-batch --- app/controllers/stock_batches_controller.ts | 59 +++++++++++++++++ app/controllers/stock_movements_controller.ts | 63 +++++++++++++++++++ database/factories/stock_batch_factory.ts | 19 ++++++ database/factories/stock_movement_factory.ts | 17 +++++ database/seeders/main_seeder.ts | 6 ++ database/seeders/stock_batch_seeder.ts | 28 +++++++++ database/seeders/stock_movement_seeder.ts | 44 +++++++++++++ start/routes.ts | 4 +- 8 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 app/controllers/stock_batches_controller.ts create mode 100644 app/controllers/stock_movements_controller.ts create mode 100644 database/factories/stock_batch_factory.ts create mode 100644 database/factories/stock_movement_factory.ts create mode 100644 database/seeders/stock_batch_seeder.ts create mode 100644 database/seeders/stock_movement_seeder.ts diff --git a/app/controllers/stock_batches_controller.ts b/app/controllers/stock_batches_controller.ts new file mode 100644 index 0000000..ddb62b5 --- /dev/null +++ b/app/controllers/stock_batches_controller.ts @@ -0,0 +1,59 @@ +import type { HttpContext } from '@adonisjs/core/http' +import StockBatch from '#models/stock_batch' + +export default class StockBatchesController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + const stockBatches = await StockBatch.query().preload('good').preload('restock') + return stockBatches + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { expirationDate, label, quantity, restockId, goodId } = request.all() + const stockBatch = await StockBatch.create({ + expirationDate, + label, + quantity, + restockId, + goodId, + }) + return stockBatch + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + const stockBatch = await StockBatch.query().where('id', params.id).preload('good').preload('restock').firstOrFail() + return stockBatch + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const stockBatch = await StockBatch.query().where('id', params.id).preload('good').preload('restock').firstOrFail() + const { expirationDate, label, quantity, restockId, goodId } = request.all() + await stockBatch.merge({ + expirationDate, + label, + quantity, + restockId, + goodId, + }).save() + return stockBatch + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const stockBatch = await StockBatch.query().where('id', params.id).preload('good').preload('restock').firstOrFail() + await stockBatch.delete() + } +} \ No newline at end of file diff --git a/app/controllers/stock_movements_controller.ts b/app/controllers/stock_movements_controller.ts new file mode 100644 index 0000000..07a2d38 --- /dev/null +++ b/app/controllers/stock_movements_controller.ts @@ -0,0 +1,63 @@ +import type { HttpContext } from '@adonisjs/core/http' +import StockMovement from '#models/stock_movement' + +export default class StockMovementsController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + const stockMovements = await StockMovement.query().preload('good').preload('stockBatch') + return stockMovements + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { quantity, movementType, goodId, stockBatchId } = request.all() + const stockMovement = await StockMovement.create({ + quantity, + movementType, + goodId, + stockBatchId, + }) + return stockMovement + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + const stockMovement = await StockMovement.query() + .where('id', params.id) + .preload('good') + .preload('stockBatch') + .firstOrFail() + + return stockMovement + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const stockMovement = await StockMovement.query().where('id', params.id).preload('good').preload('stockBatch').firstOrFail() + const { quantity, movementType, goodId, stockBatchId } = request.all() + + stockMovement.quantity = quantity + stockMovement.movementType = movementType + stockMovement.goodId = goodId + stockMovement.stockBatchId = stockBatchId + + await stockMovement.save() + return stockMovement + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const stockMovement = await StockMovement.query().where('id', params.id).preload('good').preload('stockBatch').firstOrFail() + await stockMovement.delete() + } +} \ No newline at end of file diff --git a/database/factories/stock_batch_factory.ts b/database/factories/stock_batch_factory.ts new file mode 100644 index 0000000..ff38f71 --- /dev/null +++ b/database/factories/stock_batch_factory.ts @@ -0,0 +1,19 @@ +import factory from '@adonisjs/lucid/factories' +import StockBatch from '#models/stock_batch' +import { RestockFactory } from './restock_factory.ts' +import { GoodFactory } from './good_factory.ts' +import { DateTime } from 'luxon' + +export const StockBatchFactory = factory + .define(StockBatch, async ({ faker }) => { + return { + expirationDate: DateTime.fromJSDate(faker.date.future()), + label: faker.commerce.productName(), + quantity: faker.number.int({ min: 1, max: 100 }).toString(), + restockId: null, // Will be set by relation + goodId: null, // Will be set by relation + } + }) + .relation('restock', () => RestockFactory) + .relation('good', () => GoodFactory) + .build() \ No newline at end of file diff --git a/database/factories/stock_movement_factory.ts b/database/factories/stock_movement_factory.ts new file mode 100644 index 0000000..ecbc370 --- /dev/null +++ b/database/factories/stock_movement_factory.ts @@ -0,0 +1,17 @@ +import factory from '@adonisjs/lucid/factories' +import StockMovement from '#models/stock_movement' +import { GoodFactory } from './good_factory.ts' +import { StockBatchFactory } from './stock_batch_factory.ts' + +export const StockMovementFactory = factory + .define(StockMovement, async ({ faker }) => { + return { + quantity: faker.number.int({ min: 1, max: 100 }).toString(), + movementType: faker.helpers.arrayElement(['in', 'out']), + goodId: undefined, + stockBatchId: undefined, + } + }) + .relation('good', () => GoodFactory) + .relation('stockBatch', () => StockBatchFactory) + .build() \ No newline at end of file diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index 6aad418..7e93ff4 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -8,6 +8,8 @@ import SupplierSeeder from './supplier_seeder.js' import GoodSupplierSeeder from './good_supplier_seeder.js' import MemberSeeder from './member_seeder.ts' import RestockSeeder from './restock_seeder.ts' +import StockBatchSeeder from './stock_batch_seeder.ts' +import StockMovementSeeder from './stock_movement_seeder.ts' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { @@ -31,5 +33,9 @@ export default class extends BaseSeeder { await this.runSeeder(ProductGoodSeeder) await this.runSeeder(ProductFurnitureSeeder) await this.runSeeder(GoodSupplierSeeder) + await this.runSeeder(StockBatchSeeder) + + // 5. Seeders dépendants des seeders précédents + await this.runSeeder(StockMovementSeeder) } } \ No newline at end of file diff --git a/database/seeders/stock_batch_seeder.ts b/database/seeders/stock_batch_seeder.ts new file mode 100644 index 0000000..535f65d --- /dev/null +++ b/database/seeders/stock_batch_seeder.ts @@ -0,0 +1,28 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { StockBatchFactory } from '#database/factories/stock_batch_factory' +import Good from '#models/good' +import Restock from '#models/restock' + +export default class extends BaseSeeder { + async run() { + const goods = await Good.query().select('id') + const restocks = await Restock.query().select('id') + + if (goods.length === 0) { + throw new Error('StockBatchSeeder: no goods found. Run GoodSeeder first.') + } + + if (restocks.length === 0) { + throw new Error('StockBatchSeeder: no restocks found. Run RestockSeeder first.') + } + + await StockBatchFactory + .merge( + Array.from({ length: 10 }, (_, index) => ({ + goodId: goods[index % goods.length].id, + restockId: restocks[index % restocks.length].id, + })) + ) + .createMany(10) + } +} \ No newline at end of file diff --git a/database/seeders/stock_movement_seeder.ts b/database/seeders/stock_movement_seeder.ts new file mode 100644 index 0000000..a66136a --- /dev/null +++ b/database/seeders/stock_movement_seeder.ts @@ -0,0 +1,44 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import Good from '#models/good' +import StockBatch from '#models/stock_batch' +import { StockMovementFactory } from '#database/factories/stock_movement_factory' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + const goods = await Good.query().select('id') + const stockBatches = await StockBatch.query().select('id') + + if (goods.length === 0) { + throw new Error('StockMovementSeeder: no goods found. Run GoodSeeder first.') + } + + if (stockBatches.length === 0) { + throw new Error('StockMovementSeeder: no stock batches found. Run StockBatchSeeder first.') + } + + console.log(`Seeding stock movements with ${goods.length} goods and ${stockBatches.length} stock batches...`) + + const pickId = (rows: Array<{ id: number }>) => rows[Math.floor(Math.random() * rows.length)].id + + await StockMovementFactory + .merge( + Array.from({ length: 20 }, () => { + const goodId = pickId(goods) + + let stockBatchId = pickId(stockBatches) + if (stockBatches.length > 1) { + while (stockBatchId === goodId) { + stockBatchId = pickId(stockBatches) + } + } + + return { + goodId, + stockBatchId, + } + }) + ) + .createMany(20) + } +} \ No newline at end of file diff --git a/start/routes.ts b/start/routes.ts index 7e9fc30..df2cd3c 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -23,7 +23,9 @@ router router.resource('products', () => import('#controllers/products_controller')).apiOnly(), router.resource('goods', () => import('#controllers/goods_controller')).apiOnly(), router.resource('suppliers', () => import('#controllers/suppliers_controller')).apiOnly(), - router.resource('restocks', () => import('#controllers/restocks_controller')).apiOnly()) + router.resource('restocks', () => import('#controllers/restocks_controller')).apiOnly(), + router.resource('stock-batches', () => import('#controllers/stock_batches_controller')).apiOnly(), + router.resource('stock-movements', () => import('#controllers/stock_movements_controller')).apiOnly()) }) .prefix('/v1') From 9e76ba54b946bbee184087689973660d45b45e2d Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Wed, 15 Apr 2026 16:31:29 +0200 Subject: [PATCH 20/39] Added logs --- app/controllers/logs_controller.ts | 62 ++++++++++++++++++++++++++++++ database/factories/log_factory.ts | 21 ++++++++++ database/seeders/log_seeder.ts | 24 ++++++++++++ database/seeders/main_seeder.ts | 2 + start/routes.ts | 3 +- 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 app/controllers/logs_controller.ts create mode 100644 database/factories/log_factory.ts create mode 100644 database/seeders/log_seeder.ts diff --git a/app/controllers/logs_controller.ts b/app/controllers/logs_controller.ts new file mode 100644 index 0000000..a8b856e --- /dev/null +++ b/app/controllers/logs_controller.ts @@ -0,0 +1,62 @@ +import type { HttpContext } from '@adonisjs/core/http' +import Log from '#models/log' + +export default class LogsController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + const logs = await Log.query().preload('user') + return logs + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { level, message, method, url, ip, meta, userId } = request.all() + const log = await Log.create({ + level, + message, + method, + url, + ip, + meta, + userId, + }) + return log + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + const log = await Log.query().where('id', params.id).preload('user').firstOrFail() + return log + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const log = await Log.query().where('id', params.id).firstOrFail() + const { level, message, method, url, ip, meta, userId } = request.all() + log.level = level + log.message = message + log.method = method + log.url = url + log.ip = ip + log.meta = meta + log.userId = userId + await log.save() + return log + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const log = await Log.query().where('id', params.id).preload('user').firstOrFail() + await log.delete() + } +} \ No newline at end of file diff --git a/database/factories/log_factory.ts b/database/factories/log_factory.ts new file mode 100644 index 0000000..05bc033 --- /dev/null +++ b/database/factories/log_factory.ts @@ -0,0 +1,21 @@ +import factory from '@adonisjs/lucid/factories' +import Log from '#models/log' +import { UserFactory } from './user_factory.ts' + +export const LogFactory = factory + .define(Log, async ({ faker }) => { + return { + level: faker.helpers.arrayElement(['info', 'warning', 'error']), + message: faker.lorem.sentence(), + method: faker.helpers.arrayElement(['GET', 'POST', 'PUT', 'DELETE']), + url: faker.internet.url(), + ip: faker.internet.ip(), + meta: { + userAgent: faker.internet.userAgent(), + referrer: faker.internet.url(), + }, + userId: null, // Will be set by relation if needed + } + }) + .relation('user', () => UserFactory) + .build() \ No newline at end of file diff --git a/database/seeders/log_seeder.ts b/database/seeders/log_seeder.ts new file mode 100644 index 0000000..e49baa2 --- /dev/null +++ b/database/seeders/log_seeder.ts @@ -0,0 +1,24 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import User from '#models/user' +import { LogFactory } from '#database/factories/log_factory' + +export default class extends BaseSeeder { + async run() { + const users = await User.query().select('id') + + if (users.length === 0) { + throw new Error('LogSeeder: no users found. Run UserSeeder first.') + } + + const pickUserId = () => users[Math.floor(Math.random() * users.length)].id + + await LogFactory + .merge( + Array.from({ length: 50 }, () => ({ + userId: pickUserId(), + })) + ) + .createMany(50) + + } +} \ No newline at end of file diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index 7e93ff4..3d02a92 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -10,6 +10,7 @@ import MemberSeeder from './member_seeder.ts' import RestockSeeder from './restock_seeder.ts' import StockBatchSeeder from './stock_batch_seeder.ts' import StockMovementSeeder from './stock_movement_seeder.ts' +import LogSeeder from './log_seeder.ts' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { @@ -28,6 +29,7 @@ export default class extends BaseSeeder { // 3. Seeders dépendants des seeders précédents await this.runSeeder(ProductSeeder) await this.runSeeder(RestockSeeder) + await this.runSeeder(LogSeeder) // 4. Seeders dépendants des seeders précédents await this.runSeeder(ProductGoodSeeder) diff --git a/start/routes.ts b/start/routes.ts index df2cd3c..e5490e3 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -25,7 +25,8 @@ router router.resource('suppliers', () => import('#controllers/suppliers_controller')).apiOnly(), router.resource('restocks', () => import('#controllers/restocks_controller')).apiOnly(), router.resource('stock-batches', () => import('#controllers/stock_batches_controller')).apiOnly(), - router.resource('stock-movements', () => import('#controllers/stock_movements_controller')).apiOnly()) + router.resource('stock-movements', () => import('#controllers/stock_movements_controller')).apiOnly(), + router.resource('logs', () => import('#controllers/logs_controller')).apiOnly()) }) .prefix('/v1') From bd1c958c9630e825503a5c13f4e3eea934d2bfcc Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Thu, 16 Apr 2026 08:47:02 +0200 Subject: [PATCH 21/39] Added roles --- app/controllers/members_controller.ts | 11 ++++-- app/controllers/roles_controller.ts | 54 +++++++++++++++++++++++++++ database/factories/members_factory.ts | 3 ++ database/factories/role_factory.ts | 10 +++++ database/seeders/main_seeder.ts | 2 + database/seeders/member_seeder.ts | 18 ++++++++- database/seeders/role_seeder.ts | 9 +++++ start/routes.ts | 3 +- 8 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 app/controllers/roles_controller.ts create mode 100644 database/factories/role_factory.ts create mode 100644 database/seeders/role_seeder.ts diff --git a/app/controllers/members_controller.ts b/app/controllers/members_controller.ts index dced5b4..ef24533 100644 --- a/app/controllers/members_controller.ts +++ b/app/controllers/members_controller.ts @@ -6,7 +6,7 @@ export default class MembersController { * Display a list of resource */ async index({}: HttpContext) { - const members = await Member.query() + const members = await Member.query().preload('role') return members } @@ -26,7 +26,10 @@ export default class MembersController { * Show individual record */ async show({ params }: HttpContext) { - const member = await Member.find(params.id) + const member = await Member.query().preload('role').where('id', params.id).first() + if (!member) { + throw new Error('Member not found') + } return member } @@ -34,7 +37,7 @@ export default class MembersController { * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const member = await Member.find(params.id) + const member = await Member.query().preload('role').where('id', params.id).first() if (!member) { throw new Error('Member not found') } @@ -49,7 +52,7 @@ export default class MembersController { * Delete record */ async destroy({ params }: HttpContext) { - const member = await Member.find(params.id) + const member = await Member.query().preload('role').where('id', params.id).first() if (!member) { throw new Error('Member not found') } diff --git a/app/controllers/roles_controller.ts b/app/controllers/roles_controller.ts new file mode 100644 index 0000000..9b6a41d --- /dev/null +++ b/app/controllers/roles_controller.ts @@ -0,0 +1,54 @@ +import type { HttpContext } from '@adonisjs/core/http' +import Role from '#models/role' + +export default class RolesController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + const roles = await Role.query() + return roles + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { name } = request.all() + const role = await Role.create({ name }) + return role + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + const role = await Role.find(params.id) + return role + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const { name } = request.body() + const role = await Role.find(params.id) + if (!role) { + throw new Error('Role not found') + } + role.name = name + await role.save() + return role + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const role = await Role.find(params.id) + if (!role) { + throw new Error('Role not found') + } + await role.delete() + } +} \ No newline at end of file diff --git a/database/factories/members_factory.ts b/database/factories/members_factory.ts index 16a1ab1..e61b2e9 100644 --- a/database/factories/members_factory.ts +++ b/database/factories/members_factory.ts @@ -1,12 +1,14 @@ import factory from '@adonisjs/lucid/factories' import Members from '#models/member' import { UserFactory } from '#database/factories/user_factory' +import { RoleFactory } from '#database/factories/role_factory' export const MembersFactory = factory .define(Members, async ({ faker }) => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), + roleId: null } }) .before('create', async (builder, member, ctx) => { @@ -22,4 +24,5 @@ export const MembersFactory = factory member.$setRelated('user', user) }) .relation('user', () => UserFactory) + .relation('role', () => RoleFactory) .build() diff --git a/database/factories/role_factory.ts b/database/factories/role_factory.ts new file mode 100644 index 0000000..24d08ec --- /dev/null +++ b/database/factories/role_factory.ts @@ -0,0 +1,10 @@ +import factory from '@adonisjs/lucid/factories' +import Role from '#models/role' + +export const RoleFactory = factory + .define(Role, async ({ faker }) => { + return { + name: faker.helpers.arrayElement(['President', 'Service', 'Assembly', 'Logistics', 'Finance', 'HR']), + } + }) + .build() \ No newline at end of file diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index 3d02a92..acc4ae2 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -11,6 +11,7 @@ import RestockSeeder from './restock_seeder.ts' import StockBatchSeeder from './stock_batch_seeder.ts' import StockMovementSeeder from './stock_movement_seeder.ts' import LogSeeder from './log_seeder.ts' +import RoleSeeder from './role_seeder.ts' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { @@ -19,6 +20,7 @@ export default class extends BaseSeeder { public async run() { // 1. Seeders seuls + await this.runSeeder(RoleSeeder) // 2. Seeders dépendants await this.runSeeder(MemberSeeder) diff --git a/database/seeders/member_seeder.ts b/database/seeders/member_seeder.ts index bc77f7e..6549ff8 100644 --- a/database/seeders/member_seeder.ts +++ b/database/seeders/member_seeder.ts @@ -1,8 +1,24 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' import { MembersFactory } from '#database/factories/members_factory' +import Role from '#models/role' export default class MemberSeeder extends BaseSeeder { async run() { - await MembersFactory.with('user').createMany(10) + const roles = await Role.query().select('id') + + if (roles.length === 0) { + throw new Error('MemberSeeder: no roles found. Run RoleSeeder first.') + } + + const pickRoleId = () => roles[Math.floor(Math.random() * roles.length)].id + + await MembersFactory + .with('user') + .merge( + Array.from({ length: 10 }, () => ({ + roleId: pickRoleId(), + })) + ) + .createMany(10) } } diff --git a/database/seeders/role_seeder.ts b/database/seeders/role_seeder.ts new file mode 100644 index 0000000..4c2cb7c --- /dev/null +++ b/database/seeders/role_seeder.ts @@ -0,0 +1,9 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { RoleFactory } from '#database/factories/role_factory' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + await RoleFactory.createMany(5) + } +} \ No newline at end of file diff --git a/start/routes.ts b/start/routes.ts index e5490e3..f8ff785 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -26,7 +26,8 @@ router router.resource('restocks', () => import('#controllers/restocks_controller')).apiOnly(), router.resource('stock-batches', () => import('#controllers/stock_batches_controller')).apiOnly(), router.resource('stock-movements', () => import('#controllers/stock_movements_controller')).apiOnly(), - router.resource('logs', () => import('#controllers/logs_controller')).apiOnly()) + router.resource('logs', () => import('#controllers/logs_controller')).apiOnly(), + router.resource('roles', () => import('#controllers/roles_controller')).apiOnly()) }) .prefix('/v1') From f6b4dae10b11a2ae9f43eca8931a38d92e1dca2e Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Thu, 16 Apr 2026 11:59:50 +0200 Subject: [PATCH 22/39] Added permission files and unique choices from seeder --- app/controllers/permissions_controller.ts | 49 +++++++++++++++++++++++ database/factories/permission_factory.ts | 40 ++++++++++++++++++ database/seeders/main_seeder.ts | 2 + database/seeders/permission_seeder.ts | 9 +++++ start/routes.ts | 3 +- 5 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 app/controllers/permissions_controller.ts create mode 100644 database/factories/permission_factory.ts create mode 100644 database/seeders/permission_seeder.ts diff --git a/app/controllers/permissions_controller.ts b/app/controllers/permissions_controller.ts new file mode 100644 index 0000000..6b908b0 --- /dev/null +++ b/app/controllers/permissions_controller.ts @@ -0,0 +1,49 @@ +import type { HttpContext } from '@adonisjs/core/http' +import Permission from '#models/permission' + +export default class PermissionsController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + const permissions = await Permission.all() + return permissions + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { permission } = request.all() + const newPermission = await Permission.create({ permission }) + return newPermission + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + const permission = await Permission.findOrFail(params.id) + return permission + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const permission = await Permission.findOrFail(params.id) + const { permission: newPermission } = request.all() + permission.permission = newPermission + await permission.save() + return permission + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const permission = await Permission.findOrFail(params.id) + await permission.delete() + return { message: 'Permission deleted successfully' } + } +} \ No newline at end of file diff --git a/database/factories/permission_factory.ts b/database/factories/permission_factory.ts new file mode 100644 index 0000000..c79d5c9 --- /dev/null +++ b/database/factories/permission_factory.ts @@ -0,0 +1,40 @@ +import factory from '@adonisjs/lucid/factories' +import Permission from '#models/permission' + +const permissions = [ + 'presence:write', + 'presence:read', + 'stock:read', + 'stock:update', + 'stock:create', + 'stock:delete', + 'product:read', + 'product:update', + 'product:create', + 'product:delete', + 'supplier:read', + 'supplier:update', + 'supplier:create', + 'supplier:delete', + 'restock:read', + 'restock:update', + 'restock:create', + 'restock:delete', +] + +// copie modifiable +let availablePermissions = [...permissions] + +export const PermissionFactory = factory + .define(Permission, async () => { + if (availablePermissions.length === 0) { + throw new Error('Plus de permissions disponibles (unicité garantie)') + } + + const value = availablePermissions.shift()! + + return { + permission: value, + } + }) + .build() \ No newline at end of file diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index acc4ae2..c8e4b87 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -12,6 +12,7 @@ import StockBatchSeeder from './stock_batch_seeder.ts' import StockMovementSeeder from './stock_movement_seeder.ts' import LogSeeder from './log_seeder.ts' import RoleSeeder from './role_seeder.ts' +import PermissionSeeder from './permission_seeder.ts' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { @@ -21,6 +22,7 @@ export default class extends BaseSeeder { public async run() { // 1. Seeders seuls await this.runSeeder(RoleSeeder) + await this.runSeeder(PermissionSeeder) // 2. Seeders dépendants await this.runSeeder(MemberSeeder) diff --git a/database/seeders/permission_seeder.ts b/database/seeders/permission_seeder.ts new file mode 100644 index 0000000..d19be86 --- /dev/null +++ b/database/seeders/permission_seeder.ts @@ -0,0 +1,9 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { PermissionFactory } from '#database/factories/permission_factory' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + await PermissionFactory.createMany(5) + } +} \ No newline at end of file diff --git a/start/routes.ts b/start/routes.ts index f8ff785..42538d4 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -27,7 +27,8 @@ router router.resource('stock-batches', () => import('#controllers/stock_batches_controller')).apiOnly(), router.resource('stock-movements', () => import('#controllers/stock_movements_controller')).apiOnly(), router.resource('logs', () => import('#controllers/logs_controller')).apiOnly(), - router.resource('roles', () => import('#controllers/roles_controller')).apiOnly()) + router.resource('roles', () => import('#controllers/roles_controller')).apiOnly(), + router.resource('permissions', () => import('#controllers/permissions_controller')).apiOnly()) }) .prefix('/v1') From 700ea438c86dc7e5c648e104c731f73bfde98106 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Thu, 16 Apr 2026 13:22:57 +0200 Subject: [PATCH 23/39] Added role_permission seeder (not functional) --- app/models/permission.ts | 11 ++++++++ app/models/role.ts | 8 ++++++ database/seeders/main_seeder.ts | 2 ++ database/seeders/permission_seeder.ts | 29 +++++++++++++++++++--- database/seeders/role_permission_seeder.ts | 11 ++++++++ 5 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 database/seeders/role_permission_seeder.ts diff --git a/app/models/permission.ts b/app/models/permission.ts index 5a8a820..a12f3bd 100644 --- a/app/models/permission.ts +++ b/app/models/permission.ts @@ -4,8 +4,19 @@ import Role from '#models/role' import type { ManyToMany } from '@adonisjs/lucid/types/relations' export default class Permission extends PermissionSchema { + public static primaryKey = 'permission' + public static selfAssignPrimaryKey = true + @manyToMany(() => Role, { pivotTable: 'roles_permissions', + pivotForeignKey: 'permission_id', + pivotRelatedForeignKey: 'role_id', + localKey: 'permission', + relatedKey: 'id', + pivotTimestamps: { + createdAt: 'created_at', + updatedAt: false, + }, }) declare roles: ManyToMany } diff --git a/app/models/role.ts b/app/models/role.ts index 72549b4..5541888 100644 --- a/app/models/role.ts +++ b/app/models/role.ts @@ -7,6 +7,14 @@ import Member from '#models/member' export default class Role extends RoleSchema { @manyToMany(() => Permission, { pivotTable: 'roles_permissions', + pivotForeignKey: 'role_id', + pivotRelatedForeignKey: 'permission_id', + localKey: 'id', + relatedKey: 'permission', + pivotTimestamps: { + createdAt: 'created_at', + updatedAt: false, + }, }) declare permissions: ManyToMany diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index c8e4b87..8cb7349 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -13,6 +13,7 @@ import StockMovementSeeder from './stock_movement_seeder.ts' import LogSeeder from './log_seeder.ts' import RoleSeeder from './role_seeder.ts' import PermissionSeeder from './permission_seeder.ts' +//import RolePermissionSeeder from './role_permission_seeder.ts' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { @@ -29,6 +30,7 @@ export default class extends BaseSeeder { await this.runSeeder(GoodSeeder) await this.runSeeder(FurnitureSeeder) await this.runSeeder(SupplierSeeder) + // await this.runSeeder(RolePermissionSeeder) // 3. Seeders dépendants des seeders précédents await this.runSeeder(ProductSeeder) diff --git a/database/seeders/permission_seeder.ts b/database/seeders/permission_seeder.ts index d19be86..0e11587 100644 --- a/database/seeders/permission_seeder.ts +++ b/database/seeders/permission_seeder.ts @@ -1,9 +1,32 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' -import { PermissionFactory } from '#database/factories/permission_factory' +import Permission from '#models/permission' + +const permissions = [ + 'presence:write', + 'presence:read', + 'stock:read', + 'stock:update', + 'stock:create', + 'stock:delete', + 'product:read', + 'product:update', + 'product:create', + 'product:delete', + 'supplier:read', + 'supplier:update', + 'supplier:create', + 'supplier:delete', + 'restock:read', + 'restock:update', + 'restock:create', + 'restock:delete', +] export default class extends BaseSeeder { async run() { - // Write your database queries inside the run method - await PermissionFactory.createMany(5) + await Permission.fetchOrCreateMany( + 'permission', + permissions.map((permission) => ({ permission })) + ) } } \ No newline at end of file diff --git a/database/seeders/role_permission_seeder.ts b/database/seeders/role_permission_seeder.ts new file mode 100644 index 0000000..abd6748 --- /dev/null +++ b/database/seeders/role_permission_seeder.ts @@ -0,0 +1,11 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import Permission from '#models/permission' +import Role from '#models/role' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + const roles = await Role.all() + const permissions = await Permission.all() + } +} \ No newline at end of file From 91af8917e38e68722b535e889a3e96a7d3d6d0d8 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Thu, 16 Apr 2026 13:57:36 +0200 Subject: [PATCH 24/39] Fixed warnings --- database/seeders/role_permission_seeder.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/database/seeders/role_permission_seeder.ts b/database/seeders/role_permission_seeder.ts index abd6748..3f46847 100644 --- a/database/seeders/role_permission_seeder.ts +++ b/database/seeders/role_permission_seeder.ts @@ -1,11 +1,11 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' -import Permission from '#models/permission' -import Role from '#models/role' +// import Permission from '#models/permission' +// import Role from '#models/role' export default class extends BaseSeeder { async run() { // Write your database queries inside the run method - const roles = await Role.all() - const permissions = await Permission.all() + // const roles = await Role.all() + // const permissions = await Permission.all() } } \ No newline at end of file From 9c30519944be69a8e4f833bb51600240a914b89a Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Thu, 16 Apr 2026 14:16:03 +0200 Subject: [PATCH 25/39] Added fast-passes --- app/controllers/fast_passes_controller.ts | 54 +++++++++++++++++++++++ app/models/fast_pass.ts | 8 ++-- database/factories/fast_pass_factory.ts | 13 ++++++ database/seeders/fast_pass_seeder.ts | 9 ++++ database/seeders/main_seeder.ts | 2 + start/routes.ts | 3 +- 6 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 app/controllers/fast_passes_controller.ts create mode 100644 database/factories/fast_pass_factory.ts create mode 100644 database/seeders/fast_pass_seeder.ts diff --git a/app/controllers/fast_passes_controller.ts b/app/controllers/fast_passes_controller.ts new file mode 100644 index 0000000..098d868 --- /dev/null +++ b/app/controllers/fast_passes_controller.ts @@ -0,0 +1,54 @@ +import type { HttpContext } from '@adonisjs/core/http' +import FastPass from '#models/fast_pass' + +export default class FastPassesController { + /** + * Display a list of resource + */ + async index({}: HttpContext) { + return FastPass.query() + } + + /** + * Handle form submission for the create action + */ + async store({ request }: HttpContext) { + const { price, duration, description, label } = request.all() + const fastPass = new FastPass() + fastPass.price = price + fastPass.duration = duration + fastPass.description = description + fastPass.label = label + await fastPass.save() + return fastPass + } + + /** + * Show individual record + */ + async show({ params }: HttpContext) { + return FastPass.query().where('id', params.id).firstOrFail() + } + + /** + * Handle form submission for the edit action + */ + async update({ params, request }: HttpContext) { + const fastPass = await FastPass.query().where('id', params.id).firstOrFail() // We get our fast pass by id + const { price, duration, description, label } = request.all() // We transfer the new data from the request to constants + fastPass.price = price // Assigning the data + fastPass.duration = duration + fastPass.description = description + fastPass.label = label + await fastPass.save() // We save the fast pass to the database + return fastPass + } + + /** + * Delete record + */ + async destroy({ params }: HttpContext) { + const fastPass = await FastPass.query().where('id', params.id).firstOrFail() + await fastPass.delete() + } +} \ No newline at end of file diff --git a/app/models/fast_pass.ts b/app/models/fast_pass.ts index 96dc7ae..e30557d 100644 --- a/app/models/fast_pass.ts +++ b/app/models/fast_pass.ts @@ -1,9 +1,9 @@ import { FastPassSchema } from '#database/schema' -import { belongsTo } from '@adonisjs/lucid/orm' +import { manyToMany } from '@adonisjs/lucid/orm' import User from '#models/user' -import type { BelongsTo } from '@adonisjs/lucid/types/relations' +import type { ManyToMany } from '@adonisjs/lucid/types/relations' export default class FastPass extends FastPassSchema { - @belongsTo(() => User) - declare user: BelongsTo + @manyToMany(() => User) + declare user: ManyToMany } diff --git a/database/factories/fast_pass_factory.ts b/database/factories/fast_pass_factory.ts new file mode 100644 index 0000000..47c93d1 --- /dev/null +++ b/database/factories/fast_pass_factory.ts @@ -0,0 +1,13 @@ +import factory from '@adonisjs/lucid/factories' +import FastPass from '#models/fast_pass' + +export const FastPassFactory = factory + .define(FastPass, async ({ faker }) => { + return { + price: faker.number.float({ min: 1, max: 100 }), + duration: faker.number.int({ min: 1, max: 60 }), + description: faker.lorem.sentence(), + label: faker.lorem.word(), + } + }) + .build() \ No newline at end of file diff --git a/database/seeders/fast_pass_seeder.ts b/database/seeders/fast_pass_seeder.ts new file mode 100644 index 0000000..a702db9 --- /dev/null +++ b/database/seeders/fast_pass_seeder.ts @@ -0,0 +1,9 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { FastPassFactory } from '#database/factories/fast_pass_factory' + +export default class extends BaseSeeder { + async run() { + // Write your database queries inside the run method + await FastPassFactory.createMany(10) + } +} \ No newline at end of file diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index 8cb7349..7e829b1 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -14,6 +14,7 @@ import LogSeeder from './log_seeder.ts' import RoleSeeder from './role_seeder.ts' import PermissionSeeder from './permission_seeder.ts' //import RolePermissionSeeder from './role_permission_seeder.ts' +import FastPassSeeder from './fast_pass_seeder.ts' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { @@ -36,6 +37,7 @@ export default class extends BaseSeeder { await this.runSeeder(ProductSeeder) await this.runSeeder(RestockSeeder) await this.runSeeder(LogSeeder) + await this.runSeeder(FastPassSeeder) // 4. Seeders dépendants des seeders précédents await this.runSeeder(ProductGoodSeeder) diff --git a/start/routes.ts b/start/routes.ts index 42538d4..ea3a3d3 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -28,7 +28,8 @@ router router.resource('stock-movements', () => import('#controllers/stock_movements_controller')).apiOnly(), router.resource('logs', () => import('#controllers/logs_controller')).apiOnly(), router.resource('roles', () => import('#controllers/roles_controller')).apiOnly(), - router.resource('permissions', () => import('#controllers/permissions_controller')).apiOnly()) + router.resource('permissions', () => import('#controllers/permissions_controller')).apiOnly(), + router.resource('fast-passes', () => import('#controllers/fast_passes_controller')).apiOnly()) }) .prefix('/v1') From 53601b26825d8041f7dff12c9ff8166e19d94ae1 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Thu, 16 Apr 2026 14:32:46 +0200 Subject: [PATCH 26/39] Added subscription --- app/models/user.ts | 4 ++++ ...773827516391_create_subscriptions_table.ts | 7 +++++- database/seeders/main_seeder.ts | 2 ++ database/seeders/subscription_seeder.ts | 22 +++++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 database/seeders/subscription_seeder.ts diff --git a/app/models/user.ts b/app/models/user.ts index 0b6a72c..65c55da 100644 --- a/app/models/user.ts +++ b/app/models/user.ts @@ -19,6 +19,10 @@ export default class User extends compose(UserSchema, withAuthFinder(hash)) { @manyToMany(() => FastPass, { pivotTable: 'subscriptions', + pivotForeignKey: 'user_id', + pivotRelatedForeignKey: 'fast_pass_id', + pivotColumns: ['subscribed_at'], + pivotTimestamps: true, }) declare fastPasses: ManyToMany diff --git a/database/migrations/1773827516391_create_subscriptions_table.ts b/database/migrations/1773827516391_create_subscriptions_table.ts index 1e9777b..a773ceb 100644 --- a/database/migrations/1773827516391_create_subscriptions_table.ts +++ b/database/migrations/1773827516391_create_subscriptions_table.ts @@ -6,7 +6,12 @@ export default class extends BaseSchema { async up() { this.schema.createTable(this.tableName, (table) => { table.timestamp('subscribed_at').notNullable() - table.integer('user_id').unsigned().references('id').inTable('users').onDelete('CASCADE') + table + .integer('user_id') + .unsigned() + .references('id') + .inTable('users') + .onDelete('CASCADE') table .integer('fast_pass_id') .unsigned() diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index 7e829b1..ef767aa 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -15,6 +15,7 @@ import RoleSeeder from './role_seeder.ts' import PermissionSeeder from './permission_seeder.ts' //import RolePermissionSeeder from './role_permission_seeder.ts' import FastPassSeeder from './fast_pass_seeder.ts' +import SubscriptionSeeder from './subscription_seeder.ts' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { @@ -40,6 +41,7 @@ export default class extends BaseSeeder { await this.runSeeder(FastPassSeeder) // 4. Seeders dépendants des seeders précédents + await this.runSeeder(SubscriptionSeeder) await this.runSeeder(ProductGoodSeeder) await this.runSeeder(ProductFurnitureSeeder) await this.runSeeder(GoodSupplierSeeder) diff --git a/database/seeders/subscription_seeder.ts b/database/seeders/subscription_seeder.ts new file mode 100644 index 0000000..5716f5f --- /dev/null +++ b/database/seeders/subscription_seeder.ts @@ -0,0 +1,22 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import User from '#models/user' +import FastPass from '#models/fast_pass' +import { DateTime } from 'luxon' + +export default class extends BaseSeeder { + async run() { + const users = await User.all() + const fastPasses = await FastPass.all() + + if (users.length === 0 || fastPasses.length < 2) { + return + } + + for (const user of users) { + await user.related('fastPasses').sync({ + [fastPasses[0].id]: { subscribed_at: DateTime.now() }, + [fastPasses[1].id]: { subscribed_at: DateTime.now() }, + }) + } + } +} \ No newline at end of file From 343321bce74b59869099fd2f83a18da7cd733430 Mon Sep 17 00:00:00 2001 From: Lucas ESPIET Date: Mon, 20 Apr 2026 12:03:07 +0200 Subject: [PATCH 27/39] chore: format --- app/controllers/goods_controller.ts | 25 ++++- app/controllers/logs_controller.ts | 2 +- app/controllers/members_controller.ts | 2 +- app/controllers/permissions_controller.ts | 2 +- app/controllers/products_controller.ts | 20 +++- app/controllers/restocks_controller.ts | 28 ++++- app/controllers/roles_controller.ts | 2 +- app/controllers/stock_batches_controller.ts | 36 ++++-- app/controllers/stock_movements_controller.ts | 14 ++- app/controllers/suppliers_controller.ts | 20 +++- database/factories/good_factory.ts | 2 +- database/factories/log_factory.ts | 2 +- database/factories/members_factory.ts | 10 +- database/factories/permission_factory.ts | 2 +- database/factories/product_factory.ts | 2 +- database/factories/restock_factory.ts | 2 +- database/factories/role_factory.ts | 11 +- database/factories/stock_batch_factory.ts | 2 +- database/factories/stock_movement_factory.ts | 2 +- database/factories/supplier_factory.ts | 2 +- .../1773828511747_create_members_table.ts | 2 +- database/schema.ts | 103 ++++++++++++++++-- database/seeders/good_seeder.ts | 16 ++- database/seeders/good_supplier_seeder.ts | 8 +- database/seeders/log_seeder.ts | 15 +-- database/seeders/main_seeder.ts | 2 +- database/seeders/member_seeder.ts | 3 +- database/seeders/permission_seeder.ts | 2 +- database/seeders/product_furniture_seeder.ts | 2 +- database/seeders/product_good_seeder.ts | 6 +- database/seeders/product_seeder.ts | 2 +- database/seeders/restock_seeder.ts | 16 ++- database/seeders/role_permission_seeder.ts | 2 +- database/seeders/role_seeder.ts | 2 +- database/seeders/stock_batch_seeder.ts | 16 ++- database/seeders/stock_movement_seeder.ts | 38 +++---- database/seeders/supplier_seeder.ts | 2 +- start/routes.ts | 8 +- 38 files changed, 300 insertions(+), 133 deletions(-) diff --git a/app/controllers/goods_controller.ts b/app/controllers/goods_controller.ts index 7355cd4..e8cff66 100644 --- a/app/controllers/goods_controller.ts +++ b/app/controllers/goods_controller.ts @@ -5,7 +5,7 @@ export default class GoodsController { /** * Display a list of resource */ - async index({ }: HttpContext) { + async index({}: HttpContext) { return Good.query().preload('products').preload('category').preload('suppliers') } @@ -27,14 +27,24 @@ export default class GoodsController { * Show individual record */ async show({ params }: HttpContext) { - return await Good.query().preload('products').preload('category').preload('suppliers').where('id', params.id).firstOrFail() + return await Good.query() + .preload('products') + .preload('category') + .preload('suppliers') + .where('id', params.id) + .firstOrFail() } /** * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const good = await Good.query().preload('products').preload('category').preload('suppliers').where('id', params.id).firstOrFail() // We get our good by id + const good = await Good.query() + .preload('products') + .preload('category') + .preload('suppliers') + .where('id', params.id) + .firstOrFail() // We get our good by id const { name, unit, brand, categoryId } = request.all() good.name = name good.unit = unit @@ -48,7 +58,12 @@ export default class GoodsController { * Delete record */ async destroy({ params }: HttpContext) { - const good = await Good.query().preload('products').preload('category').preload('suppliers').where('id', params.id).firstOrFail() + const good = await Good.query() + .preload('products') + .preload('category') + .preload('suppliers') + .where('id', params.id) + .firstOrFail() await good.delete() } -} \ No newline at end of file +} diff --git a/app/controllers/logs_controller.ts b/app/controllers/logs_controller.ts index a8b856e..232e372 100644 --- a/app/controllers/logs_controller.ts +++ b/app/controllers/logs_controller.ts @@ -59,4 +59,4 @@ export default class LogsController { const log = await Log.query().where('id', params.id).preload('user').firstOrFail() await log.delete() } -} \ No newline at end of file +} diff --git a/app/controllers/members_controller.ts b/app/controllers/members_controller.ts index ef24533..246b0bd 100644 --- a/app/controllers/members_controller.ts +++ b/app/controllers/members_controller.ts @@ -58,4 +58,4 @@ export default class MembersController { } await member.delete() } -} \ No newline at end of file +} diff --git a/app/controllers/permissions_controller.ts b/app/controllers/permissions_controller.ts index 6b908b0..6dc1aad 100644 --- a/app/controllers/permissions_controller.ts +++ b/app/controllers/permissions_controller.ts @@ -46,4 +46,4 @@ export default class PermissionsController { await permission.delete() return { message: 'Permission deleted successfully' } } -} \ No newline at end of file +} diff --git a/app/controllers/products_controller.ts b/app/controllers/products_controller.ts index dc4f5f7..215c49e 100644 --- a/app/controllers/products_controller.ts +++ b/app/controllers/products_controller.ts @@ -27,14 +27,22 @@ export default class ProductsController { * Show individual record */ async show({ params }: HttpContext) { - return await Product.query().preload('furnitures').preload('goods').where('id', params.id).firstOrFail() + return await Product.query() + .preload('furnitures') + .preload('goods') + .where('id', params.id) + .firstOrFail() } /** * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const product = await Product.query().preload('furnitures').preload('goods').where('id', params.id).firstOrFail() // We get our product by id + const product = await Product.query() + .preload('furnitures') + .preload('goods') + .where('id', params.id) + .firstOrFail() // We get our product by id const { name, isVegetarian, description, recipe } = request.all() // We transfer the new data from the request to constants product.name = name // Assigning the data product.isVegetarian = isVegetarian // Assigning the data @@ -48,7 +56,11 @@ export default class ProductsController { * Delete record */ async destroy({ params }: HttpContext) { - const product = await Product.query().preload('furnitures').preload('goods').where('id', params.id).firstOrFail() // Get the product by id + const product = await Product.query() + .preload('furnitures') + .preload('goods') + .where('id', params.id) + .firstOrFail() // Get the product by id await product.delete() } -} \ No newline at end of file +} diff --git a/app/controllers/restocks_controller.ts b/app/controllers/restocks_controller.ts index e48281d..cc6c6f1 100644 --- a/app/controllers/restocks_controller.ts +++ b/app/controllers/restocks_controller.ts @@ -6,7 +6,10 @@ export default class RestocksController { * Display a list of resource */ async index({}: HttpContext) { - const restocks = await Restock.query().preload('member').preload('supplier').preload('stockBatches') + const restocks = await Restock.query() + .preload('member') + .preload('supplier') + .preload('stockBatches') return restocks } @@ -27,7 +30,12 @@ export default class RestocksController { * Show individual record */ async show({ params }: HttpContext) { - const restock = await Restock.query().preload('member').preload('supplier').preload('stockBatches').where('id', params.id).firstOrFail() + const restock = await Restock.query() + .preload('member') + .preload('supplier') + .preload('stockBatches') + .where('id', params.id) + .firstOrFail() return restock } @@ -35,7 +43,12 @@ export default class RestocksController { * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const restock = await Restock.query().preload('member').preload('supplier').preload('stockBatches').where('id', params.id).firstOrFail() + const restock = await Restock.query() + .preload('member') + .preload('supplier') + .preload('stockBatches') + .where('id', params.id) + .firstOrFail() const { memberId, supplierId, totalPrice } = request.all() restock.memberId = memberId restock.supplierId = supplierId @@ -48,7 +61,12 @@ export default class RestocksController { * Delete record */ async destroy({ params }: HttpContext) { - const restock = await Restock.query().preload('member').preload('supplier').preload('stockBatches').where('id', params.id).firstOrFail() + const restock = await Restock.query() + .preload('member') + .preload('supplier') + .preload('stockBatches') + .where('id', params.id) + .firstOrFail() await restock.delete() } -} \ No newline at end of file +} diff --git a/app/controllers/roles_controller.ts b/app/controllers/roles_controller.ts index 9b6a41d..03137b1 100644 --- a/app/controllers/roles_controller.ts +++ b/app/controllers/roles_controller.ts @@ -51,4 +51,4 @@ export default class RolesController { } await role.delete() } -} \ No newline at end of file +} diff --git a/app/controllers/stock_batches_controller.ts b/app/controllers/stock_batches_controller.ts index ddb62b5..1576bdb 100644 --- a/app/controllers/stock_batches_controller.ts +++ b/app/controllers/stock_batches_controller.ts @@ -29,7 +29,11 @@ export default class StockBatchesController { * Show individual record */ async show({ params }: HttpContext) { - const stockBatch = await StockBatch.query().where('id', params.id).preload('good').preload('restock').firstOrFail() + const stockBatch = await StockBatch.query() + .where('id', params.id) + .preload('good') + .preload('restock') + .firstOrFail() return stockBatch } @@ -37,15 +41,21 @@ export default class StockBatchesController { * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const stockBatch = await StockBatch.query().where('id', params.id).preload('good').preload('restock').firstOrFail() + const stockBatch = await StockBatch.query() + .where('id', params.id) + .preload('good') + .preload('restock') + .firstOrFail() const { expirationDate, label, quantity, restockId, goodId } = request.all() - await stockBatch.merge({ - expirationDate, - label, - quantity, - restockId, - goodId, - }).save() + await stockBatch + .merge({ + expirationDate, + label, + quantity, + restockId, + goodId, + }) + .save() return stockBatch } @@ -53,7 +63,11 @@ export default class StockBatchesController { * Delete record */ async destroy({ params }: HttpContext) { - const stockBatch = await StockBatch.query().where('id', params.id).preload('good').preload('restock').firstOrFail() + const stockBatch = await StockBatch.query() + .where('id', params.id) + .preload('good') + .preload('restock') + .firstOrFail() await stockBatch.delete() } -} \ No newline at end of file +} diff --git a/app/controllers/stock_movements_controller.ts b/app/controllers/stock_movements_controller.ts index 07a2d38..3683a2a 100644 --- a/app/controllers/stock_movements_controller.ts +++ b/app/controllers/stock_movements_controller.ts @@ -41,7 +41,11 @@ export default class StockMovementsController { * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const stockMovement = await StockMovement.query().where('id', params.id).preload('good').preload('stockBatch').firstOrFail() + const stockMovement = await StockMovement.query() + .where('id', params.id) + .preload('good') + .preload('stockBatch') + .firstOrFail() const { quantity, movementType, goodId, stockBatchId } = request.all() stockMovement.quantity = quantity @@ -57,7 +61,11 @@ export default class StockMovementsController { * Delete record */ async destroy({ params }: HttpContext) { - const stockMovement = await StockMovement.query().where('id', params.id).preload('good').preload('stockBatch').firstOrFail() + const stockMovement = await StockMovement.query() + .where('id', params.id) + .preload('good') + .preload('stockBatch') + .firstOrFail() await stockMovement.delete() } -} \ No newline at end of file +} diff --git a/app/controllers/suppliers_controller.ts b/app/controllers/suppliers_controller.ts index bc3dcde..5b3f3e7 100644 --- a/app/controllers/suppliers_controller.ts +++ b/app/controllers/suppliers_controller.ts @@ -24,14 +24,22 @@ export default class SuppliersController { * Show individual record */ async show({ params }: HttpContext) { - return await Supplier.query().preload('goods').preload('restocks').where('id', params.id).firstOrFail() + return await Supplier.query() + .preload('goods') + .preload('restocks') + .where('id', params.id) + .firstOrFail() } /** * Handle form submission for the edit action */ async update({ params, request }: HttpContext) { - const supplier = await Supplier.query().preload('goods').preload('restocks').where('id', params.id).firstOrFail() // We get our supplier by id + const supplier = await Supplier.query() + .preload('goods') + .preload('restocks') + .where('id', params.id) + .firstOrFail() // We get our supplier by id const { name } = request.all() // We transfer the new data from the request to constants supplier.name = name // Assigning the data await supplier.save() // We save the supplier to the database @@ -42,7 +50,11 @@ export default class SuppliersController { * Delete record */ async destroy({ params }: HttpContext) { - const supplier = await Supplier.query().preload('goods').preload('restocks').where('id', params.id).firstOrFail() // Get the supplier by id + const supplier = await Supplier.query() + .preload('goods') + .preload('restocks') + .where('id', params.id) + .firstOrFail() // Get the supplier by id await supplier.delete() } -} \ No newline at end of file +} diff --git a/database/factories/good_factory.ts b/database/factories/good_factory.ts index 6d820f4..93a74e6 100644 --- a/database/factories/good_factory.ts +++ b/database/factories/good_factory.ts @@ -12,4 +12,4 @@ export const GoodFactory = factory } }) .relation('category', () => CategoryFactory) - .build() \ No newline at end of file + .build() diff --git a/database/factories/log_factory.ts b/database/factories/log_factory.ts index 05bc033..8a0d407 100644 --- a/database/factories/log_factory.ts +++ b/database/factories/log_factory.ts @@ -18,4 +18,4 @@ export const LogFactory = factory } }) .relation('user', () => UserFactory) - .build() \ No newline at end of file + .build() diff --git a/database/factories/members_factory.ts b/database/factories/members_factory.ts index e61b2e9..18f3d10 100644 --- a/database/factories/members_factory.ts +++ b/database/factories/members_factory.ts @@ -8,12 +8,16 @@ export const MembersFactory = factory return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), - roleId: null + roleId: null, } }) .before('create', async (builder, member, ctx) => { - const requestedBelongsTo = (builder as any).withBelongsToRelations as undefined | Array<{ name: string }> - const willCreateUserViaRelation = requestedBelongsTo?.some((relation) => relation.name === 'user') + const requestedBelongsTo = (builder as any).withBelongsToRelations as + | undefined + | Array<{ name: string }> + const willCreateUserViaRelation = requestedBelongsTo?.some( + (relation) => relation.name === 'user' + ) if (willCreateUserViaRelation) { return diff --git a/database/factories/permission_factory.ts b/database/factories/permission_factory.ts index c79d5c9..b3fc247 100644 --- a/database/factories/permission_factory.ts +++ b/database/factories/permission_factory.ts @@ -37,4 +37,4 @@ export const PermissionFactory = factory permission: value, } }) - .build() \ No newline at end of file + .build() diff --git a/database/factories/product_factory.ts b/database/factories/product_factory.ts index de87885..248285b 100644 --- a/database/factories/product_factory.ts +++ b/database/factories/product_factory.ts @@ -10,4 +10,4 @@ export const ProductFactory = factory recipe: faker.lorem.paragraph(), } }) - .build() \ No newline at end of file + .build() diff --git a/database/factories/restock_factory.ts b/database/factories/restock_factory.ts index dc6bdbf..0ee86e3 100644 --- a/database/factories/restock_factory.ts +++ b/database/factories/restock_factory.ts @@ -13,4 +13,4 @@ export const RestockFactory = factory }) .relation('member', () => MembersFactory) .relation('supplier', () => SupplierFactory) - .build() \ No newline at end of file + .build() diff --git a/database/factories/role_factory.ts b/database/factories/role_factory.ts index 24d08ec..0661138 100644 --- a/database/factories/role_factory.ts +++ b/database/factories/role_factory.ts @@ -4,7 +4,14 @@ import Role from '#models/role' export const RoleFactory = factory .define(Role, async ({ faker }) => { return { - name: faker.helpers.arrayElement(['President', 'Service', 'Assembly', 'Logistics', 'Finance', 'HR']), + name: faker.helpers.arrayElement([ + 'President', + 'Service', + 'Assembly', + 'Logistics', + 'Finance', + 'HR', + ]), } }) - .build() \ No newline at end of file + .build() diff --git a/database/factories/stock_batch_factory.ts b/database/factories/stock_batch_factory.ts index ff38f71..5adabb8 100644 --- a/database/factories/stock_batch_factory.ts +++ b/database/factories/stock_batch_factory.ts @@ -16,4 +16,4 @@ export const StockBatchFactory = factory }) .relation('restock', () => RestockFactory) .relation('good', () => GoodFactory) - .build() \ No newline at end of file + .build() diff --git a/database/factories/stock_movement_factory.ts b/database/factories/stock_movement_factory.ts index ecbc370..c02af18 100644 --- a/database/factories/stock_movement_factory.ts +++ b/database/factories/stock_movement_factory.ts @@ -14,4 +14,4 @@ export const StockMovementFactory = factory }) .relation('good', () => GoodFactory) .relation('stockBatch', () => StockBatchFactory) - .build() \ No newline at end of file + .build() diff --git a/database/factories/supplier_factory.ts b/database/factories/supplier_factory.ts index 01c31d8..258d390 100644 --- a/database/factories/supplier_factory.ts +++ b/database/factories/supplier_factory.ts @@ -7,4 +7,4 @@ export const SupplierFactory = factory name: faker.company.name(), } }) - .build() \ No newline at end of file + .build() diff --git a/database/migrations/1773828511747_create_members_table.ts b/database/migrations/1773828511747_create_members_table.ts index e87ac14..a3b5803 100644 --- a/database/migrations/1773828511747_create_members_table.ts +++ b/database/migrations/1773828511747_create_members_table.ts @@ -26,4 +26,4 @@ export default class extends BaseSchema { async down() { this.schema.dropTable(this.tableName) } -} \ No newline at end of file +} diff --git a/database/schema.ts b/database/schema.ts index a94fa91..d0a5e46 100644 --- a/database/schema.ts +++ b/database/schema.ts @@ -8,7 +8,18 @@ import { BaseModel, column } from '@adonisjs/lucid/orm' import { DateTime } from 'luxon' export class AuthAccessTokenSchema extends BaseModel { - static $columns = ['abilities', 'createdAt', 'expiresAt', 'hash', 'id', 'lastUsedAt', 'name', 'tokenableId', 'type', 'updatedAt'] as const + static $columns = [ + 'abilities', + 'createdAt', + 'expiresAt', + 'hash', + 'id', + 'lastUsedAt', + 'name', + 'tokenableId', + 'type', + 'updatedAt', + ] as const $columns = AuthAccessTokenSchema.$columns @column() declare abilities: string @@ -78,7 +89,15 @@ export class EventProductSchema extends BaseModel { } export class EventSchema extends BaseModel { - static $columns = ['createdAt', 'date', 'description', 'id', 'name', 'status', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'date', + 'description', + 'id', + 'name', + 'status', + 'updatedAt', + ] as const $columns = EventSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -97,7 +116,15 @@ export class EventSchema extends BaseModel { } export class FastPassSchema extends BaseModel { - static $columns = ['createdAt', 'description', 'duration', 'id', 'label', 'price', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'description', + 'duration', + 'id', + 'label', + 'price', + 'updatedAt', + ] as const $columns = FastPassSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime @@ -182,7 +209,17 @@ export class JobSchema extends BaseModel { } export class LogSchema extends BaseModel { - static $columns = ['createdAt', 'id', 'ip', 'level', 'message', 'meta', 'method', 'url', 'userId'] as const + static $columns = [ + 'createdAt', + 'id', + 'ip', + 'level', + 'message', + 'meta', + 'method', + 'url', + 'userId', + ] as const $columns = LogSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -278,7 +315,15 @@ export class OrderProductSchema extends BaseModel { } export class OrderSchema extends BaseModel { - static $columns = ['createdAt', 'eventId', 'id', 'memberId', 'status', 'transactionId', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'eventId', + 'id', + 'memberId', + 'status', + 'transactionId', + 'updatedAt', + ] as const $columns = OrderSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -308,7 +353,14 @@ export class PermissionSchema extends BaseModel { } export class PreOrderItemSchema extends BaseModel { - static $columns = ['createdAt', 'preOrderId', 'productId', 'quantity', 'receivedQuantity', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'preOrderId', + 'productId', + 'quantity', + 'receivedQuantity', + 'updatedAt', + ] as const $columns = PreOrderItemSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -370,7 +422,15 @@ export class ProductGoodSchema extends BaseModel { } export class ProductSchema extends BaseModel { - static $columns = ['createdAt', 'description', 'id', 'isVegetarian', 'name', 'recipe', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'description', + 'id', + 'isVegetarian', + 'name', + 'recipe', + 'updatedAt', + ] as const $columns = ProductSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -389,7 +449,14 @@ export class ProductSchema extends BaseModel { } export class RestockSchema extends BaseModel { - static $columns = ['createdAt', 'id', 'memberId', 'supplierId', 'totalPrice', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'id', + 'memberId', + 'supplierId', + 'totalPrice', + 'updatedAt', + ] as const $columns = RestockSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -430,7 +497,16 @@ export class RolesPermissionSchema extends BaseModel { } export class StockBatchSchema extends BaseModel { - static $columns = ['createdAt', 'expirationDate', 'goodId', 'id', 'label', 'quantity', 'restockId', 'updatedAt'] as const + static $columns = [ + 'createdAt', + 'expirationDate', + 'goodId', + 'id', + 'label', + 'quantity', + 'restockId', + 'updatedAt', + ] as const $columns = StockBatchSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null @@ -451,7 +527,14 @@ export class StockBatchSchema extends BaseModel { } export class StockMovementSchema extends BaseModel { - static $columns = ['createdAt', 'goodId', 'id', 'movementType', 'quantity', 'stockBatchId'] as const + static $columns = [ + 'createdAt', + 'goodId', + 'id', + 'movementType', + 'quantity', + 'stockBatchId', + ] as const $columns = StockMovementSchema.$columns @column.dateTime({ autoCreate: true }) declare createdAt: DateTime | null diff --git a/database/seeders/good_seeder.ts b/database/seeders/good_seeder.ts index 9b320f6..74ed770 100644 --- a/database/seeders/good_seeder.ts +++ b/database/seeders/good_seeder.ts @@ -3,17 +3,15 @@ import { GoodFactory } from '#database/factories/good_factory' import { CategoryFactory } from '#database/factories/category_factory' export default class extends BaseSeeder { - public async run () { + public async run() { // 1. Créer des catégories const categories = await CategoryFactory.createMany(3) // 2. Créer des goods liés aux catégories - await GoodFactory - .merge( - Array.from({ length: 10 }, (_, index) => ({ - categoryId: categories[index % categories.length].id, - })) - ) - .createMany(10) + await GoodFactory.merge( + Array.from({ length: 10 }, (_, index) => ({ + categoryId: categories[index % categories.length].id, + })) + ).createMany(10) } -} \ No newline at end of file +} diff --git a/database/seeders/good_supplier_seeder.ts b/database/seeders/good_supplier_seeder.ts index 730e70c..0ab76a9 100644 --- a/database/seeders/good_supplier_seeder.ts +++ b/database/seeders/good_supplier_seeder.ts @@ -20,21 +20,21 @@ export default class extends BaseSeeder { // Pour chaque supplier, attacher plusieurs goods avec des prices for (const supplier of suppliers) { - // Sélectionner 2-3 goods aléatoires pour chaque supplier + // Sélectionner 2-3 goods aléatoires pour chaque supplier const randomGoodsCount = Math.floor(Math.random() * 2) + 2 // 2 ou 3 goods const selectedGoods = goods .sort(() => 0.5 - Math.random()) // Mélanger .slice(0, randomGoodsCount) const pivotData: Record = {} - + for (const good of selectedGoods) { pivotData[good.id] = { - price: Math.floor(Math.random() * 1000) + 10 // prix entre 10 et 1000 + price: Math.floor(Math.random() * 1000) + 10, // prix entre 10 et 1000 } } await supplier.related('goods').sync(pivotData) } } -} \ No newline at end of file +} diff --git a/database/seeders/log_seeder.ts b/database/seeders/log_seeder.ts index e49baa2..68b53c2 100644 --- a/database/seeders/log_seeder.ts +++ b/database/seeders/log_seeder.ts @@ -12,13 +12,10 @@ export default class extends BaseSeeder { const pickUserId = () => users[Math.floor(Math.random() * users.length)].id - await LogFactory - .merge( - Array.from({ length: 50 }, () => ({ - userId: pickUserId(), - })) - ) - .createMany(50) - + await LogFactory.merge( + Array.from({ length: 50 }, () => ({ + userId: pickUserId(), + })) + ).createMany(50) } -} \ No newline at end of file +} diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index 8cb7349..7a7ca9b 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -46,4 +46,4 @@ export default class extends BaseSeeder { // 5. Seeders dépendants des seeders précédents await this.runSeeder(StockMovementSeeder) } -} \ No newline at end of file +} diff --git a/database/seeders/member_seeder.ts b/database/seeders/member_seeder.ts index 6549ff8..d5cbebd 100644 --- a/database/seeders/member_seeder.ts +++ b/database/seeders/member_seeder.ts @@ -12,8 +12,7 @@ export default class MemberSeeder extends BaseSeeder { const pickRoleId = () => roles[Math.floor(Math.random() * roles.length)].id - await MembersFactory - .with('user') + await MembersFactory.with('user') .merge( Array.from({ length: 10 }, () => ({ roleId: pickRoleId(), diff --git a/database/seeders/permission_seeder.ts b/database/seeders/permission_seeder.ts index 0e11587..f3e2a57 100644 --- a/database/seeders/permission_seeder.ts +++ b/database/seeders/permission_seeder.ts @@ -29,4 +29,4 @@ export default class extends BaseSeeder { permissions.map((permission) => ({ permission })) ) } -} \ No newline at end of file +} diff --git a/database/seeders/product_furniture_seeder.ts b/database/seeders/product_furniture_seeder.ts index d838173..33d0de3 100644 --- a/database/seeders/product_furniture_seeder.ts +++ b/database/seeders/product_furniture_seeder.ts @@ -15,4 +15,4 @@ export default class extends BaseSeeder { }) } } -} \ No newline at end of file +} diff --git a/database/seeders/product_good_seeder.ts b/database/seeders/product_good_seeder.ts index 9361050..cfb66c6 100644 --- a/database/seeders/product_good_seeder.ts +++ b/database/seeders/product_good_seeder.ts @@ -26,14 +26,14 @@ export default class extends BaseSeeder { .slice(0, randomGoodsCount) const pivotData: Record = {} - + for (const good of selectedGoods) { pivotData[good.id] = { - quantity: Math.floor(Math.random() * 10) + 1 // quantité entre 1 et 10 + quantity: Math.floor(Math.random() * 10) + 1, // quantité entre 1 et 10 } } await product.related('goods').sync(pivotData) } } -} \ No newline at end of file +} diff --git a/database/seeders/product_seeder.ts b/database/seeders/product_seeder.ts index 7ee3467..f823e45 100644 --- a/database/seeders/product_seeder.ts +++ b/database/seeders/product_seeder.ts @@ -6,4 +6,4 @@ export default class extends BaseSeeder { // Write your database queries inside the run method await ProductFactory.createMany(10) } -} \ No newline at end of file +} diff --git a/database/seeders/restock_seeder.ts b/database/seeders/restock_seeder.ts index 1e29050..5b06c80 100644 --- a/database/seeders/restock_seeder.ts +++ b/database/seeders/restock_seeder.ts @@ -9,13 +9,11 @@ export default class extends BaseSeeder { const suppliers = await SupplierFactory.createMany(5) const members = await MembersFactory.createMany(5) - await RestockFactory - .merge( - Array.from({ length: 10 }, (_, index) => ({ - supplierId: suppliers[index % suppliers.length].id, - memberId: members[index % members.length].id, - })) - ) - .createMany(10) + await RestockFactory.merge( + Array.from({ length: 10 }, (_, index) => ({ + supplierId: suppliers[index % suppliers.length].id, + memberId: members[index % members.length].id, + })) + ).createMany(10) } -} \ No newline at end of file +} diff --git a/database/seeders/role_permission_seeder.ts b/database/seeders/role_permission_seeder.ts index abd6748..b45546a 100644 --- a/database/seeders/role_permission_seeder.ts +++ b/database/seeders/role_permission_seeder.ts @@ -8,4 +8,4 @@ export default class extends BaseSeeder { const roles = await Role.all() const permissions = await Permission.all() } -} \ No newline at end of file +} diff --git a/database/seeders/role_seeder.ts b/database/seeders/role_seeder.ts index 4c2cb7c..b582eee 100644 --- a/database/seeders/role_seeder.ts +++ b/database/seeders/role_seeder.ts @@ -6,4 +6,4 @@ export default class extends BaseSeeder { // Write your database queries inside the run method await RoleFactory.createMany(5) } -} \ No newline at end of file +} diff --git a/database/seeders/stock_batch_seeder.ts b/database/seeders/stock_batch_seeder.ts index 535f65d..b249dab 100644 --- a/database/seeders/stock_batch_seeder.ts +++ b/database/seeders/stock_batch_seeder.ts @@ -16,13 +16,11 @@ export default class extends BaseSeeder { throw new Error('StockBatchSeeder: no restocks found. Run RestockSeeder first.') } - await StockBatchFactory - .merge( - Array.from({ length: 10 }, (_, index) => ({ - goodId: goods[index % goods.length].id, - restockId: restocks[index % restocks.length].id, - })) - ) - .createMany(10) + await StockBatchFactory.merge( + Array.from({ length: 10 }, (_, index) => ({ + goodId: goods[index % goods.length].id, + restockId: restocks[index % restocks.length].id, + })) + ).createMany(10) } -} \ No newline at end of file +} diff --git a/database/seeders/stock_movement_seeder.ts b/database/seeders/stock_movement_seeder.ts index a66136a..706cc54 100644 --- a/database/seeders/stock_movement_seeder.ts +++ b/database/seeders/stock_movement_seeder.ts @@ -17,28 +17,28 @@ export default class extends BaseSeeder { throw new Error('StockMovementSeeder: no stock batches found. Run StockBatchSeeder first.') } - console.log(`Seeding stock movements with ${goods.length} goods and ${stockBatches.length} stock batches...`) + console.log( + `Seeding stock movements with ${goods.length} goods and ${stockBatches.length} stock batches...` + ) const pickId = (rows: Array<{ id: number }>) => rows[Math.floor(Math.random() * rows.length)].id - await StockMovementFactory - .merge( - Array.from({ length: 20 }, () => { - const goodId = pickId(goods) + await StockMovementFactory.merge( + Array.from({ length: 20 }, () => { + const goodId = pickId(goods) - let stockBatchId = pickId(stockBatches) - if (stockBatches.length > 1) { - while (stockBatchId === goodId) { - stockBatchId = pickId(stockBatches) - } + let stockBatchId = pickId(stockBatches) + if (stockBatches.length > 1) { + while (stockBatchId === goodId) { + stockBatchId = pickId(stockBatches) } - - return { - goodId, - stockBatchId, - } - }) - ) - .createMany(20) + } + + return { + goodId, + stockBatchId, + } + }) + ).createMany(20) } -} \ No newline at end of file +} diff --git a/database/seeders/supplier_seeder.ts b/database/seeders/supplier_seeder.ts index 33c7ba6..c73ff64 100644 --- a/database/seeders/supplier_seeder.ts +++ b/database/seeders/supplier_seeder.ts @@ -6,4 +6,4 @@ export default class extends BaseSeeder { // Write your database queries inside the run method await SupplierFactory.createMany(10) } -} \ No newline at end of file +} diff --git a/start/routes.ts b/start/routes.ts index 42538d4..408583a 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -24,8 +24,12 @@ router router.resource('goods', () => import('#controllers/goods_controller')).apiOnly(), router.resource('suppliers', () => import('#controllers/suppliers_controller')).apiOnly(), router.resource('restocks', () => import('#controllers/restocks_controller')).apiOnly(), - router.resource('stock-batches', () => import('#controllers/stock_batches_controller')).apiOnly(), - router.resource('stock-movements', () => import('#controllers/stock_movements_controller')).apiOnly(), + router + .resource('stock-batches', () => import('#controllers/stock_batches_controller')) + .apiOnly(), + router + .resource('stock-movements', () => import('#controllers/stock_movements_controller')) + .apiOnly(), router.resource('logs', () => import('#controllers/logs_controller')).apiOnly(), router.resource('roles', () => import('#controllers/roles_controller')).apiOnly(), router.resource('permissions', () => import('#controllers/permissions_controller')).apiOnly()) From c8fc06c85ab656e83f9e2b6baf7eceff04e016c5 Mon Sep 17 00:00:00 2001 From: Lucas ESPIET Date: Mon, 20 Apr 2026 12:04:29 +0200 Subject: [PATCH 28/39] fix: typecheck --- database/seeders/role_permission_seeder.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/database/seeders/role_permission_seeder.ts b/database/seeders/role_permission_seeder.ts index b45546a..6b5422d 100644 --- a/database/seeders/role_permission_seeder.ts +++ b/database/seeders/role_permission_seeder.ts @@ -1,11 +1,7 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' -import Permission from '#models/permission' -import Role from '#models/role' export default class extends BaseSeeder { async run() { // Write your database queries inside the run method - const roles = await Role.all() - const permissions = await Permission.all() } } From 31e4c19ea069d87be0e7442cbf6c5b481569ea47 Mon Sep 17 00:00:00 2001 From: Lucas ESPIET Date: Mon, 20 Apr 2026 12:23:34 +0200 Subject: [PATCH 29/39] feat: add missing factories --- database/factories/event_factory.ts | 14 ++++ database/factories/fast_pass_factory.ts | 13 ++++ database/factories/job_factory.ts | 11 +++ .../member_event_assigned_job_factory.ts | 14 ++++ database/factories/order_factory.ts | 16 +++++ database/factories/pre_order_factory.ts | 14 ++++ database/factories/transaction_factory.ts | 11 +++ database/seeders/event_seeder.ts | 8 +++ database/seeders/fast_pass_seeder.ts | 8 +++ database/seeders/job_seeder.ts | 8 +++ database/seeders/main_seeder.ts | 16 +++-- database/seeders/role_permission_seeder.ts | 68 ++++++++++++++++++- database/seeders/transaction_seeder.ts | 8 +++ 13 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 database/factories/event_factory.ts create mode 100644 database/factories/fast_pass_factory.ts create mode 100644 database/factories/job_factory.ts create mode 100644 database/factories/member_event_assigned_job_factory.ts create mode 100644 database/factories/order_factory.ts create mode 100644 database/factories/pre_order_factory.ts create mode 100644 database/factories/transaction_factory.ts create mode 100644 database/seeders/event_seeder.ts create mode 100644 database/seeders/fast_pass_seeder.ts create mode 100644 database/seeders/job_seeder.ts create mode 100644 database/seeders/transaction_seeder.ts diff --git a/database/factories/event_factory.ts b/database/factories/event_factory.ts new file mode 100644 index 0000000..6e3f100 --- /dev/null +++ b/database/factories/event_factory.ts @@ -0,0 +1,14 @@ +import factory from '@adonisjs/lucid/factories' +import Event from '#models/event' +import { DateTime } from 'luxon' + +export const EventFactory = factory + .define(Event, async ({ faker }) => { + return { + name: faker.company.catchPhrase(), + description: faker.lorem.paragraph(), + date: DateTime.fromJSDate(faker.date.future()), + status: faker.helpers.arrayElement(['scheduled', 'ongoing', 'completed']), + } + }) + .build() diff --git a/database/factories/fast_pass_factory.ts b/database/factories/fast_pass_factory.ts new file mode 100644 index 0000000..a81c624 --- /dev/null +++ b/database/factories/fast_pass_factory.ts @@ -0,0 +1,13 @@ +import factory from '@adonisjs/lucid/factories' +import FastPass from '#models/fast_pass' + +export const FastPassFactory = factory + .define(FastPass, async ({ faker }) => { + return { + label: faker.helpers.arrayElement(['1 year', '2 year', '3 year']), + description: faker.lorem.sentence(), + price: faker.number.int({ min: 10, max: 100 }), + duration: faker.number.int({ min: 1, max: 12 }), + } + }) + .build() diff --git a/database/factories/job_factory.ts b/database/factories/job_factory.ts new file mode 100644 index 0000000..30f82cb --- /dev/null +++ b/database/factories/job_factory.ts @@ -0,0 +1,11 @@ +import factory from '@adonisjs/lucid/factories' +import Job from '#models/job' + +export const JobFactory = factory + .define(Job, async ({ faker }) => { + return { + name: faker.person.jobTitle(), + description: faker.lorem.paragraph(), + } + }) + .build() diff --git a/database/factories/member_event_assigned_job_factory.ts b/database/factories/member_event_assigned_job_factory.ts new file mode 100644 index 0000000..c496aee --- /dev/null +++ b/database/factories/member_event_assigned_job_factory.ts @@ -0,0 +1,14 @@ +import factory from '@adonisjs/lucid/factories' +import MemberEventAssignedJob from '#models/member_event_assigned_job' +import { MembersFactory } from '#database/factories/members_factory' +import { EventFactory } from '#database/factories/event_factory' +import { JobFactory } from '#database/factories/job_factory' + +export const MemberEventAssignedJobFactory = factory + .define(MemberEventAssignedJob, async () => { + return {} + }) + .relation('member', () => MembersFactory) + .relation('event', () => EventFactory) + .relation('job', () => JobFactory) + .build() diff --git a/database/factories/order_factory.ts b/database/factories/order_factory.ts new file mode 100644 index 0000000..ebf6cc3 --- /dev/null +++ b/database/factories/order_factory.ts @@ -0,0 +1,16 @@ +import factory from '@adonisjs/lucid/factories' +import Order from '#models/order' +import { MembersFactory } from '#database/factories/members_factory' +import { EventFactory } from '#database/factories/event_factory' +import { TransactionFactory } from '#database/factories/transaction_factory' + +export const OrderFactory = factory + .define(Order, async ({ faker }) => { + return { + status: faker.helpers.arrayElement(['pending', 'completed', 'cancelled']), + } + }) + .relation('takenBy', () => MembersFactory) + .relation('event', () => EventFactory) + .relation('transaction', () => TransactionFactory) + .build() diff --git a/database/factories/pre_order_factory.ts b/database/factories/pre_order_factory.ts new file mode 100644 index 0000000..4cf873a --- /dev/null +++ b/database/factories/pre_order_factory.ts @@ -0,0 +1,14 @@ +import factory from '@adonisjs/lucid/factories' +import PreOrder from '#models/pre_order' +import { UserFactory } from '#database/factories/user_factory' +import { EventFactory } from '#database/factories/event_factory' +import { TransactionFactory } from '#database/factories/transaction_factory' + +export const PreOrderFactory = factory + .define(PreOrder, async () => { + return {} + }) + .relation('user', () => UserFactory) + .relation('event', () => EventFactory) + .relation('transaction', () => TransactionFactory) + .build() diff --git a/database/factories/transaction_factory.ts b/database/factories/transaction_factory.ts new file mode 100644 index 0000000..7e6e719 --- /dev/null +++ b/database/factories/transaction_factory.ts @@ -0,0 +1,11 @@ +import factory from '@adonisjs/lucid/factories' +import Transaction from '#models/transaction' + +export const TransactionFactory = factory + .define(Transaction, async ({ faker }) => { + return { + amount: faker.finance.amount(), + type: faker.helpers.arrayElement(['credit', 'debit', 'refund']), + } + }) + .build() diff --git a/database/seeders/event_seeder.ts b/database/seeders/event_seeder.ts new file mode 100644 index 0000000..bac1669 --- /dev/null +++ b/database/seeders/event_seeder.ts @@ -0,0 +1,8 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { EventFactory } from '#database/factories/event_factory' + +export default class extends BaseSeeder { + async run() { + await EventFactory.createMany(10) + } +} diff --git a/database/seeders/fast_pass_seeder.ts b/database/seeders/fast_pass_seeder.ts new file mode 100644 index 0000000..dd42730 --- /dev/null +++ b/database/seeders/fast_pass_seeder.ts @@ -0,0 +1,8 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { FastPassFactory } from '#database/factories/fast_pass_factory' + +export default class extends BaseSeeder { + async run() { + await FastPassFactory.createMany(5) + } +} diff --git a/database/seeders/job_seeder.ts b/database/seeders/job_seeder.ts new file mode 100644 index 0000000..fc230ea --- /dev/null +++ b/database/seeders/job_seeder.ts @@ -0,0 +1,8 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { JobFactory } from '#database/factories/job_factory' + +export default class extends BaseSeeder { + async run() { + await JobFactory.createMany(8) + } +} diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index 7a7ca9b..2d83fec 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -13,7 +13,11 @@ import StockMovementSeeder from './stock_movement_seeder.ts' import LogSeeder from './log_seeder.ts' import RoleSeeder from './role_seeder.ts' import PermissionSeeder from './permission_seeder.ts' -//import RolePermissionSeeder from './role_permission_seeder.ts' +import RolePermissionSeeder from './role_permission_seeder.ts' +import EventSeeder from './event_seeder.ts' +import JobSeeder from './job_seeder.ts' +import TransactionSeeder from './transaction_seeder.ts' +import FastPassSeeder from './fast_pass_seeder.ts' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { @@ -21,16 +25,20 @@ export default class extends BaseSeeder { } public async run() { - // 1. Seeders seuls + // 1. Seeders seuls (no dependencies) await this.runSeeder(RoleSeeder) await this.runSeeder(PermissionSeeder) + await this.runSeeder(JobSeeder) + await this.runSeeder(TransactionSeeder) - // 2. Seeders dépendants + // 2. Seeders dépendants (depends on step 1) + await this.runSeeder(RolePermissionSeeder) await this.runSeeder(MemberSeeder) await this.runSeeder(GoodSeeder) await this.runSeeder(FurnitureSeeder) await this.runSeeder(SupplierSeeder) - // await this.runSeeder(RolePermissionSeeder) + await this.runSeeder(EventSeeder) + await this.runSeeder(FastPassSeeder) // 3. Seeders dépendants des seeders précédents await this.runSeeder(ProductSeeder) diff --git a/database/seeders/role_permission_seeder.ts b/database/seeders/role_permission_seeder.ts index 6b5422d..7640f57 100644 --- a/database/seeders/role_permission_seeder.ts +++ b/database/seeders/role_permission_seeder.ts @@ -1,7 +1,73 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' +import Role from '#models/role' +import Permission from '#models/permission' export default class extends BaseSeeder { async run() { - // Write your database queries inside the run method + // Fetch all roles and permissions + const roles = await Role.all() + const permissions = await Permission.all() + + // Define permission mapping for different roles + const rolePermissionMap: Record = { + President: [ + 'presence:write', + 'presence:read', + 'stock:read', + 'stock:update', + 'stock:create', + 'stock:delete', + 'product:read', + 'product:update', + 'product:create', + 'product:delete', + 'supplier:read', + 'supplier:update', + 'supplier:create', + 'supplier:delete', + 'restock:read', + 'restock:update', + 'restock:create', + 'restock:delete', + ], + Service: [ + 'presence:read', + 'stock:read', + 'product:read', + 'supplier:read', + 'restock:read', + 'restock:create', + ], + Assembly: ['presence:read', 'stock:read', 'product:read'], + Logistics: [ + 'stock:read', + 'stock:update', + 'stock:create', + 'product:read', + 'supplier:read', + 'supplier:update', + 'restock:read', + 'restock:update', + 'restock:create', + ], + Finance: [ + 'supplier:read', + 'supplier:update', + 'restock:read', + 'restock:update', + 'product:read', + ], + HR: ['presence:write', 'presence:read'], + } + + // Assign permissions to roles + for (const role of roles) { + const permissionNames = rolePermissionMap[role.name] || [] + const rolePermissions = permissions.filter((p) => permissionNames.includes(p.permission)) + + if (rolePermissions.length > 0) { + await role.related('permissions').attach(rolePermissions.map((p) => p.permission)) + } + } } } diff --git a/database/seeders/transaction_seeder.ts b/database/seeders/transaction_seeder.ts new file mode 100644 index 0000000..fcfeb86 --- /dev/null +++ b/database/seeders/transaction_seeder.ts @@ -0,0 +1,8 @@ +import { BaseSeeder } from '@adonisjs/lucid/seeders' +import { TransactionFactory } from '#database/factories/transaction_factory' + +export default class extends BaseSeeder { + async run() { + await TransactionFactory.createMany(15) + } +} From 6f75f010dc7b09a8140ce61d954a29a0fee78274 Mon Sep 17 00:00:00 2001 From: Lucas ESPIET Date: Mon, 20 Apr 2026 12:28:56 +0200 Subject: [PATCH 30/39] fix --- database/seeders/category_seeder.ts | 5 ++--- database/seeders/main_seeder.ts | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/database/seeders/category_seeder.ts b/database/seeders/category_seeder.ts index b654f73..5a23d9a 100644 --- a/database/seeders/category_seeder.ts +++ b/database/seeders/category_seeder.ts @@ -1,9 +1,8 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' -// import { CategoryFactory } from '#database/factories/category_factory' +import {CategoryFactory} from "#database/factories/category_factory"; export default class extends BaseSeeder { async run() { - // Write your database queries inside the run method - // await CategoryFactory.createMany(10) + await CategoryFactory.createMany(10) } } diff --git a/database/seeders/main_seeder.ts b/database/seeders/main_seeder.ts index 2d83fec..ed7b258 100644 --- a/database/seeders/main_seeder.ts +++ b/database/seeders/main_seeder.ts @@ -6,18 +6,18 @@ import ProductGoodSeeder from './product_good_seeder.js' import ProductFurnitureSeeder from './product_furniture_seeder.js' import SupplierSeeder from './supplier_seeder.js' import GoodSupplierSeeder from './good_supplier_seeder.js' -import MemberSeeder from './member_seeder.ts' -import RestockSeeder from './restock_seeder.ts' -import StockBatchSeeder from './stock_batch_seeder.ts' -import StockMovementSeeder from './stock_movement_seeder.ts' -import LogSeeder from './log_seeder.ts' -import RoleSeeder from './role_seeder.ts' -import PermissionSeeder from './permission_seeder.ts' -import RolePermissionSeeder from './role_permission_seeder.ts' -import EventSeeder from './event_seeder.ts' -import JobSeeder from './job_seeder.ts' -import TransactionSeeder from './transaction_seeder.ts' -import FastPassSeeder from './fast_pass_seeder.ts' +import MemberSeeder from './member_seeder.js' +import RestockSeeder from './restock_seeder.js' +import StockBatchSeeder from './stock_batch_seeder.js' +import StockMovementSeeder from './stock_movement_seeder.js' +import LogSeeder from './log_seeder.js' +import RoleSeeder from './role_seeder.js' +import PermissionSeeder from './permission_seeder.js' +import RolePermissionSeeder from './role_permission_seeder.js' +import EventSeeder from './event_seeder.js' +import JobSeeder from './job_seeder.js' +import TransactionSeeder from './transaction_seeder.js' +import FastPassSeeder from './fast_pass_seeder.js' export default class extends BaseSeeder { private async runSeeder(Seeder: typeof BaseSeeder) { From 5dc4e660f5e51ff9144596ed4ea1e2bc150b29e4 Mon Sep 17 00:00:00 2001 From: Lucas ESPIET Date: Mon, 20 Apr 2026 14:22:54 +0200 Subject: [PATCH 31/39] format --- database/seeders/category_seeder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/seeders/category_seeder.ts b/database/seeders/category_seeder.ts index 5a23d9a..9a33a46 100644 --- a/database/seeders/category_seeder.ts +++ b/database/seeders/category_seeder.ts @@ -1,5 +1,5 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' -import {CategoryFactory} from "#database/factories/category_factory"; +import { CategoryFactory } from '#database/factories/category_factory' export default class extends BaseSeeder { async run() { From 9cc416bfee6ba50b7b6d594f29d08a3ca8d377d4 Mon Sep 17 00:00:00 2001 From: Thibault Latxague <151643951+ThibaultLatxague@users.noreply.github.com> Date: Tue, 21 Apr 2026 09:37:26 +0200 Subject: [PATCH 32/39] Update database/factories/permission_factory.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- database/factories/permission_factory.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/database/factories/permission_factory.ts b/database/factories/permission_factory.ts index b3fc247..6cc1485 100644 --- a/database/factories/permission_factory.ts +++ b/database/factories/permission_factory.ts @@ -22,19 +22,14 @@ const permissions = [ 'restock:delete', ] -// copie modifiable -let availablePermissions = [...permissions] - export const PermissionFactory = factory - .define(Permission, async () => { - if (availablePermissions.length === 0) { + .define(Permission, async ({ index }) => { + if (index >= permissions.length) { throw new Error('Plus de permissions disponibles (unicité garantie)') } - const value = availablePermissions.shift()! - return { - permission: value, + permission: permissions[index], } }) .build() From 4f9441cea6db781a3984d4db7945ea4c69addc30 Mon Sep 17 00:00:00 2001 From: Thibault Latxague <151643951+ThibaultLatxague@users.noreply.github.com> Date: Tue, 21 Apr 2026 09:38:10 +0200 Subject: [PATCH 33/39] Update database/factories/good_factory.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- database/factories/good_factory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/factories/good_factory.ts b/database/factories/good_factory.ts index 93a74e6..c8ebcd0 100644 --- a/database/factories/good_factory.ts +++ b/database/factories/good_factory.ts @@ -1,6 +1,6 @@ import factory from '@adonisjs/lucid/factories' import Good from '#models/good' -import { CategoryFactory } from './category_factory.ts' +import { CategoryFactory } from './category_factory.js' export const GoodFactory = factory .define(Good, async ({ faker }) => { From 9a65ed54d57e1d6f945b3d23ff1825a7fe01407c Mon Sep 17 00:00:00 2001 From: Thibault Latxague <151643951+ThibaultLatxague@users.noreply.github.com> Date: Tue, 21 Apr 2026 09:38:40 +0200 Subject: [PATCH 34/39] Update database/factories/members_factory.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- database/factories/members_factory.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/database/factories/members_factory.ts b/database/factories/members_factory.ts index 18f3d10..74d662e 100644 --- a/database/factories/members_factory.ts +++ b/database/factories/members_factory.ts @@ -1,10 +1,10 @@ import factory from '@adonisjs/lucid/factories' -import Members from '#models/member' +import Member from '#models/member' import { UserFactory } from '#database/factories/user_factory' import { RoleFactory } from '#database/factories/role_factory' -export const MembersFactory = factory - .define(Members, async ({ faker }) => { +export const MemberFactory = factory + .define(Member, async ({ faker }) => { return { firstName: faker.person.firstName(), lastName: faker.person.lastName(), From 1b5db6a5c85ec6975cc9c3b9e019966f57e7a182 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 07:39:44 +0000 Subject: [PATCH 35/39] refactor: replace comma-operator route declarations Agent-Logs-Url: https://github.com/ValbionGroup/BAE-Back/sessions/fc3c5d3d-7807-42a1-9cbf-a7ac5f4b574c Co-authored-by: ThibaultLatxague <151643951+ThibaultLatxague@users.noreply.github.com> --- .adonisjs/client/data.d.ts | 5 +++++ .adonisjs/client/manifest.d.ts | 6 ++++++ .adonisjs/server/controllers.ts | 17 +++++++++++++++++ .adonisjs/server/events.ts | 5 +++++ .adonisjs/server/listeners.ts | 5 +++++ start/routes.ts | 30 ++++++++++++++---------------- 6 files changed, 52 insertions(+), 16 deletions(-) diff --git a/.adonisjs/client/data.d.ts b/.adonisjs/client/data.d.ts index 3568d52..ee014a4 100644 --- a/.adonisjs/client/data.d.ts +++ b/.adonisjs/client/data.d.ts @@ -1,3 +1,8 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + /// import type { InferData, InferVariants } from '@adonisjs/core/types/transformers' import type UserTransformer from '#transformers/user_transformer' diff --git a/.adonisjs/client/manifest.d.ts b/.adonisjs/client/manifest.d.ts index 5845626..158e306 100644 --- a/.adonisjs/client/manifest.d.ts +++ b/.adonisjs/client/manifest.d.ts @@ -1,4 +1,10 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + /// /// /// +/// /// diff --git a/.adonisjs/server/controllers.ts b/.adonisjs/server/controllers.ts index f7f61b6..5addc38 100644 --- a/.adonisjs/server/controllers.ts +++ b/.adonisjs/server/controllers.ts @@ -1,5 +1,22 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + export const controllers = { AccessToken: () => import('#controllers/access_token_controller'), + Categories: () => import('#controllers/categories_controller'), + Furnitures: () => import('#controllers/furnitures_controller'), + Goods: () => import('#controllers/goods_controller'), + Logs: () => import('#controllers/logs_controller'), + Members: () => import('#controllers/members_controller'), NewAccount: () => import('#controllers/new_account_controller'), + Permissions: () => import('#controllers/permissions_controller'), + Products: () => import('#controllers/products_controller'), Profile: () => import('#controllers/profile_controller'), + Restocks: () => import('#controllers/restocks_controller'), + Roles: () => import('#controllers/roles_controller'), + StockBatches: () => import('#controllers/stock_batches_controller'), + StockMovements: () => import('#controllers/stock_movements_controller'), + Suppliers: () => import('#controllers/suppliers_controller'), } diff --git a/.adonisjs/server/events.ts b/.adonisjs/server/events.ts index a7ab473..a74e59b 100644 --- a/.adonisjs/server/events.ts +++ b/.adonisjs/server/events.ts @@ -1 +1,6 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + export const events = {} diff --git a/.adonisjs/server/listeners.ts b/.adonisjs/server/listeners.ts index 28cbf66..05f35f8 100644 --- a/.adonisjs/server/listeners.ts +++ b/.adonisjs/server/listeners.ts @@ -1 +1,6 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + export const listeners = {} diff --git a/start/routes.ts b/start/routes.ts index 408583a..5ad130a 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -17,22 +17,20 @@ router.group(() => {}).prefix('/v1') router .group(() => { - ;(router.resource('members', () => import('#controllers/members_controller')).apiOnly(), - router.resource('categories', () => import('#controllers/categories_controller')).apiOnly(), - router.resource('furnitures', () => import('#controllers/furnitures_controller')).apiOnly(), - router.resource('products', () => import('#controllers/products_controller')).apiOnly(), - router.resource('goods', () => import('#controllers/goods_controller')).apiOnly(), - router.resource('suppliers', () => import('#controllers/suppliers_controller')).apiOnly(), - router.resource('restocks', () => import('#controllers/restocks_controller')).apiOnly(), - router - .resource('stock-batches', () => import('#controllers/stock_batches_controller')) - .apiOnly(), - router - .resource('stock-movements', () => import('#controllers/stock_movements_controller')) - .apiOnly(), - router.resource('logs', () => import('#controllers/logs_controller')).apiOnly(), - router.resource('roles', () => import('#controllers/roles_controller')).apiOnly(), - router.resource('permissions', () => import('#controllers/permissions_controller')).apiOnly()) + router.resource('members', () => import('#controllers/members_controller')).apiOnly() + router.resource('categories', () => import('#controllers/categories_controller')).apiOnly() + router.resource('furnitures', () => import('#controllers/furnitures_controller')).apiOnly() + router.resource('products', () => import('#controllers/products_controller')).apiOnly() + router.resource('goods', () => import('#controllers/goods_controller')).apiOnly() + router.resource('suppliers', () => import('#controllers/suppliers_controller')).apiOnly() + router.resource('restocks', () => import('#controllers/restocks_controller')).apiOnly() + router.resource('stock-batches', () => import('#controllers/stock_batches_controller')).apiOnly() + router + .resource('stock-movements', () => import('#controllers/stock_movements_controller')) + .apiOnly() + router.resource('logs', () => import('#controllers/logs_controller')).apiOnly() + router.resource('roles', () => import('#controllers/roles_controller')).apiOnly() + router.resource('permissions', () => import('#controllers/permissions_controller')).apiOnly() }) .prefix('/v1') From 0cf963c40b4bf8a993fa5b9689fe5a55316a360a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 07:40:25 +0000 Subject: [PATCH 36/39] chore: revert unrelated generated adonis index updates Agent-Logs-Url: https://github.com/ValbionGroup/BAE-Back/sessions/fc3c5d3d-7807-42a1-9cbf-a7ac5f4b574c Co-authored-by: ThibaultLatxague <151643951+ThibaultLatxague@users.noreply.github.com> --- .adonisjs/client/data.d.ts | 5 ----- .adonisjs/client/manifest.d.ts | 6 ------ .adonisjs/server/controllers.ts | 17 ----------------- .adonisjs/server/events.ts | 5 ----- .adonisjs/server/listeners.ts | 5 ----- 5 files changed, 38 deletions(-) diff --git a/.adonisjs/client/data.d.ts b/.adonisjs/client/data.d.ts index ee014a4..3568d52 100644 --- a/.adonisjs/client/data.d.ts +++ b/.adonisjs/client/data.d.ts @@ -1,8 +1,3 @@ -/** - * This file is automatically generated. - * DO NOT EDIT manually - */ - /// import type { InferData, InferVariants } from '@adonisjs/core/types/transformers' import type UserTransformer from '#transformers/user_transformer' diff --git a/.adonisjs/client/manifest.d.ts b/.adonisjs/client/manifest.d.ts index 158e306..5845626 100644 --- a/.adonisjs/client/manifest.d.ts +++ b/.adonisjs/client/manifest.d.ts @@ -1,10 +1,4 @@ -/** - * This file is automatically generated. - * DO NOT EDIT manually - */ - /// /// /// -/// /// diff --git a/.adonisjs/server/controllers.ts b/.adonisjs/server/controllers.ts index 5addc38..f7f61b6 100644 --- a/.adonisjs/server/controllers.ts +++ b/.adonisjs/server/controllers.ts @@ -1,22 +1,5 @@ -/** - * This file is automatically generated. - * DO NOT EDIT manually - */ - export const controllers = { AccessToken: () => import('#controllers/access_token_controller'), - Categories: () => import('#controllers/categories_controller'), - Furnitures: () => import('#controllers/furnitures_controller'), - Goods: () => import('#controllers/goods_controller'), - Logs: () => import('#controllers/logs_controller'), - Members: () => import('#controllers/members_controller'), NewAccount: () => import('#controllers/new_account_controller'), - Permissions: () => import('#controllers/permissions_controller'), - Products: () => import('#controllers/products_controller'), Profile: () => import('#controllers/profile_controller'), - Restocks: () => import('#controllers/restocks_controller'), - Roles: () => import('#controllers/roles_controller'), - StockBatches: () => import('#controllers/stock_batches_controller'), - StockMovements: () => import('#controllers/stock_movements_controller'), - Suppliers: () => import('#controllers/suppliers_controller'), } diff --git a/.adonisjs/server/events.ts b/.adonisjs/server/events.ts index a74e59b..a7ab473 100644 --- a/.adonisjs/server/events.ts +++ b/.adonisjs/server/events.ts @@ -1,6 +1 @@ -/** - * This file is automatically generated. - * DO NOT EDIT manually - */ - export const events = {} diff --git a/.adonisjs/server/listeners.ts b/.adonisjs/server/listeners.ts index 05f35f8..28cbf66 100644 --- a/.adonisjs/server/listeners.ts +++ b/.adonisjs/server/listeners.ts @@ -1,6 +1 @@ -/** - * This file is automatically generated. - * DO NOT EDIT manually - */ - export const listeners = {} From 48d3b7eb450ead51bf46afab10f633b1e7be39e8 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Tue, 21 Apr 2026 10:06:11 +0200 Subject: [PATCH 37/39] Corrected Copilot mistakes --- database/factories/member_event_assigned_job_factory.ts | 4 ++-- database/factories/order_factory.ts | 4 ++-- database/factories/permission_factory.ts | 8 +++++--- database/factories/restock_factory.ts | 4 ++-- database/seeders/member_seeder.ts | 4 ++-- database/seeders/restock_seeder.ts | 4 ++-- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/database/factories/member_event_assigned_job_factory.ts b/database/factories/member_event_assigned_job_factory.ts index c496aee..111892f 100644 --- a/database/factories/member_event_assigned_job_factory.ts +++ b/database/factories/member_event_assigned_job_factory.ts @@ -1,6 +1,6 @@ import factory from '@adonisjs/lucid/factories' import MemberEventAssignedJob from '#models/member_event_assigned_job' -import { MembersFactory } from '#database/factories/members_factory' +import { MemberFactory } from '#database/factories/members_factory' import { EventFactory } from '#database/factories/event_factory' import { JobFactory } from '#database/factories/job_factory' @@ -8,7 +8,7 @@ export const MemberEventAssignedJobFactory = factory .define(MemberEventAssignedJob, async () => { return {} }) - .relation('member', () => MembersFactory) + .relation('member', () => MemberFactory) .relation('event', () => EventFactory) .relation('job', () => JobFactory) .build() diff --git a/database/factories/order_factory.ts b/database/factories/order_factory.ts index ebf6cc3..1cb7237 100644 --- a/database/factories/order_factory.ts +++ b/database/factories/order_factory.ts @@ -1,6 +1,6 @@ import factory from '@adonisjs/lucid/factories' import Order from '#models/order' -import { MembersFactory } from '#database/factories/members_factory' +import { MemberFactory } from '#database/factories/members_factory' import { EventFactory } from '#database/factories/event_factory' import { TransactionFactory } from '#database/factories/transaction_factory' @@ -10,7 +10,7 @@ export const OrderFactory = factory status: faker.helpers.arrayElement(['pending', 'completed', 'cancelled']), } }) - .relation('takenBy', () => MembersFactory) + .relation('takenBy', () => MemberFactory) .relation('event', () => EventFactory) .relation('transaction', () => TransactionFactory) .build() diff --git a/database/factories/permission_factory.ts b/database/factories/permission_factory.ts index 6cc1485..0bf7611 100644 --- a/database/factories/permission_factory.ts +++ b/database/factories/permission_factory.ts @@ -22,14 +22,16 @@ const permissions = [ 'restock:delete', ] +let permissionIndex = 0 + export const PermissionFactory = factory - .define(Permission, async ({ index }) => { - if (index >= permissions.length) { + .define(Permission, async () => { + if (permissionIndex >= permissions.length) { throw new Error('Plus de permissions disponibles (unicité garantie)') } return { - permission: permissions[index], + permission: permissions[permissionIndex++], } }) .build() diff --git a/database/factories/restock_factory.ts b/database/factories/restock_factory.ts index 0ee86e3..8e083e6 100644 --- a/database/factories/restock_factory.ts +++ b/database/factories/restock_factory.ts @@ -1,7 +1,7 @@ import factory from '@adonisjs/lucid/factories' import Restock from '#models/restock' import { SupplierFactory } from './supplier_factory.ts' -import { MembersFactory } from './members_factory.ts' +import { MemberFactory } from './members_factory.ts' export const RestockFactory = factory .define(Restock, async ({ faker }) => { @@ -11,6 +11,6 @@ export const RestockFactory = factory supplierId: null, // Will be set by relation } }) - .relation('member', () => MembersFactory) + .relation('member', () => MemberFactory) .relation('supplier', () => SupplierFactory) .build() diff --git a/database/seeders/member_seeder.ts b/database/seeders/member_seeder.ts index d5cbebd..02adfcf 100644 --- a/database/seeders/member_seeder.ts +++ b/database/seeders/member_seeder.ts @@ -1,5 +1,5 @@ import { BaseSeeder } from '@adonisjs/lucid/seeders' -import { MembersFactory } from '#database/factories/members_factory' +import { MemberFactory } from '#database/factories/members_factory' import Role from '#models/role' export default class MemberSeeder extends BaseSeeder { @@ -12,7 +12,7 @@ export default class MemberSeeder extends BaseSeeder { const pickRoleId = () => roles[Math.floor(Math.random() * roles.length)].id - await MembersFactory.with('user') + await MemberFactory.with('user') .merge( Array.from({ length: 10 }, () => ({ roleId: pickRoleId(), diff --git a/database/seeders/restock_seeder.ts b/database/seeders/restock_seeder.ts index 5b06c80..c2bd7ea 100644 --- a/database/seeders/restock_seeder.ts +++ b/database/seeders/restock_seeder.ts @@ -1,13 +1,13 @@ import { SupplierFactory } from '#database/factories/supplier_factory' import { BaseSeeder } from '@adonisjs/lucid/seeders' import { RestockFactory } from '#database/factories/restock_factory' -import { MembersFactory } from '#database/factories/members_factory' +import { MemberFactory } from '#database/factories/members_factory' export default class extends BaseSeeder { async run() { // Write your database queries inside the run method const suppliers = await SupplierFactory.createMany(5) - const members = await MembersFactory.createMany(5) + const members = await MemberFactory.createMany(5) await RestockFactory.merge( Array.from({ length: 10 }, (_, index) => ({ From e3375451dfe10d23843f5cbad8b9a2b269c89048 Mon Sep 17 00:00:00 2001 From: Thibault LATXAGUE Date: Tue, 21 Apr 2026 10:40:10 +0200 Subject: [PATCH 38/39] Runned pnpm run format for prettier --- .adonisjs/client/data.d.ts | 5 +++++ .adonisjs/client/manifest.d.ts | 6 ++++++ .adonisjs/server/controllers.ts | 18 ++++++++++++++++++ .adonisjs/server/events.ts | 5 +++++ .adonisjs/server/listeners.ts | 5 +++++ app/controllers/fast_passes_controller.ts | 2 +- ...1773827516391_create_subscriptions_table.ts | 7 +------ database/seeders/subscription_seeder.ts | 2 +- start/routes.ts | 8 ++++++-- 9 files changed, 48 insertions(+), 10 deletions(-) diff --git a/.adonisjs/client/data.d.ts b/.adonisjs/client/data.d.ts index 3568d52..ee014a4 100644 --- a/.adonisjs/client/data.d.ts +++ b/.adonisjs/client/data.d.ts @@ -1,3 +1,8 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + /// import type { InferData, InferVariants } from '@adonisjs/core/types/transformers' import type UserTransformer from '#transformers/user_transformer' diff --git a/.adonisjs/client/manifest.d.ts b/.adonisjs/client/manifest.d.ts index 5845626..158e306 100644 --- a/.adonisjs/client/manifest.d.ts +++ b/.adonisjs/client/manifest.d.ts @@ -1,4 +1,10 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + /// /// /// +/// /// diff --git a/.adonisjs/server/controllers.ts b/.adonisjs/server/controllers.ts index f7f61b6..9abefc8 100644 --- a/.adonisjs/server/controllers.ts +++ b/.adonisjs/server/controllers.ts @@ -1,5 +1,23 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + export const controllers = { AccessToken: () => import('#controllers/access_token_controller'), + Categories: () => import('#controllers/categories_controller'), + FastPasses: () => import('#controllers/fast_passes_controller'), + Furnitures: () => import('#controllers/furnitures_controller'), + Goods: () => import('#controllers/goods_controller'), + Logs: () => import('#controllers/logs_controller'), + Members: () => import('#controllers/members_controller'), NewAccount: () => import('#controllers/new_account_controller'), + Permissions: () => import('#controllers/permissions_controller'), + Products: () => import('#controllers/products_controller'), Profile: () => import('#controllers/profile_controller'), + Restocks: () => import('#controllers/restocks_controller'), + Roles: () => import('#controllers/roles_controller'), + StockBatches: () => import('#controllers/stock_batches_controller'), + StockMovements: () => import('#controllers/stock_movements_controller'), + Suppliers: () => import('#controllers/suppliers_controller'), } diff --git a/.adonisjs/server/events.ts b/.adonisjs/server/events.ts index a7ab473..a74e59b 100644 --- a/.adonisjs/server/events.ts +++ b/.adonisjs/server/events.ts @@ -1 +1,6 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + export const events = {} diff --git a/.adonisjs/server/listeners.ts b/.adonisjs/server/listeners.ts index 28cbf66..05f35f8 100644 --- a/.adonisjs/server/listeners.ts +++ b/.adonisjs/server/listeners.ts @@ -1 +1,6 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + export const listeners = {} diff --git a/app/controllers/fast_passes_controller.ts b/app/controllers/fast_passes_controller.ts index 098d868..9ec8b47 100644 --- a/app/controllers/fast_passes_controller.ts +++ b/app/controllers/fast_passes_controller.ts @@ -51,4 +51,4 @@ export default class FastPassesController { const fastPass = await FastPass.query().where('id', params.id).firstOrFail() await fastPass.delete() } -} \ No newline at end of file +} diff --git a/database/migrations/1773827516391_create_subscriptions_table.ts b/database/migrations/1773827516391_create_subscriptions_table.ts index a773ceb..1e9777b 100644 --- a/database/migrations/1773827516391_create_subscriptions_table.ts +++ b/database/migrations/1773827516391_create_subscriptions_table.ts @@ -6,12 +6,7 @@ export default class extends BaseSchema { async up() { this.schema.createTable(this.tableName, (table) => { table.timestamp('subscribed_at').notNullable() - table - .integer('user_id') - .unsigned() - .references('id') - .inTable('users') - .onDelete('CASCADE') + table.integer('user_id').unsigned().references('id').inTable('users').onDelete('CASCADE') table .integer('fast_pass_id') .unsigned() diff --git a/database/seeders/subscription_seeder.ts b/database/seeders/subscription_seeder.ts index 5716f5f..0e3d5e3 100644 --- a/database/seeders/subscription_seeder.ts +++ b/database/seeders/subscription_seeder.ts @@ -19,4 +19,4 @@ export default class extends BaseSeeder { }) } } -} \ No newline at end of file +} diff --git a/start/routes.ts b/start/routes.ts index 90d9153..b1b8c4c 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -24,8 +24,12 @@ router router.resource('goods', () => import('#controllers/goods_controller')).apiOnly() router.resource('suppliers', () => import('#controllers/suppliers_controller')).apiOnly() router.resource('restocks', () => import('#controllers/restocks_controller')).apiOnly() - router.resource('stock-batches', () => import('#controllers/stock_batches_controller')).apiOnly() - router.resource('stock-movements', () => import('#controllers/stock_movements_controller')).apiOnly() + router + .resource('stock-batches', () => import('#controllers/stock_batches_controller')) + .apiOnly() + router + .resource('stock-movements', () => import('#controllers/stock_movements_controller')) + .apiOnly() router.resource('logs', () => import('#controllers/logs_controller')).apiOnly() router.resource('roles', () => import('#controllers/roles_controller')).apiOnly() router.resource('permissions', () => import('#controllers/permissions_controller')).apiOnly() From 04294c4ea118e31a2307c9db42fb03acc0b6deb5 Mon Sep 17 00:00:00 2001 From: Thibault Latxague <151643951+ThibaultLatxague@users.noreply.github.com> Date: Thu, 30 Apr 2026 09:18:15 +0200 Subject: [PATCH 39/39] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/controllers/roles_controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/roles_controller.ts b/app/controllers/roles_controller.ts index 03137b1..a7c9659 100644 --- a/app/controllers/roles_controller.ts +++ b/app/controllers/roles_controller.ts @@ -23,7 +23,7 @@ export default class RolesController { * Show individual record */ async show({ params }: HttpContext) { - const role = await Role.find(params.id) + const role = await Role.findOrFail(params.id) return role }