8c9da36312
- Add DELETE /users/me endpoint with cascading data removal - Implement frontend confirmation dialog and deletion flow - Add audit logging for deletion requests - Update localization files for new UI strings - Add scheduled cleanup service for AI traces - Document GDPR compliance in technical specification BREAKING CHANGE: Users can now permanently delete their profiles and associated data
215 lines
7.7 KiB
Markdown
215 lines
7.7 KiB
Markdown
# Plan: Implementera användarinitierad radering av personuppgifter
|
|
|
|
## Mål
|
|
Skapa en tydlig och stegvis plan för hur användare kan ta bort sina personuppgifter från sin profil på plattformen, inklusive teknisk implementation och användarflöde.
|
|
|
|
## Bakgrund
|
|
- GDPR kräver att användare ska kunna begära radering av sina personuppgifter.
|
|
- Nuvarande plattform saknar ett tydligt användarflöde för att initiera radering av personuppgifter.
|
|
- Användare bör kunna ta bort sin profil och associerade data på ett säkert och transparent sätt.
|
|
|
|
## Krav
|
|
1. Lägg till en "Ta bort min profil"-knapp i användarens profilinställningar.
|
|
2. Implementera en bekräftelsedialog för att förhindra oavsiktlig radering.
|
|
3. Skapa en backend-endpoint för att hantera raderingsbegäran.
|
|
4. Se till att all användardata (profil, produkter, recept, etc.) raderas eller anonymiseras.
|
|
5. Logga raderingsbegäran för revisionsändamål.
|
|
6. Skicka ett bekräftelsemeddelande till användaren efter radering.
|
|
|
|
## Implementeringsplan
|
|
|
|
### Steg 1: Lägg till "Ta bort min profil"-knapp i Flutter UI
|
|
Lägg till en knapp i användarens profilinställningar som låter användaren initiera radering av sin profil.
|
|
|
|
**Fil:** `flutter/lib/features/profile/presentation/profile_screen.dart`
|
|
**Ändring:**
|
|
```dart
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
_showDeleteProfileConfirmation();
|
|
},
|
|
child: Text('Ta bort min profil'),
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: Colors.red,
|
|
),
|
|
)
|
|
```
|
|
|
|
### Steg 2: Implementera bekräftelsedialog
|
|
Skapa en dialog som kräver att användaren bekräftar raderingen.
|
|
|
|
**Fil:** `flutter/lib/features/profile/presentation/profile_screen.dart`
|
|
**Ändring:**
|
|
```dart
|
|
Future<void> _showDeleteProfileConfirmation() async {
|
|
return showDialog<void>(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
title: Text('Bekräfta radering'),
|
|
content: SingleChildScrollView(
|
|
child: ListBody(
|
|
children: <Widget>[
|
|
Text('Är du säker på att du vill ta bort din profil?'),
|
|
Text('Alla dina data kommer att raderas permanent.'),
|
|
],
|
|
),
|
|
),
|
|
actions: <Widget>[
|
|
TextButton(
|
|
child: Text('Avbryt'),
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
),
|
|
TextButton(
|
|
child: Text('Ta bort'),
|
|
onPressed: () {
|
|
_deleteProfile();
|
|
Navigator.of(context).pop();
|
|
},
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
```
|
|
|
|
### Steg 3: Skapa backend-endpoint för radering
|
|
Implementera en endpoint som hanterar raderingsbegäran och raderar all associerad data.
|
|
|
|
**Fil:** `backend/src/users/users.controller.ts`
|
|
**Ändring:**
|
|
```typescript
|
|
@Delete('me')
|
|
@UseGuards(JwtAuthGuard)
|
|
async deleteProfile(@CurrentUser() user: UserEntity) {
|
|
await this.usersService.deleteUserAndData(user.id);
|
|
return { success: true, message: 'Din profil och data har tagits bort.' };
|
|
}
|
|
```
|
|
|
|
### Steg 4: Implementera raderingslogik i UsersService
|
|
Skapa en metod som raderar användaren och all associerad data.
|
|
|
|
**Fil:** `backend/src/users/users.service.ts`
|
|
**Ändring:**
|
|
```typescript
|
|
async deleteUserAndData(userId: number) {
|
|
await this.prisma.$transaction([
|
|
this.prisma.product.deleteMany({ where: { ownerId: userId } }),
|
|
this.prisma.recipe.deleteMany({ where: { ownerId: userId } }),
|
|
this.prisma.inventoryItem.deleteMany({ where: { userId } }),
|
|
this.prisma.mealPlanEntry.deleteMany({ where: { userId } }),
|
|
this.prisma.user.delete({ where: { id: userId } }),
|
|
]);
|
|
this.logger.log(`User ${userId} and associated data deleted.`);
|
|
}
|
|
```
|
|
|
|
### Steg 5: Logga raderingsbegäran
|
|
Lägg till loggning för att spåra raderingsbegäran för revisionsändamål.
|
|
|
|
**Fil:** `backend/src/users/users.service.ts`
|
|
**Ändring:**
|
|
```typescript
|
|
async logDeletionRequest(userId: number, userEmail: string) {
|
|
await this.prisma.auditLog.create({
|
|
data: {
|
|
action: 'USER_DELETION',
|
|
userId,
|
|
email: userEmail,
|
|
metadata: { message: 'User initiated deletion of their profile and data.' },
|
|
},
|
|
});
|
|
}
|
|
```
|
|
|
|
### Steg 6: Skicka bekräftelsemeddelande
|
|
Skicka ett e-postmeddelande till användaren för att bekräfta raderingen.
|
|
|
|
**Fil:** `backend/src/users/users.service.ts`
|
|
**Ändring:**
|
|
```typescript
|
|
async sendDeletionConfirmationEmail(email: string) {
|
|
await this.emailService.sendEmail({
|
|
to: email,
|
|
subject: 'Bekräftelse på radering av din profil',
|
|
text: 'Din profil och alla associerade data har tagits bort från vår plattform.',
|
|
});
|
|
}
|
|
```
|
|
|
|
### Steg 7: Uppdatera Flutter för att anropa backend-endpoint
|
|
Implementera metoden för att anropa backend-endpoint för radering.
|
|
|
|
**Fil:** `flutter/lib/features/profile/presentation/profile_screen.dart`
|
|
**Ändring:**
|
|
```dart
|
|
Future<void> _deleteProfile() async {
|
|
try {
|
|
final response = await ApiService.delete('/users/me');
|
|
if (response.statusCode == 200) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(content: Text('Din profil har tagits bort.'));
|
|
);
|
|
Navigator.of(context).pushNamedAndRemoveUntil('/login', (route) => false);
|
|
}
|
|
} catch (e) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(content: Text('Ett fel uppstod vid radering av din profil.'));
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Steg 8: Testa implementeringen
|
|
1. Skapa en testanvändare i systemet.
|
|
2. Navigera till profilinställningar och klicka på "Ta bort min profil".
|
|
3. Bekräfta raderingen i dialogrutan.
|
|
4. Verifiera att användaren och all associerad data har tagits bort från databasen.
|
|
5. Kontrollera att ett bekräftelsemeddelande har skickats till användarens e-post.
|
|
6. Verifiera att raderingsbegäran har loggats i `AuditLog`.
|
|
|
|
### Steg 9: Dokumentera ändringarna
|
|
Uppdatera `TEKNISK_BESKRIVNING.md` med information om den nya funktionaliteten.
|
|
|
|
**Fil:** `TEKNISK_BESKRIVNING.md`
|
|
**Ändring:**
|
|
```markdown
|
|
## Användarinitierad radering av personuppgifter
|
|
|
|
För att uppfylla GDPR-krav har en funktion implementerats som låter användare ta bort sin profil och associerade data:
|
|
|
|
- **Användarflöde**: Användaren kan initiera radering via en knapp i profilinställningarna.
|
|
- **Bekräftelse**: En dialog kräver bekräftelse för att förhindra oavsiktlig radering.
|
|
- **Backend-endpoint**: `DELETE /users/me` hanterar raderingsbegäran.
|
|
- **Data som raderas**: Profil, produkter, recept, inventarieposter och matplaner.
|
|
- **Loggning**: Raderingsbegäran loggas i `AuditLog` för revisionsändamål.
|
|
- **Bekräftelse**: Ett e-postmeddelande skickas till användaren efter radering.
|
|
|
|
### Implementation
|
|
- **Frontend**: `flutter/lib/features/profile/presentation/profile_screen.dart`
|
|
- **Backend**: `backend/src/users/users.controller.ts` och `backend/src/users/users.service.ts`
|
|
- **Loggning**: `AuditLog`-poster skapas för varje raderingsbegäran.
|
|
- **E-postbekräftelse**: Skickas via `EmailService`.
|
|
|
|
### GDPR-efterlevnad
|
|
- Användare har full kontroll över sina personuppgifter.
|
|
- Raderingsprocessen är transparent och dokumenterad.
|
|
- All data raderas eller anonymiseras enligt GDPR-krav.
|
|
```
|
|
|
|
## Frågor och överväganden
|
|
1. **Dataretention**: Bör vissa data (t.ex. transaktionshistorik) sparas för revisionsändamål även efter radering?
|
|
2. **Anonymisering**: Bör vi anonymisera data istället för att radera dem helt?
|
|
3. **Ångerperiod**: Bör vi implementera en ångerperiod där användaren kan återställa sin profil inom en viss tid?
|
|
|
|
## Nästa steg
|
|
1. Implementera planen enligt ovan.
|
|
2. Testa funktionaliteten i en testmiljö.
|
|
3. Verifiera att all data raderas korrekt och att loggning fungerar.
|
|
4. Dokumentera ändringarna i `TEKNISK_BESKRIVNING.md`.
|
|
5. Informera teamet om den nya funktionaliteten och dess påverkan på GDPR-efterlevnaden. |