Archive Asset

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)

  1. Creator clicks Move to Trash in asset list.

  2. UI confirms action through delete modal.

  3. API sets deleted_at and expires_at.

  4. Active list excludes the asset.

  5. Trash list displays asset with remaining days.

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

Tertiary Information (Hidden until needed)

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

  1. Background Assets list

  2. Move to Trash confirmation modal

  3. Trash Bin grid

  4. Trash empty state

  5. Purge confirmation modal

Annotations:

  • Active list route excludes deleted_at != null assets.

  • Trash route includes only deleted_at != null assets.

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

  1. Open Background Assets.

  2. Move one asset to Trash.

  3. Confirm it disappears from active list and appears in Trash.

  4. Restore and verify it reappears in active list.

  5. Purge and verify complete removal.


8. BACKEND SCHEMA

Database Tables

  • public.asset_metadata

Key fields used by this feature:

  • id

  • creator_id

  • file_name

  • file_path

  • file_url

  • asset_type

  • deleted_at

  • expires_at

  • created_at

  • updated_at

Indexes:

  • idx_asset_metadata_creator_id

  • idx_asset_metadata_deleted_at

  • idx_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 NULL

  • Ordered 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_at for countdown badge

  • Asset type and size metadata

API Calls Frontend Will Make

  • GET /api/creator/list-assets on background-assets load

  • DELETE /api/creator/delete-assets on archive action

  • GET /api/creator/get-trash-assets on trash page load

  • PATCH /api/creator/restore-assets on restore action

  • DELETE /api/creator/purge-assets on permanent delete action

Caching Strategy

  • No-store fetch patterns are used for freshness on asset listings.


11. PERFORMANCE CONSIDERATIONS

Database Optimization

  • Filter by deleted_at is 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.


12. SECURITY & AUTHORIZATION

Who can access this feature?

Creator: ✓
Reviewer: ✗
Learner: ✗

Authorization Logic

  • Agency-aware auth context is required.

  • Ownership verification is enforced before archive/restore/purge operations.

Data Validation

  • asset_id validated 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_at directly instead of deriving from deleted_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_metadata schema and migration

  • Supabase 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)


Was this article helpful?