feat(admin): consentement aux annonces et désabonnement sans connexion
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 5m58s
CI / Deploy production (on server) (push) Successful in 26s

Les comptes déjà créés ne sont pas inscrits. Le choix est facultatif à l’inscription et dans les paramètres. Un lien public demande confirmation avant d’arrêter les actualités, sans toucher aux messages de compte.
This commit is contained in:
Antigravity
2026-09-06 09:23:10 +00:00
parent 6fa12f6e13
commit 360e58e473
33 changed files with 1036 additions and 9 deletions

View File

@@ -54,6 +54,8 @@ model User {
usageLogs UsageLog[]
apiKeys UserAPIKey[]
aiConsentLogs AiConsentLog[]
marketingPreference MarketingPreference?
emailSuppressions EmailSuppression[]
noteClusters NoteCluster[]
bridgeNotes BridgeNote[]
bridgeSuggestions BridgeSuggestion[]
@@ -1124,3 +1126,55 @@ model ErrorLog {
@@index([createdAt])
@@index([resolved])
}
/// Explicit marketing announcements opt-in. Missing row = not opted in.
model MarketingPreference {
id String @id @default(cuid())
userId String @unique
emailNormalized String
optedIn Boolean @default(false)
preferredLanguage String?
consentVersion String?
consentText String? @db.Text
source String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
events MarketingPreferenceEvent[]
@@index([emailNormalized])
@@index([optedIn])
}
model MarketingPreferenceEvent {
id String @id @default(cuid())
preferenceId String
userId String?
emailNormalized String
optedIn Boolean
source String
consentVersion String?
consentText String? @db.Text
ip String?
userAgent String?
createdAt DateTime @default(now())
preference MarketingPreference @relation(fields: [preferenceId], references: [id], onDelete: Cascade)
@@index([preferenceId])
@@index([userId, createdAt])
@@index([emailNormalized, createdAt])
}
/// Blocks campaign mail. Kept after account deletion (userId set null).
model EmailSuppression {
id String @id @default(cuid())
emailNormalized String @unique
reason String
source String
userId String?
createdAt DateTime @default(now())
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
@@index([reason])
@@index([userId])
}