Files
stack/apps/api
Jason Woltje 00b7500d05
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
fix(tests): Skip fulltext-search tests when DB trigger not configured
The fulltext-search integration tests require PostgreSQL trigger
function and GIN index that may not be present in all environments
(e.g., CI database). This change adds dynamic detection of the
trigger function and gracefully skips tests that require it.

- Add isFulltextSearchConfigured() helper to check for trigger
- Skip trigger/index tests with clear console warnings
- Keep schema validation test (column exists) always running

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 12:41:31 -06:00
..

Mosaic Stack API

The Mosaic Stack API is a NestJS-based backend service providing REST endpoints and WebSocket support for the Mosaic productivity platform.

Overview

The API serves as the central backend for:

  • Task Management - Create, update, track tasks with filtering and sorting
  • Event Management - Calendar events and scheduling
  • Project Management - Organize work into projects
  • Knowledge Base - Wiki-style documentation with markdown support and wiki-linking
  • Ideas - Quick capture and organization of ideas
  • Domains - Categorize work across different domains
  • Personalities - AI personality configurations for the Ollama integration
  • Widgets & Layouts - Dashboard customization
  • Activity Logging - Track all user actions
  • WebSocket Events - Real-time updates for tasks, events, and projects

Available Modules

Module Base Path Description
Tasks /api/tasks CRUD operations for tasks with filtering
Events /api/events Calendar events and scheduling
Projects /api/projects Project management
Knowledge /api/knowledge/entries Wiki entries with markdown support
Knowledge Tags /api/knowledge/tags Tag management for knowledge entries
Ideas /api/ideas Quick capture and idea management
Domains /api/domains Domain categorization
Personalities /api/personalities AI personality configurations
Widgets /api/widgets Dashboard widget data
Layouts /api/layouts Dashboard layout configuration
Ollama /api/ollama LLM integration (generate, chat, embed)
Users /api/users/me/preferences User preferences

Health Check

  • GET / - API health check
  • GET /health - Detailed health status including database connectivity

Authentication

The API uses BetterAuth for authentication with the following features:

Authentication Flow

  1. Email/Password - Users can sign up and log in with email and password
  2. Session Tokens - BetterAuth generates session tokens with configurable expiration

Guards

The API uses a layered guard system:

Guard Purpose Applies To
AuthGuard Verifies user authentication via Bearer token Most protected endpoints
WorkspaceGuard Validates workspace membership and sets Row-Level Security (RLS) context Workspace-scoped resources
PermissionGuard Enforces role-based access control Admin operations

Workspace Roles

  • OWNER - Full control over workspace
  • ADMIN - Administrative functions (can delete content, manage members)
  • MEMBER - Standard access (create/edit content)
  • GUEST - Read-only access

Permission Levels

Used with @RequirePermission() decorator:

Permission.WORKSPACE_OWNER; // Requires OWNER role
Permission.WORKSPACE_ADMIN; // Requires ADMIN or OWNER
Permission.WORKSPACE_MEMBER; // Requires MEMBER, ADMIN, or OWNER
Permission.WORKSPACE_ANY; // Any authenticated member including GUEST

Providing Workspace Context

Workspace ID can be provided via:

  1. Header: X-Workspace-Id: <workspace-id> (highest priority)
  2. URL Parameter: :workspaceId
  3. Request Body: workspaceId field

Example: Protected Controller

@Controller("tasks")
@UseGuards(AuthGuard, WorkspaceGuard, PermissionGuard)
export class TasksController {
  @Post()
  @RequirePermission(Permission.WORKSPACE_MEMBER)
  async create(@Body() dto: CreateTaskDto, @Workspace() workspaceId: string) {
    // workspaceId is verified and RLS context is set
  }
}

Environment Variables

Variable Description Default
PORT API server port 3001
DATABASE_URL PostgreSQL connection string Required
NODE_ENV Environment (development, production) -
NEXT_PUBLIC_APP_URL Frontend application URL (for CORS) http://localhost:3000
WEB_URL WebSocket CORS origin http://localhost:3000

Running Locally

Prerequisites

  • Node.js 18+
  • PostgreSQL database
  • pnpm workspace (part of Mosaic Stack monorepo)

Setup

  1. Install dependencies:

    pnpm install
    
  2. Set up environment variables:

    cp .env.example .env  # If available
    # Edit .env with your DATABASE_URL
    
  3. Generate Prisma client:

    pnpm prisma:generate
    
  4. Run database migrations:

    pnpm prisma:migrate
    
  5. Seed the database (optional):

    pnpm prisma:seed
    

Development

pnpm dev

The API will start on http://localhost:3001

Production Build

pnpm build
pnpm start:prod

Database Management

# Open Prisma Studio
pnpm prisma:studio

# Reset database (dev only)
pnpm prisma:reset

# Run migrations in production
pnpm prisma:migrate:prod

API Documentation

The API does not currently include Swagger/OpenAPI documentation. Instead:

  • Controller files contain detailed JSDoc comments describing each endpoint
  • DTO classes define request/response schemas with class-validator decorators
  • Refer to the controller source files in src/ for endpoint details

Example: Reading an Endpoint

// src/tasks/tasks.controller.ts

/**
 * POST /api/tasks
 * Create a new task
 * Requires: MEMBER role or higher
 */
@Post()
@RequirePermission(Permission.WORKSPACE_MEMBER)
async create(@Body() createTaskDto: CreateTaskDto, @Workspace() workspaceId: string) {
  return this.tasksService.create(workspaceId, user.id, createTaskDto);
}

WebSocket Support

The API provides real-time updates via WebSocket. Clients receive notifications for:

  • task:created - New task created
  • task:updated - Task modified
  • task:deleted - Task removed
  • event:created - New event created
  • event:updated - Event modified
  • event:deleted - Event removed
  • project:updated - Project modified

Clients join workspace-specific rooms for scoped updates.

Testing

# Run unit tests
pnpm test

# Run tests with coverage
pnpm test:coverage

# Run e2e tests
pnpm test:e2e

# Watch mode
pnpm test:watch

Project Structure

src/
├── activity/          # Activity logging
├── auth/              # Authentication (BetterAuth config, guards)
├── common/            # Shared decorators and guards
├── database/          # Database module
├── domains/           # Domain management
├── events/            # Event management
├── filters/           # Global exception filters
├── ideas/             # Idea capture and management
├── knowledge/         # Knowledge base (entries, tags, markdown)
├── layouts/           # Dashboard layouts
├── lib/               # Utility functions
├── ollama/            # LLM integration
├── personalities/     # AI personality configurations
├── prisma/            # Prisma service
├── projects/          # Project management
├── tasks/             # Task management
├── users/             # User preferences
├── widgets/           # Dashboard widgets
├── websocket/         # WebSocket gateway
├── app.controller.ts  # Root controller (health check)
├── app.module.ts      # Root module
└── main.ts            # Application bootstrap