Archive Project

Feature Owner: scorevi (Sean Patrick Caintic)
Module: Diagnose
Priority: P1
Sprint #12: Fully Implemented
Date: 2026-06-29


EXECUTIVE SUMMARY

What is this feature? Archive Project enables creators to soft-delete quests and adventures by setting their publishing_status to "archived." Archived content is hidden from active views but recoverable via restore. It includes ownership verification and a dedicated listing endpoint for archived content.
Why does it matter? Creators accumulate drafts, experiments, and outdated content over time. Without archiving, the content library becomes cluttered and unmanageable. Archiving provides a safe "undo" path before permanent deletion.
What's the MVP scope? Archive endpoint for quests and adventures with ownership verification, list-archived endpoint returning both content types, and a TrashContent.tsx UI with Restore and Delete Forever actions.


1. USER PAIN POINT & SOLUTION

Current State (Without Feature)

Creators either keep all content indefinitely (cluttered library) or permanently delete it without a safety net. No intermediate state exists between active and deleted.

Pain Point

Type

Impact

Emotional

Anxiety about accidentally deleting valuable work

Functional

No way to hide outdated content without losing it

Business

Content library becomes unusable at scale; poor creator experience

Future State

Creators archive content they no longer need active. Archived items are hidden from the main library but visible in a dedicated trash view. Content can be restored to "draft" status or permanently deleted.

Marketing Hook

"Archive with confidence. Your content is never truly gone until you say so."


2. 4D FRAMEWORK MAPPING

Phase

Mapping

Diagnose

Archive outdated or low-quality content identified by validator

Design

Content lifecycle management (draft → published → archived → deleted)

Develop

Safe content management during active development

Deliver

Clean content library for export workflows


3. USER FLOWS

Entry Point

  • Content Library → Context menu on quest/adventure card → "Archive"

  • TrashContent.tsx component

Success Criteria

  • Content publishing_status changes to "archived"

  • Content hidden from main library views

  • Content visible in archived list

  • Ownership verification succeeds (creator can only archive own content)

Main Flow

  1. Creator selects quest or adventure to archive

  2. System calls verifyContentOwnership() to confirm ownership

  3. PATCH /api/creator/archive-content updates publishing_status to "archived"

  4. Content disappears from active library

  5. Creator can view archived content via GET /api/creator/list-archived

  6. From TrashContent.tsx, creator can Restore or Delete Forever

Edge Cases

  • Archive already-archived content: Idempotent (status already "archived")

  • Archive non-existent content: 404

  • Archive content owned by another creator: verifyContentOwnership() blocks with 403

  • Publishing status 'archived' not in Zod questSchema enum: Archive route bypasses Zod, uses raw Supabase call

Decision Points

  • Archive vs. Delete Forever (archive is reversible, delete is not)

  • Restore to "draft" vs. "published" (always restores to "draft")


4. INFORMATION ARCHITECTURE

Primary

  • Content ID (UUID), content type (quests | adventures), publishing_status

Secondary

  • Archive timestamp, archived by (creator_id)

Actions

  • Archive, List Archived, Restore, Delete Forever


5. WIREFRAMES

Excluded — existing UI (TrashContent.tsx, 300 lines).


6. WIREFLOWS

Excluded — existing UI implemented.


7. PROTOTYPE

Excluded — feature is fully implemented.


8. BACKEND SCHEMA

Publishing Status Lifecycle

draft → published → archived → (permanently deleted)
↑ |
└── Restore ─────────┘

Key Schema Note

Layer

Supports 'archived'?

DB CHECK constraint

Yes — 'archived' is a valid status

Zod questSchema enum

No — 'archived' is NOT in the enum

Archive route behavior

Bypasses Zod, uses raw Supabase .update() call

The archiveContentSchema validates only content_id (UUID) and content_type (enum of "quests" | "adventures"). The actual status update bypasses Zod validation entirely.


9. API ENDPOINTS

Method

Path

Auth

Purpose

File

PATCH

/api/creator/archive-content

Clerk

Set status to "archived"

64 lines

GET

/api/creator/list-archived

Clerk

List archived quests AND adventures

Verified existing

archive-content (PATCH)

  • Schema: archiveContentSchema{ content_id: UUID, content_type: z.enum(["quests","adventures"]) }

  • Logic:

    1. Validate input with archiveContentSchema

    2. verifyContentOwnership() — confirms creator owns the content

    3. Raw Supabase call: .from(content_type).update({ publishing_status: "archived" }).eq("id", content_id)

    4. Returns success/error response

  • Note: Bypasses Zod questSchema/adventureSchema — raw DB update

list-archived (GET)

  • Returns archived quests AND adventures in a single response

  • No pagination in MVP


10. DATA REQUIREMENTS

Frontend Needs

  • Archive button with confirmation dialog

  • Trash view with list of archived items

  • Item type indicator (quest vs. adventure)

  • Restore and Delete Forever action buttons

API Calls

  • PATCH /api/creator/archive-content (single archive)

  • GET /api/creator/list-archived (list archived)

  • PATCH /api/creator/restore-content (restore from trash)

  • DELETE /api/creator/permanent-delete (delete forever)

Caching

  • Active content list: Invalidate on archive

  • Archived list: Refetch on archive/restore/delete actions


11. PERFORMANCE CONSIDERATIONS

DB Optimization

  • publishing_status should be indexed for filtered queries (active vs. archived)

  • Single endpoint returns both quests and adventures (reduces API calls)

Response Time

  • Archive operation: Single UPDATE, sub-50ms

  • List archived: Two queries (quests + adventures), may benefit from union or parallel queries


12. SECURITY & AUTHORIZATIONAccess Control

  • Clerk authentication required

  • verifyContentOwnership() ensures creator can only archive their own content

  • RLS policies prevent cross-creator access

Auth Logic

  • Ownership check via creator_id match before any status change

  • No admin override (MVP — creators manage only their own content)

Validation

  • Input validated via archiveContentSchema (Zod)

  • Status update is raw SQL (no Zod on output) — safe because only setting a fixed value


13. ERROR HANDLING

Error

Response

Invalid content_id (not UUID)

400 — Zod validation error

Invalid content_type

400 — Zod enum validation error

Content not found

404

Content not owned by requester

403 — verifyContentOwnership() failure

Already archived

200 — Idempotent success

DB error

500 — Internal server error


14. TESTING CHECKLIST

Happy Path

  • Archive a quest → status changes to "archived"

  • Archive an adventure → status changes to "archived"

  • List archived content → both quests and adventures appear

  • Archived content NOT visible in main library

  • Restore archived content → status returns to "draft"

  • Delete forever from trash → content permanently removed

Edge Cases

  • Archive content that is already archived (idempotent)

  • Attempt to archive content owned by another creator (blocked)

  • Archive content with invalid content_type (blocked by Zod)

  • Archive content with non-UUID content_id (blocked by Zod)

  • List archived when nothing is archived (empty list)


15. OPEN QUESTIONS

  • Should Zod questSchema and adventureSchema be updated to include 'archived' in their publishing_status enums?

  • Is pagination needed for list-archived at scale?


16. OUT OF SCOPE

  • Bulk archive (multiple items at once)

  • Archive scheduling (auto-archive after inactivity)

  • Archive retention policies (auto-delete after X days)


17. SUCCESS METRICS

  • Archive-to-restore ratio (indicating safe usage)

  • Average items in trash per creator

  • Time from archive to permanent delete

  • Reduction in active library clutter


18. DEPENDENCIES

  • verifyContentOwnership() utility function

  • Publishing status DB CHECK constraint (includes 'archived')

  • Restore Project feature (1.5)

  • Permanent Delete feature (1.6)


19. TIMELINE

Completed — Feature is fully implemented in Sprint #12.


Document Version

1.0 - Initial version - 2026-06-29 08:13 UTC

1.1 - Added Document Version section and update author to have full name - 2026-06-29 08:44 UTC


Was this article helpful?