Feature Owner: Joshua Uriel Tribiana
Module: Develop (Content Production)
Priority: P1
Status: Ready for Implementation
Date: 07/03/2026
EXECUTIVE SUMMARY
What is this feature?
Archive Asset introduces a soft-delete workflow for creator background assets. Instead of hard-deleting immediately, assets are moved to Trash by setting archival metadata, allowing restore within a retention window.
Why does it matter?
Creators need safer deletion behavior to avoid accidental permanent loss. This lowers support burden, improves trust in content operations, and provides a controlled lifecycle before purge.
What’s the MVP scope?
Move asset to trash (soft delete)
Show archived assets in trash list
Restore archived asset to active library
Keep permanent purge as a separate destructive action
1. USER PAIN POINT & SOLUTION
Current State (Without Feature)
Deleting an asset risks immediate permanent loss or inconsistent recovery options.
Pain Point
Emotional: Anxiety over accidental deletion
Functional: No safe recovery window for removed assets
Business Impact: Creator friction and avoidable support tickets
Future State (With Feature)
Assets are first archived to Trash with a 30-day retention marker, and creators can restore before permanent purge.
Marketing Hook
“Delete with confidence using a safe Trash workflow and restore window.”
2. 4D FRAMEWORK MAPPING
Diagnose
Surfaces where deletion risk happens in the creator asset workflow.
Design
Implements a two-step lifecycle: archive first, purge later.
Develop
Adds API and UI behavior for soft-delete, trash retrieval, and restore actions.
Deliver
Provides safer operations in production creator environments with reduced accidental data loss.
3. USER FLOWS
Entry Point
Creator clicks delete on an asset in Background Assets.
Success Criteria
Asset disappears from active library
Asset appears in Trash
Creator can restore or permanently delete
Main Flow (Happy Path)
Creator clicks Move to Trash in asset list.
UI confirms action through delete modal.
API sets
deleted_atandexpires_at.Active list excludes the asset.
Trash list displays asset with remaining days.
Creator restores when needed.
Edge Cases
No data: Trash page shows empty state when no archived assets exist.
API error: Show toast error and keep item unchanged in UI.
Permission denied: Return unauthorized/ownership error from API.
Decision Points
IF creator confirms delete → soft-delete API executes.
ELSE modal closes with no state change.
IF creator chooses restore → clear archive fields.
ELSE IF creator chooses purge → remove storage + metadata row.
4. INFORMATION ARCHITECTURE
Primary Information (Always visible)
Asset name
Asset preview/thumbnail
Asset type
Archived state (trash only)
Secondary Information
Remaining days until retention expiry
Source and file size metadata
Internal IDs (
asset_id)Storage file paths
Ownership and agency scope filters
Actions
Primary CTA:
Move to Trash
Secondary Actions:
Restore
Delete Permanently
Edit asset name
5. WIREFRAMES
Key Screens:
Background Assets list
Move to Trash confirmation modal
Trash Bin grid
Trash empty state
Purge confirmation modal
Annotations:
Active list route excludes
deleted_at != nullassets.Trash route includes only
deleted_at != nullassets.Countdown badge is derived from
deleted_at.
6. WIREFLOWS
+------------------------+| Background Assets UI |+------------------------+ | v+------------------------------------------+| DELETE /api/creator/delete-assets |+------------------------------------------+ | v+------------------------------------------+| asset_metadata || - deleted_at = current timestamp || - expires_at = expiration timestamp |+------------------------------------------+ | v+-------------------------------+| Asset hidden from active list |+-------------------------------+ +------------------------+| Trash Bin UI |+------------------------+ | v+------------------------------------------+| GET /api/creator/get-trash-assets |+------------------------------------------+ | v+-------------------------------+| Archived Assets List |+-------------------------------+ | +-----+-----+ | | | | v v+----------------------------------+ +----------------------------------+| PATCH /api/creator/restore-assets| | DELETE /api/creator/purge-assets |+----------------------------------+ +----------------------------------+ | | v v+----------------------------------+ +-------------------------------+| deleted_at = NULL | | Remove storage object || expires_at = NULL | +-------------------------------++----------------------------------+ | | v | +-------------------------------+ | | Delete asset_metadata record | | +-------------------------------+ | v+------------------------+| Background Assets UI |+------------------------+
7. PROTOTYPE
Figma Prototype Link: Not currently available.
How to test:
Open Background Assets.
Move one asset to Trash.
Confirm it disappears from active list and appears in Trash.
Restore and verify it reappears in active list.
Purge and verify complete removal.
8. BACKEND SCHEMA
Database Tables
public.asset_metadata
Key fields used by this feature:
idcreator_idfile_namefile_pathfile_urlasset_typedeleted_atexpires_atcreated_atupdated_at
Indexes:
idx_asset_metadata_creator_ididx_asset_metadata_deleted_atidx_asset_metadata_created_at
Constraints:
RLS ownership policies enforce creator-scoped access.
9. API ENDPOINTS
DELETE /api/creator/delete-assets
Purpose: Archive asset (soft delete)
Auth: Required
Request:
{ "asset_id": "uuid" }
Success:
{ "success": true, "message": "Asset moved to trash" }
GET /api/creator/list-assets
Purpose: Fetch active assets only
Auth: Required
Behavior:
Returns assets where
deleted_at IS NULL
GET /api/creator/get-trash-assets
Purpose: Fetch archived assets
Auth: Required
Behavior:
Returns assets where
deleted_at IS NOT NULLOrdered by
deleted_at DESC
PATCH /api/creator/restore-assets
Purpose: Restore archived asset
Auth: Required
Request:
{ "asset_id": "uuid" }
Success:
{ "success": true, "message": "Asset restored" }
DELETE /api/creator/purge-assets
Purpose: Permanently delete archived asset
Auth: Required
Request:
{ "asset_id": "uuid" }
Behavior:
Removes storage object(s)
Deletes metadata row
10. DATA REQUIREMENTS
Frontend Needs
Asset identifiers and names
URLs/thumbnails for display
deleted_atfor countdown badgeAsset type and size metadata
API Calls Frontend Will Make
GET /api/creator/list-assetson background-assets loadDELETE /api/creator/delete-assetson archive actionGET /api/creator/get-trash-assetson trash page loadPATCH /api/creator/restore-assetson restore actionDELETE /api/creator/purge-assetson permanent delete action
Caching Strategy
No-store fetch patterns are used for freshness on asset listings.
11. PERFORMANCE CONSIDERATIONS
Database Optimization
Filter by
deleted_atis indexed.Creator ownership lookups are indexed by
creator_id.
Query Optimization Notes
Active and trash lists are split by clear predicates (
IS NULL/IS NOT NULL).
API Response Time
Target: sub-1s for standard list and archive operations under normal load.
Who can access this feature?
Creator: ✓
Reviewer: ✗
Learner: ✗
Agency-aware auth context is required.
Ownership verification is enforced before archive/restore/purge operations.
Data Validation
asset_idvalidated as UUID via Zod for archive/restore/purge routes.Server-side ownership checks prevent cross-tenant operations.
13. ERROR HANDLING
Common Errors
401 Unauthorized: return auth/ownership error and prevent mutation
404 Not Found: asset missing or inaccessible
400 Validation Error: invalid UUID payload
500 Server Error: show toast, keep client state unchanged
14. TESTING CHECKLIST
Happy Path
Archive moves asset to trash and removes it from active list
Restore returns asset to active list
Purge permanently deletes asset metadata and storage object
Edge Cases
Empty trash state renders correctly
API timeout/error shows user-safe feedback
Ownership mismatch blocks mutation
Invalid UUID payload returns 400
15. OPEN QUESTIONS
For Frontend
Should retention countdown use
expires_atdirectly instead of deriving fromdeleted_at?Should trash operations support optimistic UI with rollback for failures?
For Backend
Should typed DELETE confirmation be enforced server-side for purge endpoint?
Should an automatic retention job purge expired assets based on
expires_at?
16. OUT OF SCOPE (v1.1+)
Not building:
Automatic scheduled purge worker
Admin-level retention policy customization
17. SUCCESS METRICS
How will we know this feature is successful?
Archive and restore operations succeed reliably in production
Reduction in accidental permanent deletion incidents
Lower support cases related to missing background assets
18. DEPENDENCIES
This feature depends on:
asset_metadataschema and migrationSupabase storage integration
Agency ownership authorization helpers
These features depend on this:
Trash Bin behavior for background assets
Secure asset lifecycle controls before permanent deletion
19. TIMELINE & OWNERSHIP
Implementation
Backend: Christian (to do)
Frontend: Christian (to do)
QA: To assign (with JD Billate review support)