64 lines
2.5 KiB
Plaintext
64 lines
2.5 KiB
Plaintext
// Embeddable Form-Widget (Phase 05 Task #58).
|
|
//
|
|
// `Form` is the tenant-authored definition + theme + delivery config that
|
|
// powers the iframe-embedded mini-app. `FormSubmission` is the inbox for
|
|
// payloads landing through the public submission endpoint. Both rows are
|
|
// tenant-scoped so existing tenant-isolation tooling applies as-is.
|
|
|
|
model Form {
|
|
id String @id @default(cuid())
|
|
tenantId String
|
|
/// Public key used in the embed `<script data-form-key="…">`.
|
|
key String @unique @default(cuid())
|
|
name String
|
|
/// Schema-versioned form definition JSON (validated by `FormDefinitionSchema`).
|
|
definition Json
|
|
/// Theme JSON (validated by `FormThemeSchema`). Empty object inherits tenant brand.
|
|
theme Json @default("{}")
|
|
/// "generic" | "crm-contact" | "entity-row".
|
|
targetType String @default("generic")
|
|
targetEntityId String?
|
|
/// Mapping from form field-key -> target row property-key.
|
|
fieldMapping Json @default("{}")
|
|
/// Allowlist of origins permitted to POST submissions. Empty -> no submissions accepted.
|
|
allowedOrigins String[]
|
|
notifyEmails String[]
|
|
webhookUrl String?
|
|
/// Anti-spam / processing config (honeypotEnabled, turnstileEnabled, successMessage override).
|
|
config Json @default("{}")
|
|
isEnabled Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
|
submissions FormSubmission[]
|
|
|
|
@@index([tenantId, createdAt(sort: Desc)])
|
|
@@index([key])
|
|
}
|
|
|
|
model FormSubmission {
|
|
id String @id @default(cuid())
|
|
formId String
|
|
tenantId String
|
|
/// Validated payload as { values: Record<string, string|number|boolean|null> }.
|
|
payload Json
|
|
/// Origin header recorded at submission time, for audit / forensics.
|
|
sourceOrigin String?
|
|
/// SHA-256 hash of the submitter IP — no raw IP storage for PII reasons.
|
|
ipHash String?
|
|
userAgent String?
|
|
/// "received" | "processed" | "failed" | "spam".
|
|
status String @default("received")
|
|
/// JSON describing routing/webhook delivery outcome.
|
|
result Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
form Form @relation(fields: [formId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([formId, createdAt(sort: Desc)])
|
|
@@index([tenantId, createdAt(sort: Desc)])
|
|
@@index([status])
|
|
}
|