# Punchcard Development Guide ## Project Overview Punchcard is a CLI time tracking tool for freelancers and consultants, built in Go with SQLite storage. ## Architecture ### Core Components - **CLI Interface**: spf13/cobra for command structure - **Database**: SQLite with sqlc for type-safe queries - **Report Generation**: Typst templates compiled to PDF - **Storage**: Local SQLite database file ### Commands Structure - `punch in` - Starts timer (inserts row with start_time, NULL end_time) - `punch out` - Stops active timer (updates end_time), exits non-zero if no active timer - `punch invoice` - Generates invoice PDF via Typst - `punch timesheet` - Generates timesheet PDF via Typst ## Database Schema ```sql -- Time tracking entries CREATE TABLE time_entries ( id INTEGER PRIMARY KEY AUTOINCREMENT, start_time DATETIME NOT NULL, end_time DATETIME NULL, description TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); -- Future: client/project tables for invoicing ``` ## Technology Stack - **Language**: Go 1.21+ - **CLI Framework**: github.com/spf13/cobra - **Database**: SQLite3 - **Query Builder**: github.com/sqlc-dev/sqlc - **PDF Generation**: Typst (external dependency) ## File Structure ``` punchcard/ ├── cmd/ │ └── punch/ # Main CLI entry point ├── internal/ │ ├── commands/ # Cobra command implementations │ ├── database/ # Database connection and migrations │ ├── models/ # Data models │ ├── queries/ # sqlc generated queries │ └── reports/ # Typst template handling ├── templates/ # Typst templates for PDF generation ├── go.mod ├── go.sum ├── README.md └── CLAUDE.md ``` ## Development Guidelines ### Database - Use sqlc for all database interactions - Store timestamps in UTC - Active timer = row with NULL end_time ### CLI Design - Follow cobra conventions - Provide helpful error messages - Exit codes: 0 = success, 1 = general error, 2 = no active timer ### PDF Generation - Use Typst templates in `templates/` directory - Invoke `typst compile` subprocess for PDF generation - Handle Typst installation check gracefully ### Testing - Use table-driven tests for business logic - Test CLI commands with cobra testing utilities - Use in-memory SQLite for test database ## Build and Run ```bash # Build go build -o punch cmd/punch/main.go # Run ./punch in ./punch out # Install locally go install ./cmd/punch ``` ## Dependencies ```bash go get github.com/spf13/cobra go get github.com/mattn/go-sqlite3 go get modernc.org/sqlite ```