Skip to content

Latest commit

 

History

History
316 lines (216 loc) · 8.86 KB

File metadata and controls

316 lines (216 loc) · 8.86 KB

Voting Services API - Development Context

Project Overview

This is a multi-tenant voting services API built with Hono and Bun that provides democratic voting capabilities for Farcaster communities. The API was extracted from a Next.js application to enable reuse across multiple applications and AI agents.

Key Features

  • Multi-tenant group management with configurable criteria
  • Democratic voting system with 3-of-5 subgroup mechanics
  • Multi-modal authentication (Frame SDK, Bearer tokens for services)
  • Real-time participation tracking and analytics
  • XMTP integration for chat-based interactions
  • Comprehensive test coverage with Vitest

Architecture

Technology Stack

  • Runtime: Bun (TypeScript)
  • Framework: Hono (Web Standards API)
  • Database: PostgreSQL with pgvector extension
  • ORM: Drizzle ORM
  • Validation: Zod schemas
  • Testing: Vitest with coverage
  • Deployment: Docker containers, Railway

Core Services

  1. VotingService (src/db/services/voting-service.ts)

    • Handles proposal submission and voting logic
    • Manages member eligibility and subgroup selection
    • Tracks participation metrics and voting history
  2. GroupsService (src/db/services/groups-service.ts)

    • Multi-tenant group management
    • Member assignment and removal
    • Participation statistics and analytics
  3. UsersService (src/db/services/users-service.ts)

    • User management
    • Address management
    • XMTP integration

Authentication System

Located in src/middleware/auth.ts, supports Bearer token authentication:

  • Frame SDK tokens: JWT tokens for Next.js Mini App users
  • Service keys: Secret keys for Eliza agents, MCP servers, and external services

All authentication uses the standard Authorization: Bearer <token> header format.

Database Schema

Multi-Tenant Structure

The schema (src/db/voting-schema.ts) supports multi-tenancy with:

Core Tables

  • groups: Group definitions with JSON criteria
  • users: Address-based user identification
  • members: Group membership with status tracking
  • proposals: Add/remove member proposals
  • votes: Individual vote records
  • vote_groups: Voting assignments per group

Supporting Tables

  • cached_usernames: Farcaster username lookups
  • participation_snapshot: Voting participation analytics

Key Relationships

groups -> members -> proposals -> votes
     \-> vote_groups -> members
     \-> participation_snapshot -> members

Previously the users table was anchored on fid but we want to prefer userId (uuid) for consistency with address and other contexts. Any time we spin up a route that takes in users we should refer to them with userId. In routes that return users we should return both userId and fid.

API Endpoints

Public

  • GET /health - Health check

Protected (/api/v1/)

Groups Management

  • GET /groups - List all groups
  • POST /groups - Create new group
  • GET /groups/:id - Get group details (with stats/members options)
  • PUT /groups/:id - Update group
  • DELETE /groups/:id - Delete group
  • GET /groups/name/:name - Get group by name
  • GET /groups/chat/:chatId - Get group by chat ID

Group Members

  • GET /groups/:id/members - List group members
  • POST /groups/:id/members - Add member to group
  • PUT /groups/:id/members/:memberId - Update member status
  • DELETE /groups/:id/members/:memberId - Remove member
  • POST /groups/:id/verify-eligibility - Verify member eligibility

Group Analytics

  • GET /groups/:id/stats - Group participation statistics
  • POST /groups/validate-criteria - Validate group criteria

Proposals

  • GET /proposals - List proposals
  • POST /proposals - Submit proposal
  • GET /proposals/:id - Proposal details

Votes

  • POST /votes - Cast vote
  • GET /votes/current-user - User's voting history

Activity

  • GET /activity - Recent activity feed

Development Workflow

Common Commands

# Development
bun run dev              # Start dev server with hot reload
bun run test             # Run test suite
bun run test:watch       # Run tests in watch mode
bun run test:coverage    # Generate coverage report

# Database
bun run db:up            # Start PostgreSQL container
bun run db:down          # Stop PostgreSQL container
bun run db:generate      # Generate Drizzle migrations
bun run db:migrate       # Run migrations
bun run db:studio        # Open Drizzle Studio

# Testing Database
bun run db:test:up       # Start test database
bun run db:test:setup    # Run migrations on test DB
bun run db:test:down     # Stop test database

# Production
bun run build            # Build for production
bun run start            # Start production server

Test Environment

  • Test Database: PostgreSQL on port 5556
  • Test Runner: Vitest with sequential execution
  • Coverage: v8 provider with HTML reports
  • Setup: Automated database migrations and cleanup
  • CI/CD: GitHub Actions workflow (.github/workflows/test.yml) runs tests on PR and main commits

Multi-Tenant Considerations

Group Criteria System

Groups define membership criteria as a string array saved as JSON in the criteria field:

["has 1000 followers", "is into trains", "can type 60 words per minute"]

Voting Mechanics

  • Subgroup Size: 5 members per voting group
  • Approval Threshold: 3 of 5 votes needed
  • Voting Period: 16 hours
  • Cooldown: 24 hours for rejected proposals

Participation Tracking

The participation_snapshot table tracks:

  • Vote groups assigned vs. votes cast
  • Response time analytics
  • Activity-based member scoring

Integration Points

Farcaster Integration

  • Neynar API: Username/FID lookups
  • Frame SDK: Authentication tokens
  • Cast Analysis: Proposal extraction from messages

XMTP Integration

  • Chat IDs: Groups can be linked to XMTP chats
  • Address Verification: Links XMTP addresses to Farcaster identities

External Services

  • Eliza Agents: AI agents can submit proposals via Bearer tokens
  • MCP Servers: Claude Code integration for data access
  • Alerts Service: Real-time notifications

Testing Strategy

Test Structure

  • Unit Tests: Individual service methods
  • Integration Tests: API endpoint functionality
  • Database Tests: Schema and migration validation
  • Mock Data: Consistent test fixtures

Test Files

  • tests/setup.ts: Global test configuration
  • tests/helpers/: Auth mocks and test fixtures
  • tests/services/: Service layer tests
  • tests/routes/: API endpoint tests

Coverage Goals

  • Exclude migrations and generated files
  • Focus on business logic and API endpoints
  • Target comprehensive service method coverage

Configuration

Environment Variables

# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5555/postgres

# API Keys
NEYNAR_API_KEY=your-neynar-api-key
ELIZA_AGENT_SECRET=your-eliza-secret
MCP_SERVICE_SECRET=your-mcp-secret

# Features
DISABLE_NOTIFICATIONS=false
INCLUDE_ADMINS_IN_NOTIFICATIONS=true
ALERTS_URL=http://localhost:8080

Docker Setup

  • Main DB: PostgreSQL with pgvector on port 5555
  • Test DB: Separate PostgreSQL instance on port 5556
  • Health Checks: Built-in container health monitoring

Development Guidelines

Code Organization

  • Services: Business logic in src/db/services/
  • Routes: API handlers in src/routes/
  • Middleware: Authentication and validation
  • Utils: Shared constants and helpers

Database Best Practices

  • Use address-based user identification for multi-tenancy
  • Implement proper foreign key constraints
  • Add comprehensive indexes for performance
  • Use enums for status fields

API Design

  • RESTful endpoints with proper HTTP methods
  • Zod validation for all request bodies
  • Consistent error handling and responses
  • Permission-based access control

Deployment

Production Considerations

  • Environment: Node.js compatible (Bun runtime)
  • Database: PostgreSQL with pgvector extension
  • Scaling: Horizontal scaling with connection pooling
  • Monitoring: Health checks and logging

Platform Support

  • Railway (primary deployment)
  • Docker containers
  • Any Web Standards compatible platform
  • Cloudflare Workers, AWS Lambda, Vercel

Support and Maintenance

Admin Configuration

Admin FIDs are defined in src/utils/constants.ts for special permissions and notifications.

Migration Strategy

The codebase includes comprehensive migration support:

  • Database schema migrations via Drizzle
  • API versioning for backward compatibility
  • Feature flags for gradual rollouts

Documentation

  • README.md: User-facing documentation
  • API Documentation: In-code comments and schemas
  • Test Documentation: Test-specific README in /tests/

This API serves as a foundation for democratic community management across multiple Farcaster applications and AI agents.