Skip to content

FormsLang 1.3.0 - Modernization Blueprint

Choose a tag to compare

@gevianajr gevianajr released this 11 Sep 00:12
· 127 commits to main since this release

Added

  • Modernization Blueprint: deterministic application knowledge, shared
    dependencies, business-rule candidates, API reuse ranking, optional enterprise
    naming patterns and supplied database/PL/SQL metadata. formslang blueprint
    writes reproducible JSON, standalone HTML, Markdown and Mermaid artifacts.

  • Blueprint in the existing Workbench: filtered dependency exploration,
    source evidence, architecture review with stale-decision detection, separately
    evidenced modernization coverage and optional anonymized AI explanation.
    Existing conversion approvals, risk/readiness formulas and APEX exports remain
    separate. See the Blueprint guide.

  • A block whose key a reviewer confirmed exports as a form APEX fetches
    and saves. formslang apex export --key BLOCK=COLUMN records that the
    column identifies one row of the block's base table; the block's region
    then becomes a form region over that table, its items bind to their
    columns, and the page gets a formInitialization process before the
    header and a formAutoRowProcessing process at sequence 1000 -- behind
    every approved conversion, so a trigger the reviewer enabled has already
    filled its column before the row is written. --forget-key withdraws the
    confirmation and the region goes back to exactly what it was. Nothing
    binds on its own: the Forms PrimaryKey flag is offered as a hint and
    never acted on, because a wrong key raises no error -- it silently
    fetches and saves the wrong row -- so the answer is stored with a name
    and a date. A block with no confirmation is unchanged, byte for byte,
    and the export now reports both halves: Bound with the column and who
    confirmed it, Unbound with the reason and the flag that would bind it.
    Only a single-record block whose database items all sit in one region of
    their own qualifies for now.

  • A bound region gets a Create button and a Save button, not one Save.
    APEX takes insert-or-update from the pressed button's Database Action and
    not from whether the form found a row, so a single button always updates
    and the page could never create a record. Create shows when the key item
    is null, Save when it is not, and one write process runs for either. The
    submit branch is a redirect back to the page: a Show Only branch is
    refused at run time on a page whose Reload on Submit is Only for Success,
    and the submit then saves nothing without showing an error. Both facts
    were found with the page open in a browser -- apex validate and
    apex import accept either spelling.

  • An approved Forms validation exports as an APEX validation. A
    WHEN-VALIDATE-ITEM or WHEN-VALIDATE-RECORD the reviewer approved
    becomes a page validation of type PL/SQL Error -- it passes when the
    approved code runs without raising, exactly as the Forms trigger did --
    and it ships enabled, so the rule is enforced after the import instead of
    arriving as an inert process. An item rule points at the page item the
    Forms item became; a record rule, or an item that became an Interactive
    Grid column, shows its error in the notification (a validation pointing at
    an item the page does not declare fails the import with
    REFERENCE_NOT_FOUND).

  • An exported validation carries the wording the rule already had. APEX
    prints the validation's own error message and never the error the code
    raises, so the sentence is read out of the approved code
    (raise_application_error, apex_error.add_error) or, when that code
    raises without saying anything, out of the MESSAGE() of the Forms
    trigger it came from. The manifest records which of the two it was. A
    rule whose message is built at run time ('invalid: ' || :ITEM), or
    whose source says two different things, keeps the placeholder and gets
    the reason in its component comments: half a sentence in front of a user
    is worse than an honest placeholder.

  • formslang apex validate runs without a database. With no target
    configured -- or with the new --offline flag, which ignores one that
    is -- SQLcl compiles the exported package against the APEXlang grammar
    bundled in its own apexlang-compiler.jar: no connection, no workspace,
    no credentials. A narrower check than a connected validate, and still
    Oracle's verdict rather than FormsLang's. apex import is unchanged and
    still requires a workspace.

  • CI validates the showcase export on every push, and proves the gate can
    fail: a copy of the ZIP with one region type replaced by an invalid one
    must be rejected by the same command. The same job exports the module a
    second time with its rules approved, so the validations are compiled by
    Oracle too, and patches one of them to point at a page item that does not
    exist -- which must fail.

  • A demo-sized fixture, tests/fixtures/minicase/. The showcase is a
    coverage bench -- 5 blocks, 78 items, 55 triggers, 59 review units -- and
    is the wrong module to walk anyone through. MINI_PRODUTO is one block,
    8 items, 6 triggers and six review units, and still covers every element
    the smallest complete case has to show: a restricted query, an insert
    that assigns the key, required items, a rule spanning two fields, and a
    failure a user can understand. Two of its rules carry their own sentence
    and one raises silently, so a single module exercises both origins an
    exported error message can have. It round-trips through Oracle Forms
    14.1.2 with no structural differences. CI guards its shape on every OS
    and puts its package through apex validate --offline beside the
    showcase's.

Fixed

  • A saved APEX password is found whether the connection is written as
    host:port/service or as the JDBC URL for it. The account name in the
    credential store is derived from the connection, so the two spellings of
    one database used to hide each other's password and the workbench asked
    for it again.
  • The Diff report labels added and removed program units with their kind,
    as modified ones already were, so a package specification and its body
    removed together no longer appear as two identical names.

Changed

  • The installer acceptance workflow reads the candidate version from the
    checkout and defaults the baseline to the latest published release. Its
    build steps moved to a reusable workflow (build-installers.yml) so
    acceptance and release runs freeze the same binaries.
  • The installed-engine check raises on every failed step instead of relying
    on assert, finds the fixture relative to itself, verifies the unit it
    approved rather than the first in the list, and records only what each
    phase actually checked.
  • A test requires every version declaration to agree: pyproject.toml,
    the __init__ fallback, package.json, tauri.conf.json, Cargo.toml
    and both lock files.
  • The README build recipe uses the same spec file as CI; the release
    procedure is written down in docs/releasing.md.

Blueprint analysis boundaries

  • Business rules are conservative static candidates, not verified business
    semantics. Dynamic SQL, unresolved symbols, callee behavior and external callers
    can remain unknown. API ranking measures observed reuse, not API suitability.
  • Architecture recommendations require human review. Modernization coverage is
    evidence-backed review tracking, not verified functional parity. No live Oracle
    application or database validation was performed for the Blueprint feature.