Bilal Muhammad Khan 8b43aa04bd feat(009-chatkit-frontend): Phase III chatbot UX enhancements and SSE fixes (#9)
* feat(009-chatkit-frontend): implement chatbot popup UI and event system

Completed Phase 2 (Foundational) and Phase 3 (User Story 1):

Phase 2 (Foundational - T004-T008):
- T004: ChatKit integration (building custom interface, no CDN SDK)
- T005: Custom event system for task synchronization
- T006: ChatKit configuration with custom fetch interceptor
- T007: API proxy route with JWT extraction and SSE streaming
- T008: Enhanced TaskContext to emit task events

Phase 3 (User Story 1 - T013-T018):
- T013: Created FloatingChatButton component with animations
- T014: Created ChatBotPopup wrapper with shadcn/ui Dialog
- T015: Integrated chatbot into dashboard with event listener (T046)
- T016: Added Framer Motion animations (<300ms)
- T017: Configured z-index layering (FAB z-40, Dialog z-50)
- T018: Added accessibility attributes (aria-label, role)

Key files:
- frontend/src/lib/events/task-events.ts (event system)
- frontend/src/lib/chatkit-config.ts (ChatKit config)
- frontend/src/app/api/chatkit/route.ts (API proxy)
- frontend/src/components/chat/FloatingChatButton.tsx
- frontend/src/components/chat/ChatBotPopup.tsx
- frontend/src/app/dashboard/page.tsx (integrated chatbot)

Real-time sync: Chatbot events → Dashboard refresh via CustomEvent
Security: JWT extraction in API proxy (httpOnly cookies)
UX: Orange/coral theme, smooth animations, accessible

Next: Phase 4 (US5 Security), Phase 5 (US4 Streaming)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(009-chatkit-frontend): implement chat interface with SSE streaming

Completed Phase 5 (User Story 4 - Streaming AI Responses) and partial Phase 6 (User Story 2):

Phase 5 (US4 - T033-T040):
- T033: Created ChatInterface component with SSE streaming support
- T034: Created MessageList component with streaming state and typing indicator (T038)
- T035: Created MessageInput component with auto-resize and keyboard shortcuts
- T036: Integrated ChatInterface into ChatBotPopup (dashboard)
- T037: SSE streaming already implemented in API proxy (T007)
- T038: Added typing indicator with animated loader and cursor
- T039: Implemented exponential backoff retry (1s, 2s, 4s) in sendMessage
- T040: Added error banner with manual retry button

Phase 6 (US2 - T046-T050) - Already Complete:
- T046: TaskEvent listener already in dashboard (from Phase 3)
- T047: Dashboard refresh logic already implemented (from Phase 3)
- T048: Tool call result event handling in ChatInterface
- T049: TaskEvent emission using createTaskEventFromTool helper
- T050: Success confirmation UI with checkmark icons in MessageList

Key Features:
- SSE streaming: Fetch API with ReadableStream for real-time responses
- MCP tool integration: Parse tool.call.result events and emit TaskEvents
- Real-time sync: Chatbot task operations update dashboard within 1s
- Error handling: Auto-retry with exponential backoff + manual retry
- Streaming UX: Typing indicator, progressive content rendering, cursor animation
- Security: JWT authentication via API proxy, session validation
- Accessibility: ARIA labels, keyboard shortcuts (Enter/Shift+Enter)

Architecture:
- ChatInterface manages state and SSE streaming
- MessageList displays messages with tool call indicators
- MessageInput handles user input with validation
- Events flow: MCP tool result → TaskEvent → Dashboard refresh

Files:
- frontend/src/components/chat/ChatInterface.tsx (SSE + MCP)
- frontend/src/components/chat/MessageList.tsx (UI + typing)
- frontend/src/components/chat/MessageInput.tsx (input + shortcuts)
- frontend/src/app/dashboard/page.tsx (integration)

Next: Phase 7 (US3 History), Phase 8 (US6 Animations), Phase 9 (Errors), Phase 10 (Polish)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(009-chatkit-frontend): implement conversation history with pagination

Completed Phase 7 (User Story 3 - Persistent Conversation History):

Phase 7 (US3 - T056-T060):
- T056: Configured pagination with limit=50, order=desc
- T057: Implemented loadConversationHistory() with useEffect on mount
- T058: Added "Load earlier messages" button with loading state
- T059: Implemented loadMoreMessages() handler with pagination logic
- T060: Added loading states (isLoadingHistory, isLoadingMore) with spinner UI

Frontend Implementation Complete:
- Conversation state management (conversationId, currentPage, hasMoreMessages)
- loadConversationHistory(): Loads user's persistent conversation on mount
- loadMoreMessages(): Fetches older messages with pagination (page, limit)
- Loading indicators: Spinner in "Load earlier" button during fetch
- Ready for backend integration

Backend API Endpoints Required (placeholders in code):
- GET /api/v1/{user_id}/conversations - Get user's single conversation
- GET /api/v1/{user_id}/conversations/{conversation_id}/messages?page={page}&limit=50 - Paginated message history

Architecture:
- Each user has single persistent conversation (per spec)
- Backend creates conversation on first message if none exists
- Frontend loads conversation history on chatbot open
- Pagination: 50 messages per page, descending order (newest first)
- Messages prepended to list when loading older history

Files Modified:
- frontend/src/components/chat/ChatInterface.tsx (history logic)
- frontend/src/components/chat/MessageList.tsx (pagination UI)
- specs/009-chatkit-frontend/tasks.md (marked T056-T060 complete)

Testing:
- T061: Deferred - requires backend conversation history API

Next: Phase 8 (Animations - mostly done), Phase 9 (Error handling), Phase 10 (Polish)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(009-chatkit-frontend): add prefers-reduced-motion accessibility support

Completed Phase 8 (User Story 6 - Smooth Popup Animations):

Phase 8 (US6 - T065-T068):
- T065: Animation timing already optimized (250ms content, 200ms backdrop) - from Phase 3
- T066: AnimatePresence wrapper already implemented - from Phase 3
- T067: Backdrop fade animation already synchronized - from Phase 3
- T068: Added prefers-reduced-motion detection for accessibility  NEW

T068 Implementation:
- Added prefers-reduced-motion detection using window.matchMedia
- ChatBotPopup: Disables all animations (content + backdrop) if user prefers reduced motion
- FloatingChatButton: Disables spring animations and hover/tap effects if user prefers reduced motion
- Fallback: duration: 0 for instant transitions (no animation)
- useMemo optimization: Only check media query once on mount

Accessibility:
- Respects user's OS-level motion preferences
- WCAG 2.1 Level AA compliance (Success Criterion 2.3.3 - Animation from Interactions)
- Users with vestibular disorders can use chatbot without motion sickness
- Instant transitions (no animation) when prefers-reduced-motion is enabled

Animation Performance (already achieved in Phase 3):
- Content animation: 250ms (below 300ms threshold per FR-012)
- Backdrop animation: 200ms (synced with content)
- AnimatePresence: mode="wait" prevents animation stacking
- easeOut easing for smooth deceleration

Files Modified:
- frontend/src/components/chat/ChatBotPopup.tsx (prefers-reduced-motion detection)
- frontend/src/components/chat/FloatingChatButton.tsx (prefers-reduced-motion detection)
- specs/009-chatkit-frontend/tasks.md (marked T065-T068 complete)

Testing:
- T069: Manual testing with DevTools Performance tab (requires user validation)

Next: Phase 9 (Error handling), Phase 10 (Polish & accessibility)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(009-chatkit-frontend): implement Phase 9 error handling and edge cases

**What**: Comprehensive error handling for all edge cases identified in spec.md

**Implementation**:

1. **ErrorBoundary.tsx** (T070):
   - React error boundary pattern to catch errors in chat components
   - Prevents chat errors from crashing entire dashboard
   - Fallback UI with retry/reload options
   - Error logging with stack traces for debugging

2. **ErrorState.tsx** (T071):
   - Reusable error UI components for different error types:
     - RateLimitError: Countdown timer from Retry-After header
     - AuthError: 3-second countdown before redirect to sign-in
     - TimeoutError: Cancel/Keep Waiting options
     - NetworkError: Connection lost with retry button
     - BackendUnavailable: 502/503 errors with correlation ID
     - UnknownError: Generic fallback with correlation ID
   - All components follow contracts/error-messages.yaml specifications

3. **ChatInterface.tsx** (T072-T077):
   - T072: Rate limit handling (429 → countdown → clear error when done)
   - T073: Network error handling (exponential backoff 1s/2s/4s already implemented)
   - T074: Auth error handling (401 → 3s countdown → redirect to /auth/signin)
   - T075: Timeout handling (AbortController + 10s threshold → dialog)
   - T076: Correlation ID logging (already in chatkit-config.ts)
   - T077: Partial message indicator (interrupted stream → incomplete flag)
   - Enhanced sendMessage with error state integration
   - Timeout handlers: handleCancelRequest, handleKeepWaiting
   - Cleanup of timeout/abort refs on error

4. **MessageList.tsx** (T077):
   - Added metadata fields: complete, interrupted
   - Incomplete indicator UI (yellow alert icon + message)
   - Displays "Response interrupted (partial message)" for cancelled streams

**Architecture**:
- Specialized error components replace generic error banner
- Countdown timers managed with useEffect intervals
- AbortController for cancellable fetch requests
- Error states conditionally rendered based on error type
- Graceful degradation for all error scenarios

**UX Impact**:
- Users see helpful, specific error messages instead of generic failures
- Rate limits show countdown before retry is allowed
- Auth errors redirect automatically after countdown
- Timeouts give users choice to cancel or keep waiting
- Partial responses preserved and marked as incomplete
- All errors include context and recovery options

**Compliance**:
- Follows contracts/error-messages.yaml for all error types
- FR-020: Correlation ID logging throughout
- Error handling doesn't block other features
- Users never see raw error messages or stack traces

**Phase 8 Note**: Also committing PHR 0013 from Phase 8 (prefers-reduced-motion accessibility)

**Tasks**: T070-T077 complete

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(009-chatkit-frontend): implement Phase 10 core polish (T078b, T078c, T079, T085)

**What**: Log sanitization, mobile responsive design, and security audit

**Implementation**:

1. **T078b: Log Sanitization Utility** (frontend/src/lib/logging/sanitize.ts):
   - Truncate content fields to 50 chars with "[...]" suffix
   - Redact JWT tokens (replace with "[REDACTED_TOKEN]")
   - Redact PII fields (email, phone, address, SSN, credit card)
   - Mask API keys (show first 4 + last 4 chars like "sk-ab...xyz")
   - Recursive sanitization for nested objects and arrays
   - Export sanitize(obj: unknown) function for all logging

2. **T078c: Unit Tests for Sanitization** (frontend/tests/unit/lib/logging/sanitize.test.ts):
   - Test truncation of long content (50 char limit)
   - Test JWT token redaction
   - Test PII field redaction (email, phone, address, SSN, credit cards)
   - Test API key masking
   - Test nested object sanitization
   - Test realistic scenarios (chat messages, task creation, error logs)
   - 100% coverage of sanitize utility

3. **T079: Mobile Responsive Design**:
   - **ChatBotPopup.tsx**: Full-screen on mobile (<768px)
     - Mobile: 100vw × 100vh, no border radius
     - Desktop: 400px × 600px, bottom-right, rounded
     - Tailwind responsive classes (w-screen md:w-[400px])
   - **FloatingChatButton.tsx**: Larger touch target on mobile
     - Mobile: 60px × 60px (better for touch)
     - Desktop: 56px × 56px (standard FAB size)

4. **T085: Security Audit** - Fixed sensitive data logging:
   - **ChatInterface.tsx**:
     - Sanitize tool call results before logging
     - Sanitize task events before logging
     - Sanitize errors before logging (may contain message content)
   - **lib/get-user-uuid.ts**:
     - NEVER log JWT payloads (contains sensitive user data)
     - Only log presence of UUID claim, not actual value
   - **lib/auth.ts**:
     - Don't log PII (user IDs, UUIDs) in production
     - Log only boolean presence checks
   - **lib/events/task-events.ts**:
     - Apply sanitization to all task event logging
     - Wrap in development-only check

**Security Impact**:
-  No JWT payloads logged (prevents token leakage)
-  No PII logged (email, phone, address, SSN)
-  API keys masked (only show first/last 4 chars)
-  Long content truncated (prevents log bloat, reduces exposure)
-  All logging uses sanitize() utility
-  Production logs safe for viewing by support team

**UX Impact**:
-  Mobile users get full-screen chat interface
-  Larger touch targets on mobile (60px FAB button)
-  Desktop users keep familiar bottom-right popup
-  Smooth responsive transitions
-  No functionality lost on mobile

**Compliance**:
- FR-020: All logging sanitized per requirements
- WCAG 2.1: Mobile touch targets meet 48px minimum (60px exceeds)
- Security: No sensitive data exposure in logs
- Privacy: PII redacted automatically

**Tasks**: T078b, T078c, T079, T085 complete

**Remaining Phase 10 Tasks**:
- T078: Structured logging integration (deferred)
- T078a: Correlation ID tests (deferred)
- T084: SSE throttling (deferred)
- T080-T082: Optional accessibility enhancements
- T086: Quickstart validation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(009-chatkit-frontend): implement chatbot feedback and task list display improvements (T051a-T051i)

Implemented explicit confirmation messages and formatted task list queries to improve
chatbot user experience and ensure 100% visibility of task operations.

**Backend Changes (server.py)**:
- Updated SYSTEM_PROMPT with explicit instructions for confirmation messages
- Added critical markers for ALWAYS providing confirmations per FR-021
- Added task list query formatting guidelines per FR-022
- Added 5 new example interactions showing expected behavior

**Frontend Changes (ChatInterface.tsx)**:
- Added fallback confirmation message generation for task operations
- Generates explicit messages: "✓ Task 'X' has been added successfully"
- Ensures 100% confirmation visibility even if AI doesn't provide it
- Added logging for dashboard refresh timing (T051f)

**UI Improvements (MessageList.tsx)**:
- Enhanced tool call indicators with prominent visual design
- Added background colors (green for success, red for error)
- Added borders and proper spacing for visibility
- Display task title and ID in confirmation badges
- Larger icons (4x4) and better typography

**E2E Tests (chatbot-feedback.spec.ts)**:
- SC-013: Confirmation messages display within 2 seconds (create/complete/delete)
- SC-014: Task list queries return formatted data within 2 seconds
- SC-015: Dashboard refreshes within 1 second after confirmation
- Comprehensive test coverage for all three success criteria

**Spec Updates**:
- spec.md: Added FR-021 to FR-024, SC-013 to SC-015, 5 new edge cases
- plan.md: Added "Chatbot Feedback & Task List Display" section
- tasks.md: Added and completed T051a-T051i with detailed implementation notes

**Verification**:
- MCP tools return structured responses with status indicators (T051a)
- list_tasks queries database directly with no caching (T051e)
- TaskEvent emission happens immediately after tool success (T051f)

Closes T051a, T051b, T051c, T051d, T051e, T051f, T051g, T051h, T051i
Implements FR-021, FR-022, FR-023, FR-024
Validates SC-013, SC-014, SC-015

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(009-chatkit-frontend): enhance chatbot UX with emoji formatting and fix SSE handling

- Backend: Update system prompt with emoji-rich task formatting (🎯📅🔴🟡🟢)
- Backend: Add beautiful task list display grouped by priority with visual separators
- Frontend: Fix SSE handling for non-streaming 'message' events with tool_results
- Frontend: Add react-markdown for formatted chat responses
- Frontend: Improve sanitize order - mask API keys before field-name redaction
- Frontend: Add Vitest setup with test scripts for unit testing
- MCP: Add validation to convert empty strings to None for optional literal fields
- Debug: Add console logging for SSE event parsing troubleshooting

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore(009-chatkit-frontend): reorganize test files into test/ directory

- Move all temporary test scripts from root to test/ directory
- Add PHR for previous commit workflow
- Cleaner project root structure

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 15:20:51 +05:00
2026-01-05 13:42:22 +05:00

Todo Evolution - Hackathon II

Multi-user todo application with authentication, built for Panaversity Evolution of Todo Hackathon.

Project Overview

Phase II: Full-stack web application with user authentication

  • Frontend: Next.js 16 with App Router, TypeScript, Tailwind CSS
  • Backend: FastAPI with async operations
  • Database: Neon Serverless PostgreSQL
  • ORM: SQLModel with Alembic migrations
  • Authentication: Better Auth with JWT tokens (7-day expiration)
  • Password Hashing: Argon2id via pwdlib

Project Structure

todo_correct/
├── backend/                 # FastAPI backend
│   ├── src/
│   │   ├── api/            # API endpoints
│   │   ├── core/           # Config, database, security
│   │   ├── models/         # SQLModel entities
│   │   └── services/       # Business logic
│   ├── tests/              # Unit and integration tests
│   ├── alembic/            # Database migrations
│   ├── main.py             # Application entry point
│   └── pyproject.toml      # Python dependencies
├── frontend/               # Next.js 16 frontend
│   ├── src/
│   │   ├── app/            # App Router pages
│   │   ├── components/     # React components
│   │   ├── lib/            # Utilities (auth, validation)
│   │   └── types/          # TypeScript types
│   ├── package.json        # Node dependencies
│   └── tsconfig.json       # TypeScript config
└── specs/                  # Spec-driven development artifacts
    └── 001-setup-auth-foundation/
        ├── spec.md         # Feature specification
        ├── plan.md         # Architecture plan
        ├── tasks.md        # Implementation tasks
        ├── data-model.md   # Database schema
        └── contracts/      # API contracts

Prerequisites

  • Python: 3.11+
  • Node.js: 18+
  • PostgreSQL: Neon Serverless account (or local PostgreSQL)
  • Git: For version control

Windows Users

Quick Start

1. Clone Repository

git clone <repository-url>
cd todo_correct

2. Database Setup (Neon)

  1. Create account at https://neon.tech
  2. Create a new project
  3. Copy the connection string

3. Backend Setup

cd backend

# Create virtual environment
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -e .
pip install -e ".[dev]"  # Development dependencies

# Create .env file
cp .env.example .env

# Edit .env with your settings:
# DATABASE_URL=postgresql+asyncpg://user:password@host/database
# BETTER_AUTH_SECRET=<generate-32-char-secret>
# CORS_ORIGINS=http://localhost:3000

# Run database migrations
alembic upgrade head

# Start development server
python main.py

Backend will run on http://localhost:8000

API Documentation: http://localhost:8000/docs

4. Frontend Setup

cd frontend

# Install dependencies
npm install

# Create .env.local file
cp .env.example .env.local

# Edit .env.local with your settings:
# DATABASE_URL=postgresql://user:password@host/database
# BETTER_AUTH_SECRET=<same-as-backend-secret>
# NEXT_PUBLIC_APP_URL=http://localhost:3000
# NEXT_PUBLIC_BACKEND_API_URL=http://localhost:8000

# Start development server
npm run dev

Frontend will run on http://localhost:3000

Features Implemented (Phase II)

User Story 1: User Registration

  • Create new account with email, password, and name
  • Email format validation
  • Password minimum 8 characters
  • Duplicate email prevention
  • Argon2id password hashing
  • JWT token generation
  • Automatic login after registration

User Story 2: User Login

  • Authenticate with email and password
  • JWT token with 7-day expiration
  • Consistent error messages (prevents user enumeration)
  • Redirect to dashboard on success

User Story 3: User Logout

  • Secure logout with Better Auth
  • Session cleanup
  • Redirect to login page
  • Protected route enforcement

API Endpoints

Backend (FastAPI)

Endpoint Method Auth Description
/health GET No Health check
/api/auth/register POST No User registration
/api/auth/login POST No User login
/api/auth/logout POST Yes User logout
/api/auth/me GET Yes Get current user

Frontend (Better Auth)

Endpoint Method Auth Description
/api/auth/sign-up POST No Better Auth registration
/api/auth/sign-in/email POST No Better Auth login
/api/auth/sign-out POST Yes Better Auth logout
/api/auth/session GET Yes Get session

Development Workflow

Running Tests

# Backend tests
cd backend
pytest --cov=src

# Frontend tests
cd frontend
npm test

Code Quality

# Backend linting
cd backend
ruff check src/

# Frontend linting
cd frontend
npm run lint

Database Migrations

cd backend

# Create new migration
alembic revision --autogenerate -m "description"

# Apply migrations
alembic upgrade head

# Rollback one migration
alembic downgrade -1

# View migration history
alembic history

Technology Stack

Backend

  • Framework: FastAPI 0.115+
  • ORM: SQLModel 0.0.22+
  • Database Driver: asyncpg 0.30+
  • Validation: Pydantic 2.10+
  • Password Hashing: pwdlib with Argon2
  • JWT: PyJWT 2.9+
  • Migrations: Alembic 1.14+
  • Rate Limiting: slowapi 0.1.9+
  • Server: Uvicorn

Frontend

  • Framework: Next.js 16
  • UI Library: React 19
  • Language: TypeScript 5.7+
  • Authentication: Better Auth 1.2+
  • Validation: Zod 3.24+
  • HTTP Client: Axios 1.7+
  • Styling: Tailwind CSS 3.4+
  • Testing: Playwright 1.49+

Database

  • Provider: Neon Serverless PostgreSQL
  • Connection Pooling: Configured (5-10 connections)
  • Migrations: Alembic

Security Features

  • Argon2id password hashing (PHC 2015 winner)
  • JWT tokens with HS256 signature
  • HTTP-only cookies (Better Auth)
  • CSRF protection (Better Auth)
  • CORS configuration
  • Rate limiting (prevent brute force)
  • SQL injection prevention (ORM parameterized queries)
  • Input validation (Pydantic + Zod)
  • Consistent error messages (prevent user enumeration)
  • Environment-based secrets (never committed)

Performance Targets

Metric Target Status
Login Response < 500ms
Registration Flow < 30s
Logout Response < 2s
JWT Validation < 100ms
Concurrent Users 100/instance (to be tested)

Troubleshooting

Backend won't start

  • Check DATABASE_URL is correct
  • Verify PostgreSQL is accessible
  • Run alembic upgrade head to apply migrations
  • Check logs in console

Frontend won't start

  • Run npm install to ensure dependencies are installed
  • Check .env.local has all required variables
  • Verify NEXT_PUBLIC_BACKEND_API_URL points to running backend
  • Clear .next cache: rm -rf .next

Authentication not working

  • Ensure BETTER_AUTH_SECRET matches between frontend and backend
  • Check browser cookies are enabled
  • Verify database connection (Better Auth stores sessions)
  • Check browser console for errors

Database connection errors

  • Verify DATABASE_URL format is correct
  • Check Neon database is active
  • Test connection with psql or database client
  • Review firewall/network settings

Next Steps (Phase III)

  • AI-powered chatbot with OpenAI Agents SDK
  • MCP server for task management
  • Conversation history persistence
  • Natural language task creation
  • OpenAI ChatKit integration

Deployment

Environment Variables

Backend (.env)

# Database (required)
DATABASE_URL=postgresql+asyncpg://user:password@host:5432/database

# Better Auth JWT Configuration (required)
BETTER_AUTH_SECRET=<generate-32-char-secret>  # Generate with: openssl rand -hex 32
BETTER_AUTH_JWKS_URL=http://localhost:3000/.well-known/jwks.json
BETTER_AUTH_ISSUER=http://localhost:3000

# CORS Configuration (required)
FRONTEND_URL=http://localhost:3000  # Update for production
CORS_ORIGINS=http://localhost:3000  # Comma-separated list for multiple origins

# Server Configuration (optional)
HOST=0.0.0.0
PORT=8000
LOG_LEVEL=INFO

# Phase V (deferred)
# SENTRY_DSN=<your-sentry-dsn>  # External monitoring
# DATADOG_API_KEY=<your-datadog-key>

Frontend (.env.local)

# Database (required - same as backend)
DATABASE_URL=postgresql://user:password@host:5432/database

# Better Auth (required - same secret as backend)
BETTER_AUTH_SECRET=<same-as-backend-secret>

# Application URLs (required)
NEXT_PUBLIC_APP_URL=http://localhost:3000  # Frontend URL
NEXT_PUBLIC_BACKEND_URL=http://localhost:8000/api/v1  # Backend API URL

# Production: Update URLs
# NEXT_PUBLIC_APP_URL=https://yourdomain.com
# NEXT_PUBLIC_BACKEND_URL=https://api.yourdomain.com/api/v1

CORS Configuration

The backend uses a strict CORS policy for security:

Development (backend/.env):

FRONTEND_URL=http://localhost:3000

Production (backend/.env):

FRONTEND_URL=https://yourdomain.com  # Your production frontend URL

Multiple origins (staging + production):

FRONTEND_URL=https://yourdomain.com,https://staging.yourdomain.com

The CORS middleware (in backend/src/main.py) is configured to:

  • Allow credentials (cookies for JWT)
  • Expose X-Correlation-ID header for debugging
  • Only allow specific origins (no wildcards in production)

Better Auth Setup

Better Auth is configured with JWT plugin for stateless authentication:

Backend JWT Configuration

  1. Generate secret key:

    openssl rand -hex 32
    
  2. Set environment variables in backend/.env:

    BETTER_AUTH_SECRET=<generated-secret>
    BETTER_AUTH_JWKS_URL=http://localhost:3000/.well-known/jwks.json
    BETTER_AUTH_ISSUER=http://localhost:3000
    
  3. JWT verification is handled by backend/src/services/jwks.py:

    • Fetches public keys from JWKS endpoint
    • Caches keys for 1 hour (TTL)
    • Verifies EdDSA/Ed25519 signatures
    • Validates issuer and expiration

Frontend Better Auth Configuration

The frontend is configured in frontend/src/lib/auth.ts:

import { betterAuth } from "better-auth";
import { jwt } from "better-auth/plugins";

export const auth = betterAuth({
  database: { ... },
  plugins: [
    jwt({
      algorithm: "EdDSA",  // Ed25519 for fast verification
      issuer: process.env.NEXT_PUBLIC_APP_URL,
      expiresIn: "1h",
      jwks: { enabled: true },  // Enable JWKS endpoint
    }),
  ],
});

Key features:

  • EdDSA/Ed25519 algorithm (10-20x faster than RS256)
  • JWT stored in httpOnly cookies (secure by default)
  • 1-hour token expiration
  • JWKS endpoint at /.well-known/jwks.json

Production Deployment

Vercel (Frontend)

  1. Connect repository to Vercel

  2. Set environment variables:

    • DATABASE_URL
    • BETTER_AUTH_SECRET
    • NEXT_PUBLIC_APP_URL=https://yourdomain.com
    • NEXT_PUBLIC_BACKEND_URL=https://api.yourdomain.com/api/v1
  3. Deploy: Automatic on git push

Backend Hosting Options

Option 1: Railway / Render

  • Auto-deploy from GitHub
  • Set environment variables in dashboard
  • Add PostgreSQL addon or use Neon

Option 2: Docker + Cloud Run / AWS ECS

# backend/Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Option 3: VM (DigitalOcean, AWS EC2)

# Install dependencies
sudo apt update && sudo apt install python3.11 python3-pip postgresql-client

# Setup application
git clone <repo>
cd backend
pip install -e .

# Setup systemd service
sudo nano /etc/systemd/system/todo-backend.service

# Start service
sudo systemctl enable todo-backend
sudo systemctl start todo-backend

Security Checklist

Before deploying to production:

  • Generate new BETTER_AUTH_SECRET (don't reuse dev secret)
  • Update FRONTEND_URL to production domain
  • Enable HTTPS (required for httpOnly cookies)
  • Set LOG_LEVEL=WARNING or ERROR in production
  • Verify CORS allows only production origins
  • Configure database connection pooling
  • Enable database SSL (Neon provides this by default)
  • Set up monitoring (Sentry/DataDog in Phase V)

Monitoring & Debugging

Correlation IDs: Every request has a unique X-Correlation-ID header:

  • Generated by frontend (UUID v4)
  • Propagated to backend
  • Included in all logs
  • Shown in error toasts (first 8 chars)

Structured Logging: All logs are JSON-formatted per FR-029:

{
  "timestamp": "2025-12-29T10:30:00Z",
  "level": "INFO",
  "correlation_id": "abc123...",
  "user_id": "user_123",
  "endpoint": "/api/v1/user_123/tasks",
  "http_method": "GET",
  "status_code": 200,
  "duration_ms": 45
}

Log Files:

  • Backend: backend/logs/app.log (rotates at 10MB, keeps 5 backups)
  • Frontend: Browser console (development) / Vercel logs (production)

Contributing

This project follows Spec-Driven Development:

  1. Feature specifications in /specs
  2. Architecture planning in plan.md
  3. Task breakdown in tasks.md
  4. Implementation via Claude Code

License

MIT License - Panaversity Evolution of Todo Hackathon II

Resources


Built with Claude Code using Spec-Driven Development methodology.

S
Description
Browser automation using Playwright MCP. Navigate websites, fill forms, click elements, take screenshots, and extract data. Use when tasks require web…
Readme 9 MiB
Languages
Python 70.7%
TypeScript 22%
Shell 4.8%
JavaScript 2.2%
CSS 0.2%