Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

64 lines
1.4 KiB
Go

package ledger
import (
"fmt"
"time"
)
// Service is the ledger's public API over a Store.
type Service struct {
store Store
clock func() time.Time
events *Dispatcher
}
// NewService builds a Service backed by store.
func NewService(store Store) *Service {
return &Service{
store: store,
clock: time.Now,
events: NewDispatcher(),
}
}
// OpenAccount registers a new account and returns it.
func (s *Service) OpenAccount(id, name string, kind AccountKind, currency string) *Account {
acct := &Account{
ID: id,
Name: name,
Kind: kind,
Balance: Money{Currency: currency},
Created: s.clock(),
}
s.store.PutAccount(acct)
s.events.Emit(Event{Kind: EventAccountOpened, Subject: id})
return acct
}
// Post validates and records a transaction.
func (s *Service) Post(tx Transaction) error {
if tx.Posted.IsZero() {
tx.Posted = s.clock()
}
if err := post(s.store, tx); err != nil {
s.events.Emit(Event{Kind: EventPostFailed, Subject: tx.ID})
return err
}
s.events.Emit(Event{Kind: EventPosted, Subject: tx.ID})
return nil
}
// Balance returns the current balance of an account.
func (s *Service) Balance(id string) (Money, error) {
acct, ok := s.store.GetAccount(id)
if !ok {
return Money{}, fmt.Errorf("balance: %w", ErrUnknownAccount)
}
return acct.Balance, nil
}
// Subscribe registers a listener for ledger events.
func (s *Service) Subscribe(l Listener) {
s.events.Subscribe(l)
}