Initial commit
This commit is contained in:
638
references/PROFILE_DELETION_GRACE_PERIOD.md
Normal file
638
references/PROFILE_DELETION_GRACE_PERIOD.md
Normal file
@@ -0,0 +1,638 @@
|
||||
# Profile Deletion Grace Period
|
||||
|
||||
This document describes the grace period system for profile deletions, which allows profiles to be restored within a configurable timeframe after deletion.
|
||||
|
||||
## Overview
|
||||
|
||||
When a profile is deleted (either manually by the user or automatically due to inactivity), the system implements a two-phase deletion process:
|
||||
|
||||
1. **Soft Deletion**: Profile is marked as deleted but data remains intact
|
||||
2. **Permanent Deletion**: After the grace period expires, profile data is permanently anonymized and balances are handled
|
||||
|
||||
This gives users a safety window to restore their profiles if deleted accidentally or if they change their mind.
|
||||
|
||||
## Configuration
|
||||
|
||||
The grace period is configured per platform in the timebank configuration files:
|
||||
|
||||
**Location:** `config/timebank-*.php`
|
||||
|
||||
```php
|
||||
'delete_profile' => [
|
||||
'grace_period_days' => 30, // Number of days before permanent deletion
|
||||
// ... other deletion settings
|
||||
],
|
||||
```
|
||||
|
||||
**Default Value:** 30 days
|
||||
|
||||
**Recommendation:** Keep at least 14 days to give users adequate time to restore their profiles.
|
||||
|
||||
## How It Works
|
||||
|
||||
### Manual Deletion (User-Initiated)
|
||||
|
||||
1. User initiates deletion from profile settings
|
||||
2. Profile is soft-deleted:
|
||||
- `deleted_at` timestamp is set to current time
|
||||
- Balance handling preferences are stored in **Redis cache** (key: `balance_handling_{ModelClass}_{ID}`)
|
||||
- Cache TTL: grace period + 7 days buffer
|
||||
- `comment` field remains **empty** for manual deletions
|
||||
- User is logged out and redirected to goodbye page
|
||||
3. Confirmation email is sent with grace period information
|
||||
4. Profile can be restored during grace period
|
||||
5. After grace period expires, scheduled command permanently deletes the profile
|
||||
|
||||
### Auto-Deletion (Inactivity-Based)
|
||||
|
||||
1. System detects inactive profile (based on `inactive_at` timestamp)
|
||||
2. Warning emails are sent before deletion
|
||||
3. Profile is soft-deleted if user doesn't respond
|
||||
4. Profile is soft-deleted:
|
||||
- `deleted_at` timestamp is set to current time
|
||||
- Balance handling preferences are stored in **Redis cache**
|
||||
- `comment` field is set to: **"Profile automatically deleted after X days of inactivity."** (translated)
|
||||
5. Email notification sent about automatic deletion
|
||||
6. Grace period begins, allowing restoration
|
||||
7. After grace period expires, permanent deletion occurs
|
||||
|
||||
### Permanent Deletion Process
|
||||
|
||||
After the grace period expires:
|
||||
|
||||
1. **Balance handling preferences are retrieved from Redis cache**:
|
||||
- Cache key: `balance_handling_{ModelClass}_{ID}`
|
||||
- If cache found: Execute user's choice (donate or destroy currency)
|
||||
- **FALLBACK**: If cache lost, **destroy currency** (transfer to debit account)
|
||||
- Fallback triggers a warning log for monitoring
|
||||
|
||||
2. Balance handling is executed:
|
||||
- If donated: transfers to selected organization account
|
||||
- If deleted (or fallback): balances transferred to debit account (currency removed from circulation)
|
||||
|
||||
3. Profile data is anonymized:
|
||||
- Email: `removed-{id}@remove.ed`
|
||||
- Name: `Removed {profiletype} {id}`
|
||||
- Password: randomized
|
||||
- Personal data: cleared
|
||||
- Comment: cleared
|
||||
|
||||
4. Profile photo deleted
|
||||
|
||||
5. Related data cleaned up (stars, bookmarks, etc.)
|
||||
|
||||
6. **Cache is cleared** after successful completion
|
||||
|
||||
## Artisan Commands
|
||||
|
||||
### Restore Deleted Profile
|
||||
|
||||
Restore a profile that was deleted within the grace period.
|
||||
|
||||
#### Command Signature
|
||||
|
||||
```bash
|
||||
php artisan profiles:restore {username?} {--list} {--type=}
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
- `{username?}` - Optional. Username of the profile to restore
|
||||
- `--list` - Display all profiles eligible for restoration
|
||||
- `--type=` - Filter by profile type (user, organization, bank, admin)
|
||||
|
||||
#### Usage Examples
|
||||
|
||||
**List all restorable profiles:**
|
||||
```bash
|
||||
php artisan profiles:restore --list
|
||||
```
|
||||
|
||||
**List restorable profiles by type:**
|
||||
```bash
|
||||
php artisan profiles:restore --list --type=user
|
||||
php artisan profiles:restore --list --type=organization
|
||||
```
|
||||
|
||||
**Restore specific profile:**
|
||||
```bash
|
||||
php artisan profiles:restore john_doe
|
||||
```
|
||||
|
||||
**Interactive mode (prompts for username):**
|
||||
```bash
|
||||
php artisan profiles:restore
|
||||
```
|
||||
|
||||
#### Output Example
|
||||
|
||||
```
|
||||
Available profiles for restoration:
|
||||
|
||||
Users:
|
||||
┌──────────┬───────────────┬──────────────┬─────────────┐
|
||||
│ Username │ Email │ Deleted │ Time Left │
|
||||
├──────────┼───────────────┼──────────────┼─────────────┤
|
||||
│ john_doe │ john@test.com │ 2 days ago │ 28 days │
|
||||
│ jane_smith│ jane@test.com │ 5 hours ago │ 29 days │
|
||||
└──────────┴───────────────┴──────────────┴─────────────┘
|
||||
|
||||
Organizations:
|
||||
┌──────────┬───────────────┬──────────────┬─────────────┐
|
||||
│ Username │ Email │ Deleted │ Time Left │
|
||||
├──────────┼───────────────┼──────────────┼─────────────┤
|
||||
│ org_test │ org@test.com │ 1 day ago │ 29 days │
|
||||
└──────────┴───────────────┴──────────────┴─────────────┘
|
||||
|
||||
Total: 3 profile(s) can be restored
|
||||
```
|
||||
|
||||
#### Restoration Process
|
||||
|
||||
The command will:
|
||||
|
||||
1. Verify the profile exists and is within grace period
|
||||
2. Check that the profile hasn't been anonymized
|
||||
3. Clear the `deleted_at` timestamp
|
||||
4. Clear stored balance handling preferences from `comment` field
|
||||
5. Log the restoration action
|
||||
6. Display success message with profile details
|
||||
|
||||
#### Error Handling
|
||||
|
||||
The command handles various error scenarios:
|
||||
|
||||
- **Profile not found**: "Profile 'username' not found"
|
||||
- **Already active**: "Profile 'username' is not deleted"
|
||||
- **Grace period expired**: "Profile 'username' cannot be restored (grace period expired)"
|
||||
- **Already anonymized**: "Profile 'username' has already been permanently deleted"
|
||||
|
||||
### Permanent Deletion Command (Scheduled)
|
||||
|
||||
This command runs automatically via Laravel scheduler to permanently delete expired profiles.
|
||||
|
||||
#### Command Signature
|
||||
|
||||
```bash
|
||||
php artisan profiles:permanently-delete-expired
|
||||
```
|
||||
|
||||
#### Schedule Configuration
|
||||
|
||||
**Location:** `app/Console/Kernel.php`
|
||||
|
||||
```php
|
||||
$schedule->command('profiles:permanently-delete-expired')
|
||||
->daily()
|
||||
->at('02:30')
|
||||
->withoutOverlapping()
|
||||
->appendOutputTo(storage_path('logs/permanent-deletions.log'));
|
||||
```
|
||||
|
||||
**Default Schedule:** Daily at 02:30 AM
|
||||
|
||||
#### What It Does
|
||||
|
||||
1. Finds all profiles where:
|
||||
- `deleted_at` is set
|
||||
- `deleted_at` + grace_period_days < now
|
||||
- Email is not already anonymized (not deleted_user_*)
|
||||
2. For each expired profile:
|
||||
- Retrieves balance handling preferences from `comment` field
|
||||
- Calls `DeleteUser::permanentlyDelete()` method
|
||||
- Handles balances according to stored preferences
|
||||
- Anonymizes profile data
|
||||
3. Logs all actions to `storage/logs/permanent-deletions.log`
|
||||
|
||||
#### Manual Execution
|
||||
|
||||
You can manually trigger permanent deletion of expired profiles:
|
||||
|
||||
```bash
|
||||
php artisan profiles:permanently-delete-expired
|
||||
```
|
||||
|
||||
**Warning:** This command is destructive and cannot be undone. Only run manually for testing or if you need to immediately process expired profiles.
|
||||
|
||||
## Email Notifications
|
||||
|
||||
### User-Deleted Email
|
||||
|
||||
Sent immediately when a profile is deleted.
|
||||
|
||||
**Template:** `resources/views/emails/administration/user-deleted.blade.php`
|
||||
|
||||
**Contains:**
|
||||
- Account details (username, email, deletion time)
|
||||
- Balance handling information (if applicable)
|
||||
- Grace period notification
|
||||
- Data handling information
|
||||
|
||||
**Key Message:**
|
||||
> "This action will become permanent after {days} days."
|
||||
|
||||
### Auto-Deleted Email
|
||||
|
||||
Sent when a profile is automatically deleted due to inactivity.
|
||||
|
||||
**Template:** Same as user-deleted, with additional fields:
|
||||
- `autoDeleted: true`
|
||||
- Deletion reason
|
||||
- Days of inactivity
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### Data Storage During Grace Period
|
||||
|
||||
**Profile Models** (User, Organization, Bank, Admin):
|
||||
|
||||
- `deleted_at` (datetime): Timestamp when profile was soft-deleted
|
||||
- `comment` (text):
|
||||
- **Auto-deletion**: Human-readable message (e.g., "Profile automatically deleted after 120 days of inactivity.")
|
||||
- **Manual deletion**: Empty (no comment)
|
||||
|
||||
**Balance Handling Cache Storage (Redis):**
|
||||
|
||||
**Why Cache?**
|
||||
- Balance handling is stored in cache (not database) to keep the `comment` field human-readable for administrators
|
||||
- User's balance handling choice (donate vs delete) needs to persist through the grace period
|
||||
- Balances are handled during permanent deletion (after grace period expires), not during soft delete
|
||||
- Cache automatically expires after grace period + buffer, self-cleaning the data
|
||||
- Transactions table provides permanent audit trail of actual balance transfers
|
||||
|
||||
**Cache Details:**
|
||||
- **Key**: `balance_handling_{ModelClass}_{ProfileID}`
|
||||
- **TTL**: Grace period days + 7 days buffer
|
||||
- **Structure**:
|
||||
```php
|
||||
[
|
||||
'option' => 'donate|delete',
|
||||
'donation_account_id' => 123, // null if option is 'delete'
|
||||
'stored_at' => '2025-12-19 10:30:00'
|
||||
]
|
||||
```
|
||||
|
||||
**Cache Fallback:**
|
||||
- If cache is lost during permanent deletion, the system defaults to **destroying currency** (transfer to debit account)
|
||||
- A warning is logged: `Balance handling cache lost for profile deletion`
|
||||
- This ensures no orphaned balances remain in the system
|
||||
- Transaction table will show the fallback action for audit purposes
|
||||
|
||||
### Translation Keys
|
||||
|
||||
**Auto-deletion comment** (`resources/lang/*.json`):
|
||||
- English: `"Profile automatically deleted after :days days of inactivity."`
|
||||
- Dutch: `"Profiel automatisch verwijderd na :days dagen inactiviteit."`
|
||||
- French: `"Profil automatiquement supprimé après :days jours d'inactivité."`
|
||||
- Spanish: `"Perfil eliminado automáticamente después de :days días de inactividad."`
|
||||
- German: `"Profil automatisch nach :days Tagen Inaktivität gelöscht."`
|
||||
|
||||
### Key Classes and Files
|
||||
|
||||
#### Actions
|
||||
|
||||
**`app/Actions/Jetstream/DeleteUser.php`**
|
||||
- `delete()`: Soft deletes profile, stores balance preferences in Redis cache
|
||||
- `permanentlyDelete()`: Retrieves balance preferences from cache, handles balances, anonymizes profile, clears cache
|
||||
|
||||
**`app/Actions/Jetstream/RestoreProfile.php`**
|
||||
- `restore()`: Restores a soft-deleted profile within grace period
|
||||
|
||||
#### Commands
|
||||
|
||||
**`app/Console/Commands/RestoreDeletedProfile.php`**
|
||||
- Interactive CLI for restoring profiles
|
||||
- Lists eligible profiles
|
||||
- Handles restoration process
|
||||
|
||||
**`app/Console/Commands/PermanentlyDeleteExpiredProfiles.php`**
|
||||
- Scheduled task for permanent deletion
|
||||
- Processes expired profiles
|
||||
- Logs all actions
|
||||
|
||||
#### Livewire Components
|
||||
|
||||
**`app/Http/Livewire/Profile/DeleteUserForm.php`**
|
||||
- `deleteUser()`: Handles user-initiated deletion
|
||||
- Stores balance handling options
|
||||
- Manages logout and session
|
||||
- Redirects to goodbye page
|
||||
|
||||
### Views
|
||||
|
||||
**`resources/views/goodbye-deleted-user.blade.php`**
|
||||
- Displayed after manual deletion
|
||||
- Shows deletion confirmation and grace period info
|
||||
|
||||
### Routes
|
||||
|
||||
**Route:** `/goodbye-deleted-user` (Named: `goodbye-deleted-user`)
|
||||
- Displays goodbye page after deletion
|
||||
- Requires `session('result')` data
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Manual Deletion
|
||||
|
||||
1. Set grace period to 1 day in config for testing:
|
||||
```php
|
||||
'grace_period_days' => 1,
|
||||
```
|
||||
|
||||
2. Delete a test profile from profile settings
|
||||
|
||||
3. Verify:
|
||||
- Goodbye page displays
|
||||
- Email received with grace period info
|
||||
- Profile listed in `php artisan profiles:restore --list`
|
||||
|
||||
4. Restore the profile:
|
||||
```bash
|
||||
php artisan profiles:restore test_user
|
||||
```
|
||||
|
||||
5. Verify profile is active and can log in
|
||||
|
||||
### Test Automatic Deletion
|
||||
|
||||
1. Run the permanent deletion command after grace period:
|
||||
```bash
|
||||
php artisan profiles:permanently-delete-expired
|
||||
```
|
||||
|
||||
2. Verify:
|
||||
- Profile is permanently deleted
|
||||
- Data is anonymized
|
||||
- Balances handled according to preferences
|
||||
- Logged in `storage/logs/permanent-deletions.log`
|
||||
|
||||
### Test Edge Cases
|
||||
|
||||
**Grace period expired:**
|
||||
```bash
|
||||
php artisan profiles:restore expired_user
|
||||
# Should show: "Profile cannot be restored (grace period expired)"
|
||||
```
|
||||
|
||||
**Already anonymized:**
|
||||
```bash
|
||||
php artisan profiles:restore permanently_deleted_user
|
||||
# Should show: "Profile has already been permanently deleted"
|
||||
```
|
||||
|
||||
**Non-existent profile:**
|
||||
```bash
|
||||
php artisan profiles:restore nonexistent
|
||||
# Should show: "Profile 'nonexistent' not found"
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### For Administrators
|
||||
|
||||
1. **Monitor grace period activity:**
|
||||
- Check `storage/logs/permanent-deletions.log` regularly
|
||||
- Review restoration requests
|
||||
- Adjust grace period based on user feedback
|
||||
|
||||
2. **Backup before major changes:**
|
||||
- Database backup before reducing grace period
|
||||
- Test restoration process in staging first
|
||||
|
||||
3. **User communication:**
|
||||
- Clearly communicate grace period in deletion UI
|
||||
- Include grace period in Terms of Service
|
||||
- Send reminder emails before permanent deletion (optional enhancement)
|
||||
|
||||
### For Developers
|
||||
|
||||
1. **Never bypass grace period:**
|
||||
- Always use `DeleteUser@delete()` for deletions
|
||||
- Never directly set `deleted_at` without storing balance preferences
|
||||
- Use `DeleteUser@permanentlyDelete()` only after grace period
|
||||
|
||||
2. **Preserve balance preferences:**
|
||||
- Always store in `comment` field as JSON
|
||||
- Include `stored_at` timestamp
|
||||
- Validate before permanent deletion
|
||||
|
||||
3. **Testing:**
|
||||
- Use short grace period (1 day) in development
|
||||
- Test both restoration and permanent deletion
|
||||
- Verify email notifications
|
||||
|
||||
4. **Cache management:**
|
||||
- Clear account balance cache when restoring
|
||||
- Invalidate session data appropriately
|
||||
- Refresh Elasticsearch indices if needed
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Profile shows as deleted but can't be restored
|
||||
|
||||
**Possible causes:**
|
||||
1. Grace period already expired
|
||||
2. Profile already permanently deleted (email starts with `deleted_user_`)
|
||||
3. Database inconsistency
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Check profile status in database
|
||||
php artisan tinker
|
||||
>>> $user = App\Models\User::withTrashed()->where('name', 'username')->first();
|
||||
>>> $user->deleted_at
|
||||
>>> $user->email
|
||||
>>> Carbon\Carbon::parse($user->deleted_at)->addDays(config('timebank_cc.delete_profile.grace_period_days'))
|
||||
```
|
||||
|
||||
### Balance handling preferences lost
|
||||
|
||||
**Possible causes:**
|
||||
1. `comment` field was cleared manually
|
||||
2. Profile updated after deletion
|
||||
|
||||
**Solution:**
|
||||
- Check database for `comment` field content
|
||||
- If lost, you'll need to manually decide balance handling during restoration
|
||||
|
||||
### Permanent deletion not running
|
||||
|
||||
**Possible causes:**
|
||||
1. Laravel scheduler not configured
|
||||
2. Command has errors
|
||||
3. No expired profiles
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Check scheduler is running
|
||||
php artisan schedule:list
|
||||
|
||||
# Run manually to see errors
|
||||
php artisan profiles:permanently-delete-expired
|
||||
|
||||
# Check logs
|
||||
tail -f storage/logs/laravel.log
|
||||
tail -f storage/logs/permanent-deletions.log
|
||||
```
|
||||
|
||||
### Restored profile can't log in
|
||||
|
||||
**Possible causes:**
|
||||
1. Cache not cleared
|
||||
2. Session data corrupted
|
||||
3. Password was changed during soft deletion
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Clear all caches
|
||||
php artisan cache:clear
|
||||
php artisan view:clear
|
||||
php artisan config:clear
|
||||
|
||||
# Reset password if needed
|
||||
php artisan tinker
|
||||
>>> $user = App\Models\User::where('name', 'username')->first();
|
||||
>>> $user->password = Hash::make('newpassword');
|
||||
>>> $user->save();
|
||||
```
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential improvements to the grace period system:
|
||||
|
||||
1. **Reminder emails:**
|
||||
- Send email 7 days before permanent deletion
|
||||
- Send final warning 24 hours before deletion
|
||||
|
||||
2. **Self-service restoration:**
|
||||
- Allow users to restore their own profiles via email link
|
||||
- Magic link authentication for deleted accounts
|
||||
|
||||
3. **Extended grace for specific cases:**
|
||||
- Longer grace period for profiles with high balance
|
||||
- Longer grace for organization/bank profiles
|
||||
|
||||
4. **Audit trail:**
|
||||
- Track who restored profiles and when
|
||||
- Log reason for restoration
|
||||
- Activity log entries for all grace period actions
|
||||
|
||||
5. **Dashboard for admins:**
|
||||
- View all profiles in grace period
|
||||
- Bulk restore operations
|
||||
- Analytics on deletion patterns
|
||||
|
||||
### WireChat Message Handling
|
||||
|
||||
All WireChat messages are eventually deleted to prevent orphaned data. When a profile is permanently deleted, their sent messages are released for cleanup.
|
||||
|
||||
#### Configuration
|
||||
|
||||
**Location:** `config/timebank-*.php`
|
||||
|
||||
```php
|
||||
'wirechat' => [
|
||||
'disappearing_messages' => [
|
||||
'allow_users_to_keep' => true, // Allow marking messages as "kept"
|
||||
'duration' => 30, // Days before regular messages deleted
|
||||
'kept_messages_duration' => 90, // Days before kept messages deleted
|
||||
'cleanup_schedule' => 'everyFiveMinutes',
|
||||
],
|
||||
'profile_deletion' => [
|
||||
'release_kept_messages' => true, // MUST be true to prevent orphans
|
||||
],
|
||||
],
|
||||
```
|
||||
|
||||
**Note:** Disappearing messages are ALWAYS enabled. There is no 'enabled' flag - messages are always cleaned up to prevent orphaned data from deleted profiles.
|
||||
|
||||
#### Behavior
|
||||
|
||||
**All messages are eventually deleted:**
|
||||
- Regular messages: Deleted after `duration` days (default: 30 days)
|
||||
- Kept messages: Deleted after `kept_messages_duration` days (default: 90 days)
|
||||
- Messages from deleted profiles: Released and then deleted after `duration` days
|
||||
|
||||
**When profile is permanently deleted:**
|
||||
1. Profile enters grace period (default: 30 days)
|
||||
2. Grace period expires → permanent deletion runs
|
||||
3. All kept messages sent by that profile: `kept_at = null` (released)
|
||||
4. Messages become regular messages, deleted after `duration` days
|
||||
5. This prevents orphaned messages with invalid `sendable_id`
|
||||
|
||||
#### Timeline Example
|
||||
|
||||
**With default settings:**
|
||||
- `duration = 30` days
|
||||
- `kept_messages_duration = 90` days
|
||||
- `release_kept_messages = true`
|
||||
|
||||
```
|
||||
Scenario 1: Normal message lifecycle
|
||||
Day 0: User sends message
|
||||
Day 30: Message automatically deleted by DeleteExpiredWireChatMessagesJob
|
||||
|
||||
Scenario 2: Kept message lifecycle
|
||||
Day 0: User sends message, recipient marks as "kept"
|
||||
Day 90: Kept message automatically deleted by cleanup job
|
||||
|
||||
Scenario 3: Sender deletes profile
|
||||
Day 0: User sends message, recipient marks as "kept"
|
||||
Day 365: User deletes profile → grace period starts
|
||||
Day 395: Grace period expires → permanent deletion
|
||||
→ kept_at set to null (message "released")
|
||||
→ Message now subject to normal 30-day duration
|
||||
Day 425: Message deleted by cleanup job (30 days after release)
|
||||
```
|
||||
|
||||
#### Why This Prevents Orphaned Messages
|
||||
|
||||
**Without `release_kept_messages`:**
|
||||
- Deleted profile has `sendable_id = 123`, `sendable_type = 'App\Models\User'`
|
||||
- Profile anonymized: name becomes "Removed user abc123ef"
|
||||
- Kept messages still reference old `sendable_id` pointing to anonymized profile
|
||||
- Messages orphaned forever with no way to trace original sender
|
||||
- Database accumulates orphaned data indefinitely
|
||||
|
||||
**With `release_kept_messages = true`:**
|
||||
- Kept messages released when profile permanently deleted
|
||||
- Normal cleanup job deletes them after `duration` days
|
||||
- No orphaned data remains in database
|
||||
- Clean data retention without privacy concerns
|
||||
- Conversation history maintained for recipients until cleanup
|
||||
|
||||
#### Configuration Notes
|
||||
|
||||
- `release_kept_messages` should ALWAYS be `true` (default and recommended)
|
||||
- Setting it to `false` will cause orphaned messages to accumulate
|
||||
- All durations specified in DAYS (converted to seconds internally)
|
||||
- Cleanup job runs based on `cleanup_schedule` (default: every 5 minutes)
|
||||
- User control is hardcoded to `false` (users cannot change message duration)
|
||||
- Disappearing messages are hardcoded to enabled (always active)
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- **Profile Auto-Delete:** `references/PROFILE_AUTO_DELETE.md` - Automatic deletion based on inactivity
|
||||
- **Profile Inactive Config:** `references/PROFILE_INACTIVE_CONFIG.md` - Configuration for inactive profile detection
|
||||
- **Email Testing:** `references/EMAIL-TESTING-GUIDE.md` - Testing email notifications
|
||||
|
||||
## Changelog
|
||||
|
||||
### Version 1.1 (2025-12-19)
|
||||
- **BREAKING CHANGE**: Balance handling data moved from `comment` field to Redis cache
|
||||
- Added cache fallback: automatically destroys currency if cache is lost
|
||||
- Comment field now human-readable:
|
||||
- Auto-deletion: Shows translated message "Profile automatically deleted after X days of inactivity"
|
||||
- Manual deletion: Empty (no comment)
|
||||
- Added translation keys for auto-deletion comments in 5 languages (en, nl, fr, de, es)
|
||||
- Enhanced logging: Warning logged when cache fallback is triggered
|
||||
- Cache automatically expires after grace period + 7 days buffer
|
||||
- Transaction table provides complete audit trail of balance handling
|
||||
|
||||
### Version 1.0 (2025-12-19)
|
||||
- Initial implementation of grace period system
|
||||
- Two-phase deletion process (soft delete + permanent delete)
|
||||
- Restore command with interactive and list modes
|
||||
- Scheduled permanent deletion command
|
||||
- Email notifications with grace period information
|
||||
- Balance handling deferred until permanent deletion
|
||||
Reference in New Issue
Block a user