package types import ( "time" "github.com/google/uuid" ) // At the center of the application is the transaction. // // Every piece of data should be calculated based on transactions. This means potential calculation errors can be fixed later in time. // // If it becomes necessary to precalculate snapshots for performance reasons, this can be done in the future. But the transaction should always be the source of truth. type Transaction struct { Id uuid.UUID GroupId uuid.UUID AccountId uuid.UUID // nil indicates that the transaction is not yet associated with a piggy bank PiggyBankId *uuid.UUID // The internal transaction is amove between e.g. an account and a piggy bank to execute a savings plan Internal bool // The value of the transacion. Negative for outgoing and positive for incoming Value int64 Timestamp time.Time Note string CreatedAt time.Time // either "" or "system-" CreatedBy uuid.UUID UpdatedAt time.Time UpdatedBy uuid.UUID } // The Account holds money type Account struct { Id uuid.UUID GroupId uuid.UUID `db:"group_id"` // Custom Name of the account, e.g. "Bank", "Cash", "Credit Card" Name string CurrentBalance int64 `db:"current_balance"` LastTransaction *time.Time `db:"last_transaction"` // The current precalculated value of: // Account.Balance - [PiggyBank.Balance...] OinkBalance int64 `db:"oink_balance"` CreatedAt time.Time `db:"created_at"` CreatedBy uuid.UUID `db:"created_by"` UpdatedAt *time.Time `db:"updated_at"` UpdatedBy *uuid.UUID `db:"updated_by"` } // The PiggyBank is a fictional account. The money it "holds" is actually in the Account type PiggyBank struct { Id uuid.UUID GroupId uuid.UUID AccountId uuid.UUID Name string CurrentBalance int64 CreatedAt time.Time CreatedBy uuid.UUID UpdatedAt *time.Time UpdatedBy *uuid.UUID } // The SavingsPlan is applied every interval to the PiggyBank/Account as a transaction type SavingsPlan struct { Id uuid.UUID GroupId uuid.UUID PiggyBankId uuid.UUID MonthlySaving int64 ValidFrom time.Time /// nil means it is valid indefinitely ValidTo *time.Time CreatedAt time.Time CreatedBy uuid.UUID UpdatedAt *time.Time UpdatedBy *uuid.UUID }