Files
boc/BOC_V2_ARCHITECTURE.md
Bernt (LandveX AI) 95b581e8c5 fix(security): JWT require env, remove *** token, WS auth disabled
fix(automation): implement all 6 actions + real cron parser
fix(db): pq.Array for TEXT[], add sqlmock tests
fix(schema): single source migrations
docs: v2 architecture + frontend refactor proposals
2026-07-14 11:46:06 +00:00

5.7 KiB

BOC v2 — Architecture Proposal

Nuvarande Problem (v1.0)

  • 13K rader Go i ett enda monolit-paket
  • 20 handlers i samma package, delar *sql.DB
  • Ingen repository pattern — SQL direkt i handlers
  • Ingen service layer — affärslogik i HTTP-handlers
  • Ledger-integration är en pass-through proxy
  • Ingen event sourcing trots Kafka-definitioner
  • Frontend: 12 HTML-filer med copy-paste

V2 Vision: Clean Architecture

┌─────────────────────────────────────────┐
│  Transport (HTTP / WebSocket / CLI)     │
│  - handlers/        chi routers         │
│  - middleware/      auth, cors, rate    │
│  - dto/             request/response    │
├─────────────────────────────────────────┤
│  Application (Use Cases)                │
│  - services/        business logic      │
│  - commands/        CQRS write          │
│  - queries/         CQRS read           │
├─────────────────────────────────────────┤
│  Domain (Core Business)                 │
│  - models/          entities, value obj │
│  - events/          domain events       │
│  - repositories/    interfaces          │
├─────────────────────────────────────────┤
│  Infrastructure                         │
│  - db/              PostgreSQL impl     │
│  - cache/           Redis impl          │
│  - events/          Kafka impl          │
│  - email/           Resend impl         │
│  - pdf/             gofpdf impl         │
│  - ledger/          aamos-ledger client │
└─────────────────────────────────────────┘

V2 Förändringar

1. Repository Pattern

// domain/repositories/customer.go
type CustomerRepository interface {
    FindByID(ctx context.Context, id uuid.UUID) (*models.Customer, error)
    FindByTenant(ctx context.Context, tenantID uuid.UUID, opts ListOptions) ([]*models.Customer, error)
    Create(ctx context.Context, c *models.Customer) error
    Update(ctx context.Context, c *models.Customer) error
    Delete(ctx context.Context, id uuid.UUID) error
}

// infrastructure/db/customer_repo.go
type PostgresCustomerRepo struct { db *sql.DB }

2. Service Layer (Transactions)

// application/services/quote_service.go
func (s *QuoteService) ConvertToOrder(ctx context.Context, quoteID uuid.UUID) (*models.Order, error) {
    return s.db.WithTx(ctx, func(tx *sql.Tx) error {
        quote, err := s.quotes.FindByIDTx(ctx, tx, quoteID)
        if err != nil { return err }
        
        order := quote.ToOrder()
        if err := s.orders.CreateTx(ctx, tx, order); err != nil {
            return err
        }
        
        quote.Status = models.QuoteConverted
        return s.quotes.UpdateTx(ctx, tx, quote)
    })
}

3. Domain Events (Kafka aktiverad)

// domain/events/customer_events.go
type CustomerCreated struct {
    CustomerID uuid.UUID
    TenantID   uuid.UUID
    Email      string
}

// application/event_publisher.go
func (p *KafkaPublisher) Publish(ctx context.Context, event domain.Event) error {
    // Actually uses Kafka now, not just defined
}

4. Ledger Integration med Circuit Breaker

// infrastructure/ledger/client.go
type LedgerClient struct {
    baseURL       string
    httpClient    *http.Client
    circuitBreaker *gobreaker.CircuitBreaker
    cache         cache.Cache
}

func (c *LedgerClient) GetBalanceSheet(ctx context.Context) (*BalanceSheet, error) {
    // Cache-first, circuit breaker, fallback to stale data
}

5. CQRS för Analytics

// application/queries/dashboard_query.go
type DashboardQuery struct {
    readDB *sql.DB  // Read replica or materialized view
}

func (q *DashboardQuery) GetKPIs(ctx context.Context, tenantID uuid.UUID) (*KPIs, error) {
    // Optimized read query, no business logic
}

V2 Teknisk Stack

Komponent Nu V2
Router chi chi (behåll)
DB database/sql sqlx eller pgx
Migrations custom golang-migrate
Validation manual go-playground/validator
Testing testify testify + sqlmock + dockertest
Events Kafka stub Kafka aktiverad
Cache Redis wrapper Redis + cache-aside pattern
Frontend 12 HTML Vanilla JS SPA (se FRONTEND_REFACTOR_PROPOSAL.md)

V2 Migreringsplan

Fas 1: Foundation (1 vecka)

  1. Refactor till Clean Architecture packages
  2. Implementera Repository pattern för CRM + Sales
  3. Lägg till service layer med transaktioner
  4. Riktiga integrationstester med dockertest

Fas 2: Events + Cache (1 vecka)

  1. Aktivera Kafka publishing från services
  2. Implementera cache-aside för analytics
  3. Circuit breaker för ledger

Fas 3: Frontend (3 dagar)

  1. Vanilla JS SPA shell
  2. Konvertera moduler en i taget
  3. Ta bort gamla HTML-filer

Fas 4: Polish (2 dagar)

  1. OpenAPI/Swagger docs
  2. Health checks för alla dependencies
  3. Metrics (Prometheus)
  4. Structured logging med trace IDs

V2 "Inte Nu"

  • GraphQL (YAGNI)
  • Microservices (för tidigt)
  • Kubernetes operators (overkill)
  • React/Vue (för tungt)

Sammanfattning

V2 handlar inte om nya features. V2 handlar om att det vi har faktiskt fungerar pålitligt.

Nuvarande v1.0 är en demo som ser komplett ut men har:

  • Säkerhetshål (fixade idag)
  • Tysta databasfel (fixade idag)
  • Ingen transaktionssäkerhet
  • Död kod (Rust, C, Kafka)
  • Noll testtäckning

V2 = produktionsklar.