Skip to content

feat: field-bound @ SAY GET — promotes LOOKUP to full end-to-end (#59)#65

Merged
DDecoene merged 4 commits into
release/v1.3.0from
feature/59-field-bound-get
Jul 12, 2026
Merged

feat: field-bound @ SAY GET — promotes LOOKUP to full end-to-end (#59)#65
DDecoene merged 4 commits into
release/v1.3.0from
feature/59-field-bound-get

Conversation

@DDecoene

Copy link
Copy Markdown
Owner

Summary

Makes @ SAY GET bind directly to a table column when one matches — the dBASE III behavior WebBase-III's memory-variable-only forms had deviated from until now.

  • Executor.doAtSayGet recognizes a GET whose name matches the active table's column (case-insensitive) and binds to it, capturing the record's rowid and prefilling from its current value. Fields take precedence over a memory variable of the same name — the reason the m_ prefix convention exists. A field-bound GET requires a current record (** Error: GET <field>: no current record otherwise — this must be a hard failure, not a silent no-op).
  • If the bound column has a LOOKUP, the form renders the same picker BROWSE does; an unresolvable lookup degrades to free entry with a warning, same as everywhere else.
  • form-submit writes field-bound values by their captured rowid — never by trusting the client's message for which columns exist on the form, mirroring grid-edit's authoritative re-check. Submission is all-or-nothing: every field is validated (type + fresh lookup re-resolution) before any is written. A rejection sends a new form-error message; the client keeps the form open with the bad fields outlined instead of silently discarding the valid ones.
  • The browser (FormLayout, Terminal) stopped self-closing the form on submit — it now waits for the server's verdict (view-terminal on success, form-error on rejection) — and renders <select>s for lookup-bearing fields.

One pre-existing test collision surfaced and was fixed: three tests/Session.test.ts cases used a memory variable named val in a table that also has a column named VAL — under the new precedence rule this now binds to the field. Renamed the variable to m_val throughout (purely mechanical, same asserted outcomes) — verified necessary because the original sequence GETs before any record exists, which would otherwise now throw.

This is the PR that promotes LOOKUP to the full README command reference — both BROWSE and forms now declare, enforce, and render it end to end.

Plan: docs/superpowers/plans/2026-07-11-lookup-columns.md (Tasks 7, 8, 9)

Closes #59.

Test plan

  • npm test — 444/444 vitest pass
  • npm run build — clean typecheck + build
  • npx playwright test — 94/94 pass
  • Dedicated coverage in tests/FormFieldBinding.test.ts: field binding + prefill + options; fields shadow memvars; fallback to var when no column matches; hard error with no current record (and no form-open sent); lookup degradation still opens the form; all-or-nothing submit (exact form-error payload, valid sibling field confirmed NOT written); corrected resubmit succeeds; forged form-submit naming an undeclared column can't write it; DATE type validation on a field; grid-exit clears pending state so a stale resubmit is inert; the Test hardening: strict CREATE TABLE parser, demo schema pins, untested WS message types #50 bare-INPUT regression stays fixed

DDecoene added 4 commits July 12, 2026 11:13
Both BROWSE and forms now declare, enforce, and render LOOKUP end to
end, so this is the PR that adds the full command-table entry and
the field-binding precedence note to the README.
@DDecoene DDecoene merged commit 28e976a into release/v1.3.0 Jul 12, 2026
2 checks passed
@DDecoene DDecoene deleted the feature/59-field-bound-get branch July 12, 2026 09:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant