- Updated all component headers and documentation
- Changed navbar and footer branding
- Updated homepage hero badge
- Modified page title in index.html
- Simplified footer text to 'Built with ❤️'
- Consistent V2 capitalization across all references
269 lines
7.8 KiB
Plaintext
269 lines
7.8 KiB
Plaintext
// Redirect Intelligence v2 - Database Schema
|
|
// 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"
|
|
output = "../../../node_modules/.prisma/client"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
email String @unique
|
|
name String
|
|
passwordHash String @map("password_hash")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
lastLoginAt DateTime? @map("last_login_at")
|
|
|
|
memberships OrgMembership[]
|
|
auditLogs AuditLog[]
|
|
bulkJobs BulkJob[]
|
|
|
|
@@map("users")
|
|
}
|
|
|
|
model Organization {
|
|
id String @id @default(cuid())
|
|
name String
|
|
plan String @default("free")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
memberships OrgMembership[]
|
|
projects Project[]
|
|
apiKeys ApiKey[]
|
|
auditLogs AuditLog[]
|
|
bulkJobs BulkJob[]
|
|
|
|
@@map("organizations")
|
|
}
|
|
|
|
model OrgMembership {
|
|
id String @id @default(cuid())
|
|
orgId String @map("org_id")
|
|
userId String @map("user_id")
|
|
role Role
|
|
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([orgId, userId])
|
|
@@map("org_memberships")
|
|
}
|
|
|
|
model Project {
|
|
id String @id @default(cuid())
|
|
orgId String @map("org_id")
|
|
name String
|
|
settingsJson Json @default("{}") @map("settings_json")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
checks Check[]
|
|
bulkJobs BulkJob[]
|
|
|
|
@@map("projects")
|
|
}
|
|
|
|
model Check {
|
|
id String @id @default(cuid())
|
|
projectId String @map("project_id")
|
|
inputUrl String @map("input_url")
|
|
method String @default("GET")
|
|
headersJson Json @default("{}") @map("headers_json")
|
|
userAgent String? @map("user_agent")
|
|
startedAt DateTime @map("started_at")
|
|
finishedAt DateTime? @map("finished_at")
|
|
status CheckStatus
|
|
finalUrl String? @map("final_url")
|
|
totalTimeMs Int? @map("total_time_ms")
|
|
reportId String? @map("report_id")
|
|
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
hops Hop[]
|
|
sslInspections SslInspection[]
|
|
seoFlags SeoFlags?
|
|
securityFlags SecurityFlags?
|
|
reports Report[]
|
|
|
|
@@index([projectId, startedAt(sort: Desc)])
|
|
@@map("checks")
|
|
}
|
|
|
|
model Hop {
|
|
id String @id @default(cuid())
|
|
checkId String @map("check_id")
|
|
hopIndex Int @map("hop_index")
|
|
url String
|
|
scheme String?
|
|
statusCode Int? @map("status_code")
|
|
redirectType RedirectType @map("redirect_type")
|
|
latencyMs Int? @map("latency_ms")
|
|
contentType String? @map("content_type")
|
|
reason String?
|
|
responseHeadersJson Json @default("{}") @map("response_headers_json")
|
|
|
|
check Check @relation(fields: [checkId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([checkId, hopIndex])
|
|
@@map("hops")
|
|
}
|
|
|
|
model SslInspection {
|
|
id String @id @default(cuid())
|
|
checkId String @map("check_id")
|
|
host String
|
|
validFrom DateTime? @map("valid_from")
|
|
validTo DateTime? @map("valid_to")
|
|
daysToExpiry Int? @map("days_to_expiry")
|
|
issuer String?
|
|
protocol String?
|
|
warningsJson Json @default("[]") @map("warnings_json")
|
|
|
|
check Check @relation(fields: [checkId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("ssl_inspections")
|
|
}
|
|
|
|
model SeoFlags {
|
|
id String @id @default(cuid())
|
|
checkId String @unique @map("check_id")
|
|
robotsTxtStatus String? @map("robots_txt_status")
|
|
robotsTxtRulesJson Json @default("{}") @map("robots_txt_rules_json")
|
|
metaRobots String? @map("meta_robots")
|
|
canonicalUrl String? @map("canonical_url")
|
|
sitemapPresent Boolean @default(false) @map("sitemap_present")
|
|
noindex Boolean @default(false)
|
|
nofollow Boolean @default(false)
|
|
|
|
check Check @relation(fields: [checkId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("seo_flags")
|
|
}
|
|
|
|
model SecurityFlags {
|
|
id String @id @default(cuid())
|
|
checkId String @unique @map("check_id")
|
|
safeBrowsingStatus String? @map("safe_browsing_status")
|
|
mixedContent MixedContent @default(NONE) @map("mixed_content")
|
|
httpsToHttp Boolean @default(false) @map("https_to_http")
|
|
|
|
check Check @relation(fields: [checkId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("security_flags")
|
|
}
|
|
|
|
model Report {
|
|
id String @id @default(cuid())
|
|
checkId String @map("check_id")
|
|
markdownPath String? @map("markdown_path")
|
|
pdfPath String? @map("pdf_path")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
check Check @relation(fields: [checkId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("reports")
|
|
}
|
|
|
|
model BulkJob {
|
|
id String @id @default(cuid())
|
|
userId String @map("user_id")
|
|
organizationId String? @map("organization_id")
|
|
projectId String @map("project_id")
|
|
uploadPath String @map("upload_path")
|
|
status JobStatus
|
|
totalUrls Int @default(0) @map("total_urls")
|
|
processedUrls Int @default(0) @map("processed_urls")
|
|
successfulUrls Int @default(0) @map("successful_urls")
|
|
failedUrls Int @default(0) @map("failed_urls")
|
|
configJson Json @default("{}") @map("config_json")
|
|
urlsJson Json? @map("urls_json")
|
|
resultsJson Json? @map("results_json")
|
|
progressJson Json @default("{}") @map("progress_json")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
startedAt DateTime? @map("started_at")
|
|
finishedAt DateTime? @map("finished_at")
|
|
completedAt DateTime? @map("completed_at")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
organization Organization? @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("bulk_jobs")
|
|
}
|
|
|
|
model ApiKey {
|
|
id String @id @default(cuid())
|
|
orgId String @map("org_id")
|
|
name String
|
|
tokenHash String @unique @map("token_hash")
|
|
permsJson Json @default("{}") @map("perms_json")
|
|
rateLimitQuota Int @default(1000) @map("rate_limit_quota")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([tokenHash])
|
|
@@map("api_keys")
|
|
}
|
|
|
|
model AuditLog {
|
|
id String @id @default(cuid())
|
|
orgId String @map("org_id")
|
|
actorUserId String? @map("actor_user_id")
|
|
action String
|
|
entity String
|
|
entityId String @map("entity_id")
|
|
metaJson Json @default("{}") @map("meta_json")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
organization Organization @relation(fields: [orgId], references: [id], onDelete: Cascade)
|
|
actor User? @relation(fields: [actorUserId], references: [id], onDelete: SetNull)
|
|
|
|
@@map("audit_logs")
|
|
}
|
|
|
|
enum Role {
|
|
OWNER
|
|
ADMIN
|
|
MEMBER
|
|
}
|
|
|
|
enum CheckStatus {
|
|
OK
|
|
ERROR
|
|
TIMEOUT
|
|
LOOP
|
|
}
|
|
|
|
enum RedirectType {
|
|
HTTP_301
|
|
HTTP_302
|
|
HTTP_307
|
|
HTTP_308
|
|
META_REFRESH
|
|
JS
|
|
FINAL
|
|
OTHER
|
|
}
|
|
|
|
enum MixedContent {
|
|
NONE
|
|
PRESENT
|
|
FINAL_TO_HTTP
|
|
}
|
|
|
|
enum JobStatus {
|
|
PENDING
|
|
QUEUED
|
|
RUNNING
|
|
COMPLETED
|
|
FAILED
|
|
CANCELLED
|
|
ERROR
|
|
}
|