Skip to main content

Overview

Folders allow users to organize their library items into collections. The folder system supports basic CRUD operations and is integrated with the library management system.

Database Schema

Folders are stored in the user_folders table with the following structure:
id
uuid
required
Unique folder identifier (auto-generated)
user_id
uuid
required
UUID of the user who owns this folder (references auth.users)
name
string
required
Display name of the folder
description
string
Optional description of the folder’s purpose
created_at
timestamp
required
Timestamp when the folder was created (auto-generated)
updated_at
timestamp
required
Timestamp of last update (auto-generated)

Authentication & Authorization

All folder operations require authentication. Row Level Security (RLS) policies ensure:
  • Users can only view their own folders
  • Users can only create folders for themselves
  • Users can only update their own folders
  • Users can only delete their own folders
Currently, there are no dedicated REST API endpoints for folder management in the codebase. Folder operations are handled through direct database access via Supabase client.

Using Folders with Library Items

When saving items to the library, you can specify a folderId to organize items:

Example: Save Item to Folder

const { data, error } = await supabase
  .from('user_library_items')
  .insert({
    user_id: userId,
    folder_id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
    item_type: 'quiz',
    title: 'Biology Chapter 1 Quiz',
    topic: 'Biology',
    content: { /* quiz content */ }
  })
Or via the REST API:
POST /api/library/save
{
  "title": "Biology Chapter 1 Quiz",
  "topic": "Biology",
  "itemType": "quiz",
  "content": { /* quiz content */ },
  "folderId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

Direct Database Operations

Since dedicated API endpoints are not yet implemented, you can manage folders using the Supabase client:

Create Folder

import { createClient } from '@/lib/supabase/client'

const supabase = createClient()

const { data: folder, error } = await supabase
  .from('user_folders')
  .insert({
    user_id: userId,
    name: 'History Notes',
    description: 'All my history study materials'
  })
  .select()
  .single()

Get All Folders

const { data: folders, error } = await supabase
  .from('user_folders')
  .select('*')
  .eq('user_id', userId)
  .order('created_at', { ascending: false })

Update Folder

const { data: folder, error } = await supabase
  .from('user_folders')
  .update({
    name: 'Updated Folder Name',
    description: 'New description',
    updated_at: new Date().toISOString()
  })
  .eq('id', folderId)
  .eq('user_id', userId) // Ensures user owns the folder
  .select()
  .single()

Delete Folder

const { error } = await supabase
  .from('user_folders')
  .delete()
  .eq('id', folderId)
  .eq('user_id', userId) // Ensures user owns the folder
When a folder is deleted, all library items in that folder have their folder_id set to NULL (cascade behavior: ON DELETE SET NULL). The items themselves are not deleted.

Get Folder with Items

// First get the folder
const { data: folder } = await supabase
  .from('user_folders')
  .select('*')
  .eq('id', folderId)
  .eq('user_id', userId)
  .single()

// Then get all items in the folder
const { data: items } = await supabase
  .from('user_library_items')
  .select('*')
  .eq('folder_id', folderId)
  .eq('user_id', userId)
  .order('created_at', { ascending: false })

Folder Structure Example

interface Folder {
  id: string                    // UUID
  user_id: string              // UUID
  name: string                 // e.g., "Biology"
  description: string | null   // e.g., "All biology study materials"
  created_at: string           // ISO timestamp
  updated_at: string           // ISO timestamp
}

Example Folder Object

{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "user_id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Biology",
  "description": "All biology study materials for spring semester",
  "created_at": "2026-03-01T08:00:00.000Z",
  "updated_at": "2026-03-01T08:00:00.000Z"
}

Future API Endpoints

The following endpoints are recommended for future implementation to provide a complete REST API for folder management:

Proposed Endpoints

  • GET /api/folders - List all user folders
  • POST /api/folders - Create a new folder
  • GET /api/folders/[id] - Get folder details with items
  • PATCH /api/folders/[id] - Update folder name/description
  • DELETE /api/folders/[id] - Delete a folder
  • GET /api/folders/[id]/items - Get all items in a folder

Row Level Security Policies

The user_folders table has the following RLS policies active:
-- Users can view their own folders
CREATE POLICY "Users can view their own folders" ON user_folders
  FOR SELECT USING (auth.uid() = user_id);

-- Users can insert their own folders
CREATE POLICY "Users can insert their own folders" ON user_folders
  FOR INSERT WITH CHECK (auth.uid() = user_id);

-- Users can update their own folders
CREATE POLICY "Users can update their own folders" ON user_folders
  FOR UPDATE USING (auth.uid() = user_id);

-- Users can delete their own folders
CREATE "Users can delete their own folders" ON user_folders
  FOR DELETE USING (auth.uid() = user_id);
These policies ensure complete data isolation between users.

Build docs developers (and LLMs) love