Skip to content

Separate UI state from domain state in appModel (40-field bag) #246

@narthur

Description

@narthur

Problem

appModel in model.go:1–111 carries ~40 peer fields mixing two concerns:

  • Domain state: goals, config, selectedGoal, error info
  • UI state: cursor position, search query + active flag, modal visibility, input focus index, input mode flag, loading/refreshing flags, per-field input buffers (datapoint value, datapoint comment, slug, title, goal type, gunits, goaldate, goalval, rate)

handlers.go:30–485 reaches directly into these fields to mutate them. There is no seam between "what the user is trying to do" (submit a datapoint for goal X with value Y) and "how the UI is tracking that in flight" (which textbox is focused, what's been typed so far, is the modal open).

The cost shows up in test coverage: handlers_test.go tests the helper validators (validateDatapointInput, validateCreateGoalInput) but does not test the interactive handlers, because constructing an appModel for a single interaction requires populating dozens of unrelated fields. Bugs in the interaction between character filters (isAlphanumericOrDash, isLetter, isNumericOrNull, isNumericWithDecimal) and form validation only surface in manual TUI use.

Proposed direction (subject to grilling)

Split appModel into:

  • a domain state holding goals + config + selection
  • one or more UI sub-states for modals (datapoint entry, goal creation, search), each owning its own input buffers and focus

Handlers then operate on a sub-state, not the world.

Caveat — lower confidence than the API/deadline/table issues

Bubble Tea idioms push toward big model structs. This refactor fights the framework somewhat. Worth grilling before committing.

Files involved

  • model.go:1–111
  • handlers.go:30–485

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions