GDPR Compliance Guide
This guide explains the GDPR feature that ships with ChimerAI and how to install it in your project using the CLI.
Installation
chimerai add gdpr
This command requires an Enterprise license. It installs the following files into your Next.js project:
| File | Purpose |
|---|---|
lib/gdpr.ts | Helper functions for export, deletion and consent |
app/gdpr/page.tsx | Self-service portal for users |
app/api/gdpr/consent/route.ts | API route to read and write consent preferences |
app/api/gdpr/export/route.ts | API route to download personal data as JSON |
app/api/gdpr/delete/route.ts | API route to permanently delete a user account |
It also extends your Prisma schema with:
model ConsentLog {
id String @id @default(cuid())
userId String
type String
granted Boolean
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([type])
}
After installation, run:
npx prisma db push
# or
npx prisma migrate dev --name add-consent-log
What Gets Installed
lib/gdpr.ts
Contains four functions:
exportUserData(userId)
Returns a JSON object with all personal data for a user, including sessions, accounts, conversations, API keys and consent logs. Sensitive fields (password, mfaSecret) are automatically stripped from the export.
import { exportUserData } from '@/lib/gdpr';
const data = await exportUserData(session.user.id);
deleteUserData(userId)
Permanently deletes all data associated with a user in the correct cascade order:
- ConsentLog records
- Sessions
- OAuth accounts
- API keys
- Messages (via conversations)
- Conversations
- The user record itself
import { deleteUserData } from '@/lib/gdpr';
await deleteUserData(session.user.id);
recordConsent(userId, type, granted)
Writes a new row to the ConsentLog table. Each call creates an immutable audit record with a timestamp.
await recordConsent(userId, 'analytics', true);
await recordConsent(userId, 'marketing', false);
getConsentStatus(userId)
Returns the latest consent decision per type as a key/value map. If a type has been toggled multiple times, only the most recent value is returned.
const status = await getConsentStatus(userId);
// { analytics: true, marketing: false, ... }
API Routes
GET /api/gdpr/export
Returns a JSON file download (Content-Disposition: attachment) containing all personal data for the authenticated user. Requires a valid session.
Response: application/json download, filename data-export-YYYY-MM-DD.json
Use case: GDPR Art. 15 - Right of access
DELETE /api/gdpr/delete
Permanently deletes the authenticated user's account and all associated data. Requires the user to confirm by sending their email address in the request body.
Request body:
{ "confirmation": "user@example.com" }
Response:
{ "success": true, "message": "Account deleted successfully" }
Use case: GDPR Art. 17 - Right to erasure
GET /api/gdpr/consent
Returns the current consent status for the authenticated user as a JSON object.
Response:
{ "analytics": true, "marketing": false }
POST /api/gdpr/consent
Saves consent preferences for the authenticated user. Each key/value pair is written as a separate ConsentLog row with a timestamp.
Request body:
{
"consent": {
"analytics": true,
"marketing": false,
"third_party": true,
"ai_training": false
}
}
Use case: GDPR Art. 7 - Conditions for consent
User Portal
The installed page at /gdpr provides a self-service portal where users can:
- Export their data - downloads a real JSON file from the database
- Delete their account - requires email confirmation, then performs a full cascade delete
- Manage consent preferences - toggles are persisted to the
ConsentLogtable and loaded on each visit
The portal is ready to use without any additional configuration. You can link to it from your settings page or navigation.
Consent Types
The default consent types included in the portal are:
| Key | Label | Legal basis |
|---|---|---|
analytics | Analytics & Usage Tracking | Art. 6 |
marketing | Marketing Emails | Art. 6 |
third_party | Third-party Integrations | Art. 28 |
ai_training | AI Model Training on my Data | Art. 22 |
You can extend or replace these by editing the CONSENT_TYPES array in app/gdpr/page.tsx.
Audit Trail
Every consent change is stored as an immutable row in ConsentLog - it is never updated or deleted (except when the user deletes their entire account). This provides a full audit trail of when consent was given or withdrawn, as required by GDPR Art. 7(1).
Notes
- All routes require an authenticated session via NextAuth. Unauthenticated requests return
401 Unauthorized. - The delete route requires the user to type their email address as confirmation. This prevents accidental deletions.
- The
exportUserDatafunction usesprisma as anycasts for theConsentLogmodel to remain compatible with projects that do not yet have the schema extension applied.