Merge pull request 'new feautres implemnted' (#2) from ali into dev

Reviewed-on: https://gitea.maskantech.in/gitea_admin/productcatalogue_backend/pulls/2
This commit is contained in:
liyaqath
2026-07-08 06:10:17 +00:00
140 changed files with 650 additions and 6089 deletions
@@ -1,30 +0,0 @@
{
"keep": {
"days": true,
"amount": 14
},
"auditLog": "logs\\.3fa4d5e91883ce1217f62a49f94203b42caa131d-audit.json",
"files": [
{
"date": 1782885016196,
"name": "logs\\combined-2026-07-01.log",
"hash": "62273be471fbf03240935eebb5eaf8487e7a3002b6cced421c983245646bc21a"
},
{
"date": 1782968983048,
"name": "logs\\combined-2026-07-02.log",
"hash": "10138c0f35436a800870f14a317b542645e7976bcd44030300d436a715a20c36"
},
{
"date": 1783058300242,
"name": "logs\\combined-2026-07-03.log",
"hash": "a0e79e7be8f5ef13f7e6e8483c8bb663b1c7ddeb1eaa188152cda3f015df5203"
},
{
"date": 1783142857411,
"name": "logs\\combined-2026-07-04.log",
"hash": "df5726dddf64ecbb358dc871efc7f6fa558f95b33fec683e6eef801c4d9f7e4a"
}
],
"hashType": "sha256"
}
@@ -1,30 +0,0 @@
{
"keep": {
"days": true,
"amount": 14
},
"auditLog": "logs\\.944c2a6e38c8046075bb4cb64c11b1f8d919853c-audit.json",
"files": [
{
"date": 1782885016194,
"name": "logs\\error-2026-07-01.log",
"hash": "3dc68d8ca2e67e313b2363c163e011da72b07deaf5d0f5736607ec0850b50e9b"
},
{
"date": 1782968983045,
"name": "logs\\error-2026-07-02.log",
"hash": "bf64fe21cbfba23af08772bef924ee896b52bcbf80bb4e87b6f7c5fb125e38aa"
},
{
"date": 1783058300224,
"name": "logs\\error-2026-07-03.log",
"hash": "9d7b2b6bae80886841b6c099d2312d2fe37fd6e58d4eb934668e9c62e4e38bc1"
},
{
"date": 1783142857406,
"name": "logs\\error-2026-07-04.log",
"hash": "7d2caa5cd525a8a119155e3c48baeded2d8741b61d934b266de04b9140095740"
}
],
"hashType": "sha256"
}
-7
View File
@@ -2346,13 +2346,6 @@
"fn.name": "1.x.x"
}
},
"node_modules/openapi-types": {
"version": "12.1.3",
"resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz",
"integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==",
"license": "MIT",
"peer": true
},
"node_modules/package-json-from-dist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+2
View File
@@ -7,6 +7,8 @@
"scripts": {
"start": "cross-env NODE_ENV=production node index.js",
"dev": "cross-env NODE_ENV=development nodemon index.js",
"test": "cross-env NODE_ENV=test nodemon index.js",
"local": "cross-env NODE_ENV=local nodemon index.js",
"start:local": "cross-env NODE_ENV=local nodemon index.js",
"db:migrate:local": "cross-env NODE_ENV=local sequelize-cli db:migrate --config src/shared/config/database.config.cjs --migrations-path src/migrations --models-path src/shared/database",
"db:seed:local": "cross-env NODE_ENV=local sequelize-cli db:seed:all --config src/shared/config/database.config.cjs --seeders-path src/seeders --models-path src/shared/database",
@@ -5,6 +5,20 @@ import { authorize } from '../../../shared/middleware/permission.middleware.js';
const router = Router();
/**
* @swagger
* /api/v1/roles:
* get:
* summary: Retrieve all roles
* tags: [Roles]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Success
* 401:
* description: Unauthorized
*/
router.get(
'/',
authenticate,
@@ -12,6 +26,24 @@ router.get(
controller.getAll
);
/**
* @swagger
* /api/v1/roles/by-tenant/{tenantId}:
* get:
* summary: Retrieve roles by tenant
* tags: [Roles]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: tenantId
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/by-tenant/:tenantId',
authenticate,
@@ -19,6 +51,18 @@ router.get(
controller.getByTenant
);
/**
* @swagger
* /api/v1/roles/permissions:
* get:
* summary: Retrieve all permission nodes
* tags: [Roles]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Success
*/
router.get(
'/permissions',
authenticate,
@@ -26,6 +70,26 @@ router.get(
controller.getPermissions
);
/**
* @swagger
* /api/v1/roles/{id}:
* get:
* summary: Retrieve a single role
* tags: [Roles]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
* 404:
* description: Not Found
*/
router.get(
'/:id',
authenticate,
@@ -33,6 +97,32 @@ router.get(
controller.getById
);
/**
* @swagger
* /api/v1/roles:
* post:
* summary: Create a new role
* tags: [Roles]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [name]
* properties:
* name:
* type: string
* permissions:
* type: array
* items:
* type: string
* responses:
* 201:
* description: Created
*/
router.post(
'/',
authenticate,
@@ -40,6 +130,24 @@ router.post(
controller.create
);
/**
* @swagger
* /api/v1/roles/{id}:
* put:
* summary: Update a role
* tags: [Roles]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
@@ -47,6 +155,24 @@ router.put(
controller.update
);
/**
* @swagger
* /api/v1/roles/{id}:
* delete:
* summary: Delete a role
* tags: [Roles]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Deleted
*/
router.delete(
'/:id',
authenticate,
@@ -5,6 +5,20 @@ import { authorize } from '../../../shared/middleware/permission.middleware.js';
const router = Router();
/**
* @swagger
* /api/v1/users:
* get:
* summary: Retrieve all users
* tags: [Users]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Success
* 401:
* description: Unauthorized
*/
router.get(
'/',
authenticate,
@@ -12,6 +26,26 @@ router.get(
controller.getAll
);
/**
* @swagger
* /api/v1/users/{id}:
* get:
* summary: Retrieve a single user
* tags: [Users]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
* 404:
* description: Not Found
*/
router.get(
'/:id',
authenticate,
@@ -19,6 +53,32 @@ router.get(
controller.getById
);
/**
* @swagger
* /api/v1/users/invite:
* post:
* summary: Invite a new user
* tags: [Users]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [email, role_id]
* properties:
* email:
* type: string
* role_id:
* type: string
* responses:
* 201:
* description: Invitation sent
* 400:
* description: Validation Error
*/
router.post(
'/invite',
authenticate,
@@ -26,6 +86,24 @@ router.post(
controller.invite
);
/**
* @swagger
* /api/v1/users/{id}:
* put:
* summary: Update a user
* tags: [Users]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
@@ -33,6 +111,24 @@ router.put(
controller.update
);
/**
* @swagger
* /api/v1/users/{id}:
* delete:
* summary: Delete a user
* tags: [Users]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Deleted
*/
router.delete(
'/:id',
authenticate,
-18
View File
@@ -7,20 +7,11 @@ import categoriesRouter from './categories/index.js';
import brandsRouter from './brands/index.js';
import attributesRouter from './attributes/index.js';
import mediaRouter from './media/index.js';
import pricingRouter from './pricing/index.js';
import inventoryRouter from './inventory/index.js';
import suppliersRouter from './suppliers/index.js';
import localizationRouter from './localization/index.js';
import workflowsRouter from './workflows/index.js';
import integrationsRouter from './integrations/index.js';
import channelsRouter from './channels/index.js';
import importsRouter from './imports/index.js';
import exportsRouter from './exports/index.js';
import notificationsRouter from './notifications/index.js';
import reportsRouter from './reports/index.js';
import settingsRouter from './settings/index.js';
import auditLogsRouter from './auditLogs/index.js';
import unitsRouter from './units/index.js';
export default function registerRoutes(app) {
app.use('/api/v1', authenticationRouter);
@@ -32,18 +23,9 @@ export default function registerRoutes(app) {
app.use('/api/v1', brandsRouter);
app.use('/api/v1', attributesRouter);
app.use('/api/v1', mediaRouter);
app.use('/api/v1', pricingRouter);
app.use('/api/v1', inventoryRouter);
app.use('/api/v1', suppliersRouter);
app.use('/api/v1', localizationRouter);
app.use('/api/v1', workflowsRouter);
app.use('/api/v1', integrationsRouter);
app.use('/api/v1', channelsRouter);
app.use('/api/v1', importsRouter);
app.use('/api/v1', exportsRouter);
app.use('/api/v1', notificationsRouter);
app.use('/api/v1', reportsRouter);
app.use('/api/v1', settingsRouter);
app.use('/api/v1', auditLogsRouter);
app.use('/api/v1', unitsRouter);
}
-8
View File
@@ -1,8 +0,0 @@
import { Router } from 'express';
import integrationsRouter from './integrations/integration.routes.js';
const router = Router();
router.use('/integrations', integrationsRouter);
export default router;
@@ -1,5 +0,0 @@
export { default as integrationRoutes } from './integration.routes.js';
export { default as integrationController } from './integration.controller.js';
export { default as integrationService } from './integration.service.js';
export { default as integrationRepository } from './integration.repository.js';
export { default as integrationModel } from './integration.model.js';
@@ -1,50 +0,0 @@
import service from './integration.service.js';
export class IntegrationController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'Integration deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new IntegrationController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class Integration extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
Integration.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'Integration',
tableName: 'integrations',
timestamps: true,
underscored: true
});
return Integration;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class IntegrationRepository {
async findAll(options = {}) {
return await models.Integration.findAll(options);
}
async findById(id, options = {}) {
return await models.Integration.findByPk(id, options);
}
async create(data, options = {}) {
return await models.Integration.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new IntegrationRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './integration.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './integration.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/integrations:
* get:
* summary: Retrieve all integrations
* tags: [Integrations]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:integrations']),
controller.getAll
);
/**
* @swagger
* /api/v1/integrations/{id}:
* get:
* summary: Retrieve a single integration
* tags: [Integrations]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:integrations']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/integrations:
* post:
* summary: Create a integration
* tags: [Integrations]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:integrations']),
createValidation,
validate,
audit('CREATE_INTEGRATION'),
controller.create
);
/**
* @swagger
* /api/v1/integrations/{id}:
* put:
* summary: Update a integration
* tags: [Integrations]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:integrations']),
updateValidation,
validate,
audit('UPDATE_INTEGRATION'),
controller.update
);
/**
* @swagger
* /api/v1/integrations/{id}:
* delete:
* summary: Delete a integration
* tags: [Integrations]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:integrations']),
deleteValidation,
validate,
audit('DELETE_INTEGRATION'),
controller.delete
);
export default router;
@@ -1,75 +0,0 @@
import repository from './integration.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class IntegrationService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('Integration not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('integration:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'Integration',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('Integration not found');
}
SocketService.broadcast('integration:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'Integration',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('Integration not found');
}
SocketService.broadcast('integration:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'Integration',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new IntegrationService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
-8
View File
@@ -1,8 +0,0 @@
import { Router } from 'express';
import inventoryRouter from './inventory/inventory.routes.js';
const router = Router();
router.use('/inventory', inventoryRouter);
export default router;
@@ -1,5 +0,0 @@
export { default as inventoryRoutes } from './inventory.routes.js';
export { default as inventoryController } from './inventory.controller.js';
export { default as inventoryService } from './inventory.service.js';
export { default as inventoryRepository } from './inventory.repository.js';
export { default as inventoryModel } from './inventory.model.js';
@@ -1,50 +0,0 @@
import service from './inventory.service.js';
export class InventoryController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'Inventory deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new InventoryController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class Inventory extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
Inventory.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'Inventory',
tableName: 'inventorys',
timestamps: true,
underscored: true
});
return Inventory;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class InventoryRepository {
async findAll(options = {}) {
return await models.Inventory.findAll(options);
}
async findById(id, options = {}) {
return await models.Inventory.findByPk(id, options);
}
async create(data, options = {}) {
return await models.Inventory.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new InventoryRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './inventory.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './inventory.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/inventorys:
* get:
* summary: Retrieve all inventorys
* tags: [Inventorys]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:inventorys']),
controller.getAll
);
/**
* @swagger
* /api/v1/inventorys/{id}:
* get:
* summary: Retrieve a single inventory
* tags: [Inventorys]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:inventorys']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/inventorys:
* post:
* summary: Create a inventory
* tags: [Inventorys]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:inventorys']),
createValidation,
validate,
audit('CREATE_INVENTORY'),
controller.create
);
/**
* @swagger
* /api/v1/inventorys/{id}:
* put:
* summary: Update a inventory
* tags: [Inventorys]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:inventorys']),
updateValidation,
validate,
audit('UPDATE_INVENTORY'),
controller.update
);
/**
* @swagger
* /api/v1/inventorys/{id}:
* delete:
* summary: Delete a inventory
* tags: [Inventorys]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:inventorys']),
deleteValidation,
validate,
audit('DELETE_INVENTORY'),
controller.delete
);
export default router;
@@ -1,76 +0,0 @@
import repository from './inventory.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
import { ApiError } from '../../../utils/helpers/ApiError.utils.js';
export class InventoryService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new ApiError(404, 'Inventory not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('inventory:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'Inventory',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new ApiError(404, 'Inventory not found');
}
SocketService.broadcast('inventory:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'Inventory',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new ApiError(404, 'Inventory not found');
}
SocketService.broadcast('inventory:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'Inventory',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new InventoryService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
-8
View File
@@ -1,8 +0,0 @@
import { Router } from 'express';
import localizationRouter from './localization/localization.routes.js';
const router = Router();
router.use('/localization', localizationRouter);
export default router;
@@ -1,5 +0,0 @@
export { default as localizationRoutes } from './localization.routes.js';
export { default as localizationController } from './localization.controller.js';
export { default as localizationService } from './localization.service.js';
export { default as localizationRepository } from './localization.repository.js';
export { default as localizationModel } from './localization.model.js';
@@ -1,50 +0,0 @@
import service from './localization.service.js';
export class LocalizationController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'Localization deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new LocalizationController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class Localization extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
Localization.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'Localization',
tableName: 'localizations',
timestamps: true,
underscored: true
});
return Localization;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class LocalizationRepository {
async findAll(options = {}) {
return await models.Localization.findAll(options);
}
async findById(id, options = {}) {
return await models.Localization.findByPk(id, options);
}
async create(data, options = {}) {
return await models.Localization.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new LocalizationRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './localization.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './localization.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/localizations:
* get:
* summary: Retrieve all localizations
* tags: [Localizations]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:localizations']),
controller.getAll
);
/**
* @swagger
* /api/v1/localizations/{id}:
* get:
* summary: Retrieve a single localization
* tags: [Localizations]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:localizations']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/localizations:
* post:
* summary: Create a localization
* tags: [Localizations]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:localizations']),
createValidation,
validate,
audit('CREATE_LOCALIZATION'),
controller.create
);
/**
* @swagger
* /api/v1/localizations/{id}:
* put:
* summary: Update a localization
* tags: [Localizations]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:localizations']),
updateValidation,
validate,
audit('UPDATE_LOCALIZATION'),
controller.update
);
/**
* @swagger
* /api/v1/localizations/{id}:
* delete:
* summary: Delete a localization
* tags: [Localizations]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:localizations']),
deleteValidation,
validate,
audit('DELETE_LOCALIZATION'),
controller.delete
);
export default router;
@@ -1,75 +0,0 @@
import repository from './localization.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class LocalizationService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('Localization not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('localization:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'Localization',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('Localization not found');
}
SocketService.broadcast('localization:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'Localization',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('Localization not found');
}
SocketService.broadcast('localization:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'Localization',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new LocalizationService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
@@ -13,6 +13,20 @@ import {
const router = Router();
/**
* @swagger
* /api/v1/asset-families:
* get:
* summary: Retrieve all asset families
* tags: [Asset Families]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Success
* 401:
* description: Unauthorized
*/
router.get(
'/',
authenticate,
@@ -20,6 +34,26 @@ router.get(
controller.getAll
);
/**
* @swagger
* /api/v1/asset-families/{id}:
* get:
* summary: Retrieve a single asset family
* tags: [Asset Families]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
* 404:
* description: Not Found
*/
router.get(
'/:id',
authenticate,
@@ -29,6 +63,30 @@ router.get(
controller.getById
);
/**
* @swagger
* /api/v1/asset-families:
* post:
* summary: Create a new asset family
* tags: [Asset Families]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [name]
* properties:
* name:
* type: string
* responses:
* 201:
* description: Created
* 400:
* description: Validation Error
*/
router.post(
'/',
authenticate,
@@ -39,6 +97,35 @@ router.post(
controller.create
);
/**
* @swagger
* /api/v1/asset-families/{id}:
* put:
* summary: Update an asset family
* tags: [Asset Families]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* responses:
* 200:
* description: Success
* 404:
* description: Not Found
*/
router.put(
'/:id',
authenticate,
@@ -49,6 +136,26 @@ router.put(
controller.update
);
/**
* @swagger
* /api/v1/asset-families/{id}:
* delete:
* summary: Delete an asset family
* tags: [Asset Families]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Deleted
* 404:
* description: Not Found
*/
router.delete(
'/:id',
authenticate,
@@ -13,6 +13,20 @@ import {
const router = Router();
/**
* @swagger
* /api/v1/asset-types:
* get:
* summary: Retrieve all asset types
* tags: [Asset Types]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Success
* 401:
* description: Unauthorized
*/
router.get(
'/',
authenticate,
@@ -20,6 +34,26 @@ router.get(
controller.getAll
);
/**
* @swagger
* /api/v1/asset-types/{id}:
* get:
* summary: Retrieve a single asset type
* tags: [Asset Types]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
* 404:
* description: Not Found
*/
router.get(
'/:id',
authenticate,
@@ -29,6 +63,30 @@ router.get(
controller.getById
);
/**
* @swagger
* /api/v1/asset-types:
* post:
* summary: Create a new asset type
* tags: [Asset Types]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [name]
* properties:
* name:
* type: string
* responses:
* 201:
* description: Created
* 400:
* description: Validation Error
*/
router.post(
'/',
authenticate,
@@ -39,6 +97,35 @@ router.post(
controller.create
);
/**
* @swagger
* /api/v1/asset-types/{id}:
* put:
* summary: Update an asset type
* tags: [Asset Types]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* responses:
* 200:
* description: Success
* 404:
* description: Not Found
*/
router.put(
'/:id',
authenticate,
@@ -49,6 +136,26 @@ router.put(
controller.update
);
/**
* @swagger
* /api/v1/asset-types/{id}:
* delete:
* summary: Delete an asset type
* tags: [Asset Types]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Deleted
* 404:
* description: Not Found
*/
router.delete(
'/:id',
authenticate,
+107
View File
@@ -13,6 +13,20 @@ import {
const router = Router();
/**
* @swagger
* /api/v1/assets:
* get:
* summary: Retrieve all assets
* tags: [Assets]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Success
* 401:
* description: Unauthorized
*/
router.get(
'/',
authenticate,
@@ -20,6 +34,26 @@ router.get(
controller.getAll
);
/**
* @swagger
* /api/v1/assets/{id}:
* get:
* summary: Retrieve a single asset
* tags: [Assets]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
* 404:
* description: Not Found
*/
router.get(
'/:id',
authenticate,
@@ -29,6 +63,30 @@ router.get(
controller.getById
);
/**
* @swagger
* /api/v1/assets:
* post:
* summary: Create a new asset
* tags: [Assets]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [name]
* properties:
* name:
* type: string
* responses:
* 201:
* description: Created
* 400:
* description: Validation Error
*/
router.post(
'/',
authenticate,
@@ -39,6 +97,35 @@ router.post(
controller.create
);
/**
* @swagger
* /api/v1/assets/{id}:
* put:
* summary: Update an asset
* tags: [Assets]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* name:
* type: string
* responses:
* 200:
* description: Success
* 404:
* description: Not Found
*/
router.put(
'/:id',
authenticate,
@@ -49,6 +136,26 @@ router.put(
controller.update
);
/**
* @swagger
* /api/v1/assets/{id}:
* delete:
* summary: Delete an asset
* tags: [Assets]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Deleted
* 404:
* description: Not Found
*/
router.delete(
'/:id',
authenticate,
-8
View File
@@ -1,8 +0,0 @@
import { Router } from 'express';
import notificationsRouter from './notifications/notification.routes.js';
const router = Router();
router.use('/notifications', notificationsRouter);
export default router;
@@ -1,5 +0,0 @@
export { default as notificationRoutes } from './notification.routes.js';
export { default as notificationController } from './notification.controller.js';
export { default as notificationService } from './notification.service.js';
export { default as notificationRepository } from './notification.repository.js';
export { default as notificationModel } from './notification.model.js';
@@ -1,50 +0,0 @@
import service from './notification.service.js';
export class NotificationController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'Notification deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new NotificationController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class Notification extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
Notification.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'Notification',
tableName: 'notifications',
timestamps: true,
underscored: true
});
return Notification;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class NotificationRepository {
async findAll(options = {}) {
return await models.Notification.findAll(options);
}
async findById(id, options = {}) {
return await models.Notification.findByPk(id, options);
}
async create(data, options = {}) {
return await models.Notification.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new NotificationRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './notification.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './notification.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/notifications:
* get:
* summary: Retrieve all notifications
* tags: [Notifications]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:notifications']),
controller.getAll
);
/**
* @swagger
* /api/v1/notifications/{id}:
* get:
* summary: Retrieve a single notification
* tags: [Notifications]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:notifications']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/notifications:
* post:
* summary: Create a notification
* tags: [Notifications]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:notifications']),
createValidation,
validate,
audit('CREATE_NOTIFICATION'),
controller.create
);
/**
* @swagger
* /api/v1/notifications/{id}:
* put:
* summary: Update a notification
* tags: [Notifications]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:notifications']),
updateValidation,
validate,
audit('UPDATE_NOTIFICATION'),
controller.update
);
/**
* @swagger
* /api/v1/notifications/{id}:
* delete:
* summary: Delete a notification
* tags: [Notifications]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:notifications']),
deleteValidation,
validate,
audit('DELETE_NOTIFICATION'),
controller.delete
);
export default router;
@@ -1,75 +0,0 @@
import repository from './notification.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class NotificationService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('Notification not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('notification:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'Notification',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('Notification not found');
}
SocketService.broadcast('notification:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'Notification',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('Notification not found');
}
SocketService.broadcast('notification:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'Notification',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new NotificationService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
@@ -5,6 +5,20 @@ import { authorize } from '../../../shared/middleware/permission.middleware.js';
const router = Router();
/**
* @swagger
* /api/v1/tenants:
* get:
* summary: Retrieve all tenants
* tags: [Tenants]
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Success
* 401:
* description: Unauthorized
*/
router.get(
'/',
authenticate,
@@ -12,6 +26,26 @@ router.get(
controller.getAll
);
/**
* @swagger
* /api/v1/tenants/{id}:
* get:
* summary: Retrieve a single tenant
* tags: [Tenants]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
* 404:
* description: Not Found
*/
router.get(
'/:id',
authenticate,
@@ -19,6 +53,32 @@ router.get(
controller.getById
);
/**
* @swagger
* /api/v1/tenants:
* post:
* summary: Create a new tenant
* tags: [Tenants]
* security:
* - bearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [name, domain]
* properties:
* name:
* type: string
* domain:
* type: string
* responses:
* 201:
* description: Created
* 400:
* description: Validation Error
*/
router.post(
'/',
authenticate,
@@ -26,6 +86,24 @@ router.post(
controller.create
);
/**
* @swagger
* /api/v1/tenants/{id}:
* put:
* summary: Update a tenant
* tags: [Tenants]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
@@ -33,6 +111,24 @@ router.put(
controller.update
);
/**
* @swagger
* /api/v1/tenants/{id}:
* delete:
* summary: Delete a tenant
* tags: [Tenants]
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Deleted
*/
router.delete(
'/:id',
authenticate,
-8
View File
@@ -1,8 +0,0 @@
import { Router } from 'express';
import pricingRouter from './pricing/pricing.routes.js';
const router = Router();
router.use('/pricing', pricingRouter);
export default router;
-5
View File
@@ -1,5 +0,0 @@
export { default as pricingRoutes } from './pricing.routes.js';
export { default as pricingController } from './pricing.controller.js';
export { default as pricingService } from './pricing.service.js';
export { default as pricingRepository } from './pricing.repository.js';
export { default as pricingModel } from './pricing.model.js';
@@ -1,50 +0,0 @@
import service from './pricing.service.js';
export class PricingController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'Pricing deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new PricingController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class Pricing extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
Pricing.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'Pricing',
tableName: 'pricings',
timestamps: true,
underscored: true
});
return Pricing;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class PricingRepository {
async findAll(options = {}) {
return await models.Pricing.findAll(options);
}
async findById(id, options = {}) {
return await models.Pricing.findByPk(id, options);
}
async create(data, options = {}) {
return await models.Pricing.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new PricingRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './pricing.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './pricing.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/pricings:
* get:
* summary: Retrieve all pricings
* tags: [Pricings]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:pricings']),
controller.getAll
);
/**
* @swagger
* /api/v1/pricings/{id}:
* get:
* summary: Retrieve a single pricing
* tags: [Pricings]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:pricings']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/pricings:
* post:
* summary: Create a pricing
* tags: [Pricings]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:pricings']),
createValidation,
validate,
audit('CREATE_PRICING'),
controller.create
);
/**
* @swagger
* /api/v1/pricings/{id}:
* put:
* summary: Update a pricing
* tags: [Pricings]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:pricings']),
updateValidation,
validate,
audit('UPDATE_PRICING'),
controller.update
);
/**
* @swagger
* /api/v1/pricings/{id}:
* delete:
* summary: Delete a pricing
* tags: [Pricings]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:pricings']),
deleteValidation,
validate,
audit('DELETE_PRICING'),
controller.delete
);
export default router;
@@ -1,75 +0,0 @@
import repository from './pricing.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class PricingService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('Pricing not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('pricing:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'Pricing',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('Pricing not found');
}
SocketService.broadcast('pricing:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'Pricing',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('Pricing not found');
}
SocketService.broadcast('pricing:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'Pricing',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new PricingService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
@@ -1,50 +0,0 @@
import service from './approval.service.js';
export class ApprovalController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'Approval deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new ApprovalController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class Approval extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
Approval.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'Approval',
tableName: 'approvals',
timestamps: true,
underscored: true
});
return Approval;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class ApprovalRepository {
async findAll(options = {}) {
return await models.Approval.findAll(options);
}
async findById(id, options = {}) {
return await models.Approval.findByPk(id, options);
}
async create(data, options = {}) {
return await models.Approval.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new ApprovalRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './approval.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './approval.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/approvals:
* get:
* summary: Retrieve all approvals
* tags: [Approvals]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:approvals']),
controller.getAll
);
/**
* @swagger
* /api/v1/approvals/{id}:
* get:
* summary: Retrieve a single approval
* tags: [Approvals]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:approvals']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/approvals:
* post:
* summary: Create a approval
* tags: [Approvals]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:approvals']),
createValidation,
validate,
audit('CREATE_APPROVAL'),
controller.create
);
/**
* @swagger
* /api/v1/approvals/{id}:
* put:
* summary: Update a approval
* tags: [Approvals]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:approvals']),
updateValidation,
validate,
audit('UPDATE_APPROVAL'),
controller.update
);
/**
* @swagger
* /api/v1/approvals/{id}:
* delete:
* summary: Delete a approval
* tags: [Approvals]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:approvals']),
deleteValidation,
validate,
audit('DELETE_APPROVAL'),
controller.delete
);
export default router;
@@ -1,75 +0,0 @@
import repository from './approval.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class ApprovalService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('Approval not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('approval:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'Approval',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('Approval not found');
}
SocketService.broadcast('approval:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'Approval',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('Approval not found');
}
SocketService.broadcast('approval:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'Approval',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new ApprovalService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
-5
View File
@@ -1,5 +0,0 @@
export { default as approvalRoutes } from './approval.routes.js';
export { default as approvalController } from './approval.controller.js';
export { default as approvalService } from './approval.service.js';
export { default as approvalRepository } from './approval.repository.js';
export { default as approvalModel } from './approval.model.js';
@@ -1,50 +0,0 @@
import service from './bundle.service.js';
export class BundleController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'Bundle deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new BundleController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class Bundle extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
Bundle.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'Bundle',
tableName: 'bundles',
timestamps: true,
underscored: true
});
return Bundle;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class BundleRepository {
async findAll(options = {}) {
return await models.Bundle.findAll(options);
}
async findById(id, options = {}) {
return await models.Bundle.findByPk(id, options);
}
async create(data, options = {}) {
return await models.Bundle.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new BundleRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './bundle.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './bundle.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/bundles:
* get:
* summary: Retrieve all bundles
* tags: [Bundles]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:bundles']),
controller.getAll
);
/**
* @swagger
* /api/v1/bundles/{id}:
* get:
* summary: Retrieve a single bundle
* tags: [Bundles]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:bundles']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/bundles:
* post:
* summary: Create a bundle
* tags: [Bundles]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:bundles']),
createValidation,
validate,
audit('CREATE_BUNDLE'),
controller.create
);
/**
* @swagger
* /api/v1/bundles/{id}:
* put:
* summary: Update a bundle
* tags: [Bundles]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:bundles']),
updateValidation,
validate,
audit('UPDATE_BUNDLE'),
controller.update
);
/**
* @swagger
* /api/v1/bundles/{id}:
* delete:
* summary: Delete a bundle
* tags: [Bundles]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:bundles']),
deleteValidation,
validate,
audit('DELETE_BUNDLE'),
controller.delete
);
export default router;
@@ -1,75 +0,0 @@
import repository from './bundle.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class BundleService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('Bundle not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('bundle:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'Bundle',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('Bundle not found');
}
SocketService.broadcast('bundle:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'Bundle',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('Bundle not found');
}
SocketService.broadcast('bundle:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'Bundle',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new BundleService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
-5
View File
@@ -1,5 +0,0 @@
export { default as bundleRoutes } from './bundle.routes.js';
export { default as bundleController } from './bundle.controller.js';
export { default as bundleService } from './bundle.service.js';
export { default as bundleRepository } from './bundle.repository.js';
export { default as bundleModel } from './bundle.model.js';
@@ -1,50 +0,0 @@
import service from './configurableProduct.service.js';
export class ConfigurableProductController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'ConfigurableProduct deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new ConfigurableProductController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class ConfigurableProduct extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
ConfigurableProduct.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'ConfigurableProduct',
tableName: 'configurableproducts',
timestamps: true,
underscored: true
});
return ConfigurableProduct;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class ConfigurableProductRepository {
async findAll(options = {}) {
return await models.ConfigurableProduct.findAll(options);
}
async findById(id, options = {}) {
return await models.ConfigurableProduct.findByPk(id, options);
}
async create(data, options = {}) {
return await models.ConfigurableProduct.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new ConfigurableProductRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './configurableProduct.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './configurableProduct.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/configurableProducts:
* get:
* summary: Retrieve all configurableProducts
* tags: [ConfigurableProducts]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:configurableProducts']),
controller.getAll
);
/**
* @swagger
* /api/v1/configurableProducts/{id}:
* get:
* summary: Retrieve a single configurableProduct
* tags: [ConfigurableProducts]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:configurableProducts']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/configurableProducts:
* post:
* summary: Create a configurableProduct
* tags: [ConfigurableProducts]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:configurableProducts']),
createValidation,
validate,
audit('CREATE_CONFIGURABLEPRODUCT'),
controller.create
);
/**
* @swagger
* /api/v1/configurableProducts/{id}:
* put:
* summary: Update a configurableProduct
* tags: [ConfigurableProducts]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:configurableProducts']),
updateValidation,
validate,
audit('UPDATE_CONFIGURABLEPRODUCT'),
controller.update
);
/**
* @swagger
* /api/v1/configurableProducts/{id}:
* delete:
* summary: Delete a configurableProduct
* tags: [ConfigurableProducts]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:configurableProducts']),
deleteValidation,
validate,
audit('DELETE_CONFIGURABLEPRODUCT'),
controller.delete
);
export default router;
@@ -1,75 +0,0 @@
import repository from './configurableProduct.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class ConfigurableProductService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('ConfigurableProduct not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('configurableProduct:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'ConfigurableProduct',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('ConfigurableProduct not found');
}
SocketService.broadcast('configurableProduct:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'ConfigurableProduct',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('ConfigurableProduct not found');
}
SocketService.broadcast('configurableProduct:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'ConfigurableProduct',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new ConfigurableProductService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
@@ -1,5 +0,0 @@
export { default as configurableProductRoutes } from './configurableProduct.routes.js';
export { default as configurableProductController } from './configurableProduct.controller.js';
export { default as configurableProductService } from './configurableProduct.service.js';
export { default as configurableProductRepository } from './configurableProduct.repository.js';
export { default as configurableProductModel } from './configurableProduct.model.js';
@@ -1,50 +0,0 @@
import service from './digitalProduct.service.js';
export class DigitalProductController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'DigitalProduct deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new DigitalProductController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class DigitalProduct extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
DigitalProduct.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'DigitalProduct',
tableName: 'digitalproducts',
timestamps: true,
underscored: true
});
return DigitalProduct;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class DigitalProductRepository {
async findAll(options = {}) {
return await models.DigitalProduct.findAll(options);
}
async findById(id, options = {}) {
return await models.DigitalProduct.findByPk(id, options);
}
async create(data, options = {}) {
return await models.DigitalProduct.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new DigitalProductRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './digitalProduct.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './digitalProduct.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/digitalProducts:
* get:
* summary: Retrieve all digitalProducts
* tags: [DigitalProducts]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:digitalProducts']),
controller.getAll
);
/**
* @swagger
* /api/v1/digitalProducts/{id}:
* get:
* summary: Retrieve a single digitalProduct
* tags: [DigitalProducts]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:digitalProducts']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/digitalProducts:
* post:
* summary: Create a digitalProduct
* tags: [DigitalProducts]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:digitalProducts']),
createValidation,
validate,
audit('CREATE_DIGITALPRODUCT'),
controller.create
);
/**
* @swagger
* /api/v1/digitalProducts/{id}:
* put:
* summary: Update a digitalProduct
* tags: [DigitalProducts]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:digitalProducts']),
updateValidation,
validate,
audit('UPDATE_DIGITALPRODUCT'),
controller.update
);
/**
* @swagger
* /api/v1/digitalProducts/{id}:
* delete:
* summary: Delete a digitalProduct
* tags: [DigitalProducts]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:digitalProducts']),
deleteValidation,
validate,
audit('DELETE_DIGITALPRODUCT'),
controller.delete
);
export default router;
@@ -1,75 +0,0 @@
import repository from './digitalProduct.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class DigitalProductService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('DigitalProduct not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('digitalProduct:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'DigitalProduct',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('DigitalProduct not found');
}
SocketService.broadcast('digitalProduct:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'DigitalProduct',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('DigitalProduct not found');
}
SocketService.broadcast('digitalProduct:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'DigitalProduct',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new DigitalProductService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
@@ -1,5 +0,0 @@
export { default as digitalProductRoutes } from './digitalProduct.routes.js';
export { default as digitalProductController } from './digitalProduct.controller.js';
export { default as digitalProductService } from './digitalProduct.service.js';
export { default as digitalProductRepository } from './digitalProduct.repository.js';
export { default as digitalProductModel } from './digitalProduct.model.js';
@@ -1,50 +0,0 @@
import service from './family.service.js';
export class FamilyController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'Family deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new FamilyController();
@@ -1,55 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class Family extends Model {
static associate(models) {
// Define associations here if any
}
}
export default (sequelize) => {
Family.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
code: {
type: DataTypes.STRING,
allowNull: false,
unique: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.TEXT,
allowNull: true
},
category: {
type: DataTypes.STRING,
allowNull: true
},
attributes: {
type: DataTypes.JSONB,
defaultValue: []
},
variant_axes: {
type: DataTypes.JSONB,
defaultValue: []
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
}
}, {
sequelize,
modelName: 'Family',
tableName: 'families',
timestamps: true,
underscored: true
});
return Family;
};
@@ -1,34 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class FamilyRepository {
async findAll(options = {}) {
return await models.Family.findAll(options);
}
async findById(id, options = {}) {
return await models.Family.findByPk(id, options);
}
async findByCode(code, options = {}) {
return await models.Family.findOne({ where: { code }, ...options });
}
async create(data, options = {}) {
return await models.Family.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new FamilyRepository();
@@ -1,62 +0,0 @@
import { Router } from 'express';
import controller from './family.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './family.validation.js';
const router = Router();
router.get(
'/',
authenticate,
authorize(['read:products']),
controller.getAll
);
router.get(
'/:id',
authenticate,
authorize(['read:products']),
getByIdValidation,
validate,
controller.getById
);
router.post(
'/',
authenticate,
authorize(['write:products']),
createValidation,
validate,
audit('CREATE_FAMILY'),
controller.create
);
router.put(
'/:id',
authenticate,
authorize(['write:products']),
updateValidation,
validate,
audit('UPDATE_FAMILY'),
controller.update
);
router.delete(
'/:id',
authenticate,
authorize(['write:products']),
deleteValidation,
validate,
audit('DELETE_FAMILY'),
controller.delete
);
export default router;
@@ -1,72 +0,0 @@
import repository from './family.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class FamilyService {
async getAll(query = {}) {
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('Family not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
SocketService.broadcast('family:created', record);
await AuditService.log({
action: 'CREATE',
resource: 'Family',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('Family not found');
}
SocketService.broadcast('family:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'Family',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('Family not found');
}
SocketService.broadcast('family:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'Family',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new FamilyService();
@@ -1,36 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('code')
.isString()
.trim()
.notEmpty()
.withMessage('Code is required'),
body('name')
.isString()
.trim()
.notEmpty()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
-16
View File
@@ -1,24 +1,8 @@
import { Router } from 'express';
import productsRouter from './products/product.routes.js';
import variantsRouter from './variants/variant.routes.js';
import bundlesRouter from './bundles/bundle.routes.js';
import configurableProductsRouter from './configurableProducts/configurableProduct.routes.js';
import digitalProductsRouter from './digitalProducts/digitalProduct.routes.js';
import lifecycleRouter from './lifecycle/lifecycle.routes.js';
import approvalsRouter from './approvals/approval.routes.js';
import publishingRouter from './publishing/publishing.routes.js';
import familiesRouter from './families/family.routes.js';
const router = Router();
router.use('/products', productsRouter);
router.use('/variants', variantsRouter);
router.use('/bundles', bundlesRouter);
router.use('/configurableproducts', configurableProductsRouter);
router.use('/digitalproducts', digitalProductsRouter);
router.use('/lifecycle', lifecycleRouter);
router.use('/approvals', approvalsRouter);
router.use('/publishing', publishingRouter);
router.use('/families', familiesRouter);
export default router;
-5
View File
@@ -1,5 +0,0 @@
export { default as lifecycleRoutes } from './lifecycle.routes.js';
export { default as lifecycleController } from './lifecycle.controller.js';
export { default as lifecycleService } from './lifecycle.service.js';
export { default as lifecycleRepository } from './lifecycle.repository.js';
export { default as lifecycleModel } from './lifecycle.model.js';
@@ -1,50 +0,0 @@
import service from './lifecycle.service.js';
export class LifecycleController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'Lifecycle deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new LifecycleController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class Lifecycle extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
Lifecycle.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'Lifecycle',
tableName: 'lifecycles',
timestamps: true,
underscored: true
});
return Lifecycle;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class LifecycleRepository {
async findAll(options = {}) {
return await models.Lifecycle.findAll(options);
}
async findById(id, options = {}) {
return await models.Lifecycle.findByPk(id, options);
}
async create(data, options = {}) {
return await models.Lifecycle.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new LifecycleRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './lifecycle.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './lifecycle.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/lifecycles:
* get:
* summary: Retrieve all lifecycles
* tags: [Lifecycles]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:lifecycles']),
controller.getAll
);
/**
* @swagger
* /api/v1/lifecycles/{id}:
* get:
* summary: Retrieve a single lifecycle
* tags: [Lifecycles]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:lifecycles']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/lifecycles:
* post:
* summary: Create a lifecycle
* tags: [Lifecycles]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:lifecycles']),
createValidation,
validate,
audit('CREATE_LIFECYCLE'),
controller.create
);
/**
* @swagger
* /api/v1/lifecycles/{id}:
* put:
* summary: Update a lifecycle
* tags: [Lifecycles]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:lifecycles']),
updateValidation,
validate,
audit('UPDATE_LIFECYCLE'),
controller.update
);
/**
* @swagger
* /api/v1/lifecycles/{id}:
* delete:
* summary: Delete a lifecycle
* tags: [Lifecycles]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:lifecycles']),
deleteValidation,
validate,
audit('DELETE_LIFECYCLE'),
controller.delete
);
export default router;
@@ -1,75 +0,0 @@
import repository from './lifecycle.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class LifecycleService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('Lifecycle not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('lifecycle:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'Lifecycle',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('Lifecycle not found');
}
SocketService.broadcast('lifecycle:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'Lifecycle',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('Lifecycle not found');
}
SocketService.broadcast('lifecycle:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'Lifecycle',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new LifecycleService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
@@ -1,5 +0,0 @@
export { default as publishingRoutes } from './publishing.routes.js';
export { default as publishingController } from './publishing.controller.js';
export { default as publishingService } from './publishing.service.js';
export { default as publishingRepository } from './publishing.repository.js';
export { default as publishingModel } from './publishing.model.js';
@@ -1,50 +0,0 @@
import service from './publishing.service.js';
export class PublishingController {
async getAll(req, res, next) {
try {
const records = await service.getAll(req.query);
return res.status(200).json({ success: true, data: records });
} catch (error) {
next(error);
}
}
async getById(req, res, next) {
try {
const record = await service.getById(req.params.id);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async create(req, res, next) {
try {
const record = await service.create(req.body, req.user);
return res.status(201).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async update(req, res, next) {
try {
const record = await service.update(req.params.id, req.body, req.user);
return res.status(200).json({ success: true, data: record });
} catch (error) {
next(error);
}
}
async delete(req, res, next) {
try {
await service.delete(req.params.id, req.user);
return res.status(200).json({ success: true, message: 'Publishing deleted successfully' });
} catch (error) {
next(error);
}
}
}
export default new PublishingController();
@@ -1,38 +0,0 @@
import { Model, DataTypes } from 'sequelize';
export class Publishing extends Model {
static associate(models) {
// Define associations here
}
}
export default (sequelize) => {
Publishing.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: true
},
status: {
type: DataTypes.STRING,
defaultValue: 'active'
},
metadata: {
type: DataTypes.JSONB,
allowNull: true
}
}, {
sequelize,
modelName: 'Publishing',
tableName: 'publishings',
timestamps: true,
underscored: true
});
return Publishing;
};
@@ -1,30 +0,0 @@
import { models } from '../../../shared/database/models.js';
export class PublishingRepository {
async findAll(options = {}) {
return await models.Publishing.findAll(options);
}
async findById(id, options = {}) {
return await models.Publishing.findByPk(id, options);
}
async create(data, options = {}) {
return await models.Publishing.create(data, options);
}
async update(id, data, options = {}) {
const record = await this.findById(id, options);
if (!record) return null;
return await record.update(data, options);
}
async delete(id, options = {}) {
const record = await this.findById(id, options);
if (!record) return false;
await record.destroy(options);
return true;
}
}
export default new PublishingRepository();
@@ -1,126 +0,0 @@
import { Router } from 'express';
import controller from './publishing.controller.js';
import { authenticate } from '../../../shared/middleware/auth.middleware.js';
import { validate } from '../../../shared/middleware/validation.middleware.js';
import { authorize } from '../../../shared/middleware/permission.middleware.js';
import { audit } from '../../../shared/middleware/audit.middleware.js';
import {
createValidation,
updateValidation,
deleteValidation,
getByIdValidation
} from './publishing.validation.js';
const router = Router();
/**
* @swagger
* /api/v1/publishings:
* get:
* summary: Retrieve all publishings
* tags: [Publishings]
* responses:
* 200:
* description: Success
*/
router.get(
'/',
authenticate,
authorize(['read:publishings']),
controller.getAll
);
/**
* @swagger
* /api/v1/publishings/{id}:
* get:
* summary: Retrieve a single publishing
* tags: [Publishings]
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Success
*/
router.get(
'/:id',
authenticate,
authorize(['read:publishings']),
getByIdValidation,
validate,
controller.getById
);
/**
* @swagger
* /api/v1/publishings:
* post:
* summary: Create a publishing
* tags: [Publishings]
* responses:
* 201:
* description: Success
*/
router.post(
'/',
authenticate,
authorize(['write:publishings']),
createValidation,
validate,
audit('CREATE_PUBLISHING'),
controller.create
);
/**
* @swagger
* /api/v1/publishings/{id}:
* put:
* summary: Update a publishing
* tags: [Publishings]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.put(
'/:id',
authenticate,
authorize(['write:publishings']),
updateValidation,
validate,
audit('UPDATE_PUBLISHING'),
controller.update
);
/**
* @swagger
* /api/v1/publishings/{id}:
* delete:
* summary: Delete a publishing
* tags: [Publishings]
* parameters:
* - in: path
* name: id
* required: true
* responses:
* 200:
* description: Success
*/
router.delete(
'/:id',
authenticate,
authorize(['write:publishings']),
deleteValidation,
validate,
audit('DELETE_PUBLISHING'),
controller.delete
);
export default router;
@@ -1,75 +0,0 @@
import repository from './publishing.repository.js';
import { SocketService } from '../../../shared/services/socket.service.js';
import { AuditService } from '../../../shared/services/audit.service.js';
export class PublishingService {
async getAll(query = {}) {
// Add business logic filtering, pagination, etc.
return await repository.findAll();
}
async getById(id) {
const record = await repository.findById(id);
if (!record) {
throw new Error('Publishing not found');
}
return record;
}
async create(data, userContext = {}) {
const record = await repository.create(data);
// Broadcast event
SocketService.broadcast('publishing:created', record);
// Log audit
await AuditService.log({
action: 'CREATE',
resource: 'Publishing',
resourceId: record.id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async update(id, data, userContext = {}) {
const record = await repository.update(id, data);
if (!record) {
throw new Error('Publishing not found');
}
SocketService.broadcast('publishing:updated', record);
await AuditService.log({
action: 'UPDATE',
resource: 'Publishing',
resourceId: id,
userId: userContext.id || 'system',
details: data
});
return record;
}
async delete(id, userContext = {}) {
const deleted = await repository.delete(id);
if (!deleted) {
throw new Error('Publishing not found');
}
SocketService.broadcast('publishing:deleted', { id });
await AuditService.log({
action: 'DELETE',
resource: 'Publishing',
resourceId: id,
userId: userContext.id || 'system'
});
return true;
}
}
export default new PublishingService();
@@ -1,32 +0,0 @@
import { body, param } from 'express-validator';
export const createValidation = [
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const updateValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required'),
body('name')
.optional()
.isString()
.trim()
.withMessage('Name must be a string')
];
export const deleteValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];
export const getByIdValidation = [
param('id')
.isUUID()
.withMessage('Valid UUID is required')
];

Some files were not shown because too many files have changed in this diff Show More