Neo platform - First Version

This commit is contained in:
Francisco Gaona
2025-11-25 12:21:14 +01:00
commit 484af68571
59 changed files with 3699 additions and 0 deletions

View File

@@ -0,0 +1,224 @@
-- CreateTable
CREATE TABLE `tenants` (
`id` VARCHAR(191) NOT NULL,
`name` VARCHAR(191) NOT NULL,
`slug` 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 `tenants_slug_key`(`slug`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `users` (
`id` VARCHAR(191) NOT NULL,
`tenantId` VARCHAR(191) NOT NULL,
`email` VARCHAR(191) NOT NULL,
`password` VARCHAR(191) NOT NULL,
`firstName` VARCHAR(191) NULL,
`lastName` VARCHAR(191) NULL,
`isActive` BOOLEAN NOT NULL DEFAULT true,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `users_tenantId_idx`(`tenantId`),
UNIQUE INDEX `users_tenantId_email_key`(`tenantId`, `email`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `roles` (
`id` VARCHAR(191) NOT NULL,
`tenantId` VARCHAR(191) NOT NULL,
`name` VARCHAR(191) NOT NULL,
`guardName` VARCHAR(191) NOT NULL DEFAULT 'api',
`description` VARCHAR(191) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `roles_tenantId_idx`(`tenantId`),
UNIQUE INDEX `roles_tenantId_name_guardName_key`(`tenantId`, `name`, `guardName`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `permissions` (
`id` VARCHAR(191) NOT NULL,
`tenantId` VARCHAR(191) NOT NULL,
`name` VARCHAR(191) NOT NULL,
`guardName` VARCHAR(191) NOT NULL DEFAULT 'api',
`description` VARCHAR(191) NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `permissions_tenantId_idx`(`tenantId`),
UNIQUE INDEX `permissions_tenantId_name_guardName_key`(`tenantId`, `name`, `guardName`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `user_roles` (
`id` VARCHAR(191) NOT NULL,
`userId` VARCHAR(191) NOT NULL,
`roleId` VARCHAR(191) NOT NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
INDEX `user_roles_userId_idx`(`userId`),
INDEX `user_roles_roleId_idx`(`roleId`),
UNIQUE INDEX `user_roles_userId_roleId_key`(`userId`, `roleId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `role_permissions` (
`id` VARCHAR(191) NOT NULL,
`roleId` VARCHAR(191) NOT NULL,
`permissionId` VARCHAR(191) NOT NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
INDEX `role_permissions_roleId_idx`(`roleId`),
INDEX `role_permissions_permissionId_idx`(`permissionId`),
UNIQUE INDEX `role_permissions_roleId_permissionId_key`(`roleId`, `permissionId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `object_definitions` (
`id` VARCHAR(191) NOT NULL,
`tenantId` VARCHAR(191) NOT NULL,
`apiName` VARCHAR(191) NOT NULL,
`label` VARCHAR(191) NOT NULL,
`pluralLabel` VARCHAR(191) NULL,
`description` TEXT NULL,
`isSystem` BOOLEAN NOT NULL DEFAULT false,
`tableName` VARCHAR(191) NULL,
`isActive` BOOLEAN NOT NULL DEFAULT true,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `object_definitions_tenantId_idx`(`tenantId`),
UNIQUE INDEX `object_definitions_tenantId_apiName_key`(`tenantId`, `apiName`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `field_definitions` (
`id` VARCHAR(191) NOT NULL,
`objectId` VARCHAR(191) NOT NULL,
`apiName` VARCHAR(191) NOT NULL,
`label` VARCHAR(191) NOT NULL,
`type` VARCHAR(191) NOT NULL,
`description` TEXT NULL,
`isRequired` BOOLEAN NOT NULL DEFAULT false,
`isUnique` BOOLEAN NOT NULL DEFAULT false,
`isReadonly` BOOLEAN NOT NULL DEFAULT false,
`isLookup` BOOLEAN NOT NULL DEFAULT false,
`referenceTo` VARCHAR(191) NULL,
`defaultValue` VARCHAR(191) NULL,
`options` JSON NULL,
`validationRules` JSON NULL,
`isActive` BOOLEAN NOT NULL DEFAULT true,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `field_definitions_objectId_idx`(`objectId`),
UNIQUE INDEX `field_definitions_objectId_apiName_key`(`objectId`, `apiName`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `accounts` (
`id` VARCHAR(191) NOT NULL,
`tenantId` VARCHAR(191) NOT NULL,
`name` VARCHAR(191) NOT NULL,
`status` VARCHAR(191) NOT NULL DEFAULT 'active',
`ownerId` VARCHAR(191) NOT NULL,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `accounts_tenantId_idx`(`tenantId`),
INDEX `accounts_ownerId_idx`(`ownerId`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `apps` (
`id` VARCHAR(191) NOT NULL,
`tenantId` VARCHAR(191) NOT NULL,
`slug` VARCHAR(191) NOT NULL,
`label` VARCHAR(191) NOT NULL,
`description` TEXT NULL,
`icon` VARCHAR(191) NULL,
`isActive` BOOLEAN NOT NULL DEFAULT true,
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`updatedAt` DATETIME(3) NOT NULL,
INDEX `apps_tenantId_idx`(`tenantId`),
UNIQUE INDEX `apps_tenantId_slug_key`(`tenantId`, `slug`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- CreateTable
CREATE TABLE `app_pages` (
`id` VARCHAR(191) NOT NULL,
`appId` VARCHAR(191) NOT NULL,
`slug` VARCHAR(191) NOT NULL,
`label` VARCHAR(191) NOT NULL,
`type` VARCHAR(191) NOT NULL,
`objectApiName` VARCHAR(191) NULL,
`objectId` VARCHAR(191) NULL,
`config` JSON 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,
INDEX `app_pages_appId_idx`(`appId`),
INDEX `app_pages_objectId_idx`(`objectId`),
UNIQUE INDEX `app_pages_appId_slug_key`(`appId`, `slug`),
PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- AddForeignKey
ALTER TABLE `users` ADD CONSTRAINT `users_tenantId_fkey` FOREIGN KEY (`tenantId`) REFERENCES `tenants`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `roles` ADD CONSTRAINT `roles_tenantId_fkey` FOREIGN KEY (`tenantId`) REFERENCES `tenants`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `permissions` ADD CONSTRAINT `permissions_tenantId_fkey` FOREIGN KEY (`tenantId`) REFERENCES `tenants`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `user_roles` ADD CONSTRAINT `user_roles_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `user_roles` ADD CONSTRAINT `user_roles_roleId_fkey` FOREIGN KEY (`roleId`) REFERENCES `roles`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `role_permissions` ADD CONSTRAINT `role_permissions_roleId_fkey` FOREIGN KEY (`roleId`) REFERENCES `roles`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `role_permissions` ADD CONSTRAINT `role_permissions_permissionId_fkey` FOREIGN KEY (`permissionId`) REFERENCES `permissions`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `object_definitions` ADD CONSTRAINT `object_definitions_tenantId_fkey` FOREIGN KEY (`tenantId`) REFERENCES `tenants`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `field_definitions` ADD CONSTRAINT `field_definitions_objectId_fkey` FOREIGN KEY (`objectId`) REFERENCES `object_definitions`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `accounts` ADD CONSTRAINT `accounts_tenantId_fkey` FOREIGN KEY (`tenantId`) REFERENCES `tenants`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `accounts` ADD CONSTRAINT `accounts_ownerId_fkey` FOREIGN KEY (`ownerId`) REFERENCES `users`(`id`) ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `apps` ADD CONSTRAINT `apps_tenantId_fkey` FOREIGN KEY (`tenantId`) REFERENCES `tenants`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `app_pages` ADD CONSTRAINT `app_pages_appId_fkey` FOREIGN KEY (`appId`) REFERENCES `apps`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE `app_pages` ADD CONSTRAINT `app_pages_objectId_fkey` FOREIGN KEY (`objectId`) REFERENCES `object_definitions`(`id`) ON UPDATE CASCADE;

View File

@@ -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"

View File

@@ -0,0 +1,227 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
// Multi-tenancy
model Tenant {
id String @id @default(uuid())
name String
slug String @unique
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
users User[]
objectDefinitions ObjectDefinition[]
accounts Account[]
apps App[]
roles Role[]
permissions Permission[]
@@map("tenants")
}
// User & Auth
model User {
id String @id @default(uuid())
tenantId String
email String
password String
firstName String?
lastName String?
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
userRoles UserRole[]
accounts Account[]
@@unique([tenantId, email])
@@index([tenantId])
@@map("users")
}
// RBAC - Spatie-like
model Role {
id String @id @default(uuid())
tenantId String
name String
guardName String @default("api")
description String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
userRoles UserRole[]
rolePermissions RolePermission[]
@@unique([tenantId, name, guardName])
@@index([tenantId])
@@map("roles")
}
model Permission {
id String @id @default(uuid())
tenantId String
name String
guardName String @default("api")
description String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
rolePermissions RolePermission[]
@@unique([tenantId, name, guardName])
@@index([tenantId])
@@map("permissions")
}
model UserRole {
id String @id @default(uuid())
userId String
roleId String
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
@@unique([userId, roleId])
@@index([userId])
@@index([roleId])
@@map("user_roles")
}
model RolePermission {
id String @id @default(uuid())
roleId String
permissionId String
createdAt DateTime @default(now())
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
@@unique([roleId, permissionId])
@@index([roleId])
@@index([permissionId])
@@map("role_permissions")
}
// Object Definition (Metadata)
model ObjectDefinition {
id String @id @default(uuid())
tenantId String
apiName String
label String
pluralLabel String?
description String? @db.Text
isSystem Boolean @default(false)
tableName String?
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
fields FieldDefinition[]
pages AppPage[]
@@unique([tenantId, apiName])
@@index([tenantId])
@@map("object_definitions")
}
model FieldDefinition {
id String @id @default(uuid())
objectId String
apiName String
label String
type String // text, number, boolean, date, datetime, lookup, picklist, etc.
description String? @db.Text
isRequired Boolean @default(false)
isUnique Boolean @default(false)
isReadonly Boolean @default(false)
isLookup Boolean @default(false)
referenceTo String? // objectApiName for lookup fields
defaultValue String?
options Json? // for picklist fields
validationRules Json? // custom validation rules
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
object ObjectDefinition @relation(fields: [objectId], references: [id], onDelete: Cascade)
@@unique([objectId, apiName])
@@index([objectId])
@@map("field_definitions")
}
// Example static object: Account
model Account {
id String @id @default(uuid())
tenantId String
name String
status String @default("active")
ownerId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
owner User @relation(fields: [ownerId], references: [id])
@@index([tenantId])
@@index([ownerId])
@@map("accounts")
}
// Application Builder
model App {
id String @id @default(uuid())
tenantId String
slug String
label String
description String? @db.Text
icon String?
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
pages AppPage[]
@@unique([tenantId, slug])
@@index([tenantId])
@@map("apps")
}
model AppPage {
id String @id @default(uuid())
appId String
slug String
label String
type String // list, board, dashboard, form, detail
objectApiName String?
objectId String?
config Json? // page-specific configuration
sortOrder Int @default(0)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
app App @relation(fields: [appId], references: [id], onDelete: Cascade)
object ObjectDefinition? @relation(fields: [objectId], references: [id])
@@unique([appId, slug])
@@index([appId])
@@index([objectId])
@@map("app_pages")
}