276 lines
8.9 KiB
TypeScript
276 lines
8.9 KiB
TypeScript
import { PrismaClient } from '@prisma/client';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
async function main() {
|
|
console.log('Starting seeding...');
|
|
|
|
// Create roles
|
|
const adminRole = await prisma.roles.upsert({
|
|
where: { name: 'admin' },
|
|
update: {},
|
|
create: {
|
|
|
|
name: 'admin',
|
|
description: 'Administrator with full access to all features',
|
|
},
|
|
});
|
|
|
|
const viewerRole = await prisma.roles.upsert({
|
|
where: { name: 'viewer' },
|
|
update: {},
|
|
create: {
|
|
|
|
name: 'viewer',
|
|
description: 'Read-only access to data',
|
|
},
|
|
});
|
|
|
|
const staffRole = await prisma.roles.upsert({
|
|
where: { name: 'staff' },
|
|
update: {},
|
|
create: {
|
|
|
|
name: 'staff',
|
|
description: 'Staff with limited administrative access',
|
|
},
|
|
});
|
|
|
|
console.log('Roles created:', { adminRole, viewerRole, staffRole });
|
|
|
|
// Create resources based on Prisma schema models
|
|
const resources = [
|
|
{
|
|
name: 'cities',
|
|
description: 'City data management',
|
|
attributes: {
|
|
fields: ['id', 'name', 'code', 'geographic_id', 'created_at', 'updated_at']
|
|
}
|
|
},
|
|
{
|
|
name: 'contact_messages',
|
|
description: 'Contact message management',
|
|
attributes: {
|
|
fields: ['id', 'name', 'email', 'phone', 'message_type', 'message_type_label', 'message', 'status', 'created_at', 'updated_at']
|
|
}
|
|
},
|
|
{
|
|
name: 'crime_cases',
|
|
description: 'Crime case management',
|
|
attributes: {
|
|
fields: ['id', 'crime_id', 'crime_category_id', 'date', 'time', 'location', 'latitude', 'longitude', 'description', 'victim_count', 'status', 'created_at', 'updated_at']
|
|
}
|
|
},
|
|
{
|
|
name: 'crime_categories',
|
|
description: 'Crime category management',
|
|
attributes: {
|
|
fields: ['id', 'name', 'description', 'created_at', 'updated_at']
|
|
}
|
|
},
|
|
{
|
|
name: 'crimes',
|
|
description: 'Crime data management',
|
|
attributes: {
|
|
fields: ['id', 'district_id', 'city_id', 'year', 'number_of_crime', 'rate', 'heat_map', 'created_at', 'updated_at']
|
|
}
|
|
},
|
|
{
|
|
name: 'demographics',
|
|
description: 'Demographic data management',
|
|
attributes: {
|
|
fields: ['id', 'district_id', 'city_id', 'province_id', 'year', 'population', 'population_density', 'poverty_rate', 'created_at', 'updated_at']
|
|
}
|
|
},
|
|
{
|
|
name: 'districts',
|
|
description: 'District data management',
|
|
attributes: {
|
|
fields: ['id', 'city_id', 'name', 'code', 'created_at', 'updated_at']
|
|
}
|
|
},
|
|
{
|
|
name: 'geographics',
|
|
description: 'Geographic data management',
|
|
attributes: {
|
|
fields: ['id', 'district_id', 'latitude', 'longitude', 'land_area', 'polygon', 'created_at', 'updated_at']
|
|
}
|
|
},
|
|
{
|
|
name: 'profiles',
|
|
description: 'User profile management',
|
|
attributes: {
|
|
fields: ['id', 'user_id', 'avatar', 'username', 'first_name', 'last_name', 'bio', 'address', 'birth_date']
|
|
}
|
|
},
|
|
{
|
|
name: 'users',
|
|
description: 'User account management',
|
|
attributes: {
|
|
fields: ['id', 'roles_id', 'email', 'phone', 'encrypted_password', 'invited_at', 'confirmed_at', 'email_confirmed_at', 'recovery_sent_at', 'last_sign_in_at', 'app_metadata', 'user_metadata', 'created_at', 'updated_at', 'banned_until', 'is_anonymous']
|
|
}
|
|
},
|
|
{
|
|
name: 'roles',
|
|
description: 'Role management',
|
|
attributes: {
|
|
fields: ['id', 'name', 'description', 'created_at', 'updated_at']
|
|
}
|
|
},
|
|
{
|
|
name: 'resources',
|
|
description: 'Resource management',
|
|
attributes: {
|
|
fields: ['id', 'name', 'description', 'instance_role', 'relations', 'attributes', 'created_at', 'updated_at']
|
|
}
|
|
},
|
|
{
|
|
name: 'permissions',
|
|
description: 'Permission management',
|
|
attributes: {
|
|
fields: ['id', 'action', 'resource_id', 'role_id', 'created_at', 'updated_at']
|
|
}
|
|
}
|
|
];
|
|
|
|
// Create resources in the database
|
|
for (const resource of resources) {
|
|
const createdResource = await prisma.resources.upsert({
|
|
where: { name: resource.name },
|
|
update: {},
|
|
create: {
|
|
name: resource.name,
|
|
description: resource.description,
|
|
attributes: resource.attributes
|
|
},
|
|
});
|
|
console.log(`Resource ${resource.name} created/updated with ID: ${createdResource.id}`);
|
|
}
|
|
|
|
// Set up basic permissions for each role
|
|
const allResources = await prisma.resources.findMany();
|
|
|
|
// Admin permissions - full access to all resources
|
|
for (const resource of allResources) {
|
|
await createPermissions(adminRole.id, resource.id, ['create', 'read', 'update', 'delete']);
|
|
}
|
|
|
|
// Viewer permissions - read-only access to all resources
|
|
for (const resource of allResources) {
|
|
await createPermissions(viewerRole.id, resource.id, ['read']);
|
|
}
|
|
|
|
// Staff permissions - mixed permissions based on resource
|
|
for (const resource of allResources) {
|
|
if (['roles', 'permissions', 'resources', 'users'].includes(resource.name)) {
|
|
// Staff can only read roles, permissions, resources and users
|
|
await createPermissions(staffRole.id, resource.id, ['read']);
|
|
} else {
|
|
// Staff can create, read, update but not delete other resources
|
|
await createPermissions(staffRole.id, resource.id, ['create', 'read', 'update']);
|
|
}
|
|
}
|
|
|
|
console.log('Seeding completed!');
|
|
}
|
|
|
|
async function createPermissions(roleId: string, resourceId: string, actions: string[]) {
|
|
for (const action of actions) {
|
|
await prisma.permissions.createMany({
|
|
data: {
|
|
action: action,
|
|
resource_id: resourceId,
|
|
role_id: roleId,
|
|
},
|
|
skipDuplicates: true // Skip if the permission already exists
|
|
}).catch((error) => {
|
|
console.error(`Error creating permission for role ${roleId} on resource ${resourceId}:`, error);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
main()
|
|
.then(async () => {
|
|
await prisma.$disconnect();
|
|
})
|
|
.catch(async (e) => {
|
|
console.error(e);
|
|
await prisma.$disconnect();
|
|
process.exit(1);
|
|
});
|
|
|
|
// import { PrismaClient } from '@prisma/client';
|
|
// import fs from 'fs';
|
|
// import * as turf from '@turf/turf';
|
|
|
|
// const prisma = new PrismaClient();
|
|
|
|
// async function main() {
|
|
// const geojson = JSON.parse(fs.readFileSync('prisma/data/geojson/jember/districts.geojson', 'utf-8'));
|
|
|
|
// // 1. Insert Kota/Kabupaten: Jember
|
|
// const city = await prisma.cities.upsert(
|
|
// {
|
|
// where: { id: '3574' },
|
|
// update: {},
|
|
// create: {
|
|
// id: '3574',
|
|
// name: 'Jember',
|
|
// }
|
|
// }
|
|
// )
|
|
|
|
// console.log(`City Jember inserted with ID: ${city.id}`);
|
|
|
|
// // 2. Loop Semua District di GeoJSON
|
|
// for (const feature of geojson.features) {
|
|
// const properties = feature.properties;
|
|
// const geometry = feature.geometry;
|
|
|
|
// // Cleanup code
|
|
// const districtCode = properties.kode_kec.replace(/\./g, '');
|
|
|
|
// // Insert District
|
|
// const district = await prisma.districts.create({
|
|
// data: {
|
|
// id: districtCode,
|
|
// name: properties.kecamatan,
|
|
// city_id: city.id,
|
|
// }
|
|
// });
|
|
|
|
// console.log(`Inserted district: ${district.name}`);
|
|
|
|
// // 3. Hitung Centroid dan Area
|
|
// const centroid = turf.centroid(feature);
|
|
|
|
// const [longitude, latitude] = centroid.geometry.coordinates;
|
|
// const area = turf.area(feature) / 1_000_000; // dari m² ke km²
|
|
|
|
// // 4. Insert Geographics
|
|
// await prisma.geographics.create({
|
|
// data: {
|
|
// district_id: district.id,
|
|
// latitude,
|
|
// longitude,
|
|
// land_area: area,
|
|
// geometry: feature.geometry,
|
|
// }
|
|
// });
|
|
|
|
// console.log(`Inserted geographics for district: ${district.name}`);
|
|
// }
|
|
|
|
// console.log("All data imported successfully!");
|
|
// }
|
|
|
|
// main()
|
|
// .catch((e) => {
|
|
// console.error(e);
|
|
// process.exit(1);
|
|
// })
|
|
// .finally(async () => {
|
|
// await prisma.$disconnect();
|
|
// });
|