Files
ideaforge/docs/architecture.md
Kai Chappell 1fa9804be5 chore: initial project scaffold
Set up IdeaForge project structure with documentation, architecture spec,
and development guidelines for both backend (Python) and frontend (Flutter).
2026-01-28 22:13:52 +00:00

155 lines
5.1 KiB
Markdown

# architecture
## Overview
IdeaForge is a dual-stack application: a Python FastAPI backend with SQLite storage and
Claude API integration, fronted by a Flutter Web/Mobile client.
## System Context
```
┌──────────────────┐ ┌──────────────────┐
│ Flutter Client │────────▶│ FastAPI Backend │
│ (Web / Mobile) │◀────────│ │
└──────────────────┘ └────────┬─────────┘
┌───────────┼───────────┐
│ │ │
┌───────▼──┐ ┌────▼─────┐ ┌──▼──────────┐
│ SQLite │ │ Claude │ │ Seed Data │
│ (ideas.db)│ │ API │ │ (Curated) │
└──────────┘ └──────────┘ └─────────────┘
```
## Backend Architecture
### Layers
```
API Layer (FastAPI Routers)
Service Layer (Business Logic)
├──▶ AI Module (Claude API Client)
Data Layer (SQLAlchemy Models + Pydantic Schemas)
Database (SQLite via aiosqlite)
```
**Rules:**
- Services never import from API layer
- API and CLI both depend on services
- AI module is a peer of services, injected as needed
- All database access goes through SQLAlchemy async sessions
### Key Modules
| Module | Responsibility |
|--------|---------------|
| `api/ideas.py` | CRUD endpoints for ideas |
| `api/evaluations.py` | Evaluation endpoints (manual + AI) |
| `services/idea_service.py` | Idea business logic, filtering, ranking |
| `services/evaluation_service.py` | Evaluation orchestration |
| `ai/client.py` | Anthropic SDK wrapper |
| `ai/evaluator.py` | Prompt construction, response parsing |
| `ai/prompts.py` | Evaluation prompt templates |
### AI Evaluation Flow
```
Client triggers evaluation
POST /api/ideas/{id}/ai-evaluate
EvaluationService.run_ai_evaluation(idea_id)
├──▶ Load idea + metrics from DB
├──▶ Build evaluation prompt (ai/prompts.py)
├──▶ Call Claude API (ai/client.py)
├──▶ Parse structured response (ai/evaluator.py)
├──▶ Store scores in DB
Return evaluation results with scores + reasoning
```
### Demo Mode
When `IDEAFORGE_DEMO_MODE=true`:
- Database seeded with curated ideas on startup
- Write endpoints return 403 for unauthenticated requests
- AI evaluation rate-limited (N requests per hour per IP)
- Data resets on restart (ephemeral SQLite)
## Frontend Architecture
### Feature-First Structure
Each feature is self-contained with domain/data/presentation layers:
```
features/
├── ideas/
│ ├── domain/ # IdeaEntity, IdeaRepository (interface)
│ ├── data/ # IdeaDto, ApiIdeaRepository
│ └── presentation/ # IdeasController, IdeasScreen, IdeaCard
├── evaluation/
│ ├── domain/ # EvaluationEntity, MetricScore
│ ├── data/ # EvaluationDto, ApiEvaluationRepository
│ └── presentation/ # EvaluationController, ScoreRadarChart
└── dashboard/
└── presentation/ # DashboardScreen, RankingTable
```
### State Management
Riverpod providers manage all state:
- `ideasControllerProvider` — idea list with filters
- `ideaDetailProvider(id)` — single idea with evaluations
- `evaluationControllerProvider` — AI evaluation trigger and results
### Key Screens
| Screen | Path | Purpose |
|--------|------|---------|
| Ideas List | `/ideas` | Browse and filter ideas |
| Idea Detail | `/ideas/:id` | Full idea with scores and radar chart |
| Evaluate | `/ideas/:id/evaluate` | Trigger and view AI evaluation |
| Dashboard | `/dashboard` | Rankings and comparisons |
## Database Schema
Core tables (inherited from idea-manager):
- `ideas` — idea content (title, description, status, category)
- `evaluation_metrics` — metric definitions with scoring guides
- `idea_evaluations` — scores linking ideas to metrics
- `tags` / `idea_tags` — tagging system
## Deployment
```
┌──────────────┐ ┌──────────────┐
│ Flutter Web │ │ FastAPI │
│ (Static CDN) │────▶│ (Container) │
└──────────────┘ └──────┬───────┘
┌───────▼───────┐
│ SQLite Volume │
└───────────────┘
```
- Backend: Docker container on Fly.io / Railway
- Frontend: Static Flutter Web build on CDN
- Database: SQLite file on persistent volume