managarten/memoro/apps/mobile/features/spaces
Till-JS e7f5f942f3 chore: initial commit - consolidate 4 projects into monorepo
Projects included:
- maerchenzauber (NestJS backend + Expo mobile + SvelteKit web + Astro landing)
- manacore (Expo mobile + SvelteKit web + Astro landing)
- manadeck (NestJS backend + Expo mobile + SvelteKit web)
- memoro (Expo mobile + SvelteKit web + Astro landing)

This commit preserves the current state before monorepo restructuring.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 23:38:24 +01:00
..
components chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
contexts chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
hooks chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
services chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
store chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
BACKEND_DOC.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
index.ts chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
README.md chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00
SpaceCard.tsx chore: initial commit - consolidate 4 projects into monorepo 2025-11-22 23:38:24 +01:00

Spaces Feature

This document provides comprehensive documentation for the Spaces feature in the Memoro app.

Overview

The Spaces feature allows users to organize their memos into logical groups or containers. Each space can contain multiple memos, and users can manage spaces (create, edit, delete) directly from the app interface.

Architecture

The Spaces feature is implemented across multiple components:

  1. Express Backend API - Serves as the source of truth for space management and authentication
  2. Memoro App Frontend (in /memoro_app/features/spaces/) - Provides UI and client logic
  3. Supabase Database - Stores space data, accessed directly by the Express Backend
┌─────────────────┐                ┌────────────────────┐
│                 │   API Calls    │                    │
│   Memoro App    │───────────────►│   Express Backend  │
│   (Frontend)    │                │   (Source of Truth)│
│                 │◄───────────────│                    │
└─────────────────┘                └─────────┬──────────┘
                                             │
                                             │ Direct Database
                                             │ Operations
                                             ▼
                                   ┌───────────────────┐
                                   │                   │
                                   │ Supabase Database │
                                   │                   │
                                   └───────────────────┘

Database Schema

Spaces Table

CREATE TABLE IF NOT EXISTS public.spaces (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name TEXT NOT NULL,
  description TEXT DEFAULT '',
  color TEXT DEFAULT '#4CAF50',
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  is_default BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

Memo Spaces Junction Table

CREATE TABLE IF NOT EXISTS public.memo_spaces (
  memo_id UUID NOT NULL REFERENCES public.memos(id) ON DELETE CASCADE,
  space_id UUID NOT NULL REFERENCES public.spaces(id) ON DELETE CASCADE,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  PRIMARY KEY (memo_id, space_id)
);

The schema includes foreign key constraints to ensure referential integrity between spaces, memos, and users.

Authentication

The application uses custom JWT tokens generated by the mana-core-middleware:

  1. The user authenticates using email/password through the middleware API
  2. The middleware generates a JWT token with a sub claim containing the user ID
  3. This token is used for both Supabase and Express backend authentication
  4. Row Level Security (RLS) policies use auth.jwt() ->> 'sub' to extract the user ID

Component Details

1. Space Service (Client-Side)

The spaceService.ts provides the following methods:

  • getSpaces() - Retrieves all spaces for the current user
  • getSpace(id) - Gets a specific space by ID
  • createSpace(data) - Creates a new space
  • updateSpace(id, data) - Updates an existing space
  • deleteSpace(id) - Deletes a space

These methods make API calls to the Express backend for all operations, ensuring that data is always managed through the source of truth before being synchronized to the local database.

2. Express Backend API

The Express Backend API serves as the intermediary between the app and the database. It:

  • Accepts requests from the app with space data
  • Validates the requests using the JWT token
  • Performs operations directly on the Supabase database
  • Returns responses to the client

The Express Backend handles all CRUD operations for spaces, ensuring data consistency.

3. Express Backend Controllers

The Express backend provides endpoints for space management:

  • GET /api/spaces - List all spaces for a user
  • GET /api/spaces/:id - Get a specific space
  • POST /api/spaces - Create a new space
  • PUT /api/spaces/:id - Update a space
  • DELETE /api/spaces/:id - Delete a space

4. UI Components

The UI implementation includes:

  • SpacesScreen.tsx - Main screen for displaying and managing spaces
  • SpaceCard.tsx - Component for displaying individual spaces
  • SpaceContext.tsx - React context for sharing space data across components

Data Flow

When a user creates a space:

  1. The app calls spaceService.createSpace()
  2. SpaceService makes an API call to the Express backend
  3. The Express backend validates the request
  4. The Express backend creates the space directly in the Supabase database
  5. The Express backend returns the space data to the app
  6. The UI updates to show the new space

Row Level Security (RLS)

The spaces table uses RLS to ensure users can only access their own spaces:

-- For retrieving spaces
CREATE POLICY "Users can view their own spaces" 
  ON public.spaces 
  FOR SELECT 
  USING ((auth.jwt() ->> 'sub')::uuid = user_id);

-- For creating spaces
CREATE POLICY "Users can create their own spaces" 
  ON public.spaces 
  FOR INSERT 
  WITH CHECK ((auth.jwt() ->> 'sub')::uuid = user_id);

-- For updating spaces
CREATE POLICY "Users can update their own spaces" 
  ON public.spaces 
  FOR UPDATE 
  USING ((auth.jwt() ->> 'sub')::uuid = user_id);

-- For deleting spaces
CREATE POLICY "Users can delete their own spaces" 
  ON public.spaces 
  FOR DELETE 
  USING ((auth.jwt() ->> 'sub')::uuid = user_id);

-- For edge function operations
CREATE POLICY "Service role can access all spaces"
  ON public.spaces
  USING (auth.role() = 'service_role');

Usage Example

// Create a space
const newSpace = await spaceService.createSpace({
  name: "Work Notes",
  description: "All my work-related memos",
  color: "#2196F3",
  appId: "550e8400-e29b-41d4-a716-446655440000"
});

// Update a space
await spaceService.updateSpace(spaceId, {
  name: "Updated Work Notes",
  description: "New description",
  color: "#FF9800"
});

// Delete a space
await spaceService.deleteSpace(spaceId);

Setup and Deployment

To fully set up the Spaces feature:

  1. Deploy the database migration in /memoro_app/supabase/migrations/20240705000000_spaces_table.sql
  2. Ensure the Express backend is running with space endpoints enabled
  3. Configure the Express backend with proper Supabase credentials
  4. Set up the appropriate environment variables in the app

Environments and Configuration

The feature respects the following environment variables:

  • EXPO_PUBLIC_MIDDLEWARE_URL - URL for the Express backend API
  • EXPO_PUBLIC_MIDDLEWARE_APP_ID - Application ID for the Memoro app
  • EXPO_PUBLIC_SUPABASE_URL - URL for the Supabase project (used by Express backend)
  • EXPO_PUBLIC_SUPABASE_ANON_KEY - Anon key for Supabase (used by Express backend)

Future Enhancements

Potential enhancements to consider:

  1. Space sharing with other users
  2. Space templates or blueprints
  3. Advanced filtering of memos within spaces
  4. Space-specific settings and preferences
  5. Hierarchical spaces (sub-spaces)

Troubleshooting

Common issues:

  1. Authentication failures - Ensure the JWT token is properly formatted with the sub claim
  2. RLS policy issues - Verify RLS policies are using the JWT claim correctly
  3. API communication problems - Check for network issues between the app and Express backend
  4. Database access issues - Ensure Express backend has proper permissions to access Supabase