cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 🍃
charm leaflet readability golang
1# System Architecture 2 3Noteleaf is a CLI/TUI application for task and content management built on Go with SQLite persistence and terminal-based interfaces. 4 5## Core Architecture 6 7### Application Structure 8 9The application follows a layered architecture with clear separation between presentation, business logic, and data access layers. 10 11**Entry Point** - `cmd/main.go` initializes the application with dependency injection, creates handlers, and configures the Cobra command tree using the CommandGroup pattern. 12 13**CLI Framework** - Built on `spf13/cobra` with `charmbracelet/fang` providing enhanced CLI features including color schemes, versioning, and improved help formatting. 14 15**TUI Components** - Interactive interfaces use `charmbracelet/bubbletea` for state management and `charmbracelet/lipgloss` for styling with a consistent color palette system in `internal/ui/colors.go`. 16 17### Data Layer 18 19**Database** - SQLite with schema migrations in `internal/store/sql/migrations/`. The `internal/store` package manages database connections and configuration. 20 21**Repository Pattern** - Data access abstracts through repository interfaces in `internal/repo/` with validation logic ensuring data integrity at the persistence boundary. 22 23**Models** - Entity definitions in `internal/models/` implement standardized Model interfaces with common fields (ID, Created, Modified). 24 25### Business Logic 26 27**Handlers** - Business logic resides in `internal/handlers/` with one handler per domain (TaskHandler, NoteHandler, ArticleHandler, etc.). Handlers receive repository dependencies through constructor injection. 28 29**Services** - Domain-specific operations in `internal/services/` handle complex business workflows and external integrations. 30 31**Validation** - Schema-based validation at repository level with custom ValidationError types providing detailed field-level error messages. 32 33## Domain Features 34 35### Content Management 36 37**Articles** - Web scraping using `gocolly/colly` with domain-specific extraction rules stored in `internal/articles/rules/`. Articles are parsed to markdown and stored with dual file references (markdown + HTML). 38 39**Tasks** - Todo/task management inspired by TaskWarrior with filtering, status tracking, and interactive TUI views. 40 41**Notes** - Simple note management with markdown support and glamour-based terminal rendering. 42 43**Media Queues** - Separate queues for books, movies, and TV shows with status tracking and metadata management. 44 45### User Interface 46 47**Command Groups** - Commands organized into core functionality (task, note, article, media) and management operations (setup, config, status) using the CommandGroup interface pattern. 48 49**Interactive Views** - Bubbletea-based TUI components for list navigation, item selection, and data entry with consistent styling through the lipgloss color system. 50 51**Terminal Output** - Markdown rendering through `charmbracelet/glamour` for rich text display in terminal environments. 52 53## Dependencies 54 55**CLI/TUI** - Cobra command framework, Bubbletea state management, Lipgloss styling, Fang CLI enhancements. 56 57**Data** - SQLite driver (`mattn/go-sqlite3`), TOML configuration parsing. 58 59**Content Processing** - Colly web scraping, HTML/XML query libraries, Glamour markdown rendering, text processing utilities. 60 61**Utilities** - UUID generation, time handling, logging through `charmbracelet/log`. 62 63## Design Decisions and Tradeoffs 64 65### Technology Choices 66 67**Go over Rust** - Go was selected for its simplicity, excellent CLI ecosystem (Cobra, Charm libraries), and faster development velocity. While Rust + Ratatui would provide better memory safety and potentially superior performance, Go's straightforward concurrency model and mature tooling ecosystem made it the pragmatic choice for rapid prototyping and iteration. 68 69**SQLite over PostgreSQL** - SQLite provides zero-configuration deployment and sufficient performance for single-user CLI applications. The embedded database eliminates setup complexity while supporting full SQL features needed for filtering and querying. PostgreSQL would add deployment overhead without meaningful benefits for this use case. 70 71**Repository Pattern over Active Record** - Repository interfaces enable clean separation between business logic and data access, facilitating testing through dependency injection. This pattern scales better than Active Record for complex domain logic while maintaining clear boundaries between layers. 72 73### Architectural Tradeoffs 74 75**CommandGroup Interface** - Centralizes command registration while enabling modular command organization. The pattern requires additional abstraction but provides consistent dependency injection and testing capabilities across all command groups. 76 77**Handler-based Business Logic** - Business logic in handlers rather than rich domain models keeps the codebase simple and avoids over-engineering. While this approach may not scale to complex business rules, it provides clear separation of concerns for the current feature set. 78 79**Dual Storage for Articles** - Articles store both markdown and HTML versions to balance processing speed with format flexibility. This doubles storage requirements but eliminates runtime conversion overhead and preserves original formatting. 80 81### Component Interactions 82 83**Handler → Repository → Database** - Request flow follows a linear path from CLI commands through business logic to data persistence. This pattern ensures consistent validation and error handling while maintaining clear separation of concerns. 84 85**TUI State Management** - Bubbletea's unidirectional data flow provides predictable state updates for interactive components. The model-view-update pattern ensures consistent UI behavior across different terminal environments. 86 87**Configuration and Migration** - Application startup validates configuration and runs database migrations before initializing handlers. This fail-fast approach prevents runtime errors and ensures consistent database schema across deployments.