Files
pos-system/services/iam-service/prisma/seed.ts
Ho Ngoc Hai 8cc2f66df6 Update IAM Service with various enhancements and fixes
- Added `xmlchars` dependency to `pnpm-lock.yaml` for improved XML character handling.
- Updated IAM Service audit plan to streamline post-deployment monitoring tasks.
- Enhanced Dockerfile to prune development dependencies after build for a leaner production image.
- Introduced a new encryption key configuration in the environment example for better security practices.
- Refactored multiple service files to improve import organization and maintainability.
- Improved error handling in seed scripts to provide more detailed logging on failures.
- Updated various controllers and services to ensure consistent import statements and enhance readability.

These changes aim to improve the overall functionality, security, and maintainability of the IAM Service.
2026-01-02 16:13:36 +07:00

261 lines
7.0 KiB
TypeScript

import { PrismaClient } from '@prisma/client';
import bcrypt from 'bcryptjs';
import { logger } from '@goodgo/logger';
const prisma = new PrismaClient();
/**
* EN: Seed database with initial data
* VI: Seed database với dữ liệu ban đầu
*/
async function main() {
logger.info('Starting database seed / Bắt đầu seed database');
// EN: Create default roles
// VI: Tạo roles mặc định
const adminRole = await prisma.role.upsert({
where: { name: 'ADMIN' },
update: {},
create: {
name: 'ADMIN',
displayName: 'Administrator',
description: 'Full system access',
isSystem: true,
},
});
const userRole = await prisma.role.upsert({
where: { name: 'USER' },
update: {},
create: {
name: 'USER',
displayName: 'User',
description: 'Standard user access',
isSystem: true,
},
});
const moderatorRole = await prisma.role.upsert({
where: { name: 'MODERATOR' },
update: {},
create: {
name: 'MODERATOR',
displayName: 'Moderator',
description: 'Moderation access',
isSystem: true,
},
});
logger.info('Roles created / Roles đã được tạo', { adminRole, userRole, moderatorRole });
// EN: Create default permissions
// VI: Tạo permissions mặc định
const permissions = [
// User permissions
{ resource: 'users', action: 'create', scope: null },
{ resource: 'users', action: 'read', scope: 'own' },
{ resource: 'users', action: 'read', scope: 'all' },
{ resource: 'users', action: 'update', scope: 'own' },
{ resource: 'users', action: 'update', scope: 'all' },
{ resource: 'users', action: 'delete', scope: 'all' },
// RBAC permissions
{ resource: 'rbac', action: 'assign', scope: null },
{ resource: 'rbac', action: 'revoke', scope: null },
{ resource: 'rbac', action: 'grant', scope: null },
{ resource: 'rbac', action: 'read', scope: null },
// Auth permissions
{ resource: 'auth', action: 'manage', scope: null },
];
const createdPermissions = [];
for (const perm of permissions) {
// EN: Handle nullable scope in upsert
// VI: Xử lý scope nullable trong upsert
let permission;
if (perm.scope !== null) {
// Use compound unique constraint when scope is not null
permission = await prisma.permission.upsert({
where: {
resource_action_scope: {
resource: perm.resource,
action: perm.action,
scope: perm.scope,
},
},
update: {},
create: {
resource: perm.resource,
action: perm.action,
scope: perm.scope,
description: `${perm.action} ${perm.resource}${perm.scope ? ` (${perm.scope})` : ''}`,
},
});
} else {
// Use find/create when scope is null to avoid unique constraint issues
permission = await prisma.permission.findFirst({
where: {
resource: perm.resource,
action: perm.action,
scope: null,
},
});
if (!permission) {
permission = await prisma.permission.create({
data: {
resource: perm.resource,
action: perm.action,
scope: perm.scope,
description: `${perm.action} ${perm.resource}${perm.scope ? ` (${perm.scope})` : ''}`,
},
});
}
}
createdPermissions.push(permission);
}
logger.info('Permissions created / Permissions đã được tạo', { count: createdPermissions.length });
// EN: Assign permissions to roles
// VI: Gán permissions cho roles
// Admin gets all permissions
for (const permission of createdPermissions) {
await prisma.rolePermission.upsert({
where: {
roleId_permissionId: {
roleId: adminRole.id,
permissionId: permission.id,
},
},
update: {},
create: {
roleId: adminRole.id,
permissionId: permission.id,
},
});
}
// User gets basic permissions
const userPermissions = createdPermissions.filter(p =>
(p.resource === 'users' && p.action === 'read' && p.scope === 'own') ||
(p.resource === 'users' && p.action === 'update' && p.scope === 'own')
);
for (const permission of userPermissions) {
await prisma.rolePermission.upsert({
where: {
roleId_permissionId: {
roleId: userRole.id,
permissionId: permission.id,
},
},
update: {},
create: {
roleId: userRole.id,
permissionId: permission.id,
},
});
}
// EN: Create admin user
// VI: Tạo user admin
const adminPassword = await bcrypt.hash('admin123', 12);
const adminUser = await prisma.user.upsert({
where: { email: 'admin@goodgo.com' },
update: {},
create: {
email: 'admin@goodgo.com',
username: 'admin',
passwordHash: adminPassword,
isActive: true,
emailVerified: true,
},
});
// Assign admin role
await prisma.userRole.upsert({
where: {
userId_roleId: {
userId: adminUser.id,
roleId: adminRole.id,
},
},
update: {},
create: {
userId: adminUser.id,
roleId: adminRole.id,
},
});
logger.info('Admin user created / User admin đã được tạo', {
email: adminUser.email,
password: 'admin123', // Only for development!
});
// EN: Create test user
// VI: Tạo user test
const testPassword = await bcrypt.hash('test123', 12);
const testUser = await prisma.user.upsert({
where: { email: 'test@goodgo.com' },
update: {},
create: {
email: 'test@goodgo.com',
username: 'testuser',
passwordHash: testPassword,
isActive: true,
emailVerified: true,
},
});
// Assign user role
await prisma.userRole.upsert({
where: {
userId_roleId: {
userId: testUser.id,
roleId: userRole.id,
},
},
update: {},
create: {
userId: testUser.id,
roleId: userRole.id,
},
});
logger.info('Test user created / User test đã được tạo', {
email: testUser.email,
password: 'test123', // Only for development!
});
// EN: Create sample organization (optional - for IAM features)
// VI: Tạo tổ chức mẫu (tùy chọn - cho tính năng IAM)
const sampleOrg = await prisma.organization.upsert({
where: { domain: 'goodgo.com' },
update: {},
create: {
name: 'GoodGo',
domain: 'goodgo.com',
isActive: true,
settings: {},
},
}).catch(() => null); // Ignore if already exists or schema not migrated yet
if (sampleOrg) {
logger.info('Sample organization created / Tổ chức mẫu đã được tạo', { organizationId: sampleOrg.id });
}
logger.info('Database seed completed / Seed database đã hoàn thành');
}
main()
.catch((error) => {
logger.error('Seed failed / Seed thất bại', { error: error.message, stack: error.stack });
console.error('Full error:', error);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});