first commit
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
console.log('Adding contract categories...');
|
||||
|
||||
// Create contract categories (matching existing enum values)
|
||||
const contractCategories = [
|
||||
{ code: 'ELECTRICITY', name: 'Strom', icon: 'Zap', color: '#FFC107', sortOrder: 1 },
|
||||
{ code: 'GAS', name: 'Gas', icon: 'Flame', color: '#FF5722', sortOrder: 2 },
|
||||
{ code: 'DSL', name: 'DSL', icon: 'Wifi', color: '#2196F3', sortOrder: 3 },
|
||||
{ code: 'FIBER', name: 'Glasfaser', icon: 'Cable', color: '#9C27B0', sortOrder: 4 },
|
||||
{ code: 'MOBILE', name: 'Mobilfunk', icon: 'Smartphone', color: '#4CAF50', sortOrder: 5 },
|
||||
{ code: 'TV', name: 'TV', icon: 'Tv', color: '#E91E63', sortOrder: 6 },
|
||||
{ code: 'CAR_INSURANCE', name: 'KFZ-Versicherung', icon: 'Car', color: '#607D8B', sortOrder: 7 },
|
||||
];
|
||||
|
||||
for (const category of contractCategories) {
|
||||
await prisma.contractCategory.upsert({
|
||||
where: { code: category.code },
|
||||
update: { name: category.name, icon: category.icon, color: category.color, sortOrder: category.sortOrder },
|
||||
create: category,
|
||||
});
|
||||
console.log(`Created/updated category: ${category.name}`);
|
||||
}
|
||||
|
||||
// Update existing contracts to link to their categories
|
||||
console.log('Linking existing contracts to categories...');
|
||||
|
||||
for (const category of contractCategories) {
|
||||
const cat = await prisma.contractCategory.findUnique({ where: { code: category.code } });
|
||||
if (cat) {
|
||||
const result = await prisma.contract.updateMany({
|
||||
where: {
|
||||
type: category.code as any,
|
||||
contractCategoryId: null,
|
||||
},
|
||||
data: {
|
||||
contractCategoryId: cat.id,
|
||||
},
|
||||
});
|
||||
if (result.count > 0) {
|
||||
console.log(`Linked ${result.count} ${category.name} contracts`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Contract categories setup completed!');
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
console.log('Adding developer:access permission...');
|
||||
|
||||
// Create or get the developer:access permission
|
||||
const developerPerm = await prisma.permission.upsert({
|
||||
where: { resource_action: { resource: 'developer', action: 'access' } },
|
||||
update: {},
|
||||
create: { resource: 'developer', action: 'access' },
|
||||
});
|
||||
|
||||
console.log('Permission created/found:', developerPerm);
|
||||
|
||||
// Get the Admin role
|
||||
const adminRole = await prisma.role.findUnique({
|
||||
where: { name: 'Admin' },
|
||||
include: { permissions: true },
|
||||
});
|
||||
|
||||
if (!adminRole) {
|
||||
console.log('Admin role not found!');
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if Admin already has this permission
|
||||
const hasPermission = adminRole.permissions.some(
|
||||
(rp) => rp.permissionId === developerPerm.id
|
||||
);
|
||||
|
||||
if (!hasPermission) {
|
||||
await prisma.rolePermission.create({
|
||||
data: {
|
||||
roleId: adminRole.id,
|
||||
permissionId: developerPerm.id,
|
||||
},
|
||||
});
|
||||
console.log('Added developer:access permission to Admin role');
|
||||
} else {
|
||||
console.log('Admin role already has developer:access permission');
|
||||
}
|
||||
|
||||
console.log('Done!');
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
@@ -0,0 +1,117 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
console.log('Adding provider permissions...');
|
||||
|
||||
// Create provider permissions
|
||||
const actions = ['create', 'read', 'update', 'delete'];
|
||||
|
||||
for (const action of actions) {
|
||||
await prisma.permission.upsert({
|
||||
where: { resource_action: { resource: 'providers', action } },
|
||||
update: {},
|
||||
create: { resource: 'providers', action },
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Provider permissions created');
|
||||
|
||||
// Get all provider permissions
|
||||
const providerPermissions = await prisma.permission.findMany({
|
||||
where: { resource: 'providers' },
|
||||
});
|
||||
|
||||
// Get admin role
|
||||
const adminRole = await prisma.role.findUnique({
|
||||
where: { name: 'Admin' },
|
||||
include: { permissions: true },
|
||||
});
|
||||
|
||||
if (adminRole) {
|
||||
// Add provider permissions to admin role if not already assigned
|
||||
for (const perm of providerPermissions) {
|
||||
const exists = adminRole.permissions.some(rp => rp.permissionId === perm.id);
|
||||
if (!exists) {
|
||||
await prisma.rolePermission.create({
|
||||
data: {
|
||||
roleId: adminRole.id,
|
||||
permissionId: perm.id,
|
||||
},
|
||||
});
|
||||
console.log(`Added providers:${perm.action} to Admin role`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get employee role and add read permission
|
||||
const employeeRole = await prisma.role.findUnique({
|
||||
where: { name: 'Mitarbeiter' },
|
||||
include: { permissions: true },
|
||||
});
|
||||
|
||||
const providerReadPerm = providerPermissions.find(p => p.action === 'read');
|
||||
|
||||
if (employeeRole && providerReadPerm) {
|
||||
const exists = employeeRole.permissions.some(rp => rp.permissionId === providerReadPerm.id);
|
||||
if (!exists) {
|
||||
await prisma.rolePermission.create({
|
||||
data: {
|
||||
roleId: employeeRole.id,
|
||||
permissionId: providerReadPerm.id,
|
||||
},
|
||||
});
|
||||
console.log('Added providers:read to Mitarbeiter role');
|
||||
}
|
||||
}
|
||||
|
||||
// Get read-only role and add read permission
|
||||
const readOnlyRole = await prisma.role.findUnique({
|
||||
where: { name: 'Mitarbeiter (Nur-Lesen)' },
|
||||
include: { permissions: true },
|
||||
});
|
||||
|
||||
if (readOnlyRole && providerReadPerm) {
|
||||
const exists = readOnlyRole.permissions.some(rp => rp.permissionId === providerReadPerm.id);
|
||||
if (!exists) {
|
||||
await prisma.rolePermission.create({
|
||||
data: {
|
||||
roleId: readOnlyRole.id,
|
||||
permissionId: providerReadPerm.id,
|
||||
},
|
||||
});
|
||||
console.log('Added providers:read to Mitarbeiter (Nur-Lesen) role');
|
||||
}
|
||||
}
|
||||
|
||||
// Get customer role and add read permission
|
||||
const customerRole = await prisma.role.findUnique({
|
||||
where: { name: 'Kunde' },
|
||||
include: { permissions: true },
|
||||
});
|
||||
|
||||
if (customerRole && providerReadPerm) {
|
||||
const exists = customerRole.permissions.some(rp => rp.permissionId === providerReadPerm.id);
|
||||
if (!exists) {
|
||||
await prisma.rolePermission.create({
|
||||
data: {
|
||||
roleId: customerRole.id,
|
||||
permissionId: providerReadPerm.id,
|
||||
},
|
||||
});
|
||||
console.log('Added providers:read to Kunde role');
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Provider permissions setup completed!');
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
@@ -0,0 +1,64 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
// Create settings permissions
|
||||
const settingsPermissions = [
|
||||
{ resource: 'settings', action: 'read' },
|
||||
{ resource: 'settings', action: 'update' },
|
||||
];
|
||||
|
||||
for (const perm of settingsPermissions) {
|
||||
await prisma.permission.upsert({
|
||||
where: {
|
||||
resource_action: {
|
||||
resource: perm.resource,
|
||||
action: perm.action,
|
||||
},
|
||||
},
|
||||
update: {},
|
||||
create: perm,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Settings permissions created');
|
||||
|
||||
// Add to Admin role
|
||||
const adminRole = await prisma.role.findUnique({
|
||||
where: { name: 'Admin' },
|
||||
});
|
||||
|
||||
if (adminRole) {
|
||||
const newPermissions = await prisma.permission.findMany({
|
||||
where: { resource: 'settings' },
|
||||
});
|
||||
|
||||
for (const perm of newPermissions) {
|
||||
await prisma.rolePermission.upsert({
|
||||
where: {
|
||||
roleId_permissionId: {
|
||||
roleId: adminRole.id,
|
||||
permissionId: perm.id,
|
||||
},
|
||||
},
|
||||
update: {},
|
||||
create: {
|
||||
roleId: adminRole.id,
|
||||
permissionId: perm.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Settings permissions added to Admin role');
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
@@ -0,0 +1,354 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `User` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`email` VARCHAR(191) NOT NULL,
|
||||
`password` VARCHAR(191) NOT NULL,
|
||||
`firstName` VARCHAR(191) NOT NULL,
|
||||
`lastName` VARCHAR(191) NOT NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`customerId` INTEGER NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `User_email_key`(`email`),
|
||||
UNIQUE INDEX `User_customerId_key`(`customerId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Role` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`description` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Role_name_key`(`name`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Permission` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`resource` VARCHAR(191) NOT NULL,
|
||||
`action` VARCHAR(191) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Permission_resource_action_key`(`resource`, `action`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `RolePermission` (
|
||||
`roleId` INTEGER NOT NULL,
|
||||
`permissionId` INTEGER NOT NULL,
|
||||
|
||||
PRIMARY KEY (`roleId`, `permissionId`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `UserRole` (
|
||||
`userId` INTEGER NOT NULL,
|
||||
`roleId` INTEGER NOT NULL,
|
||||
|
||||
PRIMARY KEY (`userId`, `roleId`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Customer` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`customerNumber` VARCHAR(191) NOT NULL,
|
||||
`type` ENUM('PRIVATE', 'BUSINESS') NOT NULL DEFAULT 'PRIVATE',
|
||||
`salutation` VARCHAR(191) NULL,
|
||||
`firstName` VARCHAR(191) NOT NULL,
|
||||
`lastName` VARCHAR(191) NOT NULL,
|
||||
`companyName` VARCHAR(191) NULL,
|
||||
`email` VARCHAR(191) NULL,
|
||||
`phone` VARCHAR(191) NULL,
|
||||
`mobile` VARCHAR(191) NULL,
|
||||
`taxNumber` VARCHAR(191) NULL,
|
||||
`businessRegistration` TEXT NULL,
|
||||
`commercialRegister` VARCHAR(191) NULL,
|
||||
`notes` TEXT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Customer_customerNumber_key`(`customerNumber`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Address` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`customerId` INTEGER NOT NULL,
|
||||
`type` ENUM('DELIVERY_RESIDENCE', 'BILLING') NOT NULL DEFAULT 'DELIVERY_RESIDENCE',
|
||||
`street` VARCHAR(191) NOT NULL,
|
||||
`houseNumber` VARCHAR(191) NOT NULL,
|
||||
`postalCode` VARCHAR(191) NOT NULL,
|
||||
`city` VARCHAR(191) NOT NULL,
|
||||
`country` VARCHAR(191) NOT NULL DEFAULT 'Deutschland',
|
||||
`isDefault` BOOLEAN NOT NULL DEFAULT false,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `BankCard` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`customerId` INTEGER NOT NULL,
|
||||
`accountHolder` VARCHAR(191) NOT NULL,
|
||||
`iban` VARCHAR(191) NOT NULL,
|
||||
`bic` VARCHAR(191) NULL,
|
||||
`bankName` VARCHAR(191) NULL,
|
||||
`expiryDate` DATETIME(3) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `IdentityDocument` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`customerId` INTEGER NOT NULL,
|
||||
`type` ENUM('ID_CARD', 'PASSPORT', 'DRIVERS_LICENSE', 'OTHER') NOT NULL DEFAULT 'ID_CARD',
|
||||
`documentNumber` VARCHAR(191) NOT NULL,
|
||||
`issuingAuthority` VARCHAR(191) NULL,
|
||||
`issueDate` DATETIME(3) NULL,
|
||||
`expiryDate` DATETIME(3) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Meter` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`customerId` INTEGER NOT NULL,
|
||||
`meterNumber` VARCHAR(191) NOT NULL,
|
||||
`type` ENUM('ELECTRICITY', 'GAS') NOT NULL,
|
||||
`location` VARCHAR(191) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `MeterReading` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`meterId` INTEGER NOT NULL,
|
||||
`readingDate` DATETIME(3) NOT NULL,
|
||||
`value` DOUBLE NOT NULL,
|
||||
`unit` VARCHAR(191) NOT NULL DEFAULT 'kWh',
|
||||
`notes` VARCHAR(191) NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `SalesPlatform` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`contactInfo` TEXT NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `SalesPlatform_name_key`(`name`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Contract` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`contractNumber` VARCHAR(191) NOT NULL,
|
||||
`customerId` INTEGER NOT NULL,
|
||||
`type` ENUM('ELECTRICITY', 'GAS', 'DSL', 'FIBER', 'MOBILE', 'TV', 'CAR_INSURANCE') NOT NULL,
|
||||
`status` ENUM('DRAFT', 'PENDING', 'ACTIVE', 'CANCELLED', 'EXPIRED') NOT NULL DEFAULT 'DRAFT',
|
||||
`addressId` INTEGER NULL,
|
||||
`bankCardId` INTEGER NULL,
|
||||
`identityDocumentId` INTEGER NULL,
|
||||
`salesPlatformId` INTEGER NULL,
|
||||
`previousContractId` INTEGER NULL,
|
||||
`providerName` VARCHAR(191) NULL,
|
||||
`tariffName` VARCHAR(191) NULL,
|
||||
`customerNumberAtProvider` VARCHAR(191) NULL,
|
||||
`startDate` DATETIME(3) NULL,
|
||||
`endDate` DATETIME(3) NULL,
|
||||
`cancellationPeriod` INTEGER NULL,
|
||||
`commission` DOUBLE NULL,
|
||||
`portalUsername` VARCHAR(191) NULL,
|
||||
`portalPasswordEncrypted` VARCHAR(191) NULL,
|
||||
`notes` TEXT NULL,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Contract_contractNumber_key`(`contractNumber`),
|
||||
UNIQUE INDEX `Contract_previousContractId_key`(`previousContractId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `EnergyContractDetails` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`contractId` INTEGER NOT NULL,
|
||||
`meterId` INTEGER NULL,
|
||||
`annualConsumption` DOUBLE NULL,
|
||||
`basePrice` DOUBLE NULL,
|
||||
`unitPrice` DOUBLE NULL,
|
||||
`bonus` DOUBLE NULL,
|
||||
`previousProviderName` VARCHAR(191) NULL,
|
||||
`previousCustomerNumber` VARCHAR(191) NULL,
|
||||
|
||||
UNIQUE INDEX `EnergyContractDetails_contractId_key`(`contractId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `InternetContractDetails` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`contractId` INTEGER NOT NULL,
|
||||
`downloadSpeed` INTEGER NULL,
|
||||
`uploadSpeed` INTEGER NULL,
|
||||
`routerModel` VARCHAR(191) NULL,
|
||||
`routerSerialNumber` VARCHAR(191) NULL,
|
||||
`installationDate` DATETIME(3) NULL,
|
||||
|
||||
UNIQUE INDEX `InternetContractDetails_contractId_key`(`contractId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `PhoneNumber` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`internetContractDetailsId` INTEGER NOT NULL,
|
||||
`phoneNumber` VARCHAR(191) NOT NULL,
|
||||
`isMain` BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `MobileContractDetails` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`contractId` INTEGER NOT NULL,
|
||||
`phoneNumber` VARCHAR(191) NULL,
|
||||
`simCardNumber` VARCHAR(191) NULL,
|
||||
`dataVolume` DOUBLE NULL,
|
||||
`includedMinutes` INTEGER NULL,
|
||||
`includedSMS` INTEGER NULL,
|
||||
`deviceModel` VARCHAR(191) NULL,
|
||||
`deviceImei` VARCHAR(191) NULL,
|
||||
|
||||
UNIQUE INDEX `MobileContractDetails_contractId_key`(`contractId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `TvContractDetails` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`contractId` INTEGER NOT NULL,
|
||||
`receiverModel` VARCHAR(191) NULL,
|
||||
`smartcardNumber` VARCHAR(191) NULL,
|
||||
`package` VARCHAR(191) NULL,
|
||||
|
||||
UNIQUE INDEX `TvContractDetails_contractId_key`(`contractId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `CarInsuranceDetails` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`contractId` INTEGER NOT NULL,
|
||||
`licensePlate` VARCHAR(191) NULL,
|
||||
`hsn` VARCHAR(191) NULL,
|
||||
`tsn` VARCHAR(191) NULL,
|
||||
`vin` VARCHAR(191) NULL,
|
||||
`vehicleType` VARCHAR(191) NULL,
|
||||
`firstRegistration` DATETIME(3) NULL,
|
||||
`noClaimsClass` VARCHAR(191) NULL,
|
||||
`insuranceType` ENUM('LIABILITY', 'PARTIAL', 'FULL') NOT NULL DEFAULT 'LIABILITY',
|
||||
`deductiblePartial` DOUBLE NULL,
|
||||
`deductibleFull` DOUBLE NULL,
|
||||
`policyNumber` VARCHAR(191) NULL,
|
||||
`previousInsurer` VARCHAR(191) NULL,
|
||||
|
||||
UNIQUE INDEX `CarInsuranceDetails_contractId_key`(`contractId`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `User` ADD CONSTRAINT `User_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `Customer`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `RolePermission` ADD CONSTRAINT `RolePermission_roleId_fkey` FOREIGN KEY (`roleId`) REFERENCES `Role`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `RolePermission` ADD CONSTRAINT `RolePermission_permissionId_fkey` FOREIGN KEY (`permissionId`) REFERENCES `Permission`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `UserRole` ADD CONSTRAINT `UserRole_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `UserRole` ADD CONSTRAINT `UserRole_roleId_fkey` FOREIGN KEY (`roleId`) REFERENCES `Role`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Address` ADD CONSTRAINT `Address_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `Customer`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `BankCard` ADD CONSTRAINT `BankCard_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `Customer`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `IdentityDocument` ADD CONSTRAINT `IdentityDocument_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `Customer`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Meter` ADD CONSTRAINT `Meter_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `Customer`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `MeterReading` ADD CONSTRAINT `MeterReading_meterId_fkey` FOREIGN KEY (`meterId`) REFERENCES `Meter`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_customerId_fkey` FOREIGN KEY (`customerId`) REFERENCES `Customer`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_addressId_fkey` FOREIGN KEY (`addressId`) REFERENCES `Address`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_bankCardId_fkey` FOREIGN KEY (`bankCardId`) REFERENCES `BankCard`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_identityDocumentId_fkey` FOREIGN KEY (`identityDocumentId`) REFERENCES `IdentityDocument`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_salesPlatformId_fkey` FOREIGN KEY (`salesPlatformId`) REFERENCES `SalesPlatform`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_previousContractId_fkey` FOREIGN KEY (`previousContractId`) REFERENCES `Contract`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `EnergyContractDetails` ADD CONSTRAINT `EnergyContractDetails_contractId_fkey` FOREIGN KEY (`contractId`) REFERENCES `Contract`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `EnergyContractDetails` ADD CONSTRAINT `EnergyContractDetails_meterId_fkey` FOREIGN KEY (`meterId`) REFERENCES `Meter`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `InternetContractDetails` ADD CONSTRAINT `InternetContractDetails_contractId_fkey` FOREIGN KEY (`contractId`) REFERENCES `Contract`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `PhoneNumber` ADD CONSTRAINT `PhoneNumber_internetContractDetailsId_fkey` FOREIGN KEY (`internetContractDetailsId`) REFERENCES `InternetContractDetails`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `MobileContractDetails` ADD CONSTRAINT `MobileContractDetails_contractId_fkey` FOREIGN KEY (`contractId`) REFERENCES `Contract`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `TvContractDetails` ADD CONSTRAINT `TvContractDetails_contractId_fkey` FOREIGN KEY (`contractId`) REFERENCES `Contract`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `CarInsuranceDetails` ADD CONSTRAINT `CarInsuranceDetails_contractId_fkey` FOREIGN KEY (`contractId`) REFERENCES `Contract`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `BankCard` ADD COLUMN `documentPath` VARCHAR(191) NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `IdentityDocument` ADD COLUMN `documentPath` VARCHAR(191) NULL;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `Customer` ADD COLUMN `birthDate` DATETIME(3) NULL,
|
||||
ADD COLUMN `birthPlace` VARCHAR(191) NULL;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `IdentityDocument` ADD COLUMN `licenseClasses` VARCHAR(191) NULL,
|
||||
ADD COLUMN `licenseIssueDate` DATETIME(3) NULL;
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `businessRegistration` on the `Customer` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `commercialRegister` on the `Customer` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `Customer` DROP COLUMN `businessRegistration`,
|
||||
DROP COLUMN `commercialRegister`,
|
||||
ADD COLUMN `businessRegistrationPath` VARCHAR(191) NULL,
|
||||
ADD COLUMN `commercialRegisterNumber` VARCHAR(191) NULL,
|
||||
ADD COLUMN `commercialRegisterPath` VARCHAR(191) NULL,
|
||||
ADD COLUMN `foundingDate` DATETIME(3) NULL;
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `cancellationPeriod` on the `Contract` table. All the data in the column will be lost.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE `Contract` DROP COLUMN `cancellationPeriod`,
|
||||
ADD COLUMN `cancellationPeriodId` INTEGER NULL,
|
||||
ADD COLUMN `priceAfter24Months` VARCHAR(191) NULL,
|
||||
ADD COLUMN `priceFirst12Months` VARCHAR(191) NULL,
|
||||
ADD COLUMN `priceFrom13Months` VARCHAR(191) NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `Customer` ADD COLUMN `privacyPolicyPath` VARCHAR(191) NULL;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `CancellationPeriod` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`code` VARCHAR(191) NOT NULL,
|
||||
`description` VARCHAR(191) NOT NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `CancellationPeriod_code_key`(`code`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_cancellationPeriodId_fkey` FOREIGN KEY (`cancellationPeriodId`) REFERENCES `CancellationPeriod`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,18 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `Contract` ADD COLUMN `contractDurationId` INTEGER NULL;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `ContractDuration` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`code` VARCHAR(191) NOT NULL,
|
||||
`description` VARCHAR(191) NOT NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `ContractDuration_code_key`(`code`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_contractDurationId_fkey` FOREIGN KEY (`contractDurationId`) REFERENCES `ContractDuration`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `Contract` ADD COLUMN `cancellationConfirmationDate` DATETIME(3) NULL,
|
||||
ADD COLUMN `cancellationConfirmationOptionsDate` DATETIME(3) NULL,
|
||||
ADD COLUMN `cancellationConfirmationOptionsPath` VARCHAR(191) NULL,
|
||||
ADD COLUMN `cancellationConfirmationPath` VARCHAR(191) NULL,
|
||||
ADD COLUMN `cancellationLetterOptionsPath` VARCHAR(191) NULL,
|
||||
ADD COLUMN `cancellationLetterPath` VARCHAR(191) NULL,
|
||||
ADD COLUMN `wasSpecialCancellation` BOOLEAN NOT NULL DEFAULT false;
|
||||
@@ -0,0 +1,40 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `Contract` ADD COLUMN `providerId` INTEGER NULL,
|
||||
ADD COLUMN `tariffId` INTEGER NULL;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Provider` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`portalUrl` VARCHAR(191) NULL,
|
||||
`usernameFieldName` VARCHAR(191) NULL,
|
||||
`passwordFieldName` VARCHAR(191) NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Provider_name_key`(`name`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `Tariff` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`providerId` INTEGER NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `Tariff_providerId_name_key`(`providerId`, `name`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Tariff` ADD CONSTRAINT `Tariff_providerId_fkey` FOREIGN KEY (`providerId`) REFERENCES `Provider`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_providerId_fkey` FOREIGN KEY (`providerId`) REFERENCES `Provider`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_tariffId_fkey` FOREIGN KEY (`tariffId`) REFERENCES `Tariff`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,21 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `MobileContractDetails` ADD COLUMN `requiresMultisim` BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `SimCard` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`mobileDetailsId` INTEGER NOT NULL,
|
||||
`phoneNumber` VARCHAR(191) NULL,
|
||||
`simCardNumber` VARCHAR(191) NULL,
|
||||
`pin` VARCHAR(191) NULL,
|
||||
`puk` VARCHAR(191) NULL,
|
||||
`isMultisim` BOOLEAN NOT NULL DEFAULT false,
|
||||
`isMain` BOOLEAN NOT NULL DEFAULT false,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `SimCard` ADD CONSTRAINT `SimCard_mobileDetailsId_fkey` FOREIGN KEY (`mobileDetailsId`) REFERENCES `MobileContractDetails`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,21 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `Contract` ADD COLUMN `contractCategoryId` INTEGER NULL;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `ContractCategory` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`code` VARCHAR(191) NOT NULL,
|
||||
`name` VARCHAR(191) NOT NULL,
|
||||
`icon` VARCHAR(191) NULL,
|
||||
`color` VARCHAR(191) NULL,
|
||||
`sortOrder` INTEGER NOT NULL DEFAULT 0,
|
||||
`isActive` BOOLEAN NOT NULL DEFAULT true,
|
||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||
`updatedAt` DATETIME(3) NOT NULL,
|
||||
|
||||
UNIQUE INDEX `ContractCategory_code_key`(`code`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `Contract` ADD CONSTRAINT `Contract_contractCategoryId_fkey` FOREIGN KEY (`contractCategoryId`) REFERENCES `ContractCategory`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,13 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `Contract` MODIFY `type` ENUM('ELECTRICITY', 'GAS', 'DSL', 'CABLE', 'FIBER', 'MOBILE', 'TV', 'CAR_INSURANCE') NOT NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `InternetContractDetails` ADD COLUMN `activationCode` VARCHAR(191) NULL,
|
||||
ADD COLUMN `homeId` VARCHAR(191) NULL,
|
||||
ADD COLUMN `internetPasswordEncrypted` VARCHAR(191) NULL,
|
||||
ADD COLUMN `internetUsername` VARCHAR(191) NULL;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE `PhoneNumber` ADD COLUMN `sipPasswordEncrypted` VARCHAR(191) NULL,
|
||||
ADD COLUMN `sipServer` VARCHAR(191) NULL,
|
||||
ADD COLUMN `sipUsername` VARCHAR(191) NULL;
|
||||
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "mysql"
|
||||
@@ -0,0 +1,623 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "mysql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// ==================== APP SETTINGS ====================
|
||||
|
||||
model AppSetting {
|
||||
id Int @id @default(autoincrement())
|
||||
key String @unique
|
||||
value String @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== USERS & AUTH ====================
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
email String @unique
|
||||
password String
|
||||
firstName String
|
||||
lastName String
|
||||
isActive Boolean @default(true)
|
||||
customerId Int? @unique
|
||||
customer Customer? @relation(fields: [customerId], references: [id])
|
||||
roles UserRole[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Role {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique
|
||||
description String?
|
||||
permissions RolePermission[]
|
||||
users UserRole[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model Permission {
|
||||
id Int @id @default(autoincrement())
|
||||
resource String
|
||||
action String
|
||||
roles RolePermission[]
|
||||
|
||||
@@unique([resource, action])
|
||||
}
|
||||
|
||||
model RolePermission {
|
||||
roleId Int
|
||||
permissionId Int
|
||||
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
||||
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@id([roleId, permissionId])
|
||||
}
|
||||
|
||||
model UserRole {
|
||||
userId Int
|
||||
roleId Int
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@id([userId, roleId])
|
||||
}
|
||||
|
||||
// ==================== CUSTOMERS ====================
|
||||
|
||||
enum CustomerType {
|
||||
PRIVATE
|
||||
BUSINESS
|
||||
}
|
||||
|
||||
model Customer {
|
||||
id Int @id @default(autoincrement())
|
||||
customerNumber String @unique
|
||||
type CustomerType @default(PRIVATE)
|
||||
salutation String?
|
||||
firstName String
|
||||
lastName String
|
||||
companyName String?
|
||||
foundingDate DateTime? // Gründungsdatum (für Firmen)
|
||||
birthDate DateTime?
|
||||
birthPlace String?
|
||||
email String?
|
||||
phone String?
|
||||
mobile String?
|
||||
taxNumber String?
|
||||
businessRegistrationPath String? // PDF-Pfad zur Gewerbeanmeldung
|
||||
commercialRegisterPath String? // PDF-Pfad zum Handelsregisterauszug
|
||||
commercialRegisterNumber String? // Handelsregisternummer (Text)
|
||||
privacyPolicyPath String? // PDF-Pfad zur Datenschutzerklärung (für alle Kunden)
|
||||
notes String? @db.Text
|
||||
|
||||
// ===== Portal-Zugangsdaten =====
|
||||
portalEnabled Boolean @default(false) // Portal aktiviert?
|
||||
portalEmail String? @unique // Portal-Login E-Mail
|
||||
portalPasswordHash String? // Gehashtes Passwort (für Login)
|
||||
portalPasswordEncrypted String? // Verschlüsseltes Passwort (für Anzeige)
|
||||
portalLastLogin DateTime? // Letzte Anmeldung
|
||||
|
||||
user User?
|
||||
addresses Address[]
|
||||
bankCards BankCard[]
|
||||
identityDocuments IdentityDocument[]
|
||||
meters Meter[]
|
||||
stressfreiEmails StressfreiEmail[]
|
||||
contracts Contract[]
|
||||
|
||||
// Vertreter-Beziehungen (Kunde kann für andere Kunden handeln)
|
||||
representingFor CustomerRepresentative[] @relation("RepresentativeCustomer")
|
||||
representedBy CustomerRepresentative[] @relation("RepresentedCustomer")
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== CUSTOMER REPRESENTATIVES ====================
|
||||
// Vertretungsbeziehung: Ein Kunde kann die Verträge eines anderen Kunden einsehen
|
||||
// z.B. Sohn (representativeId) kann Verträge der Mutter (customerId) sehen
|
||||
|
||||
model CustomerRepresentative {
|
||||
id Int @id @default(autoincrement())
|
||||
customerId Int // Der Kunde, dessen Verträge eingesehen werden (z.B. Mutter)
|
||||
customer Customer @relation("RepresentedCustomer", fields: [customerId], references: [id], onDelete: Cascade)
|
||||
representativeId Int // Der Kunde, der einsehen darf (z.B. Sohn)
|
||||
representative Customer @relation("RepresentativeCustomer", fields: [representativeId], references: [id], onDelete: Cascade)
|
||||
notes String? // Notizen zur Vertretung
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([customerId, representativeId]) // Keine doppelten Einträge
|
||||
}
|
||||
|
||||
// ==================== ADDRESSES ====================
|
||||
|
||||
enum AddressType {
|
||||
DELIVERY_RESIDENCE
|
||||
BILLING
|
||||
}
|
||||
|
||||
model Address {
|
||||
id Int @id @default(autoincrement())
|
||||
customerId Int
|
||||
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
|
||||
type AddressType @default(DELIVERY_RESIDENCE)
|
||||
street String
|
||||
houseNumber String
|
||||
postalCode String
|
||||
city String
|
||||
country String @default("Deutschland")
|
||||
isDefault Boolean @default(false)
|
||||
contracts Contract[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== BANK CARDS ====================
|
||||
|
||||
model BankCard {
|
||||
id Int @id @default(autoincrement())
|
||||
customerId Int
|
||||
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
|
||||
accountHolder String
|
||||
iban String
|
||||
bic String?
|
||||
bankName String?
|
||||
expiryDate DateTime?
|
||||
documentPath String? // Pfad zur hochgeladenen PDF
|
||||
isActive Boolean @default(true)
|
||||
contracts Contract[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== IDENTITY DOCUMENTS ====================
|
||||
|
||||
enum DocumentType {
|
||||
ID_CARD
|
||||
PASSPORT
|
||||
DRIVERS_LICENSE
|
||||
OTHER
|
||||
}
|
||||
|
||||
model IdentityDocument {
|
||||
id Int @id @default(autoincrement())
|
||||
customerId Int
|
||||
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
|
||||
type DocumentType @default(ID_CARD)
|
||||
documentNumber String
|
||||
issuingAuthority String?
|
||||
issueDate DateTime?
|
||||
expiryDate DateTime?
|
||||
documentPath String? // Pfad zur hochgeladenen PDF
|
||||
isActive Boolean @default(true)
|
||||
// Führerschein-spezifische Felder
|
||||
licenseClasses String? // z.B. "B, BE, AM, L" - kommasepariert
|
||||
licenseIssueDate DateTime? // Datum des Führerscheinerwerbs (Klasse B)
|
||||
contracts Contract[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== EMAIL PROVIDER CONFIG (Plesk, cPanel etc.) ====================
|
||||
|
||||
enum EmailProviderType {
|
||||
PLESK
|
||||
CPANEL
|
||||
DIRECTADMIN
|
||||
}
|
||||
|
||||
model EmailProviderConfig {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique // z.B. "Plesk Hauptserver"
|
||||
type EmailProviderType
|
||||
apiUrl String // API-URL (z.B. https://server.de:8443)
|
||||
apiKey String? // API-Key (verschlüsselt)
|
||||
username String? // Benutzername für API
|
||||
passwordEncrypted String? // Passwort (verschlüsselt)
|
||||
domain String // Domain für E-Mails (z.B. stressfrei-wechseln.de)
|
||||
defaultForwardEmail String? // Standard-Weiterleitungsadresse (unsere eigene)
|
||||
isActive Boolean @default(true)
|
||||
isDefault Boolean @default(false) // Standard-Provider
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== STRESSFREI-WECHSELN EMAIL ADDRESSES ====================
|
||||
|
||||
model StressfreiEmail {
|
||||
id Int @id @default(autoincrement())
|
||||
customerId Int
|
||||
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
|
||||
email String // Die Weiterleitungs-E-Mail-Adresse
|
||||
platform String? // Für welche Plattform (z.B. "Freenet", "Klarmobil")
|
||||
notes String? @db.Text // Optionale Notizen
|
||||
isActive Boolean @default(true)
|
||||
isProvisioned Boolean @default(false) // Wurde bei Provider angelegt?
|
||||
provisionedAt DateTime? // Wann wurde provisioniert?
|
||||
provisionError String? @db.Text // Fehlermeldung falls Provisionierung fehlschlug
|
||||
contracts Contract[] // Verträge die diese E-Mail als Benutzername verwenden
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== METERS (Energy) ====================
|
||||
|
||||
enum MeterType {
|
||||
ELECTRICITY
|
||||
GAS
|
||||
}
|
||||
|
||||
model Meter {
|
||||
id Int @id @default(autoincrement())
|
||||
customerId Int
|
||||
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
|
||||
meterNumber String
|
||||
type MeterType
|
||||
location String?
|
||||
isActive Boolean @default(true)
|
||||
readings MeterReading[]
|
||||
energyDetails EnergyContractDetails[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model MeterReading {
|
||||
id Int @id @default(autoincrement())
|
||||
meterId Int
|
||||
meter Meter @relation(fields: [meterId], references: [id], onDelete: Cascade)
|
||||
readingDate DateTime
|
||||
value Float
|
||||
unit String @default("kWh")
|
||||
notes String?
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
// ==================== SALES PLATFORMS ====================
|
||||
|
||||
model SalesPlatform {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique
|
||||
contactInfo String? @db.Text
|
||||
isActive Boolean @default(true)
|
||||
contracts Contract[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== CANCELLATION PERIODS ====================
|
||||
|
||||
model CancellationPeriod {
|
||||
id Int @id @default(autoincrement())
|
||||
code String @unique // z.B. "14T", "1M", "3M", "12M", "1J"
|
||||
description String // z.B. "14 Tage", "1 Monat", "3 Monate"
|
||||
isActive Boolean @default(true)
|
||||
contracts Contract[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== CONTRACT DURATIONS ====================
|
||||
|
||||
model ContractDuration {
|
||||
id Int @id @default(autoincrement())
|
||||
code String @unique // z.B. "12M", "24M", "1J", "2J"
|
||||
description String // z.B. "12 Monate", "24 Monate", "1 Jahr"
|
||||
isActive Boolean @default(true)
|
||||
contracts Contract[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== PROVIDERS (Anbieter) ====================
|
||||
|
||||
model Provider {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique // Anbietername
|
||||
portalUrl String? // Kundenkontourl (Login-Seite)
|
||||
usernameFieldName String? // Benutzernamefeld (z.B. "email", "username")
|
||||
passwordFieldName String? // Kennwortfeld (z.B. "password", "pwd")
|
||||
isActive Boolean @default(true)
|
||||
tariffs Tariff[]
|
||||
contracts Contract[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== TARIFFS (Tarife) ====================
|
||||
|
||||
model Tariff {
|
||||
id Int @id @default(autoincrement())
|
||||
providerId Int
|
||||
provider Provider @relation(fields: [providerId], references: [id], onDelete: Cascade)
|
||||
name String // Tarifname
|
||||
isActive Boolean @default(true)
|
||||
contracts Contract[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([providerId, name]) // Eindeutiger Tarif pro Anbieter
|
||||
}
|
||||
|
||||
// ==================== CONTRACT CATEGORIES ====================
|
||||
|
||||
model ContractCategory {
|
||||
id Int @id @default(autoincrement())
|
||||
code String @unique // Technischer Code (z.B. ELECTRICITY, GAS)
|
||||
name String // Anzeigename (z.B. Strom, Gas)
|
||||
icon String? // Icon-Name für UI (z.B. "Zap", "Flame")
|
||||
color String? // Farbe für UI (z.B. "#FFC107")
|
||||
sortOrder Int @default(0)
|
||||
isActive Boolean @default(true)
|
||||
contracts Contract[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== CONTRACTS ====================
|
||||
|
||||
// Legacy Enum - wird durch ContractCategory ersetzt
|
||||
enum ContractType {
|
||||
ELECTRICITY
|
||||
GAS
|
||||
DSL
|
||||
CABLE
|
||||
FIBER
|
||||
MOBILE
|
||||
TV
|
||||
CAR_INSURANCE
|
||||
}
|
||||
|
||||
enum ContractStatus {
|
||||
DRAFT
|
||||
PENDING
|
||||
ACTIVE
|
||||
CANCELLED
|
||||
EXPIRED
|
||||
DEACTIVATED
|
||||
}
|
||||
|
||||
model Contract {
|
||||
id Int @id @default(autoincrement())
|
||||
contractNumber String @unique
|
||||
customerId Int
|
||||
customer Customer @relation(fields: [customerId], references: [id], onDelete: Cascade)
|
||||
type ContractType
|
||||
status ContractStatus @default(DRAFT)
|
||||
|
||||
// Neue konfigurierbare Kategorie (ersetzt langfristig das type-Enum)
|
||||
contractCategoryId Int?
|
||||
contractCategory ContractCategory? @relation(fields: [contractCategoryId], references: [id])
|
||||
|
||||
addressId Int?
|
||||
address Address? @relation(fields: [addressId], references: [id])
|
||||
|
||||
bankCardId Int?
|
||||
bankCard BankCard? @relation(fields: [bankCardId], references: [id])
|
||||
|
||||
identityDocumentId Int?
|
||||
identityDocument IdentityDocument? @relation(fields: [identityDocumentId], references: [id])
|
||||
|
||||
salesPlatformId Int?
|
||||
salesPlatform SalesPlatform? @relation(fields: [salesPlatformId], references: [id])
|
||||
|
||||
cancellationPeriodId Int?
|
||||
cancellationPeriod CancellationPeriod? @relation(fields: [cancellationPeriodId], references: [id])
|
||||
|
||||
contractDurationId Int?
|
||||
contractDuration ContractDuration? @relation(fields: [contractDurationId], references: [id])
|
||||
|
||||
previousContractId Int? @unique
|
||||
previousContract Contract? @relation("ContractHistory", fields: [previousContractId], references: [id])
|
||||
followUpContract Contract? @relation("ContractHistory")
|
||||
|
||||
// Anbieter & Tarif (neue Verknüpfung)
|
||||
providerId Int?
|
||||
provider Provider? @relation(fields: [providerId], references: [id])
|
||||
tariffId Int?
|
||||
tariff Tariff? @relation(fields: [tariffId], references: [id])
|
||||
|
||||
// Legacy-Felder (für Abwärtskompatibilität)
|
||||
providerName String?
|
||||
tariffName String?
|
||||
customerNumberAtProvider String?
|
||||
priceFirst12Months String? // Preis erste 12 Monate
|
||||
priceFrom13Months String? // Preis ab 13. Monat
|
||||
priceAfter24Months String? // Preis nach 24 Monaten
|
||||
|
||||
startDate DateTime?
|
||||
endDate DateTime? // Wird aus startDate + contractDuration berechnet
|
||||
commission Float?
|
||||
|
||||
// Kündigungsdokumente
|
||||
cancellationLetterPath String? // Kündigungsschreiben PDF
|
||||
cancellationConfirmationPath String? // Kündigungsbestätigung PDF
|
||||
cancellationLetterOptionsPath String? // Kündigungsschreiben Optionen PDF
|
||||
cancellationConfirmationOptionsPath String? // Kündigungsbestätigung Optionen PDF
|
||||
|
||||
// Kündigungsdaten
|
||||
cancellationConfirmationDate DateTime? // Kündigungsbestätigungsdatum
|
||||
cancellationConfirmationOptionsDate DateTime? // Kündigungsbestätigungsoptionendatum
|
||||
wasSpecialCancellation Boolean @default(false) // Wurde sondergekündigt?
|
||||
|
||||
portalUsername String?
|
||||
portalPasswordEncrypted String?
|
||||
|
||||
// Stressfrei-Wechseln E-Mail als Benutzername (Alternative zu portalUsername)
|
||||
stressfreiEmailId Int?
|
||||
stressfreiEmail StressfreiEmail? @relation(fields: [stressfreiEmailId], references: [id])
|
||||
|
||||
notes String? @db.Text
|
||||
|
||||
energyDetails EnergyContractDetails?
|
||||
internetDetails InternetContractDetails?
|
||||
mobileDetails MobileContractDetails?
|
||||
tvDetails TvContractDetails?
|
||||
carInsuranceDetails CarInsuranceDetails?
|
||||
|
||||
tasks ContractTask[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== CONTRACT TASKS ====================
|
||||
|
||||
enum ContractTaskStatus {
|
||||
OPEN
|
||||
COMPLETED
|
||||
}
|
||||
|
||||
model ContractTask {
|
||||
id Int @id @default(autoincrement())
|
||||
contractId Int
|
||||
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
||||
title String
|
||||
description String? @db.Text
|
||||
status ContractTaskStatus @default(OPEN)
|
||||
visibleInPortal Boolean @default(false)
|
||||
createdBy String? // Name des Erstellers
|
||||
completedAt DateTime?
|
||||
subtasks ContractTaskSubtask[]
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
model ContractTaskSubtask {
|
||||
id Int @id @default(autoincrement())
|
||||
taskId Int
|
||||
task ContractTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
||||
title String
|
||||
status ContractTaskStatus @default(OPEN)
|
||||
createdBy String?
|
||||
completedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== ENERGY CONTRACT DETAILS ====================
|
||||
|
||||
model EnergyContractDetails {
|
||||
id Int @id @default(autoincrement())
|
||||
contractId Int @unique
|
||||
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
||||
meterId Int?
|
||||
meter Meter? @relation(fields: [meterId], references: [id])
|
||||
annualConsumption Float?
|
||||
basePrice Float?
|
||||
unitPrice Float?
|
||||
bonus Float?
|
||||
previousProviderName String?
|
||||
previousCustomerNumber String?
|
||||
}
|
||||
|
||||
// ==================== INTERNET CONTRACT DETAILS ====================
|
||||
|
||||
model InternetContractDetails {
|
||||
id Int @id @default(autoincrement())
|
||||
contractId Int @unique
|
||||
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
||||
downloadSpeed Int?
|
||||
uploadSpeed Int?
|
||||
routerModel String?
|
||||
routerSerialNumber String?
|
||||
installationDate DateTime?
|
||||
// Internet-Zugangsdaten
|
||||
internetUsername String?
|
||||
internetPasswordEncrypted String? // Verschlüsselt gespeichert
|
||||
// Glasfaser-spezifisch
|
||||
homeId String?
|
||||
// Vodafone DSL/Kabel spezifisch
|
||||
activationCode String?
|
||||
phoneNumbers PhoneNumber[]
|
||||
}
|
||||
|
||||
model PhoneNumber {
|
||||
id Int @id @default(autoincrement())
|
||||
internetContractDetailsId Int
|
||||
internetDetails InternetContractDetails @relation(fields: [internetContractDetailsId], references: [id], onDelete: Cascade)
|
||||
phoneNumber String
|
||||
isMain Boolean @default(false)
|
||||
// SIP-Zugangsdaten
|
||||
sipUsername String?
|
||||
sipPasswordEncrypted String? // Verschlüsselt gespeichert
|
||||
sipServer String?
|
||||
}
|
||||
|
||||
// ==================== MOBILE CONTRACT DETAILS ====================
|
||||
|
||||
model MobileContractDetails {
|
||||
id Int @id @default(autoincrement())
|
||||
contractId Int @unique
|
||||
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
||||
requiresMultisim Boolean @default(false) // Multisim erforderlich?
|
||||
dataVolume Float?
|
||||
includedMinutes Int?
|
||||
includedSMS Int?
|
||||
deviceModel String?
|
||||
deviceImei String?
|
||||
simCards SimCard[]
|
||||
// Legacy-Felder (für Abwärtskompatibilität, werden durch simCards ersetzt)
|
||||
phoneNumber String?
|
||||
simCardNumber String?
|
||||
}
|
||||
|
||||
model SimCard {
|
||||
id Int @id @default(autoincrement())
|
||||
mobileDetailsId Int
|
||||
mobileDetails MobileContractDetails @relation(fields: [mobileDetailsId], references: [id], onDelete: Cascade)
|
||||
phoneNumber String? // Rufnummer
|
||||
simCardNumber String? // SIM-Kartennummer
|
||||
pin String? // PIN (verschlüsselt gespeichert)
|
||||
puk String? // PUK (verschlüsselt gespeichert)
|
||||
isMultisim Boolean @default(false) // Ist dies eine Multisim-Karte?
|
||||
isMain Boolean @default(false) // Ist dies die Hauptkarte?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// ==================== TV CONTRACT DETAILS ====================
|
||||
|
||||
model TvContractDetails {
|
||||
id Int @id @default(autoincrement())
|
||||
contractId Int @unique
|
||||
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
||||
receiverModel String?
|
||||
smartcardNumber String?
|
||||
package String?
|
||||
}
|
||||
|
||||
// ==================== CAR INSURANCE DETAILS ====================
|
||||
|
||||
enum InsuranceType {
|
||||
LIABILITY
|
||||
PARTIAL
|
||||
FULL
|
||||
}
|
||||
|
||||
model CarInsuranceDetails {
|
||||
id Int @id @default(autoincrement())
|
||||
contractId Int @unique
|
||||
contract Contract @relation(fields: [contractId], references: [id], onDelete: Cascade)
|
||||
licensePlate String?
|
||||
hsn String?
|
||||
tsn String?
|
||||
vin String?
|
||||
vehicleType String?
|
||||
firstRegistration DateTime?
|
||||
noClaimsClass String?
|
||||
insuranceType InsuranceType @default(LIABILITY)
|
||||
deductiblePartial Float?
|
||||
deductibleFull Float?
|
||||
policyNumber String?
|
||||
previousInsurer String?
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import bcrypt from 'bcryptjs';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
console.log('Seeding database...');
|
||||
|
||||
// Create permissions
|
||||
const resources = ['customers', 'contracts', 'users', 'platforms', 'providers', 'developer'];
|
||||
const actions = ['create', 'read', 'update', 'delete', 'access'];
|
||||
|
||||
const permissions: { resource: string; action: string }[] = [];
|
||||
for (const resource of resources) {
|
||||
for (const action of actions) {
|
||||
// developer nur mit 'access' action
|
||||
if (resource === 'developer' && action !== 'access') continue;
|
||||
// andere resources ohne 'access' action
|
||||
if (resource !== 'developer' && action === 'access') continue;
|
||||
permissions.push({ resource, action });
|
||||
}
|
||||
}
|
||||
|
||||
for (const perm of permissions) {
|
||||
await prisma.permission.upsert({
|
||||
where: { resource_action: perm },
|
||||
update: {},
|
||||
create: perm,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Permissions created');
|
||||
|
||||
// Get all permissions
|
||||
const allPermissions = await prisma.permission.findMany();
|
||||
const customerReadPerm = allPermissions.find(
|
||||
(p) => p.resource === 'customers' && p.action === 'read'
|
||||
);
|
||||
const contractReadPerm = allPermissions.find(
|
||||
(p) => p.resource === 'contracts' && p.action === 'read'
|
||||
);
|
||||
const platformReadPerm = allPermissions.find(
|
||||
(p) => p.resource === 'platforms' && p.action === 'read'
|
||||
);
|
||||
const providerReadPerm = allPermissions.find(
|
||||
(p) => p.resource === 'providers' && p.action === 'read'
|
||||
);
|
||||
|
||||
// Create roles
|
||||
// Admin - all permissions EXCEPT developer:access (that's controlled separately)
|
||||
const adminPermissions = allPermissions.filter(
|
||||
(p) => !(p.resource === 'developer' && p.action === 'access')
|
||||
);
|
||||
const adminRole = await prisma.role.upsert({
|
||||
where: { name: 'Admin' },
|
||||
update: {},
|
||||
create: {
|
||||
name: 'Admin',
|
||||
description: 'Voller Zugriff auf alle Funktionen',
|
||||
permissions: {
|
||||
create: adminPermissions.map((p) => ({ permissionId: p.id })),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Employee - full access to customers, contracts, read platforms and providers
|
||||
const employeePermIds = allPermissions
|
||||
.filter(
|
||||
(p) =>
|
||||
p.resource === 'customers' ||
|
||||
p.resource === 'contracts' ||
|
||||
(p.resource === 'platforms' && p.action === 'read') ||
|
||||
(p.resource === 'providers' && p.action === 'read')
|
||||
)
|
||||
.map((p) => p.id);
|
||||
|
||||
const employeeRole = await prisma.role.upsert({
|
||||
where: { name: 'Mitarbeiter' },
|
||||
update: {},
|
||||
create: {
|
||||
name: 'Mitarbeiter',
|
||||
description: 'Kann Kunden und Verträge verwalten',
|
||||
permissions: {
|
||||
create: employeePermIds.map((id) => ({ permissionId: id })),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Read-only employee
|
||||
const readOnlyPermIds = [customerReadPerm?.id, contractReadPerm?.id, platformReadPerm?.id, providerReadPerm?.id].filter(
|
||||
(id): id is number => id !== undefined
|
||||
);
|
||||
|
||||
const readOnlyRole = await prisma.role.upsert({
|
||||
where: { name: 'Mitarbeiter (Nur-Lesen)' },
|
||||
update: {},
|
||||
create: {
|
||||
name: 'Mitarbeiter (Nur-Lesen)',
|
||||
description: 'Kann nur lesen, keine Änderungen',
|
||||
permissions: {
|
||||
create: readOnlyPermIds.map((id) => ({ permissionId: id })),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Customer role - read own data only (handled in middleware)
|
||||
const customerRole = await prisma.role.upsert({
|
||||
where: { name: 'Kunde' },
|
||||
update: {},
|
||||
create: {
|
||||
name: 'Kunde',
|
||||
description: 'Kann nur eigene Daten lesen',
|
||||
permissions: {
|
||||
create: readOnlyPermIds.map((id) => ({ permissionId: id })),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log('Roles created');
|
||||
|
||||
// Create admin user
|
||||
const hashedPassword = await bcrypt.hash('admin', 10);
|
||||
|
||||
const adminUser = await prisma.user.upsert({
|
||||
where: { email: 'admin@admin.com' },
|
||||
update: {},
|
||||
create: {
|
||||
email: 'admin@admin.com',
|
||||
password: hashedPassword,
|
||||
firstName: 'Admin',
|
||||
lastName: 'User',
|
||||
roles: {
|
||||
create: [{ roleId: adminRole.id }],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log('Admin user created: admin@admin.com / admin');
|
||||
|
||||
// Create some sales platforms
|
||||
const platforms = ['Moon Fachhandel', 'Verivox', 'Check24', 'Eigenvermittlung'];
|
||||
for (const name of platforms) {
|
||||
await prisma.salesPlatform.upsert({
|
||||
where: { name },
|
||||
update: {},
|
||||
create: { name, isActive: true },
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Sales platforms created');
|
||||
|
||||
// Create contract categories (matching existing enum values)
|
||||
const contractCategories = [
|
||||
{ code: 'ELECTRICITY', name: 'Strom', icon: 'Zap', color: '#FFC107', sortOrder: 1 },
|
||||
{ code: 'GAS', name: 'Gas', icon: 'Flame', color: '#FF5722', sortOrder: 2 },
|
||||
{ code: 'DSL', name: 'DSL', icon: 'Wifi', color: '#2196F3', sortOrder: 3 },
|
||||
{ code: 'FIBER', name: 'Glasfaser', icon: 'Cable', color: '#9C27B0', sortOrder: 4 },
|
||||
{ code: 'MOBILE', name: 'Mobilfunk', icon: 'Smartphone', color: '#4CAF50', sortOrder: 5 },
|
||||
{ code: 'TV', name: 'TV', icon: 'Tv', color: '#E91E63', sortOrder: 6 },
|
||||
{ code: 'CAR_INSURANCE', name: 'KFZ-Versicherung', icon: 'Car', color: '#607D8B', sortOrder: 7 },
|
||||
];
|
||||
|
||||
for (const category of contractCategories) {
|
||||
await prisma.contractCategory.upsert({
|
||||
where: { code: category.code },
|
||||
update: { name: category.name, icon: category.icon, color: category.color, sortOrder: category.sortOrder },
|
||||
create: category,
|
||||
});
|
||||
}
|
||||
|
||||
console.log('Contract categories created');
|
||||
|
||||
console.log('Seeding completed!');
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
Reference in New Issue
Block a user