Ingests Square invoices/payments, extracts event scheduling from order notes, and pushes approved entries to a CalDAV calendar after human review. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
102 lines
2.7 KiB
Plaintext
102 lines
2.7 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
enum Role {
|
|
ADMIN
|
|
USER
|
|
}
|
|
|
|
enum SourceType {
|
|
SQUARE_INVOICE
|
|
SQUARE_PAYMENT
|
|
}
|
|
|
|
enum CandidateStatus {
|
|
PENDING
|
|
APPROVED
|
|
REJECTED
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(uuid())
|
|
email String @unique
|
|
passwordHash String
|
|
name String
|
|
role Role @default(USER)
|
|
active Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
|
|
createdById String?
|
|
createdBy User? @relation("UserCreatedBy", fields: [createdById], references: [id])
|
|
createdUsers User[] @relation("UserCreatedBy")
|
|
|
|
approvals CalendarCandidate[] @relation("ApprovedBy")
|
|
}
|
|
|
|
model CalendarCandidate {
|
|
id String @id @default(uuid())
|
|
sourceType SourceType
|
|
squareId String
|
|
squareEnvironment String
|
|
status CandidateStatus @default(PENDING)
|
|
// Square's own status (invoice: DRAFT/UNPAID/PAID/etc, payment: COMPLETED/etc) —
|
|
// independent of our review `status` above, kept for filtering.
|
|
squareStatus String?
|
|
|
|
title String
|
|
description String?
|
|
// When Square created the invoice/payment — distinct from `startAt` (the
|
|
// event's own date/time). Square's own invoice list sorts by this.
|
|
squareCreatedAt DateTime?
|
|
startAt DateTime
|
|
endAt DateTime
|
|
allDay Boolean @default(false)
|
|
location String?
|
|
customerName String?
|
|
customerEmail String?
|
|
amountCents Int?
|
|
currency String? @default("USD")
|
|
|
|
rawPayload Json
|
|
fetchedAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
approvedById String?
|
|
approvedBy User? @relation("ApprovedBy", fields: [approvedById], references: [id])
|
|
approvedAt DateTime?
|
|
rejectedAt DateTime?
|
|
|
|
caldavEventUid String? @unique
|
|
caldavEventUrl String?
|
|
caldavEtag String?
|
|
|
|
// Strike (teardown/pickup) as its own, separate calendar entry — often a
|
|
// different day than the main event, so it gets its own CalDAV event too.
|
|
hasStrike Boolean @default(false)
|
|
strikeStartAt DateTime?
|
|
strikeEndAt DateTime?
|
|
strikeCaldavEventUid String? @unique
|
|
strikeCaldavEventUrl String?
|
|
strikeCaldavEtag String?
|
|
|
|
@@unique([sourceType, squareId, squareEnvironment], name: "square_source_unique")
|
|
@@index([status])
|
|
}
|
|
|
|
model SyncRun {
|
|
id String @id @default(uuid())
|
|
startedAt DateTime @default(now())
|
|
finishedAt DateTime?
|
|
trigger String
|
|
invoicesFetched Int @default(0)
|
|
paymentsFetched Int @default(0)
|
|
candidatesCreated Int @default(0)
|
|
error String?
|
|
}
|