LINUS ROUND 1: Delete dead code (rust/c), generic Store[T], tests, slim main.go
- Removed rust-service/, c-runtime/, kafka stubs - Generic Store[T] pattern with real tests - Slimmed main.go from 324 to ~50 lines - Added config, middleware, store, ledger, pdf tests - Frontend SPA shell with router - Binary: 15.5MB -> 12MB
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
// Package models contains domain entities.
|
||||
// No SQL, no JSON tags for external APIs — pure domain.
|
||||
package models
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
// Customer represents a CRM customer
|
||||
type Customer struct {
|
||||
ID string
|
||||
TenantID string
|
||||
Name string
|
||||
Email string
|
||||
Phone string
|
||||
Company string
|
||||
OrgNumber string
|
||||
Status string
|
||||
Source string
|
||||
Tags []string
|
||||
AssignedTo *string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// ScanRow scans a sql.Rows into Customer
|
||||
func (c *Customer) ScanRow(rows *sql.Rows) error {
|
||||
var tags pq.StringArray
|
||||
err := rows.Scan(&c.ID, &c.Name, &c.Email, &c.Phone, &c.Company, &c.OrgNumber,
|
||||
&c.Status, &c.Source, &tags, &c.AssignedTo, &c.CreatedAt, &c.UpdatedAt)
|
||||
c.Tags = []string(tags)
|
||||
return err
|
||||
}
|
||||
|
||||
// ScanOneRow scans a sql.Row into Customer
|
||||
func (c *Customer) ScanOneRow(row *sql.Row) error {
|
||||
var tags pq.StringArray
|
||||
err := row.Scan(&c.ID, &c.Name, &c.Email, &c.Phone, &c.Company, &c.OrgNumber,
|
||||
&c.Status, &c.Source, &tags, &c.AssignedTo, &c.CreatedAt, &c.UpdatedAt)
|
||||
c.Tags = []string(tags)
|
||||
return err
|
||||
}
|
||||
|
||||
// Deal represents a sales opportunity
|
||||
type Deal struct {
|
||||
ID string
|
||||
TenantID string
|
||||
CustomerID string
|
||||
ContactID *string
|
||||
Name string
|
||||
Description string
|
||||
Value float64
|
||||
Currency string
|
||||
Status string
|
||||
Stage string
|
||||
Probability int
|
||||
ExpectedClose *time.Time
|
||||
ActualClose *time.Time
|
||||
AssignedTo *string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// ScanRow scans a sql.Rows into Deal
|
||||
func (d *Deal) ScanRow(rows *sql.Rows) error {
|
||||
return rows.Scan(&d.ID, &d.TenantID, &d.CustomerID, &d.ContactID, &d.Name,
|
||||
&d.Description, &d.Value, &d.Currency, &d.Status, &d.Stage,
|
||||
&d.Probability, &d.ExpectedClose, &d.ActualClose, &d.AssignedTo,
|
||||
&d.CreatedAt, &d.UpdatedAt)
|
||||
}
|
||||
|
||||
// ScanOneRow scans a sql.Row into Deal
|
||||
func (d *Deal) ScanOneRow(row *sql.Row) error {
|
||||
return row.Scan(&d.ID, &d.TenantID, &d.CustomerID, &d.ContactID, &d.Name,
|
||||
&d.Description, &d.Value, &d.Currency, &d.Status, &d.Stage,
|
||||
&d.Probability, &d.ExpectedClose, &d.ActualClose, &d.AssignedTo,
|
||||
&d.CreatedAt, &d.UpdatedAt)
|
||||
}
|
||||
|
||||
// Invoice represents a financial invoice
|
||||
type Invoice struct {
|
||||
ID string
|
||||
TenantID string
|
||||
CustomerID string
|
||||
Amount float64
|
||||
Currency string
|
||||
Status string
|
||||
DueDate *time.Time
|
||||
PaidAt *time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
// ScanRow scans a sql.Rows into Invoice
|
||||
func (i *Invoice) ScanRow(rows *sql.Rows) error {
|
||||
return rows.Scan(&i.ID, &i.TenantID, &i.CustomerID, &i.Amount, &i.Currency,
|
||||
&i.Status, &i.DueDate, &i.PaidAt, &i.CreatedAt)
|
||||
}
|
||||
|
||||
// ScanOneRow scans a sql.Row into Invoice
|
||||
func (i *Invoice) ScanOneRow(row *sql.Row) error {
|
||||
return row.Scan(&i.ID, &i.TenantID, &i.CustomerID, &i.Amount, &i.Currency,
|
||||
&i.Status, &i.DueDate, &i.PaidAt, &i.CreatedAt)
|
||||
}
|
||||
Reference in New Issue
Block a user