forked from InsurNiffy/niff-Stellar-shurance
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathschema.prisma
More file actions
247 lines (215 loc) · 6.81 KB
/
Copy pathschema.prisma
File metadata and controls
247 lines (215 loc) · 6.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
// 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"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Claim {
id Int @id // claimId from contract
policyId String // holderAddress:policyId
creatorAddress String
amount String
asset String?
description String?
imageUrls String[] @default([])
status ClaimStatus @default(PENDING)
isFinalized Boolean @default(false)
approveVotes Int @default(0)
rejectVotes Int @default(0)
paidAt DateTime?
createdAtLedger Int
updatedAtLedger Int @default(0)
txHash String?
eventIndex Int?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relations
policy Policy @relation(fields: [policyId], references: [id])
votes Vote[]
@@index([status])
@@index([createdAt])
@@index([policyId])
@@index([createdAt, id]) // keyset pagination: ORDER BY createdAt DESC, id DESC
@@map("claims")
}
model Vote {
id Int @id @default(autoincrement())
claimId Int
voterAddress String
vote VoteType
votingPower Int @default(1)
txHash String?
eventIndex Int?
votedAtLedger Int
createdAt DateTime @default(now())
// Relations
claim Claim @relation(fields: [claimId], references: [id], onDelete: Cascade)
@@unique([claimId, voterAddress])
@@index([voterAddress])
@@index([claimId])
@@map("votes")
}
model Policy {
id String @id // holderAddress:policyId
policyId Int
holderAddress String
policyType String
region String
coverageAmount String
premium String
isActive Boolean @default(true)
startLedger Int
endLedger Int
/// SEP-41 asset contract ID bound to this policy for premium and payout.
/// Null for legacy policies created before multi-asset support.
assetContractId String?
txHash String?
eventIndex Int?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relations
claims Claim[]
@@unique([holderAddress, policyId])
@@index([holderAddress])
@@index([isActive])
@@index([createdAt, id]) // keyset pagination: ORDER BY createdAt DESC, id DESC
@@map("policies")
}
model IndexerState {
id Int @id @default(autoincrement())
lastLedger Int
lastCursor String?
updatedAt DateTime @updatedAt
@@map("indexer_state")
}
model RawEvent {
id Int @id @default(autoincrement())
txHash String
eventIndex Int
contractId String
ledger Int
ledgerClosedAt DateTime
topic1 String?
topic2 String?
topic3 String?
topic4 String?
data Json
createdAt DateTime @default(now())
@@unique([txHash, eventIndex])
@@index([contractId])
@@index([ledger])
@@map("raw_events")
}
enum ClaimStatus {
PENDING
APPROVED
PAID
REJECTED
}
enum VoteType {
APPROVE
REJECT
}
/// Immutable operational audit trail written by admin endpoints.
/// Rows must never be updated or deleted — append-only.
model AdminAuditLog {
id String @id @default(uuid())
actor String /// wallet address or staff email of the operator
action String /// e.g. "reindex", "pause", "feature_flag_update"
payload Json /// full request payload for forensic replay
ipAddress String?
createdAt DateTime @default(now())
@@index([actor])
@@index([action])
@@index([createdAt])
@@map("admin_audit_logs")
}
/// Runtime feature flags toggled by admin operators.
model FeatureFlag {
key String @id
enabled Boolean @default(false)
description String?
updatedBy String
updatedAt DateTime @updatedAt
@@map("feature_flags")
}
/// Deduplication table for wasm drift alerts — one row per (contract, actual-hash) pair.
/// Prevents repeated webhook spam for the same unresolved drift.
model WasmDriftAlert {
id String @id @default(uuid())
dedupKey String @unique /// "<contractName>:<actualHash>"
contractName String
contractId String
expectedHash String
actualHash String
resolvedAt DateTime?
createdAt DateTime @default(now())
@@index([contractName])
@@map("wasm_drift_alerts")
}
/// Tracks staff-initiated privacy requests (GDPR/CCPA-style) for off-chain data.
/// On-chain and IPFS data is immutable and cannot be erased — see runbook.
model PrivacyRequest {
id String @id @default(uuid())
subjectWalletAddress String
requestType String /// "ANONYMIZE" | "DELETE"
requestedBy String /// staff actor (wallet address or email)
status String @default("IN_PROGRESS") /// "IN_PROGRESS" | "COMPLETED" | "FAILED"
rowsAffected Int @default(0)
notes String?
errorMessage String?
completedAt DateTime?
createdAt DateTime @default(now())
@@index([subjectWalletAddress])
@@index([status])
@@map("privacy_requests")
}
/// Off-chain metadata for allowlisted SEP-41 asset contracts.
/// Populated by the indexer when it observes AssetAdded events.
/// Used by the frontend and API to display correct symbol/decimals.
model AllowedAsset {
/// SEP-41 contract address (Stellar strkey format).
contractId String @id
/// Token symbol, e.g. "USDC", "XLM". Populated off-chain.
symbol String?
/// Decimal places, e.g. 7 for XLM/USDC on Stellar.
decimals Int @default(7)
/// Whether this asset is currently on the allowlist.
isAllowed Boolean @default(true)
/// Ledger at which the asset was added to the allowlist.
addedAtLedger Int?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("allowed_assets")
}
/// Support ticket submitted via the /support contact form.
model SupportTicket {
id String @id @default(uuid())
email String
subject String
message String
/// One-way hash of submitter IP for spam detection (no raw IP stored).
ipHash String?
status TicketStatus @default(OPEN)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([status])
@@index([createdAt])
@@map("support_tickets")
}
/// Privacy-safe FAQ expansion counters.
model FaqStat {
faqId String @id
expansions Int @default(0)
updatedAt DateTime @updatedAt
@@map("faq_stats")
}
enum TicketStatus {
OPEN
IN_PROGRESS
RESOLVED
CLOSED
}