FormsLang 1.3.0 - Modernization Blueprint
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=COLUMNrecords 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 aformInitializationprocess before the
header and aformAutoRowProcessingprocess at sequence 1000 -- behind
every approved conversion, so a trigger the reviewer enabled has already
filled its column before the row is written.--forget-keywithdraws the
confirmation and the region goes back to exactly what it was. Nothing
binds on its own: the FormsPrimaryKeyflag 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:Boundwith the column and who
confirmed it,Unboundwith 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 validateand
apex importaccept either spelling. -
An approved Forms validation exports as an APEX validation. A
WHEN-VALIDATE-ITEMorWHEN-VALIDATE-RECORDthe 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 theMESSAGE()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 validateruns without a database. With no target
configured -- or with the new--offlineflag, which ignores one that
is -- SQLcl compiles the exported package against the APEXlang grammar
bundled in its ownapexlang-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 importis 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_PRODUTOis 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 throughapex validate --offlinebeside the
showcase's.
Fixed
- A saved APEX password is found whether the connection is written as
host:port/serviceor 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
onassert, 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 indocs/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.