Documentation
¶
Index ¶
- Constants
- Variables
- type APIError
- type APIResponse
- type Account
- type AccountBalance
- type AccountType
- type Branch
- type Company
- type Customer
- type Discount
- type DiscountType
- type Expense
- type File
- type InventoryLine
- type InventoryReport
- type JournalEntry
- type JournalLine
- type MovementReason
- type Order
- type OrderItem
- type OrderReturn
- type OrderReturnItem
- type OrderStatus
- type PLReport
- type PLSummary
- type POSSession
- type POSStation
- type Payment
- type PaymentMethod
- type PaymentMethodRevenue
- type PaymentStatus
- type Product
- type ProductType
- type RecipeComponent
- type RecipeOverhead
- type SalesPeriod
- type SalesReport
- type SalesSummary
- type SessionReconciliation
- type SessionStatus
- type StockMovement
- type Supplier
- type SupplierPayment
- type TopProduct
- type User
Constants ¶
const ( AcctCash = "1000" // Cash & Cash Equivalents (asset) AcctInventory = "1300" // Inventory Asset (asset) AcctAccountsPayable = "2100" // Accounts Payable (liability) AcctSalesRevenue = "4000" // Sales Revenue (revenue) AcctSalesDiscount = "4100" // Sales Discounts (expense/contra-revenue) AcctCOGS = "5000" // Cost of Goods Sold (expense) AcctInventoryWriteoff = "5100" // Inventory Write-off/Waste (expense) AcctOperatingExpenses = "6000" // Operating Expenses (expense) AcctSupplierCosts = "6100" // Supplier / Purchase Costs (expense) )
Standard COA codes — seeded by migration 000024.
Variables ¶
var DefaultCashDrawerMethods = []PaymentMethod{PaymentCash}
DefaultCashDrawerMethods controls which payment methods count toward the physical cash drawer for session reconciliation. QRIS/ewallet settle digitally — override via WithCashDrawerMethods().
var DefaultPaymentMethods = []PaymentMethod{PaymentCash, PaymentCard, PaymentTransfer}
DefaultPaymentMethods is the OSS allowed set. Pro injects additional methods (e.g. qris, ewallet) via WithPaymentMethods().
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
// Code is the HTTP status code.
Code int
// Internal is the original error (logged but never sent to clients).
Internal error
// Public is the human-readable message sent to clients.
Public string
}
APIError represents an HTTP error returned from a handler. It implements the error interface so it can be returned directly from Echo handlers.
type APIResponse ¶
type APIResponse struct {
RequestID uuid.UUID `json:"request_id,omitempty"`
Status int `json:"status"`
Data any `json:"data,omitempty"`
Error string `json:"error,omitempty"`
}
APIResponse is the standard envelope for all JSON API responses.
type Account ¶
type Account struct {
ID uuid.UUID
Code string
Name string
Type AccountType
}
Account is a node in the chart of accounts. The OSS COA is system-wide (not per-company); rows are seeded in migration 000024.
type AccountBalance ¶
type AccountBalance struct {
AccountCode string
AccountName string
AccountType AccountType
TotalDebit int64
TotalCredit int64
}
AccountBalance summarizes debits and credits for one account within a company.
type AccountType ¶
type AccountType string
AccountType classifies a chart-of-accounts entry.
const ( AccountAsset AccountType = "asset" AccountLiability AccountType = "liability" AccountEquity AccountType = "equity" AccountRevenue AccountType = "revenue" AccountExpense AccountType = "expense" )
type Branch ¶
type Branch struct {
ID uuid.UUID
CompanyID uuid.UUID
Name string
Address string
CreatedAt time.Time
UpdatedAt time.Time
}
Branch represents a physical location (shop/outlet) belonging to a company. A company may have multiple branches sharing a single inventory.
type Company ¶
type Company struct {
ID uuid.UUID
OwnerID uuid.UUID
Name string
Handle string // URL slug, globally unique, lowercase alphanum + hyphens
Currency string // ISO 4217, e.g. "USD", "IDR"
CreatedAt time.Time
UpdatedAt time.Time
// LogoFileID references the company's current logo, if any, in the
// files table. nil means no logo has been uploaded.
LogoFileID *uuid.UUID
}
Company represents a business entity owned by a user with the owner role. Currency is an ISO 4217 code (e.g. "USD", "IDR") stored as display metadata; all monetary values are integers in that currency's smallest unit. Handle is a globally-unique URL slug (e.g. "acme-coffee") used in /@handle/ routes.
type Customer ¶
type Customer struct {
ID uuid.UUID
CompanyID uuid.UUID
Name string
Email string
Phone string
CreatedAt time.Time
UpdatedAt time.Time
}
Customer represents a buyer registered in the company's contact book.
type Discount ¶
type Discount struct {
ID uuid.UUID
CompanyID uuid.UUID
Name string
Type DiscountType
// Value is cents for fixed discounts and 1–100 (integer %) for percentage discounts.
Value int64
Active bool
CreatedAt time.Time
}
Discount is a named, reusable discount rule stored per company.
type DiscountType ¶
type DiscountType string
DiscountType determines how a discount value is applied.
const ( // DiscountFixed applies a fixed amount in the smallest currency unit. DiscountFixed DiscountType = "fixed" // DiscountPercentage applies an integer percentage (1–100) of the basis amount. DiscountPercentage DiscountType = "percentage" )
type Expense ¶
type Expense struct {
ID uuid.UUID
CompanyID uuid.UUID
Description string
Amount int64 // smallest currency unit, > 0
AccountCode string // COA debit account (default "6000")
PaidFrom string // COA credit account representing payment source (default "1000")
CreatedAt time.Time
}
Expense is a general business expense record (rent, utilities, etc.).
type File ¶
type File struct {
ID uuid.UUID
CompanyID uuid.UUID
Intent string
StorageKey string
MimeType string
SizeBytes int64
UploadedBy *uuid.UUID
CreatedAt time.Time
}
File is an uploaded object tracked by the File API, scoped to one company. StorageKey never contains an absolute path — it is relative to the storage backend's root (e.g. "<companyID>/avatars/<uuid>.webp").
type InventoryLine ¶
type InventoryLine struct {
ProductID uuid.UUID `json:"product_id"`
ProductName string `json:"product_name"`
ProductType string `json:"product_type"`
CurrentStock float64 `json:"current_stock"`
LastPurchasePrice int64 `json:"last_purchase_price"`
StockValue int64 `json:"stock_value"`
LowStock bool `json:"low_stock"`
}
InventoryLine holds the current stock position for a single product.
type InventoryReport ¶
type InventoryReport struct {
Items []InventoryLine `json:"items"`
}
InventoryReport is the full inventory snapshot response.
type JournalEntry ¶
type JournalEntry struct {
ID uuid.UUID
CompanyID uuid.UUID
Description string
EventName string // originating domain event, for audit/filtering
Reference string // e.g. order_id, expense_id
Lines []JournalLine
CreatedAt time.Time
}
JournalEntry is an immutable double-entry accounting record. ∑(Lines[i].Debit) must equal ∑(Lines[i].Credit) before the entry is persisted.
type JournalLine ¶
type JournalLine struct {
ID uuid.UUID
EntryID uuid.UUID
AccountID uuid.UUID
Debit int64 // amount in smallest currency unit; 0 when this is a credit leg
Credit int64 // amount in smallest currency unit; 0 when this is a debit leg
}
JournalLine is one leg of a journal entry. Exactly one of Debit or Credit should be non-zero per line.
type MovementReason ¶
type MovementReason string
MovementReason is the type of a stock movement.
const ( // ReasonProcurement is stock received from a supplier (unit_cost required). ReasonProcurement MovementReason = "procurement" // ReasonOpeningBalance is the initial stock level recorded at system setup // (unit_cost required). ReasonOpeningBalance MovementReason = "opening_balance" // ReasonWaste is stock lost due to spoilage, spillage, or expiry. // LPP is resolved at the moment of recording to compute valueLost. ReasonWaste MovementReason = "waste" // ReasonAdjustmentUp increases stock to correct a discrepancy found during // an audit (no unit_cost; no accounting event). ReasonAdjustmentUp MovementReason = "adjustment_up" // ReasonAdjustmentDown decreases stock to correct a discrepancy found during // an audit (no unit_cost; no accounting event). ReasonAdjustmentDown MovementReason = "adjustment_down" // ReasonPosSale is a negative movement created at POS checkout. ReasonPosSale MovementReason = "pos_sale" // ReasonPosVoid is a positive movement that restores stock when a paid order // is voided. ReasonPosVoid MovementReason = "pos_void" // ReasonPosReturn is a positive movement that restores stock when items are // returned. ReasonPosReturn MovementReason = "pos_return" )
type Order ¶
type Order struct {
ID uuid.UUID
CompanyID uuid.UUID
BranchID uuid.UUID // denormalized from session at create time
StationID uuid.UUID // denormalized from session at create time
SessionID uuid.UUID
CustomerID *uuid.UUID
ReceiptNumber string // stamped during checkout; empty while open
Status OrderStatus
Total int64 // net total = ∑(item.Subtotal) − DiscountAmount
DiscountAmount int64 // order-level discount in smallest currency unit; 0 when none
DiscountID *uuid.UUID // optional reference to the named Discount applied at order level
VoidedBy *uuid.UUID
VoidedAt *time.Time
CreatedAt time.Time
UpdatedAt time.Time
}
Order is a sales transaction within a POS session. An order starts open, transitions to paid on checkout, or voided.
type OrderItem ¶
type OrderItem struct {
ID uuid.UUID
OrderID uuid.UUID
ProductID uuid.UUID
Quantity int64 // whole units only
UnitPrice int64 // snapshot of Product.BasePrice at AddItem time
DiscountAmount int64 // item-level discount in smallest currency unit; 0 when none
DiscountID *uuid.UUID // optional reference to the named Discount applied at item level
Subtotal int64 // (UnitPrice × Quantity) − DiscountAmount
}
OrderItem is one product line on an order.
type OrderReturn ¶
type OrderReturn struct {
ID uuid.UUID
CompanyID uuid.UUID
OriginalOrderID uuid.UUID
RefundAmount int64
RefundMethod PaymentMethod
Reason string
CreatedBy uuid.UUID
CreatedAt time.Time
}
OrderReturn records a return against a previously paid order.
type OrderReturnItem ¶
type OrderReturnItem struct {
ID uuid.UUID
ReturnID uuid.UUID
OrderItemID uuid.UUID
ProductID uuid.UUID
Quantity int64
UnitPrice int64
Subtotal int64
}
OrderReturnItem is one returned product line within an OrderReturn.
type OrderStatus ¶
type OrderStatus string
OrderStatus represents the lifecycle state of an order.
const ( OrderOpen OrderStatus = "open" OrderPaid OrderStatus = "paid" OrderVoided OrderStatus = "voided" )
type PLReport ¶
type PLReport struct {
Summary PLSummary `json:"summary"`
}
PLReport is the full profit-and-loss response.
type PLSummary ¶
type PLSummary struct {
Revenue int64 `json:"revenue"`
Expenses int64 `json:"expenses"`
NetProfit int64 `json:"net_profit"`
}
PLSummary holds period profit-and-loss totals.
type POSSession ¶
type POSSession struct {
ID uuid.UUID
CompanyID uuid.UUID
BranchID uuid.UUID // denormalized from station at open time
StationID uuid.UUID
UserID uuid.UUID // user who opened the session
Status SessionStatus
OpeningCash int64 // cash float placed in drawer before trading; default 0
OpenedAt time.Time
ClosedAt *time.Time
}
POSSession represents a cashier's shift at a specific POS station. A station may have at most one open session at a time.
type POSStation ¶
type POSStation struct {
ID uuid.UUID
CompanyID uuid.UUID // denormalized from branch for efficient queries
BranchID uuid.UUID
Name string
CreatedAt time.Time
UpdatedAt time.Time
}
POSStation represents a physical point-of-sale terminal within a branch. Multiple stations may be active simultaneously in the same branch.
type Payment ¶
type Payment struct {
ID uuid.UUID
OrderID uuid.UUID
Amount int64
Method PaymentMethod
Status PaymentStatus
CreatedAt time.Time
}
Payment is one payment leg on an order (supports split payments).
type PaymentMethod ¶
type PaymentMethod string
PaymentMethod is the tender type used for a payment leg.
const ( PaymentCash PaymentMethod = "cash" PaymentCard PaymentMethod = "card" PaymentTransfer PaymentMethod = "transfer" )
type PaymentMethodRevenue ¶
PaymentMethodRevenue holds revenue totals broken down by payment method.
type PaymentStatus ¶
type PaymentStatus string
PaymentStatus tracks whether a payment is completed or refunded.
const ( PaymentCompleted PaymentStatus = "completed" PaymentRefunded PaymentStatus = "refunded" )
type Product ¶
type Product struct {
ID uuid.UUID
CompanyID uuid.UUID
Type ProductType
Name string
BasePrice int64 // smallest currency unit; must be 0 for ingredients
Unit string // "kg", "ml", "pcs" — must be used consistently throughout
// LowStockThreshold flags CurrentStock at or below this level (but above
// zero) as "low" on the Inventory page and dashboard. Not meaningful for
// recipe products, which have no stock of their own.
LowStockThreshold int64
// SKU is the barcode/lookup code used at the POS. Unique per company.
// Defaults to the product's own ID (as a string) when not explicitly set.
SKU string
CreatedAt time.Time
UpdatedAt time.Time
ImageFileID *uuid.UUID // nil = no image
}
Product represents an item in the company's product catalog.
type ProductType ¶
type ProductType string
ProductType classifies how a product is made and sold.
const ( // ProductTypeIngredient is a raw material used in recipes. // It has BasePrice = 0 and is never sold directly at the POS. ProductTypeIngredient ProductType = "ingredient" // ProductTypeSimple is a finished good sold as-is with stock tracked directly. ProductTypeSimple ProductType = "simple" // ProductTypeRecipe is a manufactured product sold at the POS. // Its stock is derived from the ingredient stock of its components. ProductTypeRecipe ProductType = "recipe" )
type RecipeComponent ¶
type RecipeComponent struct {
ID uuid.UUID
RecipeID uuid.UUID
IngredientID uuid.UUID
Quantity float64 // NUMERIC(12,4); same unit as the ingredient's Unit field
}
RecipeComponent links a recipe product to one of its ingredient products.
type RecipeOverhead ¶
type RecipeOverhead struct {
ID uuid.UUID
RecipeID uuid.UUID
Description string
Cost int64 // smallest currency unit
}
RecipeOverhead is a fixed cost line added to a recipe's COGS (e.g. packaging, labor allocation).
type SalesPeriod ¶
type SalesPeriod struct {
Period string `json:"period"` // "2026-01-15" | "2026-W03" | "2026-01"
Revenue int64 `json:"revenue"`
Orders int64 `json:"orders"`
}
SalesPeriod holds aggregated sales data for a single time bucket.
type SalesReport ¶
type SalesReport struct {
Summary SalesSummary `json:"summary"`
ByPeriod []SalesPeriod `json:"by_period"`
ByPaymentMethod []PaymentMethodRevenue `json:"by_payment_method"`
TopProducts []TopProduct `json:"top_products"`
}
SalesReport is the full sales analytics response.
type SalesSummary ¶
type SalesSummary struct {
TotalRevenue int64 `json:"total_revenue"`
TotalOrders int64 `json:"total_orders"`
TotalReturns int64 `json:"total_returns"`
NetRevenue int64 `json:"net_revenue"`
}
SalesSummary aggregates top-level sales metrics for a date range.
type SessionReconciliation ¶
type SessionReconciliation struct {
SessionID uuid.UUID
CompanyID uuid.UUID
ExpectedCash int64 // OpeningCash + SUM of cash-method payments in the session
DeclaredCash int64 // physically counted by the cashier at close
Difference int64 // DeclaredCash − ExpectedCash; negative = shortage
ReconciledBy uuid.UUID
ReconciledAt time.Time
}
SessionReconciliation is written when a cashier closes a session and declares their cash count. The system computes ExpectedCash and records the difference.
type SessionStatus ¶
type SessionStatus string
SessionStatus represents the lifecycle state of a POS session.
const ( SessionOpen SessionStatus = "open" SessionClosed SessionStatus = "closed" )
type StockMovement ¶
type StockMovement struct {
ID uuid.UUID
CompanyID uuid.UUID
ProductID uuid.UUID
Reason MovementReason
Delta float64 // signed quantity in the product's unit
UnitCost *int64 // smallest currency unit; non-nil only for procurement/opening_balance
Notes string
CreatedAt time.Time // immutable; no UpdatedAt
}
StockMovement is an immutable append-only record of a change in stock for a single ingredient or simple product.
Delta is signed: positive for in-flow (procurement, opening_balance, adjustment_up), negative for out-flow (waste, adjustment_down). CurrentStock = SUM(delta) for a given product_id.
type Supplier ¶
type Supplier struct {
ID uuid.UUID
CompanyID uuid.UUID
Name string
Contact string
Phone string
Email string
Address string
CreatedAt time.Time
UpdatedAt time.Time
}
Supplier represents a vendor that provides raw materials or goods to the company.
type SupplierPayment ¶
type SupplierPayment struct {
ID uuid.UUID
CompanyID uuid.UUID
SupplierID uuid.UUID
Amount int64 // smallest currency unit, > 0
Notes string
PaidFrom string // COA credit account representing payment source (default "1000")
CreatedAt time.Time
}
SupplierPayment records a cash or transfer payment made to a supplier.
type TopProduct ¶
type TopProduct struct {
ProductID uuid.UUID `json:"product_id"`
ProductName string `json:"product_name"`
Revenue int64 `json:"revenue"`
UnitsSold int64 `json:"units_sold"`
}
TopProduct holds revenue and units-sold for a single product.
type User ¶
type User struct {
ID uuid.UUID
Email string
Name string
Role auth.UserRole
PasswordHash string
CompanyID *uuid.UUID // nil for owners; required for managers and cashiers
CreatedAt time.Time
UpdatedAt time.Time
// TokenValidAfter, when set, invalidates any JWT issued (iat) before this
// time for this user — checked in handler.JWTParserMiddleware and
// AuthService.RefreshTokens. nil means no restriction.
TokenValidAfter *time.Time
}
User represents a registered user of the system.