Documentation
¶
Index ¶
- func AddAggregate(aggregateName string) error
- func AddCRUD(name string, fields []FieldDef) error
- func AddEvent(aggregateName, eventName string, fields []FieldDef) error
- func AddHandler(handlerName, aggregateName string) error
- func AddIdempotency() error
- func AddLedger(name string) error
- func AddOutbox(name string) error
- func AddProjection(projectionName string, aggregateNames []string) error
- func AddQuery(queryName, aggregateName string) error
- func AddSaga(name string) error
- func AddStateMachine(name, statesCSV, transitionsCSV string) error
- func AddUpcaster(aggregateName, eventName string) error
- func InitProject(moduleName, destDir string) error
- func ReadModuleName() (string, error)
- func RemoveEvent(aggregateName, eventName string) error
- type AggregateData
- type CRUDData
- type CRUDField
- type EventData
- type FieldDef
- type HandlerData
- type LedgerData
- type ProjectData
- type ProjectionData
- type QueryData
- type SMFromTransitions
- type SMState
- type StateMachineData
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AddAggregate ¶
AddAggregate generates domain/service/projection files for a new aggregate and updates projection/db.go, wire/wire.go, and main.go. All file writes are staged in a single transaction and committed together, so a missing marker or bad render leaves the project untouched rather than half-wired.
func AddCRUD ¶
AddCRUD scaffolds a complete CRUD vertical slice for an entity aggregate: domain aggregate + Created/Updated/Archived events, a service with Create/Update/Archive commands (invariants enforced on the aggregate), a read-model row + projection worker, List/Get queries, write-side HTTP handlers, and Given-When-Then scenario tests. Everything is staged in one injector.Tx and committed together, so a failure leaves the project untouched.
func AddEvent ¶
AddEvent injects a new event struct, Apply() case, constructor, and projection worker case into the existing aggregate files.
func AddHandler ¶
AddHandler generates an HTTP handler skeleton and updates routes + wire. Every file write is staged in one transaction so a failure anywhere leaves the project untouched instead of partially wired.
func AddIdempotency ¶
func AddIdempotency() error
AddIdempotency generates a reusable idempotency guard (AlreadyProcessed / Once) in the service package, backed by the event stream's IdempotencyKey. Use it to make command handling safe to retry: check at the top of a command and store the event with the same key. It is a shared helper, so it is generated once per project.
func AddLedger ¶
AddLedger scaffolds a double-entry-style ledger account aggregate: an append-only balance with Open/Deposit/Withdraw/Freeze/Close commands, a non-negative-balance invariant, a balance read model + statement journal, balance/statement queries, write-side HTTP handlers, and Given-When-Then scenario tests (including a concurrent no-double-spend test). Everything is staged in one injector.Tx and committed together.
func AddOutbox ¶
AddOutbox scaffolds a transactional outbox for an aggregate's events: an ingest worker that appends each event to an outbox table (idempotent by source event id) and a publisher worker that relays unpublished rows through a Publisher port (with a log stub), marking them published. Everything is staged in one injector.Tx.
func AddProjection ¶
AddProjection generates a multi-aggregate projection worker. All writes are staged in one transaction so a failure leaves the project untouched.
func AddSaga ¶
AddSaga scaffolds an orchestration saga (process manager): a two-step transfer with compensation. It coordinates a Debit then a Credit through a Port interface, recording its own event stream (Requested -> Debited -> Credited -> Completed, or -> Failed / -> Compensated) so the outcome is auditable. Everything is staged in one injector.Tx.
func AddStateMachine ¶
AddStateMachine scaffolds a state-machine aggregate: one event per state, a transition table, a generic guarded Transition command, a read model + worker, queries, an HTTP handler, and Given-When-Then scenario tests. statesCSV is a comma-separated list of snake_case states (the first is the initial state); transitionsCSV is a comma-separated list of "from->to" pairs. Everything is staged in one injector.Tx.
func AddUpcaster ¶
AddUpcaster registers an event upcaster: a function that migrates a stored event's JSON payload from an older shape to the current one on read. Aggregate Replay routes every stored event through the registered chain before Apply, so Apply only ever sees the latest shape. The generated function is an identity stub for you to fill in.
func InitProject ¶
InitProject scaffolds a new event sourcing project in destDir.
func ReadModuleName ¶
readModuleName reads the module name from go.mod in the current directory.
func RemoveEvent ¶
RemoveEvent deletes an event's generated code from an aggregate: its struct, its New<Event>Event constructor (when present), its Apply() case, and its projection worker case. It is the inverse of AddEvent, done AST-based and staged in one injector.Tx so the whole removal is atomic and gofmt-valid.
It refuses to run when an upcaster targets the event (that file would no longer compile, and removing it automatically risks silent data-migration loss) — remove the upcaster first. It does NOT touch any stored event data; callers that care about existing history must check before calling.
Types ¶
type AggregateData ¶
type AggregateData struct {
ModuleName string
PackageName string
AggregateName string // snake_case: "bank_account"
AggregateNamePascal string // PascalCase: "BankAccount"
AggregateNameKebab string // kebab-case: "bank-account" (ESB aggregate_name value)
ReceiverName string // Go receiver variable: "b" for "BankAccount"
TableName string // snake_case plural: "bank_accounts"
}
AggregateData is passed to add-aggregate templates.
type CRUDData ¶
type CRUDData struct {
ModuleName string
PackageName string
Name string // snake_case: "product"
NamePascal string // PascalCase: "Product"
NameKebab string // kebab-case aggregate-store name: "product"
Receiver string // Go receiver variable: "p"
TableName string // snake_case plural: "products"
Fields []CRUDField
}
CRUDData is passed to the CRUD recipe templates. It describes one entity aggregate (product, customer, …) plus the fields carried by its Created/Updated events and mirrored in the read-model row.
type CRUDField ¶
type CRUDField struct {
NamePascal string // Go struct field name: "Price"
JSONTag string // json tag / gorm column: "price"
Type string // Go type: "string", "int64", ...
Sample string // Go literal for tests: `"sample"`, `1`, `true`
}
CRUDField extends a plain field with a Go literal sample value used by the generated Given-When-Then scenario tests.
type EventData ¶
type EventData struct {
ModuleName string
PackageName string
AggregateName string // snake_case
AggregateNamePascal string // PascalCase
EventName string // PascalCase: "OrderPlaced"
Fields []FieldDef
}
EventData is passed to add-event templates and injectors.
type FieldDef ¶
type FieldDef struct {
NamePascal string // Go struct field name: "BuyerID"
JSONTag string // json tag value: "buyer_id"
Type string // Go type: "string", "int64", "float64", "bool"
}
FieldDef describes one field of a domain event.
func ParseFields ¶
ParseFields parses "field:type ..." arguments into FieldDef slices.
type HandlerData ¶
type HandlerData struct {
ModuleName string
PackageName string
HandlerName string // snake_case: "place_order"
HandlerNamePascal string // PascalCase: "PlaceOrder"
AggregateName string // snake_case
AggregateNamePascal string // PascalCase
}
HandlerData is passed to add-handler templates.
type LedgerData ¶
type LedgerData struct {
ModuleName string
PackageName string
Name string // snake_case: "account"
NamePascal string // PascalCase: "Account"
NameKebab string // kebab-case aggregate-store name: "account"
Receiver string // Go receiver variable: "a"
TableName string // balance table: "accounts"
EntryTableName string // statement table: "account_entries"
}
LedgerData is passed to the ledger recipe templates. A ledger has a fixed event shape (Opened/Deposited/Withdrawn/Frozen/Closed), so unlike CRUD it takes no user-defined fields.
type ProjectData ¶
type ProjectData struct {
ModuleName string // e.g. "github.com/myorg/toko"
PackageName string // last path segment, valid identifier: "toko"
}
ProjectData is passed to init-time templates.
type ProjectionData ¶
type ProjectionData struct {
ModuleName string
PackageName string
ProjectionName string // snake_case: "sales_report"
ProjectionNamePascal string // PascalCase: "SalesReport"
AggregateNames []string // ["order", "payment"]
TableName string // snake_case plural: "sales_reports"
}
ProjectionData is passed to add-projection templates.
type QueryData ¶
type QueryData struct {
ModuleName string
PackageName string
QueryName string // snake_case: "order_by_buyer"
QueryNamePascal string // PascalCase: "OrderByBuyer"
AggregateName string // snake_case
AggregateNamePascal string // PascalCase
}
QueryData is passed to add-query templates.
type SMFromTransitions ¶
SMFromTransitions lists the states reachable from one state.
type SMState ¶
type SMState struct {
Raw string // "placed"
Pascal string // "Placed"
Event string // "<NamePascal>Placed" — the event emitted when entering it
}
SMState is one state of a state-machine aggregate.
type StateMachineData ¶
type StateMachineData struct {
ModuleName string
PackageName string
Name string // snake_case: "order"
NamePascal string // PascalCase: "Order"
NameKebab string // kebab-case aggregate-store name: "order"
Receiver string // Go receiver variable: "o"
TableName string // snake_case plural: "orders"
States []SMState
InitialState string // raw name of the entry state
TransitionGroups []SMFromTransitions
// Precomputed values for the generated scenario tests.
InitialEvent string // event of the initial state
HasSecond bool
SecondState string // a non-initial state (for "invalid from nothing")
HasValidTo bool
ValidTo string // a state reachable from the initial state
ValidEvent string // its event
HasInvalidTo bool
InvalidTo string // a state NOT reachable from the initial state
}
StateMachineData is passed to the state-machine recipe templates.