Archive & Delete
The platform supports both soft-delete (archive) and hard-delete (permanent deletion) for guilds and characters, with smart business rules to prevent accidental data loss.
Overview
Two types of deletion are available:
- Archive (Soft Delete): Hides the entity from lists but preserves all data. Can be restored later.
- Delete (Hard Delete): Permanently removes the entity and all related data. Cannot be undone.
Business Rules
Guilds
Who can archive/delete:
- Guild Master (WoW rank 0)
- Officers with
canManageGuildpermission - Standalone guild creators
Archive:
- ✅ Available for all guilds
- Sets
active = falseandarchivedAt = timestamp - Excluded from default guild list
- All data preserved
- Can be restored by authorized users
Hard Delete:
- ⚠️ Only available for standalone guilds
- Blizzard-synced guilds cannot be permanently deleted
- Removes guild and CASCADE deletes:
- All roles
- All memberships
- All events
- All participation records
- Role assignment history
Characters
Who can archive/delete:
- Character owner only (verified by
userId)
Archive:
- ✅ Available for all characters
- Sets
active = false - Excluded from default character list
- Can be restored by owner
Hard Delete:
- ⚠️ Only available for manual characters
- Blizzard-synced characters cannot be permanently deleted
- Removes character and CASCADE deletes:
- All memberships
- Related guild member records (if linked)
API Endpoints
Guilds
# Archive a guild (soft delete)
PATCH /api/v1/guilds/:guildId/archive
Authorization: Bearer <token>
Requires: Action.Delete on Guild
# Restore an archived guild
PATCH /api/v1/guilds/:guildId/restore
Authorization: Bearer <token>
Requires: Action.Update on Guild
# Permanently delete a guild
DELETE /api/v1/guilds/:guildId
Authorization: Bearer <token>
Requires: Action.Delete on Guild
Note: Only standalone guilds
# List guilds (with optional archived)
GET /api/v1/guilds?includeArchived=true
Characters
# Archive a character (soft delete)
PATCH /api/v1/characters/:characterId/archive
Authorization: Bearer <token>
# Restore an archived character
PATCH /api/v1/characters/:characterId/restore
Authorization: Bearer <token>
# Permanently delete a character
DELETE /api/v1/characters/:characterId
Authorization: Bearer <token>
Note: Only manual characters
# List characters (with optional archived)
GET /api/v1/characters?includeInactive=true
Frontend UI
Guild List (Home Page)
Show Archived Toggle:
- Switch to include archived guilds in the list
- Preference persisted in localStorage (
guilds:showArchived) - Shows count of archived guilds
- Archived guilds displayed with:
- Reduced opacity (60%)
- "Archived" chip badge
- Click to view (read-only)
Guild Settings
Danger Zone (Active Guilds):
- Archive button (warning color)
- Delete button (danger color, standalone only)
- Both require confirmation dialog
Archived Notice:
- Prominent warning banner
- "Restore Guild" button
- Delete option still available
Character List
Character Card Actions:
- Dropdown menu (⋮) on each card
- Active characters:
- Archive option
- Delete option (manual only)
- Archived characters:
- Restore option
Show Inactive Toggle:
- Similar to guild list
- Includes archived characters when enabled
Confirmation Dialogs
All destructive actions require confirmation with clear messaging:
Archive (Warning):
- Yellow theme
- "You can restore it later"
- Action: Archive
Restore (Primary):
- Blue theme
- "Make it active again"
- Action: Restore
Delete (Danger):
- Red theme
- "This action cannot be undone"
- Strong warning about data loss
- Action: Delete Permanently
Cache Invalidation
Frontend
Invalidates all related queries:
queryClient.invalidateQueries({ queryKey: ['guilds'] });
Clears:
- Guild list (active)
- Guild list (with archived)
- Archived count query
- Individual guild details
Backend
Redis cache patterns cleared:
http:${userId}:/api/v1/guilds
http:${userId}:/api/v1/guilds?*
http:guest:/api/v1/guilds
http:guest:/api/v1/guilds?*
Database Schema
Guild
model Guild {
// ... other fields
active Boolean @default(true)
archivedAt DateTime? @map("archived_at")
@@index([active])
}
Character
model Character {
// ... other fields
active Boolean @default(true) // false = archived/inactive
@@index([active])
}
Implementation Notes
Why Two Types?
Soft Delete (Archive):
- Preserves data integrity
- Maintains relationships
- Allows restoration
- Audit trail preserved
- Safe for Blizzard-synced data
Hard Delete:
- True data removal
- User privacy (GDPR)
- Clean up test data
- Only for user-created data
Sync Source Protection
The platform prevents permanent deletion of synced data because:
- May be re-synced from external source
- Could cause sync conflicts
- User doesn't "own" the data
- External source is authoritative
Permission Model
Uses CASL for authorization:
// Guild Master - full control
if (wowRank === 0) {
can(Action.Manage, 'all');
}
// Officers with guild management
if (permissions.canManageGuild) {
can([Action.Update, Action.Delete], 'Guild', { id: guildId });
}
Best Practices
For Users
- Archive first - Try archiving before permanent deletion
- Export data - Back up important information before deleting
- Verify ownership - Only delete content you created manually
- Confirm carefully - Read confirmation messages thoroughly
For Developers
- Always soft-delete first - Default to archiving
- Verify sync source - Block hard delete for synced entities
- Clear all caches - Frontend + backend invalidation
- Use transactions - For operations with multiple steps
- Log deletions - Maintain audit trail for compliance
Testing
Manual testing checklist:
Guilds:
- Archive standalone guild
- Restore archived guild
- Delete standalone guild (permanent)
- Try to delete synced guild (should fail)
- Verify permissions (only authorized users)
- Check cache invalidation
- Verify Show Archived toggle
Characters:
- Archive manual character
- Restore archived character
- Delete manual character (permanent)
- Try to delete synced character (should fail)
- Verify ownership check
- Check Show Inactive toggle
Future Enhancements
Potential improvements:
- Bulk archive/restore operations
- Scheduled auto-archive for inactive guilds
- Trash/recycle bin with 30-day retention
- Export archived data before deletion
- Admin panel for managing archived content
- Metrics on archived vs active content