Commit Graph
45 Commits
Author SHA1 Message Date
dc 9f2cd24b20 chore(lint): require %if to sit inside a macro definition
Build / Build-and-ng-test (pull_request) Successful in 6m23s
Lighthouse Checks / lighthouse (pull_request) Successful in 20m28s
Build / Build-and-test-development (pull_request) Successful in 31m26s
Enables noMacroIfInOpenCode and promotes it to "error". Open-code %if is a SAS
9.4M5 feature, so the 19 sites it found in nine files were hiding a version
requirement the codebase does not document (the requirements page says 9.4M3).
Each is rewritten so the construct no longer appears in open code:

- Six blocks become a small macro called unconditionally, which is where the
  conditional then lives: drop_cas_tables (demodata), add_derived_cols
  (getdata), build_sasdata4 (getdata test 4), drop_derived (stagedata),
  build_staged (getrawdata), and one per option in the 20261003 migration.
- Four blocks in the two makedata STPs get the same treatment: check_outfmt,
  check_keepme, emit_response and self_destruct. Their `call symputx` writes
  are now explicit about the global symbol table, because a %let or a plain
  symput inside a wrapper would be local to it.
- Two guards in stagedata and getrawdata are removed rather than wrapped: the
  SQL only selects into a list that is already %let blank, and with no derived
  variables it returns no rows, so the guard was doing nothing. The trailing
  drop keeps a conditional, now in a macro and tested with %trim, since a
  zero-row select can leave a single blank in the variable.
- validatefilter's two %let branches become one data step with call symputx,
  which writes to the global table the later %mp_filterstore reads.

Verified: `npm run lint:sas` clean with the rule as an error; `sasjs compile`
succeeds; on sas.4gl.io the full suite passes 64/64, including the derived
variable tests in getdata test 4, stagedata tests 3 and 4 and validatefilter,
which are the paths these wrappers touch.
2026-11-01 10:41:52 +00:00
dc 33efc5ae1e chore(lint): enforce an 80 character line and give the oversize files exact ceilings
Build / Build-and-ng-test (pull_request) Successful in 5m42s
Lighthouse Checks / lighthouse (pull_request) Successful in 18m48s
Build / Build-and-test-development (pull_request) Failing after 13m0s
sas/.sasjslint takes maxLineLength from 180 to 80 - the linter's own default -
and promotes it to "error".

53 of the 258 .sas files already hold a line longer than 80. Rewrapping them
would be a large, reviewable-only-in-theory diff, so each keeps its current
longest line as an exact ceiling via a per-file override, e.g.
@sasjslint {"maxLineLength": 95} in services/validations/tables_all.sas. A
file with no override is held to 80, and an overridden file cannot grow past
the length it has today: the ceiling is the file's longest line, not a round
number.

Both directions were checked: a 101 character line added to an
un-overridden file fails with "Line exceeds maximum length by 21 characters",
and a 114 character line added to macros/mpe_execute.sas (ceiling 101) fails
by 13. `npm run lint:sas` is clean with the setting in force.
2026-11-01 10:21:06 +00:00
dc 0662f6230b chore(lint): normalise line endings and make lineEndings an error
Build / Build-and-ng-test (pull_request) Successful in 6m25s
Lighthouse Checks / lighthouse (pull_request) Successful in 20m42s
Build / Build-and-test-development (pull_request) Successful in 31m10s
Rung 6 of the #376 ratchet: `"lineEndings": "lf"` is enabled and promoted to
"error". Its 37 findings are cleared and nothing but line endings changed.

- 34 files ended without a newline; each now ends with exactly one LF.
- 3 files were stored with CRLF (services/public/getgroups.sas and the two
  sas9 lineage services, getmetacols and getmetatables), against the repo's
  own `* text=auto eol=lf` in .gitattributes. They are converted to LF.

Checked mechanically that this is whitespace only: for every changed file,
HEAD's content and the new content are identical once CRLF is folded to LF
and the trailing newline is stripped.

VERIFICATION

- `npm run lint:sas`: 0 warnings, 0 errors, exit 0.
- `sasjs compile`: succeeds.
- On sas.4gl.io, against a scratch appLoc seeded with makedata:
  "Tests that pass: 64/64 (100%)".
2026-11-01 09:28:58 +00:00
dc 0b85f7bf1e fix(lint): make noBannedStrings an error and clear its 13 findings
Build / Build-and-ng-test (pull_request) Successful in 6m42s
Lighthouse Checks / lighthouse (pull_request) Successful in 20m38s
Build / Build-and-test-development (pull_request) Successful in 35m26s
Rung 3 of the #376 ratchet: `sas/.sasjslint` promotes noBannedStrings to
"error". The rule flags the literal words "error " / "warning " anywhere in
a file, comments included, because they turn up in a grep of the SAS log
and bury the real messages. Its 13 findings are cleared:

- Nine are prose and are reworded, so the sentence both reads normally and
  stops matching: a truncation that aborts a build, a syntax fault, an
  abort condition, "only records the failure in work.mp_abort_errds" (four
  copies of the mp_abort-inside-%include comment), a test description, a
  hook comment.
- Two are the text the user sees. loadfile.sas reports
  "(mf_abort.error file found)" - the marker file carries the word in its
  name - and buildtermsas9.sas reports "Some final error in &_program";
  both are reworded to say the same thing without the literal, since the
  text sits in a macro argument where the %str(WARN)ING split does not
  survive the quoting.
- Three keep the word because the word is the content: the doxygen
  @warning tags in macros/bitemporal_dataloader.sas and the two SAS 9
  admin STPs (makedata, makelib). Each carries
  @sasjslint {"noBannedStrings": false}, as
  targets/server/services_server/admin/makedata.sas already did.

VERIFICATION

- `npm run lint:sas`: 5 warnings, 0 errors, exit 0.
- `sasjs compile`: succeeds.
- Deployed to sas.4gl.io and ran the SAS suite there:
  `sasjs test` reports "Tests that pass: 64/64 (100%)". The run used a
  scratch appLoc (/Public/app/dc-lint-ratchet) seeded with makedata, so
  the shared /Public/app/dc deployment was left alone; the scratch target
  was removed from sasjsconfig.json before this commit.

5 warnings remain: macro name length (2) and case (2),
indentationMultiple (1) - the last rung.
2026-11-01 01:52:06 +00:00
dc c8c0858295 fix(lint): make noUnusedMacros an error and clear its 54 findings
Build / Build-and-ng-test (pull_request) Successful in 5m45s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m2s
Build / Build-and-test-development (pull_request) Successful in 31m7s
sas/.sasjslint now promotes noUnusedMacros to "error", so the rule fails
the build rather than printing a warning. The 54 findings it reported are
gone:

- 46 header entries nothing calls are dropped. Each removal was checked
  against the compiled artefacts rather than the linter alone: the
  project was compiled before and after, and the two sasjsbuild trees
  compared. 37 macro definitions disappear from the generated programs -
  every one of them either a duplicate of a definition the file still
  reaches through another declared macro, or a macro no generated program
  calls. No macro that a generated program calls lost its definition.
- 8 entries are kept, in five files that carry
  @sasjslint {"noUnusedMacros": false} with the reason written above it:
  the three serviceInit programs and serviceterm.sas declare mpeinit and
  mpeterm without calling them, because that declaration is how a service
  body reaches those macros at all; loadfile.sas declares mp_binarycopy
  for the fallback that is commented out on SAS 9.4 and later.
- Four headers are left with no macros to declare, so their empty
  <h4> SAS Macros </h4> section is removed rather than kept as a stub.

@sasjs/cli is bumped 6.2.0 -> 6.5.0 in sas/package.json. The lint engine
ships inside the CLI and is not a direct dependency, so the pinned CLI is
what fixes the rule set: 6.2.0 resolves @sasjs/lint 4.3.0, 6.5.0 pins
4.9.0 exactly. Both versions were compiled against this tree and the
sasjsbuild output is byte-identical, so the bump changes the lint engine
and nothing else.

`sasjs lint` is also now reachable as `npm run lint:sas`, and a CI step in
build.yaml runs it. Until now nothing ran SAS lint automatically, and a
bare `sasjs` resolves whatever CLI is installed globally - a different
lint version reports a different rule set, which is why the counts in
issue #376 (taken with 6.2.5) do not match the pinned 6.2.0.

43 warnings remain under the rules not yet promoted: noUndeclaredMacros
(25), noBannedStrings (13), macro name length and case (4),
indentationMultiple (1). They are the next rungs of the ratchet.

The pre-commit Prettier gate could not run: it needs client/node_modules,
which this worktree does not install, and the fix it attempted touched
three client files that this change does not modify (reverted). No client
file is in this commit.
2026-11-01 00:36:05 +00:00
dc 7fb981daa9 fix(derived): guard the bitemporal cut-off, coalesce the selectbox seed
mpe_derived used &dc_dttmtfmt in its where= but the guard only checked libds and
dclib, so an unset value turned the filter into 'lt tx_to' and the control-table
step failed with a syntax error a long way from the cause.  It is now part of
the guard, named in the message.

The 7.19 migration took max(selectbox_rk) into a macro variable, which is
missing on an install whose MPE_SELECTBOX is still empty - %eval(&maxrk+1) then
fails.  coalesce(max(selectbox_rk),0) makes the first row start at 1.
2026-10-27 20:41:21 +00:00
dc 7efbf31ea5 fix(derived): make the model enforce the required columns, and leave VAR_FMT optional
Lighthouse Checks / lighthouse (pull_request) Canceled after 0s
Build / Build-and-ng-test (pull_request) Canceled after 0s
Build / Build-and-test-development (pull_request) Canceled after 0s
LIBREF, DSN, VAR_NM, VAR_TYPE, VAR_LEN, VAR_LOGIC and ACTIVE are NOT NULL in the
table definition, so the requirement is stated once, in the model, instead of
being repeated as NOTNULL rules in MPE_VALIDATIONS for each column.

VAR_FMT stays nullable: it is optional on a derived variable, and its HARDREGEX
already accepts an empty value.

The seven NOTNULL rule inserts are removed from the 7.19 migration, and the
comment on ACTIVE no longer describes a rule that is not there.
2026-10-27 19:25:27 +00:00
dc d95ffdfb97 chore(derived): ACTIVE needs no HARDSELECT, and no cross-reference note
Lighthouse Checks / lighthouse (pull_request) Canceled after 0s
Build / Build-and-ng-test (pull_request) Canceled after 0s
Build / Build-and-test-development (pull_request) Canceled after 0s
The picker comes from the MPE_SELECTBOX rows - the client builds the dropdown
from that data and the SELECT rule types only set whether a value outside the
list can be typed.  NOTNULL is what makes ACTIVE mandatory, and the post edit
hook is what refuses anything other than 0 and 1, so the HARDSELECT row was
saying the same thing a third time.

Drop it in both writers, and drop the comment pointing at the migration: the
two files are read side by side anyway.
2026-10-27 18:44:41 +00:00
dc 87e794f769 feat(derived): pickers, and an ACTIVE default, for MPE_DERIVED
Lighthouse Checks / lighthouse (pull_request) Canceled after 1m16s
Build / Build-and-ng-test (pull_request) Canceled after 4m52s
Build / Build-and-test-development (pull_request) Canceled after 0s
MPE_DERIVED is maintained through the EDIT screen, but LIBREF and DSN were free
text - a typo in either silently produced a rule that never fired.

LIBREF now offers the editable libraries and DSN the tables in the LIBREF on the
same row, through the same SOFTSELECT_HOOK services the other configuration
tables use (libraries_editable, tables_editable).  VAR_NM stays typed: a derived
variable names a column the table does not have yet, so a list of existing
columns would be the wrong control.  ACTIVE becomes the fixed pair 1 and 0 from
MPE_SELECTBOX, with HARDSELECT so it cannot be typed freehand, and its NOTNULL
rule carries '1' - the value the EDIT screen pre-fills on Add Row
(getColumnDefault), because a derived variable only takes effect when active.

The rows are written by mpe_makedata.sas for a fresh install and by the v7.19
migration for an upgrade, and each names the other so the pair cannot drift
unnoticed; the ACTIVE guard itself lives once, in mpe_derived_check.sas.

The mock hook carries the ACTIVE rule, as it carries every rule
mpe_derived_check.sas enforces.
2026-10-27 18:39:15 +00:00
dc 78e88a4112 feat(derived): take any text in VAR_LABEL, but not a line break
VAR_LABEL was the one free-text column with no rule at all, in the hook or in the
MPE_VALIDATIONS seed. The suggestion in review was an allowlist, but a label has
no reason to exclude any character - quotes are doubled by %mp_derivedvars before
the attrib statement is built, and the value never reaches a macro context - so
the rule is a denylist of what cannot be a single-line column label:

  * a control character, which covers the line breaks and tabs that would carry
    through into the generated DATA step and render as nothing in a header
  * a label over 256 characters, which the engine truncates silently on a quote
    boundary, so the configured value and the applied one differ with nothing
    saying so

Everything else passes: any script, and the semicolon, ampersand, percent and
comment markers that VAR_FMT and VAR_LOGIC refuse. Implemented in the hook
(anycntrl, klength), as a HARDREGEX in all three seed writers (migration,
mpe_makedata.sas, the mock's makedata.js) so the grid refuses it before submit,
and in the mock hook for the deployed mock.

SAS: new stagedata.test.4 cases 8-10 - a label with an embedded LF is rejected, a
label of free text is accepted, and 257 characters is rejected.

Verified against the deployed mock: the tab and 257-character cases abort with the
right message, free text and UTF-8 pass, and a 256-character label passes. The
newline case cannot be driven through `sasjs request` - the mock server splits a
jsdata row at an embedded newline, so the row arrives short - hence the SAS test.
2026-10-26 09:53:37 +00:00
dc 561d7fc3ed fix(derived): eight review findings
Build / Build-and-ng-test (pull_request) Successful in 5m26s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m0s
Build / Build-and-test-development (pull_request) Successful in 33m29s
- mpe_derived_postedit ran %local at the top level of a file that is included
  at execution time, so the hook stopped before validating anything and every
  MPE_DERIVED submission failed. The macro language now lives in a macro
  definition, errflag and errmsg are declared global, and the file calls it.
- the cycle check aborts after leaving its loop, and the self, undeclared and
  field aborts are driven by a count at the point of call rather than by a
  wrapping %if, so an abort cannot be outlived. The same shapes are fixed
  upstream in sasjs/core#468.
- a case-variant duplicate survived mpe_loader, which compares raw values:
  the hook now rejects it after normalisation and names the variable.
- stagedata dropped the derived columns from the output of the security step
  rather than from its input, so a crafted submission could still satisfy an
  RLS clause through a derived column. work.jsdata itself is rewritten now.
- the VAR_FMT validation rule rejected the bare w.d forms that the hook and
  the engine accept.
- the migration carried the same four dangling insert headers as mpe_makedata,
  so the v7.19 migration failed for existing installs.
- the filter fixtures in getdata.test and validatefilter.test had been caught
  by the variable rename: the filter schema column is VARIABLE_NM.
- the TX_FROM/TX_TO definitions agree across the ddl, the migration and
  mpe_makedatamodel.

@sasjs/core bumped to 5.7.1, which carries the where= fix.
2026-10-21 12:54:34 +00:00
dc 7c9ce9a712 feat(derived): optional VAR_LABEL on MPE_DERIVED
Build / Build-and-ng-test (pull_request) Successful in 5m27s
Lighthouse Checks / lighthouse (pull_request) Successful in 20m23s
Build / Build-and-test-development (pull_request) Successful in 31m25s
A configured label replaces the default NAME=expression; when it is missing or
blank the default is used, so existing rows are unaffected.

- MPE_DERIVED gains VAR_LABEL varchar(256), in the ddl, mpe_makedatamodel and
  the v7.19 migration
- mpe_derived uses it, through the same escaping and 256-char truncation as
  the default label
- the hook trims it; the mock mirrors the fallback
- test 1 now sets a label on BAND and asserts it
2026-10-21 08:14:53 +00:00
dc ee5d7c678e refactor(derived): VAR_DEPS instead of VAR_DEPENDENCIES
Build / Build-and-ng-test (pull_request) Successful in 5m25s
Lighthouse Checks / lighthouse (pull_request) Successful in 20m43s
Build / Build-and-test-development (pull_request) Successful in 31m50s
Shorter column name, same meaning: every input the expression uses,
physical columns and derived variables alike.
2026-10-20 18:33:24 +00:00
dc 813bce6856 feat(derived): declare VAR_DEPENDENCIES instead of VAR_ORDER
Build / Build-and-ng-test (pull_request) Successful in 5m49s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m29s
Build / Build-and-test-development (pull_request) Successful in 32m28s
A sequence number has to be maintained by the administrator: inserting a
variable means renumbering everything after it, and a wrong number fails
silently - the derived value comes back missing, not wrong.

VAR_DEPENDENCIES names every input the expression uses, physical columns and
derived variables alike, eg 'REGION STATE'.  The statements are emitted in
dependency order, so a variable can build on another one with no sequence to
maintain, and a cycle is rejected.

The declaration is checked against the expression in both directions: a
derived variable referenced by VAR_LOGIC must be declared, and a declared
name that the expression does not reference is an error; a declared name must
resolve to a column of the target table or to a derived variable of the same
table.

Changes:
- MPE_DERIVED: VAR_ORDER (num) becomes VAR_DEPENDENCIES (varchar(4000)), in
  the ddl, mpe_makedatamodel and the v7.19 migration
- mpe_derived: dependency validation and a topological sort replace the
  VAR_ORDER sort and the forward-reference check
- mpe_derived_postedit: checks self reference, undeclared derived references
  and cycles at submit time, across the incoming rows plus the current rows
  they do not replace
- MPE_VALIDATIONS: the VAR_ORDER MINVAL/MAXVAL rules are replaced by UPCASE
  and a character pattern on VAR_DEPENDENCIES
- mocks: the dependency order is applied in JS, so a chained variable works
  even when the rows are loaded child first
- docs and tests updated
2026-10-20 16:51:08 +00:00
dc 27ddcfb575 fix(derived): raise the VAR_ORDER ceiling to 10000
Build / Build-and-ng-test (pull_request) Successful in 6m7s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m47s
Build / Build-and-test-development (pull_request) Successful in 32m0s
The client side MAXVAL cannot express 'integer', so integrality stays in the
macro and the hook. The ceiling is only there to catch a typo.
2026-10-20 09:07:18 +00:00
dc aa6d50e1ea feat(derived): validation rules and a VAR_TYPE dropdown for MPE_DERIVED
Build / Build-and-ng-test (pull_request) Successful in 5m30s
Build / Build-and-test-development (pull_request) Canceled after 7m45s
Lighthouse Checks / lighthouse (pull_request) Canceled after 19m16s
Client side rules on the table itself, so mistakes show up in the grid:
  - NOTNULL on LIBREF, DSN, VAR_NM, VAR_ORDER, VAR_TYPE, VAR_LEN, VAR_LOGIC
  - UPCASE on LIBREF, DSN, VAR_NM, VAR_TYPE, VAR_FMT
  - MINVAL 1 / MAXVAL 999 on VAR_ORDER, MINVAL 1 / MAXVAL 32767 on VAR_LEN
  - HARDREGEX on VAR_NM, VAR_FMT and VAR_LOGIC
  - HARDSELECT on VAR_TYPE, with C and N in MPE_SELECTBOX

Seeded in mpe_makedata and in the v7.19 migration. The post edit hook stays
the server side enforcement, since these rules are evaluated in the browser.

Also fixes the MPE_DERIVED create in mpe_makedatamodel, which still used the
old VARIABLE_* column names.
2026-10-20 09:01:55 +00:00
dc 0b010f2c65 feat(derived): validate MPE_DERIVED at submit time
Build / Build-and-ng-test (pull_request) Successful in 6m19s
Lighthouse Checks / lighthouse (pull_request) Successful in 22m24s
Build / Build-and-test-development (pull_request) Successful in 32m50s
A post edit hook on MPE_DERIVED applies the configuration rules when a row
is submitted, rather than only when the EDIT screen next builds the view.

It normalises LIBREF, DSN, VAR_NM, VAR_TYPE and VAR_FMT, and rejects:
  - a missing LIBREF, DSN or VAR_NM
  - an invalid or reserved name, or one starting with a digit
  - a VAR_ORDER that is not a positive integer
  - a VAR_TYPE other than C or N
  - a VAR_LEN outside 1-32767 (character) or 1-8 (numeric)
  - a VAR_FMT that is not a plain format name
  - a VAR_LOGIC that is not a single expression
  - the same VAR_NM twice for one table
  - a reference to a derived variable that is not defined earlier

The name collision with a physical column is left to %mpe_derived, which runs
with the target library assigned; the hook does not have it.
2026-10-20 08:20:52 +00:00
dc 52803225df refactor(derived): shorten the MPE_DERIVED column names to VAR_*
Build / Build-and-ng-test (pull_request) Successful in 5m25s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m5s
Build / Build-and-test-development (pull_request) Successful in 32m53s
MPE_DERIVED columns:
  VARIABLE_NM     -> VAR_NM
  VARIABLE_ORDER  -> VAR_ORDER
  VARIABLE_TYPE   -> VAR_TYPE
  VARIABLE_LENGTH -> VAR_LEN
  VARIABLE_FORMAT -> VAR_FMT
  VARIABLE_LOGIC  -> VAR_LOGIC

Updated in the ddl, mpe_makedatamodel, the migration, the MPE_TABLES buskey,
the macro (reads and validation messages), the tests, the mocks and the docs.
2026-10-20 07:57:49 +00:00
dc 33d043ea92 feat(derived): VARIABLE_ORDER, so a derived variable can build on another
Build / Build-and-ng-test (pull_request) Successful in 5m15s
Lighthouse Checks / lighthouse (pull_request) Successful in 20m15s
Build / Build-and-test-development (pull_request) Successful in 31m0s
A derived variable may need to reference one defined before it (a label that
concatenates a derived region, for example), so the order has to be
configured rather than assumed.

- MPE_DERIVED: new VARIABLE_ORDER column (ddl, makedatamodel, migration).
- mpe_derived: statements are generated in VARIABLE_ORDER then name sequence.
  VARIABLE_ORDER is required and must be a positive integer. A reference to a
  derived variable with an equal or higher order is rejected, because SAS
  would otherwise treat it as uninitialised and return a missing value with no
  error; references to lower-order variables are allowed.
- mock: same ordering, each variable compiled against the physical columns
  plus those defined earlier, so the frontend can exercise a chained variable.
- makedata: VARIABLE_ORDER on both demo rows plus a chained REGION_LABEL.
- cypress: asserts the chained value in the grid.
- tests: the getdata test seeds a second variable built on the first.
- docs: VARIABLE_ORDER documented, with the ordered rule replacing the
  self-contained one.
2026-10-20 02:09:37 +00:00
dc b0fd354ecd feat(editor): derived variables in the EDIT screen
Build / Build-and-ng-test (pull_request) Successful in 5m21s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m24s
Build / Build-and-test-development (pull_request) Successful in 31m28s
Adds user-defined computed variables, configured per table in the new
MPE_DERIVED control table. A derived variable is declared with a name,
type, length, optional format and a SAS expression.

The expression is applied in a DATA step view, and the filter is applied
by the step that reads the view, so the variables exist before the
filter is evaluated and can therefore be filtered on. A WHERE clause
cannot see a variable created in the same data step, hence the view.

- getdata: derived columns are added to the COLS payload (read only,
  labelled DERIVED: <expression>) and to the data returned to the grid
- getcolvals: values are taken from the derived view, so filter dropdowns
  work for derived columns
- validatefilter: the filter is validated against the view, and stored
  against the physical table (needs mp_filterstore targetds=)
- stagedata: derived columns are dropped before the approval package
- mpe_makedata / mpe_makedatamodel / ddl / migration: new MPE_DERIVED
  table, registered in MPE_TABLES

Values are display-time only - nothing derived is ever written back.
2026-10-19 22:58:19 +00:00
dc a51d9e5574 fix(makedata): shorten the DC_MAXCELLS_WEBEDIT description to fit var_desc
Lighthouse Checks / lighthouse (pull_request) Successful in 20m46s
Build / Build-and-ng-test (pull_request) Successful in 5m23s
Build / Build-and-test-development (pull_request) Successful in 30m13s
MPE_CONFIG.VAR_DESC is varchar(300), but the description written for
DC_MAXCELLS_WEBEDIT is 336 characters, so the insert truncates it.  The
truncation raises a WARNING, which sets SYSCC, and makedata aborts on
`&syscc ne 0` immediately after %mpe_makedata():

    WARNING: Character expression will be truncated when assigned to
      character column var_desc.
    ERROR: Execution terminated by an ABORT CANCEL statement

The abort happens before the settings job is written, so a fresh deploy
ends with no control library and no settings.sas at all.  It goes
unnoticed because the SAS test suite reuses whatever library is already
on the estate - the first time it bites is a deploy from scratch.

The description is shortened to 201 characters in both places it is
written - mpe_makedata (new installs) and the 20261003 row/cell limits
migration (existing installs).  The rationale it carried is user-visible
help text, so it moves to a SAS comment above each insert rather than
being dropped.

Verified on a real Viya estate, deploying from scratch:
  - before: makedata aborted, "Err during VIYA1337 build", no settings.sas
  - after:  makedata completed with zero warnings, and the SAS test suite
            then ran 59/59 green
2026-10-19 12:22:13 +00:00
dc 90af6b8515 fix(sas): run the row/cell limit migration as a Viya job
Build / Build-and-ng-test (pull_request) Successful in 6m26s
Lighthouse Checks / lighthouse (pull_request) Successful in 23m33s
Build / Build-and-test-development (pull_request) Successful in 32m38s
Each of the three blocks ended with a single-statement %else %put, which the
Viya compute engine rejects in open code (outside a %macro) with
'Expected %DO not found' - so the migration aborted whenever it was run as a
job. Both branches now use %do/%end. Verified by executing the script as a
real Viya job: all three options updated and inserted, no errors.
2026-10-05 12:25:50 +00:00
dc f08c4c231f fix(editor): check the EDIT limits once, and skip switched-off options
Build / Build-and-ng-test (pull_request) Successful in 5m35s
Lighthouse Checks / lighthouse (pull_request) Successful in 22m41s
Build / Build-and-test-development (pull_request) Successful in 30m42s
Review follow-ups on the row/cell limits:

- getdata.sas checked the limits twice - once before the sort that caps
  work.out, and again after PRE_EDIT_HOOK.  It is now a single check,
  after both, so the counts cover everything that could reach the
  browser: the rows the selection matched, plus anything a hook has
  added.  The payload cap moves to where work.outdata is built, which is
  the only place that needs it.  Each mp_abort also names its option once
  - the limit was repeated in the message text as well as the condition.

- The migration closed only var_active=1 rows but inserted active rows
  unconditionally, so an option a site had switched off was silently
  switched back on.  It now leaves those alone and logs a note.

- row-cell-limits.cy.ts test 1 matched a regex against the grid's text,
  which the fixture's own columns satisfy (DEPTH_M reaches 4293,
  SAMPLE_COUNT 4210), so it did not pin the raised VIEW cap.  It now
  reads the PK column - the first td of a .ht_master row - and requires
  values in the PK range 1001-2000 with a maximum above 1500, which the
  old 500 row cap could never render.
2026-10-03 18:00:46 +00:00
dc 3de6655f26 feat(editor): raise the row limits and add a cell limit to the EDIT screen
Build / Build-and-ng-test (pull_request) Successful in 5m22s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m58s
Build / Build-and-test-development (pull_request) Successful in 30m41s
VIEW default 500 -> 2000. EDIT default 100 -> 250, plus a new
DC_MAXCELLS_WEBEDIT (200000) so a wide selection is refused on cells as
well as rows, whichever is reached first. Measured end-to-end: 2000 rows
of a 9 column table is ~1s in VIEW / ~6s in EDIT, but 100 rows of a 1001
column table is already ~17s in EDIT - a row cap cannot bound that.

The EDIT guard also moves: it now checks the filtered row count before
the sort that caps work.out, and again after PRE_EDIT_HOOK, which can
replace work.out with a larger table.
2026-10-03 13:15:58 +00:00
4gl 9cd976495b chore(tidy up): remove trailing space and deprecated logic
Build / Build-and-ng-test (pull_request) Successful in 5m2s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m22s
Build / Build-and-test-development (pull_request) Successful in 24m50s
2026-08-12 21:39:28 +01:00
4gl c07a01a38d fix: adding formula types
Build / Build-and-test-development (pull_request) Canceled after 0s
Build / Build-and-ng-test (pull_request) Canceled after 2m17s
Lighthouse Checks / lighthouse (pull_request) Canceled after 4s
2026-08-07 09:54:09 +01:00
4gl 62ff0aee4a feat: using ALL libraries as validation in MPE_SECURITY. Closes #279
Build / Build-and-ng-test (pull_request) Successful in 5m20s
Build / Build-and-test-development (pull_request) Successful in 15m19s
Lighthouse Checks / lighthouse (pull_request) Successful in 21m50s
2026-07-21 18:08:42 +01:00
4gl d2c93a46fa feat(regex): backend validations on regex strings
Build / Build-and-ng-test (pull_request) Successful in 5m36s
Build / Build-and-test-development (pull_request) Successful in 15m57s
Lighthouse Checks / lighthouse (pull_request) Successful in 22m28s
2026-07-20 20:52:38 +01:00
allan 1fb5e8eb37 chore: fixing header
Lighthouse Checks / lighthouse (pull_request) Has been cancelled
Build / Build-and-ng-test (pull_request) Successful in 4m3s
Build / Build-and-test-development (pull_request) Successful in 10m31s
2026-07-10 12:53:08 +01:00
allan ba7b61082d feat: adding DC_MAXOBS_WEBVIEW config item, closes #258
Build / Build-and-ng-test (pull_request) Successful in 4m1s
Build / Build-and-test-development (pull_request) Has been cancelled
Lighthouse Checks / lighthouse (pull_request) Successful in 18m17s
2026-07-10 12:45:09 +01:00
allan adc6424211 fix: rule_type
Build / Build-and-ng-test (pull_request) Successful in 4m1s
Lighthouse Checks / lighthouse (pull_request) Successful in 18m26s
Build / Build-and-test-development (pull_request) Successful in 9m48s
2026-06-25 17:48:52 +01:00
allan 74442096ba fix: incrementing rk val
Build / Build-and-ng-test (pull_request) Successful in 4m6s
Lighthouse Checks / lighthouse (pull_request) Successful in 17m52s
Build / Build-and-test-development (pull_request) Successful in 10m11s
2026-06-25 17:47:22 +01:00
allan 9f84a580fb feat: migration script for adding new validation rules under #241
Build / Build-and-ng-test (pull_request) Successful in 4m5s
Lighthouse Checks / lighthouse (pull_request) Successful in 18m31s
Build / Build-and-test-development (pull_request) Successful in 10m2s
2026-06-25 17:46:16 +01:00
allan 2ccf0d1100 feat: configurable email alerts. Closes #217
Build / Build-and-ng-test (pull_request) Successful in 4m42s
Build / Build-and-test-development (pull_request) Has been cancelled
Lighthouse Checks / lighthouse (pull_request) Has been cancelled
2026-04-03 18:34:23 +01:00
allan e44a25dcc3 fix: showing catalog_cnt in libinfo
Build / Build-and-ng-test (pull_request) Successful in 4m19s
Build / Build-and-test-development (pull_request) Successful in 8m53s
Closes #160
2025-06-11 10:06:52 +01:00
allan efb5ffa906 chore: reverting accidental change
Build / Build-and-ng-test (pull_request) Successful in 4m4s
Build / Build-and-test-development (pull_request) Successful in 8m33s
2025-06-10 22:45:39 +01:00
allan b4c586a859 feat: capturing catalog specific information, closes #159
Build / Build-and-ng-test (pull_request) Successful in 4m12s
Build / Build-and-test-development (pull_request) Successful in 8m35s
BREAKING CHANGE:  Introduction of 4 new tables for capturing information related to catalogs and their objects.  Migration script prepared and available in the DB folder (usual place)
2025-06-10 22:40:09 +01:00
allan e4dbab8b16 feat: adding 4 new tables for catalogs 2025-06-10 16:18:30 +01:00
^ 93758efb27 fix: dc_request_logs option feature
Build / Build-and-ng-test (pull_request) Successful in 4m3s
see: https://docs.datacontroller.io/dcc-options/#dc_request_logs
2024-05-02 23:09:14 +01:00
zmaj eac0104d7a fix: ensuring submitter email can be pulled from mpe_emails
Release / Build-production-and-ng-test (push) Successful in 4m46s
Release / Build-and-test-development (push) Successful in 8m34s
Release / release (push) Successful in 6m51s
2024-02-02 11:20:43 +00:00
zmaj c86fba9dc7 feat: adding ability to define the target table for excel maps
Build / Build-and-ng-test (pull_request) Failing after 13s
2024-01-11 18:11:22 +00:00
zver 3e009f3037 chore: adding migration for new tables
Build / Build-and-ng-test (pull_request) Failing after 13s
2024-01-03 12:12:38 +00:00
zver 2d4d068413 fix: increasing length of mpe_excel_map cols to
Build / Build-and-ng-test (pull_request) Failing after 14s
2024-01-01 12:23:07 +00:00
zver 271543a446 feat: model changes for #69
Build / Build-and-ng-test (pull_request) Successful in 47s
2023-12-27 16:57:48 +01:00
Mihajlo Medjedovic f268de21a3 init
Test / Build-and-test-development (push) Failing after 6m14s
Test / Build-and-test-development-latest-adapter (push) Failing after 6m13s
2023-07-13 13:44:05 +02:00