Initial commit: SDI SaaS Platform foundation
- Complete monorepo structure with pnpm workspaces - Prisma database schema with 20+ entities - NestJS API with 9 core modules - BullMQ orchestration worker - AWS and Azure provider adapters - Docker Compose infrastructure - Complete documentation
This commit is contained in:
389
packages/database/prisma/schema.prisma
Normal file
389
packages/database/prisma/schema.prisma
Normal file
@@ -0,0 +1,389 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// TENANCY & IDENTITY
|
||||
// ============================================================================
|
||||
|
||||
model Tenant {
|
||||
id String @id @default(uuid())
|
||||
name String
|
||||
slug String @unique
|
||||
status String @default("active") // active, suspended, terminated
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
users User[]
|
||||
orders ServiceOrder[]
|
||||
services Service[]
|
||||
apiKeys ApiKey[]
|
||||
webhookEndpoints WebhookEndpoint[]
|
||||
providerAccounts ProviderAccount[]
|
||||
invoices Invoice[]
|
||||
|
||||
@@map("tenants")
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(uuid())
|
||||
tenantId String
|
||||
email String @unique
|
||||
name String
|
||||
status String @default("active")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
roles Role[]
|
||||
orders ServiceOrder[]
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model Role {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
name String // admin, operator, viewer
|
||||
permissions Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@map("roles")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PROVIDERS & CONNECTIVITY
|
||||
// ============================================================================
|
||||
|
||||
model Provider {
|
||||
id String @id @default(uuid())
|
||||
name String
|
||||
type String // aws, azure, carrier, exchange
|
||||
status String @default("active")
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
endpoints Endpoint[]
|
||||
productOfferings ProductOffering[]
|
||||
orders ServiceOrder[]
|
||||
accounts ProviderAccount[]
|
||||
|
||||
@@map("providers")
|
||||
}
|
||||
|
||||
model ProviderAccount {
|
||||
id String @id @default(uuid())
|
||||
tenantId String
|
||||
providerId String
|
||||
accountId String
|
||||
credentials Json // encrypted
|
||||
status String @default("active")
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
provider Provider @relation(fields: [providerId], references: [id])
|
||||
|
||||
@@unique([tenantId, providerId, accountId])
|
||||
@@map("provider_accounts")
|
||||
}
|
||||
|
||||
model Endpoint {
|
||||
id String @id @default(uuid())
|
||||
providerId String
|
||||
kind String // cloud_region, datacenter, exchange, customer_site
|
||||
region String?
|
||||
metro String?
|
||||
location String?
|
||||
status String @default("available")
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
provider Provider @relation(fields: [providerId], references: [id])
|
||||
sourceOrders ServiceOrder[] @relation("SourceEndpoint")
|
||||
targetOrders ServiceOrder[] @relation("TargetEndpoint")
|
||||
|
||||
@@map("endpoints")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// CATALOG & PRODUCTS
|
||||
// ============================================================================
|
||||
|
||||
model ProductOffering {
|
||||
id String @id @default(uuid())
|
||||
providerId String
|
||||
name String
|
||||
description String?
|
||||
type String // cloud_interconnect, multi_cloud, partner_connect
|
||||
status String @default("active")
|
||||
pricing Json @default("{}")
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
provider Provider @relation(fields: [providerId], references: [id])
|
||||
orders ServiceOrder[]
|
||||
|
||||
@@map("product_offerings")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ORDERS & SERVICES
|
||||
// ============================================================================
|
||||
|
||||
model Quote {
|
||||
id String @id @default(uuid())
|
||||
tenantId String
|
||||
productOfferingId String
|
||||
sourceEndpointId String
|
||||
targetEndpointId String
|
||||
bandwidthMbps Int
|
||||
monthlyRecurring Decimal @db.Decimal(10, 2)
|
||||
setupFee Decimal @db.Decimal(10, 2)
|
||||
currency String @default("USD")
|
||||
validUntil DateTime
|
||||
status String @default("draft") // draft, valid, expired, accepted
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("quotes")
|
||||
}
|
||||
|
||||
model ServiceOrder {
|
||||
id String @id @default(uuid())
|
||||
tenantId String
|
||||
userId String
|
||||
productOfferingId String
|
||||
providerId String
|
||||
sourceEndpointId String
|
||||
targetEndpointId String
|
||||
bandwidthMbps Int
|
||||
status String @default("draft")
|
||||
externalReference String?
|
||||
quoteId String?
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
productOffering ProductOffering @relation(fields: [productOfferingId], references: [id])
|
||||
provider Provider @relation(fields: [providerId], references: [id])
|
||||
sourceEndpoint Endpoint @relation("SourceEndpoint", fields: [sourceEndpointId], references: [id])
|
||||
targetEndpoint Endpoint @relation("TargetEndpoint", fields: [targetEndpointId], references: [id])
|
||||
service Service?
|
||||
provisioningTasks ProvisioningTask[]
|
||||
|
||||
@@map("service_orders")
|
||||
}
|
||||
|
||||
model Service {
|
||||
id String @id @default(uuid())
|
||||
orderId String @unique
|
||||
tenantId String
|
||||
status String @default("provisioning")
|
||||
activatedAt DateTime?
|
||||
suspendedAt DateTime?
|
||||
terminatedAt DateTime?
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
order ServiceOrder @relation(fields: [orderId], references: [id])
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
usageRecords UsageRecord[]
|
||||
inventoryRecords InventoryRecord[]
|
||||
|
||||
@@map("services")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PROVISIONING & ORCHESTRATION
|
||||
// ============================================================================
|
||||
|
||||
model ProvisioningTask {
|
||||
id String @id @default(uuid())
|
||||
orderId String
|
||||
taskType String // validate, provision, configure, activate
|
||||
status String @default("pending")
|
||||
adapterName String?
|
||||
externalTaskId String?
|
||||
retryCount Int @default(0)
|
||||
maxRetries Int @default(3)
|
||||
error String?
|
||||
metadata Json @default("{}")
|
||||
startedAt DateTime?
|
||||
completedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
order ServiceOrder @relation(fields: [orderId], references: [id])
|
||||
|
||||
@@map("provisioning_tasks")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// INVENTORY & MONITORING
|
||||
// ============================================================================
|
||||
|
||||
model InventoryRecord {
|
||||
id String @id @default(uuid())
|
||||
serviceId String
|
||||
recordType String // connection, circuit, port
|
||||
externalId String
|
||||
providerData Json @default("{}")
|
||||
status String
|
||||
lastSyncedAt DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
service Service @relation(fields: [serviceId], references: [id])
|
||||
|
||||
@@map("inventory_records")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// BILLING
|
||||
// ============================================================================
|
||||
|
||||
model UsageRecord {
|
||||
id String @id @default(uuid())
|
||||
serviceId String
|
||||
recordType String // bandwidth, port_hour, data_transfer
|
||||
quantity Decimal @db.Decimal(15, 4)
|
||||
unit String
|
||||
startTime DateTime
|
||||
endTime DateTime
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
service Service @relation(fields: [serviceId], references: [id])
|
||||
|
||||
@@map("usage_records")
|
||||
}
|
||||
|
||||
model Invoice {
|
||||
id String @id @default(uuid())
|
||||
tenantId String
|
||||
invoiceNumber String @unique
|
||||
status String @default("draft")
|
||||
subtotal Decimal @db.Decimal(10, 2)
|
||||
tax Decimal @db.Decimal(10, 2)
|
||||
total Decimal @db.Decimal(10, 2)
|
||||
currency String @default("USD")
|
||||
periodStart DateTime
|
||||
periodEnd DateTime
|
||||
dueDate DateTime
|
||||
paidAt DateTime?
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
|
||||
@@map("invoices")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// API & WEBHOOKS
|
||||
// ============================================================================
|
||||
|
||||
model ApiKey {
|
||||
id String @id @default(uuid())
|
||||
tenantId String
|
||||
name String
|
||||
keyHash String @unique
|
||||
scopes Json @default("[]")
|
||||
status String @default("active")
|
||||
lastUsedAt DateTime?
|
||||
expiresAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
|
||||
@@map("api_keys")
|
||||
}
|
||||
|
||||
model WebhookEndpoint {
|
||||
id String @id @default(uuid())
|
||||
tenantId String
|
||||
url String
|
||||
events Json @default("[]")
|
||||
secret String
|
||||
status String @default("active")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
deliveries WebhookDelivery[]
|
||||
|
||||
@@map("webhook_endpoints")
|
||||
}
|
||||
|
||||
model WebhookDelivery {
|
||||
id String @id @default(uuid())
|
||||
endpointId String
|
||||
eventType String
|
||||
payload Json
|
||||
status String @default("pending")
|
||||
attempts Int @default(0)
|
||||
lastAttempt DateTime?
|
||||
response String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
endpoint WebhookEndpoint @relation(fields: [endpointId], references: [id])
|
||||
|
||||
@@map("webhook_deliveries")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// AUDIT & INCIDENTS
|
||||
// ============================================================================
|
||||
|
||||
model AuditEvent {
|
||||
id String @id @default(uuid())
|
||||
aggregateType String
|
||||
aggregateId String
|
||||
eventType String
|
||||
actorId String?
|
||||
actorType String?
|
||||
payload Json @default("{}")
|
||||
ipAddress String?
|
||||
userAgent String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([aggregateType, aggregateId])
|
||||
@@index([eventType])
|
||||
@@index([createdAt])
|
||||
@@map("audit_events")
|
||||
}
|
||||
|
||||
model Incident {
|
||||
id String @id @default(uuid())
|
||||
tenantId String?
|
||||
serviceId String?
|
||||
severity String // critical, high, medium, low
|
||||
status String @default("open")
|
||||
title String
|
||||
description String
|
||||
metadata Json @default("{}")
|
||||
resolvedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@map("incidents")
|
||||
}
|
||||
Reference in New Issue
Block a user