Files
workspace/apps/go-crm
gabspereira 9c3bfd131d feat(go-crm): industrial terminal-core UI redesign
Complete visual overhaul of the go-crm web interface:

- New shared layout system (internal/templates/ui.go) with dark zinc
  industrial theme, JetBrains Mono typography, grid/noise textures
- Redesigned all pages: Dashboard, Login/Signup, Clients, Customers,
  Services, Scheduling, Payments, Questions, Answers, Leads,
  Review Queue, Report, Keyword Mapping
- Tailwind CSS via CDN with custom color palette (amber/emerald/rose/sky)
- HTMX-powered interactions with CSS swap animations
- Status pills, KPI cards, data tables, empty states, inline forms
- Mobile-responsive sidebar with collapsible navigation
- All existing tests updated and passing
- Zero new build dependencies — works with existing go run/air workflow
2026-05-23 18:00:32 -03:00
..

go-crm (lightweight local dev)

This service is intentionally small so junior Go developers can understand it end-to-end without Docker, hot reloads, or other heavy tooling. The goal: go run main.go with a single SQLite file in .dev-data/.

Local development (junior-friendly)

  1. Ensure Go 1.25+ is installed and go is in your PATH.
  2. Run the helper script (no Docker):
    ./scripts/dev.sh
    
  3. The server boots on http://localhost:8080.
  4. The database and WhatsApp store live under .dev-data/ (auto-created).

There are no file watchers or air hot reloads—just the plain Go toolchain so newcomers can focus on code, not tooling.

Project layout (modern, clean layers)

go-crm/
├── cmd/                  # optional commands (e.g. migrations)
│   └── migrate/           # lightweight migration CLI (future)
├── config/               # templated configs (kept simple)
├── data/                 # production data path (gitignored)
├── internal/             # HTTP handlers (usecases wired to HTTP)
│   ├── handlers/
│   ├── middleware/
│   └── templates/
├── pkg/                  # reusable application packages
│   ├── domain/            # entities + repository interfaces
│   ├── usecase/           # application services / business logic
│   └── repo/              # persistence adapters (SQLite, etc.)
├── scripts/              # helper scripts (dev runner, migrations)
├── main.go               # application entrypoint (wire handlers → usecases)
├── go.mod
└── go.sum

pkg/domain/lead.go

package domain

// Lead is the core business entity.
type Lead struct {
    LeadID         int64
    ClientID       int64
    Name           string
    PhoneRaw       string
    PhoneNormalized string
    ServiceInterest string
    Status         string
    PaymentStatus  string
}

// LeadRepository abstracts persistence.
type LeadRepository interface {
    FindAll(ctx context.Context, clientID int64) ([]Lead, error)
    FindByID(ctx context.Context, clientID, leadID int64) (*Lead, error)
    Update(ctx context.Context, lead Lead) error
}

pkg/usecase/lead_service.go

package usecase

import (
    "context"
    "go-crm/pkg/domain"
)

// LeadService orchestrates business logic.
type LeadService struct {
    Repo domain.LeadRepository
}

func (s *LeadService) ListAll(ctx context.Context, clientID int64) ([]domain.Lead, error) {
    return s.Repo.FindAll(ctx, clientID)
}

pkg/repo/sqlite_lead_repo.go

package repo

import (
    "context"
    "database/sql"
    "go-crm/pkg/domain"
)

// SQLiteLeadRepository implements LeadRepository using sqlite.
type SQLiteLeadRepository struct {
    DB *sql.DB
}

func (r *SQLiteLeadRepository) FindAll(ctx context.Context, clientID int64) ([]domain.Lead, error) {
    // query leads table, scan rows, return []domain.Lead
}

Handlers in internal/handlers should accept a clear service layer (usecase.LeadService), not raw DB logic. Keep controllers thin: parse request, call service, write HTML/JSON.

Migration strategy

  • Do not scan/clean the entire leads table on every startup (that was causing RAM blowups).
  • Run the lightweight CLI with make migrate (which builds and runs the migration binary) whenever you need to refresh the schema or re-decode legacy Latin-1 data. To target non-default files, run the migration binary directly:
    go build -o migrate cmd/migrate/main.go && ./migrate --db /path/to/go-crm.db
    

Running tests

go test ./...

Summary

  • No Docker or air watchers—just go run main.go.
  • Clean package boundaries (domain/usecase/repo) improve readability and testability.
  • Scripts under scripts/ orchestrate database setup or helper tasks.
  • Use the architecture sketch above to guide future refactors.