Skip to content

Latest commit

 

History

History
68 lines (54 loc) · 5.66 KB

File metadata and controls

68 lines (54 loc) · 5.66 KB

ARCHITECTURE.md

Topology

  • main.go boots Wails, embeds frontend/dist, and binds a single App.
  • app.go is the Wails RPC boundary. Public methods on App are callable from the frontend.
  • internal/ contains the backend domain logic, persistence, broker integrations, and lifecycle managers.
  • frontend/src/ contains the React desktop UI. frontend/src/shared/api/index.ts is the frontend entry point for Wails RPC bindings.
  • frontend/wailsjs/ is generated from the Go surface and is not a hand-edited source of truth.
  • Runtime user state lives in the resolved local config file and OS config directory.

Startup And Event Flow

  1. main.go calls wails.Run(...) with App bound into the runtime.
  2. App.startup() initializes profile storage, stream/search managers, the cancellable metadata scan manager, broker client pool, metadata cache, local Avro codec cache, and the async update check.
  3. Frontend code calls generated Wails bindings through @shared/api.
  4. Long-running stream/search sessions and namespace metadata scans emit request-scoped events back to the frontend through runtime.EventsEmit.
  5. Frontend Zustand stores and feature UIs reconcile RPC responses plus event streams into visible state.

Backend Package Map

Path Responsibility Notes
internal/apperr User-facing error helpers Keeps validation/not-found errors structured.
internal/broker Shared broker-facing DTOs and topic metadata cache Pulsar runtime calls live in internal/pulsar* packages.
internal/pulsarmeta Topic/subscription metadata reads and bounded-concurrency namespace scans Namespace scans use four workers, emit incremental Wails events, and apply a timeout to each Admin request instead of one shared scan deadline.
internal/config Runtime config path resolution Owns .topicconsole.json path resolution.
internal/profile Profile and broker data model plus JSON storage This is the source of truth for user connection config.
internal/schema Local .avsc schema loading plus Avro encode/decode Stream/search fall back to raw display on decode miss; mapped production validates JSON and emits bare Avro binary.
internal/search Long-running history search sessions Mirrors stream lifecycle patterns.
internal/stream Observer and consumer session lifecycle Owns streaming session creation, commit, and shutdown.
internal/updater Release update checks Runs asynchronously after startup.

Frontend Shape

  • frontend/src/app/ wires providers, error boundaries, styles, and the minimal router.
  • frontend/src/pages/ owns top-level screens. Today the app is effectively two views: the main shell and settings.
  • frontend/src/widgets/ composes major panes such as the sidebar, dashboard, stream pane, and profile bar.
  • frontend/src/features/ owns task-focused UI such as broker connect, topic observe/consume, and update checks.
  • frontend/src/entities/ owns reusable domain state, types, and small UI units.
  • frontend/src/shared/ holds UI primitives, formatting helpers, config, and the Wails API facade.

State And Persistence

  • Saved Pulsar connection configs, topic groups, pinned topics, pinned tenants, credential metadata, and Pulsar bearer tokens are stored in .topicconsole.json.
  • If the current working directory already contains .topicconsole.json, that file is used for both reads and writes; otherwise the app falls back to $HOME/.topicconsole.json.
  • A saved Pulsar config persists connection endpoints plus auth mode, plaintext Pulsar tokens, and TLS settings. Tenant and namespace lists are discovered live from the Pulsar admin API and are not stored in config; only pinned tenant names are stored, so they sort to the top of the sidebar.
  • The main shell treats each saved profile as one Pulsar connection, discovers tenants and namespaces live in the left sidebar, and shows the selected namespace's topics in the main dashboard.
  • Shell navigation keeps connection selection and resource browsing separate: the top profile bar owns config switching, while the left sidebar owns active-config tenant and namespace selection.
  • TLS certificate settings store file paths only; the certificate files themselves stay outside the repository.

High-Value Invariants

  • App should orchestrate, not contain business logic.
  • Long-lived background work must have an explicit shutdown path on app shutdown and profile switch.
  • Frontend code should not reach into generated Wails bindings directly; keep the indirection through @shared/api.
  • Namespace-scoped UI such as topic creation, stats, and subscription views should derive their context from the current tree selection, not from persisted profile fields.
  • The left sidebar does not duplicate top-level config selection, and topic action menus stay in the main topic list.
  • User-destructive Pulsar actions should remain explicit product actions, not hidden side effects.
  • Repo-local docs should explain recurring architecture and product choices that an agent cannot infer from filenames alone.

Common Change Routing

  • Add or change a Wails API method: app.go, related internal/*, then make generate.
  • Change profile storage or secret handling: internal/profile/, internal/config/, then update .trellis/spec/guides/security-guidelines.md.
  • Change Pulsar runtime behavior: internal/pulsar*, internal/stream/, internal/search/, then update .trellis/spec/guides/reliability-guidelines.md.
  • Change settings workflows: frontend/src/pages/settings/, relevant features/broker-connect/, maybe entities/profile/.
  • Change stream UI behavior: frontend/src/widgets/stream-pane/, entities/message/, and session stores.