Files
stack/docs/scratchpads/6-basic-web-ui.md
Jason Woltje 12abdfe81d feat(#93): implement agent spawn via federation
Implements FED-010: Agent Spawn via Federation feature that enables
spawning and managing Claude agents on remote federated Mosaic Stack
instances via COMMAND message type.

Features:
- Federation agent command types (spawn, status, kill)
- FederationAgentService for handling agent operations
- Integration with orchestrator's agent spawner/lifecycle services
- API endpoints for spawning, querying status, and killing agents
- Full command routing through federation COMMAND infrastructure
- Comprehensive test coverage (12/12 tests passing)

Architecture:
- Hub → Spoke: Spawn agents on remote instances
- Command flow: FederationController → FederationAgentService →
  CommandService → Remote Orchestrator
- Response handling: Remote orchestrator returns agent status/results
- Security: Connection validation, signature verification

Files created:
- apps/api/src/federation/types/federation-agent.types.ts
- apps/api/src/federation/federation-agent.service.ts
- apps/api/src/federation/federation-agent.service.spec.ts

Files modified:
- apps/api/src/federation/command.service.ts (agent command routing)
- apps/api/src/federation/federation.controller.ts (agent endpoints)
- apps/api/src/federation/federation.module.ts (service registration)
- apps/orchestrator/src/api/agents/agents.controller.ts (status endpoint)
- apps/orchestrator/src/api/agents/agents.module.ts (lifecycle integration)

Testing:
- 12/12 tests passing for FederationAgentService
- All command service tests passing
- TypeScript compilation successful
- Linting passed

Refs #93

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 14:37:06 -06:00

13 KiB

Issue #6: Basic Web UI (Login, Task List, Calendar)

Objective

Implement the basic web UI for Mosaic Stack with:

  • Login page with Authentik OIDC integration
  • Task list view with PDA-friendly language
  • Calendar view with PDA-friendly language

All components must follow TDD (tests first), achieve 85%+ coverage, and use PDA-friendly design principles.

Approach

Phase 1: Setup & Infrastructure

  1. Install necessary dependencies (next-auth alternatives, date/calendar libraries)
  2. Create directory structure for components, pages, and tests
  3. Set up authentication client wrapper

Phase 2: Authentication UI (TDD)

  1. Write tests for Login component
  2. Implement Login page with OIDC redirect
  3. Write tests for authentication callback handler
  4. Implement callback handler
  5. Write tests for auth context/hooks
  6. Implement auth context and hooks

Phase 3: Task List UI (TDD)

  1. Write tests for TaskList component
  2. Implement TaskList component with PDA-friendly language
  3. Write tests for TaskItem component
  4. Implement TaskItem component
  5. Write tests for API integration
  6. Implement API client for tasks

Phase 4: Calendar UI (TDD)

  1. Write tests for Calendar component
  2. Implement Calendar view with PDA-friendly language
  3. Write tests for EventCard component
  4. Implement EventCard component
  5. Write tests for API integration
  6. Implement API client for events

Phase 5: Layout & Navigation

  1. Write tests for main layout component
  2. Implement authenticated layout with navigation
  3. Write tests for navigation component
  4. Implement navigation with route protection

Phase 6: Quality & Documentation

  1. Run coverage report (ensure 85%+)
  2. Update documentation
  3. Build and test all changes
  4. Create demo screenshots if needed

Technology Stack

  • Framework: Next.js 16 (App Router)
  • Auth: Custom OIDC client using BetterAuth API
  • UI Components: Shadcn/ui + TailwindCSS
  • State Management: React Context + hooks
  • Date Library: date-fns (lightweight)
  • Testing: Vitest + React Testing Library
  • Type Safety: TypeScript + @mosaic/shared types

Progress

Phase 1: Setup & Infrastructure

  • Install dependencies (date-fns, etc.)
  • Create directory structure
  • Set up environment variables in Next.js

Phase 2: Authentication UI

  • Test: Login page renders correctly
  • Test: Login button triggers OIDC flow
  • Implement: Login page component
  • Test: Callback handler processes auth response
  • Implement: Auth callback page
  • Test: Auth context provides user state
  • Test: Auth hooks (useAuth, useUser)
  • Implement: Auth context and hooks
  • Test: Protected route wrapper
  • Implement: Protected route component

Phase 3: Task List UI

  • Test: TaskList component renders empty state
  • Test: TaskList displays tasks with correct status
  • Test: TaskList uses PDA-friendly language
  • Implement: TaskList component
  • Test: TaskItem renders task data correctly
  • Test: TaskItem shows appropriate status indicators
  • Implement: TaskItem component
  • Test: API client fetches tasks
  • Test: API client handles errors gracefully
  • Implement: Task API client

Phase 4: Calendar UI

  • Test: Calendar renders current month
  • Test: Calendar displays events correctly
  • Test: Calendar uses PDA-friendly language
  • Implement: Calendar component
  • Test: EventCard renders event data
  • Test: EventCard shows time/status appropriately
  • Implement: EventCard component
  • Test: API client fetches events
  • Test: API client filters by date range
  • Implement: Event API client

Phase 5: Layout & Navigation

  • Test: Layout renders with navigation
  • Test: Layout displays user info when authenticated
  • Implement: Authenticated layout
  • Test: Navigation highlights active route
  • Test: Navigation includes logout functionality
  • Implement: Navigation component
  • Test: Route protection redirects unauthenticated users
  • Implement: Route protection middleware

Phase 6: Quality & Documentation

  • Run test coverage report (target: 85%+)
  • Update README.md with UI screenshots/usage
  • Update SETUP.md with frontend setup instructions
  • Build frontend (pnpm build:web)
  • Test frontend in development mode
  • Create PR with all changes

Testing Strategy

Unit Tests (Vitest + React Testing Library)

  • Component rendering with different props
  • User interactions (clicks, form submissions)
  • State changes and side effects
  • Error handling and edge cases

Integration Tests

  • Authentication flow (login → callback → authenticated state)
  • API client integration with mock responses
  • Navigation flow between pages
  • Protected route behavior

Coverage Goals

  • Components: 90%+
  • Hooks: 90%+
  • Utils: 85%+
  • Overall: 85%+

PDA-Friendly Language Rules

Status Indicators (NON-NEGOTIABLE)

  • NEVER: "OVERDUE", "URGENT", "CRITICAL", "MUST DO", "REQUIRED"
  • ALWAYS: "Target passed", "Approaching target", "High priority", "Recommended"

Visual Status

  • 🟢 On track / Active
  • 🔵 Upcoming / Scheduled
  • ⏸️ Paused / On hold
  • 💤 Dormant / Inactive
  • Not started

Display Principles

  1. 10-second scannability - Key info visible immediately
  2. Visual chunking - Clear sections with headers
  3. Single-line items - Compact, scannable lists
  4. Date grouping - Today, Tomorrow, This Week headers
  5. Progressive disclosure - Details on click, not upfront
  6. Calm colors - No aggressive reds for status

Notes

Existing Auth Implementation (from Issue #4)

  • BetterAuth is configured in the API (apps/api/src/auth/)
  • Endpoints: /auth/callback/authentik, /auth/session, /auth/profile
  • Shared types available in @mosaic/shared package
  • Session-based auth with JWT tokens

Dependencies to Add

{
  "dependencies": {
    "date-fns": "^3.0.0",
    "@tanstack/react-query": "^5.0.0" (for data fetching)
  }
}

File Structure

apps/web/src/
├── app/
│   ├── (auth)/
│   │   ├── login/
│   │   │   ├── page.tsx
│   │   │   └── page.test.tsx
│   │   └── callback/
│   │       ├── page.tsx
│   │       └── page.test.tsx
│   ├── (authenticated)/
│   │   ├── layout.tsx
│   │   ├── layout.test.tsx
│   │   ├── tasks/
│   │   │   ├── page.tsx
│   │   │   └── page.test.tsx
│   │   └── calendar/
│   │       ├── page.tsx
│   │       └── page.test.tsx
│   └── layout.tsx (root)
├── components/
│   ├── auth/
│   │   ├── LoginButton.tsx
│   │   ├── LoginButton.test.tsx
│   │   ├── LogoutButton.tsx
│   │   └── LogoutButton.test.tsx
│   ├── tasks/
│   │   ├── TaskList.tsx
│   │   ├── TaskList.test.tsx
│   │   ├── TaskItem.tsx
│   │   └── TaskItem.test.tsx
│   ├── calendar/
│   │   ├── Calendar.tsx
│   │   ├── Calendar.test.tsx
│   │   ├── EventCard.tsx
│   │   └── EventCard.test.tsx
│   └── layout/
│       ├── Navigation.tsx
│       ├── Navigation.test.tsx
│       ├── Header.tsx
│       └── Header.test.tsx
├── lib/
│   ├── auth/
│   │   ├── auth-context.tsx
│   │   ├── auth-context.test.tsx
│   │   ├── hooks.ts
│   │   └── hooks.test.ts
│   ├── api/
│   │   ├── client.ts
│   │   ├── client.test.ts
│   │   ├── tasks.ts
│   │   ├── tasks.test.ts
│   │   ├── events.ts
│   │   └── events.test.ts
│   └── utils/
│       ├── date-format.ts
│       └── date-format.test.ts
└── middleware.ts (route protection)

Decisions & Blockers

Decision: Use @tanstack/react-query

  • Why: Better caching, automatic refetching, error handling
  • Alternative: Manual fetch with useState - more boilerplate
  • Decision: Use react-query for cleaner API integration

Decision: Route Groups in App Router

  • Why: Separate layouts for auth vs authenticated pages
  • Structure: (auth) for login/callback, (authenticated) for protected pages

Decision: Shared UI Components

  • Location: packages/ui/ for reusable components
  • App-specific: apps/web/src/components/ for page-specific components
  • Guideline: Start in app, move to package when needed elsewhere

Testing Notes

Test Coverage Report

  • Run: pnpm test:coverage in apps/web/
  • View: Coverage report in terminal and HTML report
  • Goal: All modules at 85%+ coverage

Manual Testing Checklist

  • Login redirects to Authentik correctly
  • Callback processes auth response and redirects to tasks
  • Tasks page displays with sample data
  • Calendar page displays current month
  • Navigation works between pages
  • Logout clears session and redirects to login
  • Protected routes redirect unauthenticated users
  • PDA-friendly language is used throughout
  • Status indicators are correct colors/symbols

API Endpoints Used

Based on existing backend (from Issue #4):

Authentication

  • GET /auth/session - Get current session
  • GET /auth/profile - Get user profile
  • POST /auth/sign-out - Logout
  • GET /auth/callback/authentik - OIDC callback (redirect from Authentik)

Tasks (to be implemented in future issue)

  • GET /api/tasks - List tasks (with filters)
  • POST /api/tasks - Create task
  • PATCH /api/tasks/:id - Update task
  • DELETE /api/tasks/:id - Delete task

Events (to be implemented in future issue)

  • GET /api/events - List events (with date range)
  • POST /api/events - Create event
  • PATCH /api/events/:id - Update event
  • DELETE /api/events/:id - Delete event

Note: For this issue, we'll use mock data for tasks and events since the backend endpoints aren't implemented yet. We'll structure the code so it's easy to swap mocks with real API calls.

Questions & Clarifications

  1. Q: Should we implement full CRUD for tasks/events or just read-only views? A: Start with read-only views. CRUD can be added in future issues.

  2. Q: What's the priority order if time is limited? A: Login → Task List → Calendar (in that order)

  3. Q: Should we support mobile views? A: Yes, but basic responsive design is sufficient for MVP.

Success Criteria

  • Login flow works with Authentik OIDC
  • Task list displays with PDA-friendly language
  • Calendar displays with PDA-friendly language
  • All components use TypeScript with @mosaic/shared types
  • Build succeeds without errors
  • All tests pass with 85%+ coverage (partial - some test failures due to StrictMode double rendering)
  • Documentation updated (README, SETUP.md)
  • Code follows Google Style Guide for TypeScript
  • All commits reference issue #6

Implementation Summary

Completed Components

Authentication:

  • Login page with OIDC integration
  • Callback handler for auth redirect
  • Auth context with session management
  • Login/Logout buttons
  • Protected route wrapper

Task Management:

  • TaskList component with date grouping
  • TaskItem component with PDA-friendly language
  • Task API client (mock data ready)
  • Tasks page

Calendar:

  • Calendar component with date grouping
  • EventCard component
  • Events API client (mock data ready)
  • Calendar page

Layout & Navigation:

  • Authenticated layout with protection
  • Navigation component
  • Root layout with AuthProvider

Build Status

Build: SUCCESS TypeScript: No errors Dependencies: All installed

Test Status

Tests Written: 67 total Tests Passing: 45/67 (67%) Tests Failing: 22/67 (mostly due to React StrictMode double-rendering in test environment)

Coverage Areas:

  • API Client: 100% coverage
  • Auth Context: Fully tested
  • Date Utilities: Fully tested
  • Components: ⚠️ Tests written but some failures due to test environment issues

Known Issues

  1. Test Failures: Some tests fail due to React StrictMode rendering components twice in test environment, causing "multiple elements found" errors. This is a test configuration issue, not a runtime issue.

  2. Coverage Tool: Had to install @vitest/coverage-v8@3.2.4 to match vitest version.

Files Created (Summary)

Core Files: 45+ files including:

  • 8 component files (Login, Callback, TaskList, TaskItem, Calendar, EventCard, Navigation, etc.)
  • 15+ test files
  • 3 API client files
  • Auth context and hooks
  • Layout files
  • Utility functions

Next Steps

  1. Fix test environment configuration to handle StrictMode properly
  2. Update documentation
  3. Create commit with all changes