15 KiB
stepsCompleted, inputDocuments, workflowType, classification
| stepsCompleted | inputDocuments | workflowType | classification | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
architecture |
|
Architecture Decisions - FlowReader
Date: 2026-02-04 Project: FlowReader User: Michael Status: DRAFT
0. Executive Summary
This architecture document defines the technical decisions for FlowReader, a self-hosted RSS reader focused on radical simplicity and performance.
Core Vision: Mobile-first, "Lecture Plaisir" experience. Key Constraints: < 150MB RAM, < 100ms latency, Docker deployment.
1. Project Context Analysis
Requirements Overview
Functional Requirements: The system must manage the full lifecycle of RSS feed consumption for multiple isolated users.
- Core Capabilities: Feed CRUD, RSS/Atom Parsing, Content Normalization ("Reading Pleasure"), Read State Management (Read/Unread/Favorites).
- Real-time: Push notifications (Websockets) for new article arrivals.
- Multi-tenancy: Strict isolation of user data.
Non-Functional Requirements (Drivers): NFRs are particularly constraining and will drive technological choices:
- Reliability (Priority): PostgreSQL required for robust data persistence.
- Resource Efficiency (Critical): < 150-250MB RAM Total target. This is a significant challenge with PostgreSQL. Heavy stacks (Java/Spring, unoptimized Node) are ruled out.
- Performance: < 100ms TTI. Implies efficient rendering and likely aggressive local caching (Optimistic UI).
- Resilience: Strict 5s timeout on external feeds. Backend must be asynchronous and non-blocking.
Scale & Complexity:
- Primary domain: Web Application (SPA + API + Worker)
- Complexity level: Low (Scope well-defined, personal use scale)
- Estimated architectural components: 4 (Frontend, API Server, Feed Fetcher Worker, Database).
Technical Constraints & Dependencies
- Database: PostgreSQL (Dockerized).
- Deployment: Docker Compose (App + DB Containers).
- Offline: "Offline First" strategy implies local storage and sync logic in Frontend.
Cross-Cutting Concerns Identified
- Concurrency: Feed fetching must be parallelized but throttled to control RAM/CPU usage.
- Sanitization: Article HTML "cleaning" is critical for security (XSS) and readability.
- Authentication: Stateless session management (JWT?) or optimized stateful to limit overhead.
2. Starter Template Evaluation
Primary Technology Domain
Full-Stack Web Application (Dockerized Monolith).
Starter Options Considered
- Option 1: AESRAEL/go-postgres-react-starter:
- Stack: Go (Fiber) + React + PostgreSQL.
- Pros: Ready to run.
- Cons: Uses Fiber (non-standard
net/http), potentially higher learning curve. Dockerfile optimization for <150MB not guaranteed.
- Option 2: vladannovi1234/Golang-React-psql-docker:
- Stack: Go + React + Postgres.
- Pros: Simple DB connection.
- Cons: Old/Not actively maintained.
- Option 3: Custom "Low-Res" Composite Stack (Recommended):
- Stack: Go (Chi) + React (Vite) + PostgreSQL.
- Pros: Total control over binary size. Chi is standard and fast. Vite is the modern standard.
- Cons: Requires manual "wiring", but guarantees we hit the 150-250MB RAM target.
Selected Strategy: Custom Composite Stack (Go Chi + Vite)
Rationale for Selection: To strictly meet the <250MB RAM constraint (with Postgres taking ~70MB+), we cannot afford framework bloat or unoptimized containers.
- Go Chi: Only the router, no "Framework magic". Closer to metal.
- React + Vite: Optimized build.
- Single Dockerfile: We will use a Multi-Stage Docker build to embed the React Assets into the Go Binary to minimize container count (1 App Container + 1 DB Container).
Initialization Commands (To be executed in Implementation Phase):
# Frontend
npm create vite@latest frontend -- --template react-ts
# Backend
mkdir backend
cd backend
go mod init github.com/user/flowreader
go get -u github.com/go-chi/chi/v5
go get -u github.com/jackc/pgx/v5
Architectural Decisions Provided:
- Language: Go 1.22+ (Standard
net/httpcompatible). - Routing:
go-chi/chi(Middlewares, context-aware). - Database Driver:
pgx/v5(High performance). - Frontend: React 18 + TypeScript + Vite.
- Deployment: Docker Compose (services:
app,db).
3. Core Architectural Decisions
Decision Priority Analysis
- Critical Decisions: Authentication Strategy, Database Schema Design, API Interaction Pattern.
- Important Decisions: State Management Library, CSS Framework, Folder Structure.
Data Architecture
- Database: PostgreSQL 16+ (Alpine).
- Migration Tool:
golang-migrateorgoose(SQL based migrations). - Data Access:
pgxnative queries (No ORM). We choose No ORM to maintain raw performance and control over generated SQL, critical for the RAM constraint. Struct mapping viascanyor manual scan.
Authentication & Security
- Method: Stateful Session (server-side).
- Storage: PostgreSQL (
sessionstable). No Redis (saves RAM). - Transport:
HttpOnly,SecureCookies.
- Storage: PostgreSQL (
- Rationale: Simplifies revocation (logout from all devices), strictly binds session to user context, avoids JWT complexity/insecurity for this scale.
API & Communication Patterns
- Protocol: REST JSON.
- Documentation: OpenAPI 3.0 via code annotations (
swaggo). - Real-time: WebSockets (using
nhooyr/websocketlibrary) for "New Article" notifications.
Frontend Architecture
- State Management:
- Server State: TanStack Query (React Query). Handles caching, deduping, background updates.
- Client State: Zustand. For UI state (sidebar open, theme, etc.). Ultra-lightweight.
- Styling: Tailwind CSS. Utility-first, zero runtime cost.
- Routing: React Router v6.
Backend Code Organization
- Structure: Standard Go Project Layout.
cmd/server: Application entry point.internal/domain: core business logic & interfaces (Dependency Inversion).internal/adapters: database implementation, web handlers.internal/service: application logic orchestration.
Decision Impact Analysis
- Strict Memory Budget: The choice of "No ORM" and "No Redis" is directly driven by the <250MB constraint.
- Latency: React Query's aggressive client-side caching will mask network latency, achieving the <100ms perceived performance goal.
4. Implementation Patterns & Consistency Rules
Naming Patterns
- Database:
snake_casefor all tables (plural) and columns.- Ex:
users,feed_items,created_at.
- Ex:
- Go Code:
CamelCasefor exported structs/interfaces,camelCasefor private.- Ex:
type UserService struct,func (s *UserService) getUser().
- Ex:
- API (JSON):
camelCase.- Ex:
{ "userId": 1, "firstName": "Alice" }. - Implementation Note: Go Struct tags must align:
json:"userId"
- Ex:
Structure Patterns (Backend Layers)
- Handler Layer: HTTP specifics only. Decodes JSON, calls Service, encodes JSON. No Logic.
- File naming:
handler/user_handler.go
- File naming:
- Service Layer: Business logic (Validation, Authorization, Orchestration). No SQL.
- File naming:
service/user_service.go
- File naming:
- Repository Layer: Database access only. Raw SQL / Builder. No Logic.
- File naming:
repository/user_repository.go
- File naming:
Format Patterns
API Response Envelope: All successful responses must follow this wrapper:
{
"data": { ... }, // The actual resource(s)
"meta": { ... } // Pagination, etc (optional)
}
Error Format: All errors must return standard codes:
{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "User with ID 123 does not exist",
"details": { ... } // Optional validation errors
}
}
Communication Patterns
- Dependency Injection: All dependencies (DB, Config, other Services) must be explicitly injected via constructor (
New...). Global variables are forbidden. - Interfaces: Define interfaces where they are used (Consumer side), not where they are defined.
- Rule: "Accept Interfaces, Return Structs".
Enforcement Guidelines
- Linter: Use
golangci-lintwith strict settings to enforce naming and complexity rules. - Review: PRs must verify that controllers do not contain SQL and Repositories do not contain business axioms.
5. Project Structure & Boundaries
Complete Project Directory Structure
flowreader/
├── docker-compose.yml # Production & Dev orchestration services (App, DB)
├── Dockerfile # Multi-stage build (Node Build -> Go Builder -> Alpine Runtime)
├── Makefile # Automation (install, dev, build, test, migrate)
├── go.mod # Backend dependencies
├── api/ # API Definition
│ └── openapi.yaml # OpenAPI 3.0 Specification
├── cmd/
│ └── server/ # Application Entry Point
│ └── main.go # Wires Config, DB, Services, and starts Server
├── internal/ # Private Application Code (Go Standard Layout)
│ ├── config/ # Configuration loading (Env vars)
│ ├── core/
│ │ ├── domain/ # Core Business Entities (User, Feed, Item) - Pure Structs
│ │ ├── ports/ # Interfaces (Repository, Service, TtsProvider) - Hexagonal Arch
│ │ └── errors/ # Domain Errors definitions
│ ├── service/ # Business Logic Implementation (orchestrates Repo + Domain)
│ └── adapter/
│ ├── handler/ # HTTP Handlers (REST) - Decodes JSON, Validates, Calls Service
│ └── repository/ # Database implementation (PostgreSQL/pgx)
├── migrations/ # Database Migrations (SQL)
│ ├── 000001_create_users_table.up.sql
│ └── 000002_create_feeds_table.up.sql
└── web/ # Frontend Application (React + Vite)
├── package.json
├── vite.config.ts
├── index.html
└── src/
├── api/ # API Clients (axios/fetch wrappers)
├── components/ # Shared Atomic Components (Button, Input, Layout)
├── features/ # Feature-based organization
│ ├── auth/ # Login, Register forms & hooks
│ ├── feed/ # Feed List, Add Feed modal
│ └── reader/ # Article View, Reading modes
├── hooks/ # Shared React Hooks
├── stores/ # Global State (Zustand)
└── types/ # Shared TypeScript Types
Architectural Boundaries
- API Boundary: The
internal/adapter/handlerpackage is the only entry point for external HTTP traffic. It strictly translates HTTP to Domain calls. - Database Boundary: The
internal/adapter/repositorypackage is the only place SQL is allowed. No other layer knows about the database implementation. - Frontend/Backend Boundary: Rigid separation. The Frontend in
web/is a completely independent SPA that consumes the API. It is served by Nginx or embedded in the Go binary for production.
Requirements to Structure Mapping
- FR-UserManagement:
- Backend:
internal/core/domain/user.go,internal/service/auth.go,internal/adapter/repository/user_repo.go - Frontend:
web/src/features/auth/
- Backend:
- FR-FeedManagement:
- Backend:
internal/service/feed.go - Frontend:
web/src/features/feed/
- Backend:
- NFR-Performance:
- Database connection pool configured in
internal/adapter/repository/postgres.go - Frontend caching configured in
web/src/api/queryClient.ts(React Query)
- Database connection pool configured in
6. Architecture Validation Results
Coherence Validation ✅
Decision Compatibility: The Composite Stack (Go Chi + Vite) is highly coherent. No framework bloat. The choice of "No ORM" aligns perfectly with the "Resource Efficiency" driver.
Risk Assessment:
- Critical Risk: PostgreSQL RAM usage vs 150MB Limit.
- Mitigation: Strict PostgreSQL configuration required (
shared_buffers=24MB,max_connections=20).
Requirements Coverage Validation ✅
- Real-time: Covered by Websockets (
nhooyr/websocket). - Performance: Covered by Go (Backend) + React Query (Frontend Optimistic UI).
- Mobility: Covered by Tailwind Mobile-First approach.
Architecture readiness Assessment
Overall Status: READY FOR IMPLEMENTATION Confidence Level: High (Technical choices are standard and robust).
Implementation Handoff
Critical First Steps:
- Initialize Git Repository.
- Setup Docker Compose with RAM limits and Postgres Tuning.
- Initialize Go Module and React Project.
7. Architecture Completion Summary
Workflow Completion
Architecture Decision Workflow: COMPLETED ✅ Date Completed: 2026-02-04 Document Location: c:\Users\Michael\VSCODE\FlowReader_bmad-output\planning-artifacts\architecture.md
Final Architecture Deliverables
📋 Complete Architecture Document
- All architectural decisions documented with specific versions
- Implementation patterns ensuring AI agent consistency
- Complete project structure with all files and directories
- Requirements to architecture mapping
- Validation confirming coherence and completeness
🏗️ Implementation Ready Foundation
- 7 architectural decisions made
- 4 implementation patterns defined
- 4 architectural components specified
- All requirements fully supported
Implementation Handoff
AI Agent Guidelines: This architecture document is your complete guide for implementing FlowReader. Follow all decisions, patterns, and structures exactly as documented.
First Implementation Priority: Initialize project structure:
# Frontend
npm create vite@latest frontend -- --template react-ts
# Backend
mkdir backend
cd backend
go mod init github.com/user/flowreader
go get -u github.com/go-chi/chi/v5
go get -u github.com/jackc/pgx/v5
Quality Assurance Checklist
- ✅ Architecture Coherence: Go/Chi/Postgres stack is coherent and minimal.
- ✅ Requirements Coverage: All FRs and NFRs (including <150MB RAM) are addressed.
- ✅ Implementation Readiness: Patterns for API, DB, and Code style are defined.
Architecture Status: READY FOR IMPLEMENTATION ✅