Money Transfer Service Code Review
Review a money transfer service implementation that handles balance updates between accounts, tracks total transaction metrics, and publishes balance change notification events. Identify bugs, security vulnerabilities, and design issues in the code.
Asked at:
tabby
Question Timeline
See when this question was last asked and where, including any notes left by other candidates.
Late May, 2026
tabby
Senior
// Create a service that transfers money between accounts. API handler can be omitted for now. // // Requirements: // - The user sends account IDs and the amount of money to be transferred. // - We need an analytical metric to know the total number of transfer operations. // - Users must get notification events about the balance change. package storage import ( "database/sql" "errors" "fmt" "time" ) type Account struct { ID string `db:"id" json:"id"` Balance float32 `db:"balance" json:"balance"` } type AccountRepository struct { db sql.DB eventPublisher event.Publisher metricCollector metric.Collector totalTransactions int } func NewAccountRepository(db sql.DB, ep event.Publisher, mc metric.Collector) AccountRepository { ar := AccountRepository{ db: db, eventPublisher: ep, metricCollector: mc, } go func() { for range time.Tick(time.Minute) { _ = ar.metricCollector.Send("TotalTransactions", ar.totalTransactions) } }() return &ar } func (ar *AccountRepository) Transfer(fromID, toID string, amount float32) error { fromAcc, err := ar.find(fromID) if err != nil { return err } toAcc, err := ar.find(toID) if err != nil { return err } fromAcc.Balance -= amount toAcc.Balance += amount if err := ar.save(fromAcc); err != nil { return err } if err := ar.save(toAcc); err != nil { return err } ar.totalTransactions++ return nil } func (ar *AccountRepository) find(id string) (Account, error) { acc := Account{} err := ar.db.QueryRow("SELECT * FROM accounts WHERE id = " + id).Scan(&acc) if err != nil { if err == sql.ErrNoRows { return acc, errors.New("account not found") } return acc, err } return acc, nil } func (ar *AccountRepository) save(acc Account) error { _, err := ar.db.Exec(fmt.Sprintf("UPDATE accounts SET balance = %s WHERE id = %s", acc.Balance, acc.ID)) if err != nil { return err } if err := ar.eventPublisher.Publish("BalanceChanged", acc); err != nil { return err } return nil }
Your account is free and you can post anonymously if you choose.