mirror of
https://github.com/Smile-QWQ/SubTracker.git
synced 2026-06-03 07:29:51 +08:00
- replace legacy category-based subscription flow with tag-based models, routes, types and UI management - rebuild Prisma schema around Tag and SubscriptionTag, remove legacy category relation fields, and reseed defaults - add unified Wallos import inspect/commit flow for JSON, SQLite and ZIP packages with ZIP logo ingestion and DB-version compatibility - add auto-renew execution in scheduler plus payment record drawer entry in subscription actions - rename user-facing renewal wording to 续订 in key views and align subscription form with tag selection and auto-renew - improve logo handling with local library support, remote import persistence, and ZIP asset matching fallback
144 lines
3.9 KiB
Plaintext
144 lines
3.9 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "sqlite"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
enum SubscriptionStatus {
|
|
active
|
|
paused
|
|
cancelled
|
|
expired
|
|
}
|
|
|
|
enum BillingIntervalUnit {
|
|
day
|
|
week
|
|
month
|
|
quarter
|
|
year
|
|
}
|
|
|
|
enum WebhookDeliveryStatus {
|
|
pending
|
|
success
|
|
failed
|
|
}
|
|
|
|
model Tag {
|
|
id String @id @default(cuid())
|
|
name String @unique
|
|
color String @default("#3b82f6")
|
|
icon String @default("apps-outline")
|
|
sortOrder Int @default(0)
|
|
subscriptionTags SubscriptionTag[]
|
|
}
|
|
|
|
model Subscription {
|
|
id String @id @default(cuid())
|
|
name String
|
|
description String @default("")
|
|
websiteUrl String?
|
|
logoUrl String?
|
|
logoSource String?
|
|
logoFetchedAt DateTime?
|
|
status SubscriptionStatus @default(active)
|
|
amount Float
|
|
currency String
|
|
billingIntervalCount Int @default(1)
|
|
billingIntervalUnit BillingIntervalUnit
|
|
autoRenew Boolean @default(false)
|
|
startDate DateTime
|
|
nextRenewalDate DateTime
|
|
notifyDaysBefore Int @default(3)
|
|
webhookEnabled Boolean @default(true)
|
|
notes String @default("")
|
|
tags SubscriptionTag[]
|
|
paymentRecords PaymentRecord[]
|
|
deliveries WebhookDelivery[]
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([status, nextRenewalDate])
|
|
@@index([autoRenew, nextRenewalDate])
|
|
}
|
|
|
|
model SubscriptionTag {
|
|
subscriptionId String
|
|
tagId String
|
|
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
|
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([subscriptionId, tagId])
|
|
@@index([tagId])
|
|
}
|
|
|
|
model PaymentRecord {
|
|
id String @id @default(cuid())
|
|
subscriptionId String
|
|
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
|
amount Float
|
|
currency String
|
|
baseCurrency String
|
|
convertedAmount Float
|
|
exchangeRate Float
|
|
paidAt DateTime
|
|
periodStart DateTime
|
|
periodEnd DateTime
|
|
createdAt DateTime @default(now())
|
|
|
|
@@index([subscriptionId, paidAt])
|
|
}
|
|
|
|
model ExchangeRateSnapshot {
|
|
id String @id @default(cuid())
|
|
baseCurrency String @unique
|
|
ratesJson Json
|
|
provider String
|
|
fetchedAt DateTime
|
|
isStale Boolean @default(false)
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model WebhookEndpoint {
|
|
id String @id @default(cuid())
|
|
name String
|
|
url String
|
|
secret String
|
|
enabled Boolean @default(true)
|
|
eventsJson Json
|
|
deliveries WebhookDelivery[]
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model WebhookDelivery {
|
|
id String @id @default(cuid())
|
|
endpointId String
|
|
endpoint WebhookEndpoint @relation(fields: [endpointId], references: [id], onDelete: Cascade)
|
|
subscriptionId String?
|
|
subscription Subscription? @relation(fields: [subscriptionId], references: [id], onDelete: SetNull)
|
|
eventType String
|
|
resourceKey String
|
|
periodKey String
|
|
payloadJson Json
|
|
status WebhookDeliveryStatus @default(pending)
|
|
responseCode Int?
|
|
responseBody String?
|
|
attemptCount Int @default(0)
|
|
lastAttemptAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
|
|
@@unique([endpointId, eventType, resourceKey, periodKey])
|
|
@@index([status, createdAt])
|
|
}
|
|
|
|
model Setting {
|
|
key String @id
|
|
valueJson Json
|
|
updatedAt DateTime @updatedAt
|
|
}
|