Commit Graph
143 Commits
Author SHA1 Message Date
blog-dev 838bc7a96f feed: correct the Excel retention wording and mention rollback 2026-09-26 20:10:08 +00:00
blog-dev 53c0de0960 feed: add a placeholder cover for the who-is-it-for post 2026-09-26 19:53:21 +00:00
blog-dev 549ecc36aa feed: add a who-is-it-for post for Data Controller 2026-09-26 19:41:36 +00:00
allan 463de81ffa Merge pull request 'blog: document the concurrency caveat of two librefs over one table' (#21) from blog/concurrency-caveat into main
publish / Build-and-publish (push) Successful in 3m55s
Reviewed-on: #21
2026-09-24 17:22:47 +00:00
dc 79d2e887d3 blog: document the concurrency caveat of two librefs over one table
mp_lockanytable keys its control table on (lock_lib, lock_ds), and the
approve service takes that lock on the base table named in the submit
record. The MPE_DATALOADS staleness check is keyed the same way. So two
registrations of one physical file neither lock nor observe each other,
and a second approval can overwrite the first silently.

Spell that out, note that the hook route routes both mirrors to one base
table and so does not have the gap, and give the two ways to close it.
2026-09-24 17:09:34 +00:00
allan 1119645a00 Merge pull request 'blog: add a post on running two rule sets against one table' (#20) from feed/two-rule-sets-one-table into main
publish / Build-and-publish (push) Successful in 4m19s
Reviewed-on: #20
2026-09-24 16:37:16 +00:00
dc a1513b871e blog: add a post on running two rule sets against one table
Capture all four screenshots against a licensed instance, so the
free-tier licence banner is no longer in frame.
2026-09-24 16:34:29 +00:00
allan 59ff2b13fc Merge pull request 'feed: add a special missings post' (#19) from blog/special-missings-education into main
publish / Build-and-publish (push) Successful in 4m13s
Reviewed-on: #19
2026-09-23 22:42:31 +00:00
dc 7d950cbdbe feed: copy-edit the special missings post
The LinkedIn opener did not parse - "A SAS numeric missing is not a lone wolf.
It is 28." - and reading the rest of the post and its LinkedIn version together
turned up a further set of style defects:

- the article opener made the missing value the wolf, and padded the count
- "All numeric values means numeric; all strings means character" was clumsy
- procedure and function names were lowercase in places (proc means, cats,
  options MISSING), and "and friends" was too casual for a list of procedures
- "gotcha" and "harmless" undersold the points they introduced
- "One thing worth knowing" opened two separate paragraphs
- "a value ... and as a value with its own place" repeated itself, in both the
  article and the LinkedIn version
- the adapter bullet list mixed trailing periods with none
- the LinkedIn list was split in two by a stray blank line, and "a physical
  constraint" did not say which constraint
- "the most common of them" echoed the "28 of them" in the line above

No claims changed - the range-rule behaviour, the period, the primary key and
the strict dropdown all read as they did.
2026-09-23 22:41:12 +00:00
dc 66d5fecb0e feed: embed the special missings recording, and correct the copy
Embeds the "Special Missings in Data Controller" recording from vid.4gl.io as a
responsive PeerTube iframe, in place of the older YouTube embed, and drops the
stray `video: [...]` line that was sitting in the body as literal text.

Copy corrections, each verified against the running app rather than the source:

- the range rules compare in SAS's order, so MINVAL .A with MAXVAL .C takes .B
  and refuses .D, a missing fails a numeric MINVAL and passes a numeric MAXVAL,
  and a number sits above every missing. The old wording said the range rules
  step aside for a missing value
- a lone "." is another way of typing the regular missing; the previous claim
  that a literal "." is refused in favour of null is not what happens
- a strict dropdown does accept a special missing when its list holds one (the
  list shows it as a bare letter), and still rejects a value that is not listed
- NOTNULL rejects a special missing, and a primary key column is NOT NULL
  whether or not a rule is configured for it

The LinkedIn version of the post is kept in sync, and carries the new video URL.
2026-09-23 22:00:16 +00:00
dc 0b18658686 fix(blog): the range rules compare in SAS's own order
A range rule keys both sides into the order SAS uses for a numeric variable, so a
range written in special missings means what SAS would mean by it: MINVAL .A with
MAXVAL .C accepts .B and rejects .D, a blank fails a floor of .A, and a number
sits above every missing - passing a floor of .A and failing a ceiling of .C.
Against a numeric bound the same order gives the obvious answer: a missing fails
MINVAL 1 and passes MAXVAL 100.

Replaces the "the range rules step aside for a missing value" wording.
2026-09-23 21:27:58 +00:00
dc bbd5793d8b fix(blog): the period is optional, and a range rule ignores a missing
Three corrections to the special missings post:

- a special missing is typed with or without its leading period - `.a` and `a`
  are the same missing
- MINVAL and MAXVAL both accept a special missing, and both still reject a real
  number that is out of range. A minimum constrains a number, and a missing is
  not a number; NOTNULL is the rule for a column that must be populated
- the formula rules are the one case where a special missing genuinely does not
  work, so the range rules are no longer grouped with them
2026-09-23 21:01:16 +00:00
dc 0bda92b091 blog: note the one cell that cannot take a special missing 2026-09-23 15:38:37 +00:00
dc bf9fca1b9a blog: the dropdowns support special missings, simply 2026-09-23 08:37:07 +00:00
dc d542ac442f blog: NOTNULL simply works the same as SAS (no special missings)
Also reflects the HARDSELECT fix: a strict dropdown now accepts a special
missing when the list contains it.
2026-09-23 08:19:34 +00:00
dc 0ee0b4ea7c blog: NOTNULL now rejects special missings; range rules and formulas do not support them
The validator fix lands in dc/dc (PR #323), so the post describes the fixed
behaviour rather than the mismatch: a special missing fails NOTNULL, matching
a physical SAS NOT NULL / primary key constraint.

Also records what ROUND and SOFTSELECT/HARDSELECT do with one, and groups
MINVAL/MAXVAL/HARDFORMULA/SOFTFORMULA under 'not supported'.
2026-09-23 07:48:44 +00:00
dc 2fe1bc2eea blog: add formula, range-value and NOTNULL-constraint caveats to the special missings post
Verified on a real SAS estate:
- a physical NOT NULL (or primary key) constraint rejects a special missing,
  and getdata merges that constraint into a frontend NOTNULL rule - which
  passes a special missing, so the editor is more lenient than the constraint
- a special missing as a MINVAL rule value fails every cell; as a MAXVAL rule
  value it fails every real number
- a HARDFORMULA/SOFTFORMULA reading a special-missing cell returns #VALUE!
- PRX and the JS engine agree on the value; SAS pads the numeric-to-character
  conversion, so an anchored pattern re-used in SAS needs strip()
2026-09-23 07:29:04 +00:00
dc 3e39339332 blog: scope the validation section to Data Controller rules and note the MISSING= gotcha
- heading + intro now say these are Data Controller's MPE_VALIDATIONS rules,
  applied in the browser
- new paragraph on options MISSING: a regular missing prints as . unless the
  option changes it (eg to blank); special missings are never affected
- CASE split out of the rule list: it is a character rule, and a special
  missing always reaches the browser as an uppercase letter
- HARDREGEX and SOFTREGEX separated (SOFTREGEX warns rather than blocks, and
  is ignored when the column also has a HARDREGEX)
- LinkedIn copy kept in sync

Behaviour confirmed against the deployed services on a real Viya estate.
2026-09-23 07:17:46 +00:00
dc 6d554930be docs(feed): add the cover image to the special missings post
Cover art for "28 Ways to Be Missing in SAS": a pack of wolves on a snow plain
at dusk with one animal standing apart, carrying the post's opening line - a
numeric missing is not a lone wolf, there are 28 of them.

Source image was 4:3, so it is cropped to 1.91:1 (1200x627) to match the other
feed covers and double as the LinkedIn share card. The crop was chosen to keep
both the lone wolf on the left and the full pack on the right in frame, losing
only sky above the clouds and foreground snow.

Sets previewImg in the front matter; the template renders it, so it is not
embedded in the body as well. Verified through gatsby build - the image
pipeline emits 300/600/1200-wide variants.
2026-09-22 21:36:39 +00:00
dc a56c2f8d48 docs(feed): record the final cover image prompt on the special missings post
Replaces the placeholder one-liner with the prompt actually intended for the
cover: the pack of wolves on a snow plain at dusk with one animal standing
apart, plus the negative constraints, the output spec (./cover.jpeg at
1200x627, previewImg in front matter) and a fallback single-subject variant.

Two deliberate choices are recorded so they are not lost on a regenerate:

- No text, letters or numbers anywhere in the image. The subject is letters
  standing in for numbers, so a stray glyph undercuts the cover.
- No exact head count of 28. Generators cannot count, and a crowded pack reads
  worse than a dozen clear animals; the number belongs in the headline.

Links to the full prompt and variants on paste.4gl.io.
2026-09-22 21:17:41 +00:00
dc 27ff40b739 blog: correct the video label on the v4.0 special missings post
The special missings video was labelled "Retain Formulas when Loading Excel
to SAS", which is a different video. Restores the one-line correction that
was in the earlier revision of this branch, kept separate from the feed post.
2026-09-22 18:10:28 +00:00
dc 4937edd7f4 feed: add a special missings post, and revert the blog edits
The special missings material that was added to the v4.0 blog post belongs in
its own post: that article is a release announcement for v4.0, not a teaching
piece. This reverts the blog change and publishes the content under /feed/.

The new post covers what SAS special missings are, how the SASjs Adapter
carries them between the browser and SAS, and how Data Controller's validation
rules treat them - NOTNULL passes, MINVAL fails, MAXVAL passes, and the regex
rules apply as they would to any other value.

The LinkedIn version of the copy, and the image prompt for the cover, are
recorded in a comment at the foot of the file.
2026-09-22 17:53:55 +00:00
allan fcba390804 Merge pull request 'feed: render poem fenced blocks as verse, not code' (#18) from feat/poem-format into main
publish / Build-and-publish (push) Successful in 4m13s
Reviewed-on: #18
2026-09-20 19:25:54 +00:00
allan 8b6e3e60bc Merge pull request 'feed: add the carousel assets (PDF + slides) to the poem post folder' (#17) from feat/if-ode-carousel into main
publish / Build-and-publish (push) Successful in 4m3s
Reviewed-on: #17
Reviewed-by: Allan <allan@4gl.io>
2026-09-20 19:25:17 +00:00
blog-dev d244a34fc9 feed: render poem fenced blocks as verse, not code 2026-09-20 19:18:11 +00:00
blog-dev 686a745f0b feed: break the carousel stanza slides between the two quatrains 2026-09-20 19:09:38 +00:00
blog-dev 510947d173 feed: add the LinkedIn carousel (PDF + slides) to the post folder 2026-09-20 18:55:18 +00:00
allan 589a745c5b Merge pull request 'Update content/feed/if-an-ode-to-data-control/index.md' (#16) from allan-patch-1 into main
publish / Build-and-publish (push) Successful in 3m53s
Reviewed-on: #16
2026-09-20 17:39:19 +00:00
allan d04c55c731 Update content/feed/if-an-ode-to-data-control/index.md 2026-09-20 17:39:07 +00:00
allan a6a6abf009 Merge pull request 'feat(feed): If - An Ode to Data Control' (#15) from feat/if-ode-to-data-control into main
publish / Build-and-publish (push) Successful in 4m0s
Reviewed-on: #15
Reviewed-by: Allan <allan@4gl.io>
2026-09-20 17:31:40 +00:00
blog-dev 88368fa31d feed: trim the boast and the repeated first-line echo from the intro 2026-09-20 17:21:19 +00:00
blog-dev fdb1db216d feed: rework the poem cover into a title-page design; note the 2022 publication year 2026-09-20 16:37:23 +00:00
blog-dev 6d833f9654 feat(feed): If - An Ode to Data Control 2026-09-20 15:54:56 +00:00
allan 6bcd0adf81 Merge pull request 'feed: correct the case sensitivity example in the full table search post' (#14) from fix/full-table-search-case-sensitivity into main
publish / Build-and-publish (push) Successful in 3m58s
Reviewed-on: #14
Reviewed-by: Allan <allan@4gl.io>
2026-09-17 07:47:31 +00:00
blog-dev 93348ad604 feed: tighten the case sensitivity note to a single sentence 2026-09-17 07:44:53 +00:00
dc 7561bb0c39 feed: correct the case sensitivity example in the full table search post
The post claimed `smith` finds `Smithson`, which only holds for a case
insensitive match. The comparison is case sensitive, so the search term has
to match the case as stored: `Smith` finds `Smithson`, and `smith` finds
`Goldsmith`, but `smith` will not find `Smithson`.
2026-09-16 23:42:45 +00:00
allan 959a9ffab4 Merge pull request 'Feed post: Full Table Search' (#13) from feat/full-table-search into main
publish / Build-and-publish (push) Successful in 4m34s
Reviewed-on: #13
Reviewed-by: Allan <allan@4gl.io>
2026-09-16 23:22:22 +00:00
blog-dev 2348575737 feed: full table search - new demo video, copy matches the recording
- embed the re-recorded 16:9 demo video (search walkthrough, 39s)
- drop the one million row CAS claim from the description, the body and the
  social copy: the recording demonstrates a table in the Viewer, so the
  text now says only what the video shows
2026-09-16 23:17:43 +00:00
blog-dev b2aac21b90 feed: full table search - any value, any column, no query 2026-09-15 17:19:07 +00:00
allan 438b1e93d7 Merge pull request 'Move Cyber Essentials badge to who-is section + about page' (#12) from fix/cert-badge-placement into main
publish / Build-and-publish (push) Successful in 3m56s
Reviewed-on: #12
2026-09-11 20:27:09 +00:00
blog-dev 674737f840 fix: move Cyber Essentials badge to who-is section + about page, drop hero/footer placements 2026-09-11 20:22:29 +00:00
hermes 150be89246 Merge pull request 'Surface Cyber Essentials certification on homepage hero and footer' (#11) from feat/cyber-essentials-badge into main
publish / Build-and-publish (push) Successful in 3m57s
2026-09-11 19:45:26 +00:00
blog-dev b6fea27963 feat: surface Cyber Essentials certification on homepage hero and footer 2026-09-11 19:45:06 +00:00
blog-dev aa1f015f5a docs(blog): punchier LinkedIn draft for non-DC users - pain-first, no jargon
publish / Build-and-publish (push) Successful in 6m39s
2026-09-04 09:29:20 +00:00
blog-dev 79b62e4cfc docs(blog): add source LinkedIn post comment for the v7.13 article
publish / Build-and-publish (push) Successful in 6m33s
2026-09-04 08:06:46 +00:00
blog-dev 73d4796638 fix(blog): show sasdemo instead of root user in audit demo screenshot
publish / Build-and-publish (push) Successful in 6m36s
2026-09-04 07:51:32 +00:00
blog-dev 7267af58c4 ci: drop npm cache from setup-node - save/restore costs exceed the benefit at this repo size
publish / Build-and-publish (push) Successful in 7m0s
2026-09-04 07:23:58 +00:00
blog-dev e5dfcd84da feat(blog): add audit-column demo image showing the IF formula resolving live
publish / Build-and-publish (push) Successful in 13m17s
2026-09-04 01:28:42 +00:00
blog-dev 02295334b3 fix(blog): restore hardening and polishing phrasing in v7.13 post
publish / Build-and-publish (push) Successful in 13m11s
2026-09-04 01:09:48 +00:00
blog-dev e7a538ed9a feat(blog): link getdata and postedit hook to code.datacontroller.io
publish / Build-and-publish (push) Successful in 15m42s
2026-09-04 00:53:20 +00:00