Skip to main content

Project Structure

The project follows a monorepo layout with backend/, frontend/, and docs-site/ at the root.

invoice/
├── CLAUDE.md # Project guide for Claude Code
├── SPEC.md # Full technical specification
├── Makefile # Build, test, run commands
├── docker-compose.yml # PostgreSQL + services
├── docs/standards/ # 17 coding standards documents

├── backend/
│ ├── cmd/server/main.go # Entrypoint only
│ ├── internal/
│ │ ├── config/ # Env var + config loading
│ │ ├── database/
│ │ │ ├── postgres.go # pgx connection pool
│ │ │ └── clickhouse.go # ClickHouse HTTP client
│ │ ├── models/ # Domain models (Go structs)
│ │ │ ├── invoice.go # Invoice + GenerateRequest
│ │ │ ├── line_item.go # InvoiceLineItem + LineItemInput
│ │ │ ├── rate_rule.go # RateRule + Financials
│ │ │ ├── client.go # Application + Customer + Worklog
│ │ │ └── event.go # InvoiceEvent + EditHistory
│ │ ├── services/
│ │ │ ├── invoice/ # Invoice CRUD, status transitions
│ │ │ └── generator/ # Prefill pipeline, PDF generation
│ │ ├── handlers/
│ │ │ ├── router.go # Route registration
│ │ │ ├── invoice_handler.go # Invoice endpoints
│ │ │ ├── client_handler.go # Client endpoints
│ │ │ ├── auth_handler.go # Login endpoint
│ │ │ ├── health_handler.go # Health checks
│ │ │ ├── response.go # JSON response helpers
│ │ │ └── middleware.go # Auth, CORS, logging, recovery
│ │ └── templates/ # HTML invoice templates
│ │ ├── act_template.html # Russian (local UZS)
│ │ └── invoice_template.html # English (international)
│ ├── migrations/ # SQL migrations (up + down)
│ └── go.mod # Go module

├── frontend/
│ ├── src/
│ │ ├── App.tsx # Root component + routing
│ │ ├── components/
│ │ │ ├── common/ # Shared components
│ │ │ ├── invoice/ # Invoice-specific components
│ │ │ ├── generate/ # Generate wizard components
│ │ │ ├── calculator/ # Pricing calculator (Phase 5)
│ │ │ ├── layout/ # Layout components
│ │ │ └── ui/ # shadcn/ui primitives
│ │ ├── hooks/ # Custom React hooks (use-*.ts)
│ │ ├── lib/
│ │ │ ├── api.ts # API client (fetch wrapper)
│ │ │ ├── format.ts # Number/date formatting
│ │ │ └── query-keys.ts # React Query key factory
│ │ ├── pages/ # One component per route
│ │ └── types/ # Shared TypeScript interfaces
│ ├── package.json
│ ├── vite.config.ts
│ ├── tailwind.config.ts
│ └── tsconfig.json

└── docs-site/ # Docusaurus documentation
├── docs/ # Markdown documentation files
├── docusaurus.config.ts
├── sidebars.ts
└── package.json

Key Conventions

Backend

ConventionExample
Packages are lowercase, single wordinvoice, generator, handlers
Files are lowercase with underscoresinvoice_handler.go, rate_rule.go
Tests next to codeinvoice_handler_test.go
Entrypoint in cmd/server/main.goOnly wiring, no business logic
Domain models in internal/models/Pure structs, no DB dependencies

Frontend

ConventionExample
Components are PascalCaseInvoiceRegistry.tsx
Hooks start with useuseInvoices.ts
API functions are verb + nounfetchInvoices(), generateInvoice()
React Query keys in query-keys.tsCentralized key factory
shadcn/ui in components/ui/Do not modify directly

Database

ConventionExample
Tables are plural, snake_caseinvoices, invoice_line_items
Migrations are sequential000001_enable_extensions.up.sql
Every up has a matching down000001_enable_extensions.down.sql
PostgreSQL uses $1 placeholdersNever fmt.Sprintf for SQL
ClickHouse uses ? placeholdersNever string interpolation