inspector

package
v0.0.0-...-20536d3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package inspector reads the structure of an ESB-generated project without writing anything. It walks the file tree produced by `esb init` and surfaces an in-memory ProjectModel that the printer turns into a single-screen summary.

Declaration-based facts (aggregates, events, handlers, queries, projection aggregate lists) are recovered with go/ast, so the scanner is indifferent to gofmt spacing and comment wording and never treats an unrelated struct as an event. The few marker-anchored blocks the generator injects into hand-shaped slices (wire App fields/init, AutoMigrate models, main.go workers) are still read by locating their `// esb:inject:*` markers, because there the contract is precisely "what was injected after this marker", not a declaration.

Index

Constants

View Source
const (
	StorageModeEmbedded  = "embedded"
	StorageModeESBServer = "esb-server"
	// StorageModeUnknown marks an unrecognised EVENT_STORE_MODE value.
	// The UI displays it as a warning so a typo (e.g. "esb-sever")
	// is not silently treated as embedded.
	StorageModeUnknown = "unknown"
)

StorageMode values the inspector recognizes in EVENT_STORE_MODE.

Variables

This section is empty.

Functions

func Print

func Print(w io.Writer, m ProjectModel, focus string) error

Print writes a single-screen summary of m to w. When focus is non-empty, only the parts of the project that touch that aggregate name are shown; unrelated aggregate names remain on one compact context line.

Types

type Aggregate

type Aggregate struct {
	Name         string // aggregate-store name from the generated constant (for example "bank-account")
	FileName     string // snake_case file name (without .go), used to identify the root struct
	Events       []string
	EventDetails []EventDetail
}

Aggregate is one file in domain/ (excluding event.go / errors.go).

type EventDetail

type EventDetail struct {
	Name   string
	Fields []EventField
}

EventDetail describes one event's fields, extracted from its generated struct declaration in domain/<aggregate>.go. Fields is empty when the event name was found only via an Apply() case branch with no matching generated struct (e.g. a hand-written event that skipped `esb add event`).

type EventField

type EventField struct {
	Name    string // Go field name, PascalCase
	Type    string // Go type as written (string, int64, ...)
	JSONTag string
}

EventField is one field of a generated event struct.

type Handler

type Handler struct {
	Name      string // snake_case file name (without .go)
	Aggregate string // resolved via the service field ("" if not detected)
}

Handler is one file in server/handler/.

type LockInfo

type LockInfo struct {
	Key        string
	OwnerToken string
	ExpiresAt  time.Time
	Held       bool // false when ExpiresAt is in the past
}

LockInfo describes one row from the embedded "locks" table.

type NotFound

type NotFound struct {
	Dir string
}

NotFound is returned when Scan is run outside an ESB project (no go.mod).

func (*NotFound) Error

func (e *NotFound) Error() string

type ProjectModel

type ProjectModel struct {
	ModuleName  string
	PackageName string
	Aggregate   []Aggregate // every aggregate discovered in domain/, sorted by aggregate-store name
	Projection  []Projection
	Handler     []Handler
	Query       []Query
	Wire        WireGraph
	Migrate     []string    // GORM models in projection/db.go AutoMigrate
	RunWorker   []string    // workers in main.go
	Storage     StorageInfo // event store mode + per-aggregate event counts
}

ProjectModel is the in-memory picture of one ESB project.

func Scan

func Scan(rootDir string) (ProjectModel, error)

Scan walks rootDir and returns a populated ProjectModel. A missing go.mod is reported as *NotFound so the CLI can print a friendly message.

type Projection

type Projection struct {
	Name       string // worker file name without _worker.go suffix
	Multi      bool
	Aggregates []string // aggregate names listened to
}

Projection is one projection worker. Multi is true when the worker applies events from several aggregates (the worker file contains a `switch e.AggregateName` branch, or declares a "<name>AggregateNames" slice).

type Query

type Query struct {
	Name      string
	Aggregate string // best-effort: derived from the row type the function returns
}

Query is one query function in projection/query.go.

type Storage

type Storage struct {
	Info StorageInfo
}

Storage exposes the storage mode + per-aggregate event counts for the UI. It is populated by ScanStorage and attached to the ProjectModel by Scan.

type StorageInfo

type StorageInfo struct {
	// Mode is "embedded" or "esb-server". When the .env has no
	// EVENT_STORE_MODE entry the inspector defaults to "embedded"
	// because that is what `esb init` generates today.
	Mode string
	// DSN is the SQLite path used by the embedded event store, or
	// empty when mode == esb-server. The path is resolved against
	// the project root so relative DSNs ("app.db") display as
	// "<root>/app.db" in the UI.
	DSN string
	// ESBURL is the remote endpoint when mode == esb-server, or
	// empty otherwise.
	ESBURL string
	// Counts maps aggregate_name -> event row count, populated from
	// the embedded SQLite file when mode == embedded and the file
	// exists. Counts is nil otherwise.
	Counts map[string]int
	// SnapshotCounts maps aggregate_name -> snapshot row count, same
	// scope/lifetime rules as Counts. A project generated before
	// snapshot support existed simply has no "snapshots" table yet —
	// that surfaces as an empty map, not an error.
	SnapshotCounts map[string]int
	// EventCounts maps aggregate_name -> event_name -> stored row count,
	// populated from the embedded SQLite file (embedded mode only). Used
	// to warn before deleting an event definition whose events already
	// exist in history. Nil in esb-server mode or when the file is absent.
	EventCounts map[string]map[string]int
	// Locks lists the rows currently in the embedded "locks" table
	// (both held and expired-but-not-yet-cleaned-up), sorted by key.
	// Only populated in embedded mode — esb-server mode exposes no
	// "list all locks" endpoint, only per-key lookups.
	Locks []LockInfo
	// HasSQLite reports whether the embedded SQLite file was
	// opened successfully. When false, Counts is nil even if the
	// DSN points somewhere — a useful signal for the UI so the
	// page can render "no events yet" instead of pretending the
	// table exists.
	HasSQLite bool
}

StorageInfo describes how the project's event store is currently configured. It is read-only — the inspector never mutates the project. Embedded mode points at a local SQLite file; esb-server mode points at a remote HTTP endpoint.

func ScanStorage

func ScanStorage(rootDir string) StorageInfo

ScanStorage inspects rootDir for the project's event store configuration. It is tolerant: a missing .env, an unparseable EVENT_STORE_MODE, or a missing SQLite file all surface as a zero-value StorageInfo with sensible defaults rather than errors.

The function is intentionally cheap — it runs on every UI page load. SQLite is opened read-only with no busy timeout; a corrupt file surfaces as HasSQLite=false without failing the rest of the scan.

func (StorageInfo) EventCount

func (s StorageInfo) EventCount(aggregateName, eventName string) int

EventCount returns how many rows are stored for (aggregateName, eventName) in embedded mode, or 0 when unknown (esb-server mode, no SQLite, or none).

func (StorageInfo) HeldLockCount

func (s StorageInfo) HeldLockCount() int

HeldLockCount returns how many rows in Locks are currently held (not expired). Expired-but-not-yet-cleaned-up rows are excluded.

func (StorageInfo) SortedAggregateNames

func (s StorageInfo) SortedAggregateNames() []string

SortedAggregateNames returns the aggregate names from the count map in lexical order. The UI uses it to render a stable table without depending on Go's randomized map iteration.

func (StorageInfo) String

func (s StorageInfo) String() string

String renders a one-line summary suitable for the inspector's CLI output. Keep it stable — the snapshot golden file pins the exact wording.

func (StorageInfo) TotalEvents

func (s StorageInfo) TotalEvents() int

TotalEvents sums Counts into a single number for the dashboard card. Returns 0 when Counts is empty.

func (StorageInfo) TotalSnapshots

func (s StorageInfo) TotalSnapshots() int

TotalSnapshots sums SnapshotCounts into a single number for the dashboard card. Returns 0 when no snapshots have been taken yet.

type WireGraph

type WireGraph struct {
	Fields []WireNode // declared fields on App (besides Env/Handler)
	Nodes  []WireNode // constructor expressions inside NewApp
}

WireGraph is the deconstructed wire/wire.go App.

type WireNode

type WireNode struct {
	VarName  string // local var in NewApp, e.g. "orderWorker"
	Field    string // matching App field, e.g. "OrderProjectionWorker"
	Type     string // concrete type, e.g. "*projection.OrderProjectionWorker"
	Provider string // constructor call, e.g. "projection.NewOrderProjectionWorker(...)"
}

WireNode is one provider edge in the wire graph.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL