Files
recipe-app/.kilo/plans/1779393360746-neon-island.md
Nils-Johan Gynther 8c9da36312
Test Suite / backend-pr-quick (push) Has been skipped
Test Suite / quick-import-pr-quick (push) Has been skipped
Test Suite / backend-full (push) Failing after 4m36s
Test Suite / flutter-quality (push) Failing after 40s
feat(profile): implement user-initiated GDPR-compliant profile deletion
- 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
2026-05-21 22:19:50 +02:00

7.7 KiB

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:

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:

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:

@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:

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:

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:

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:

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:

## 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.