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

174 lines
5.7 KiB
Markdown

# 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
```go
// 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)
```go
// 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)
```go
// 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
```go
// 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
```go
// 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.