--- name: dc-sas description: > Use this skill alongside the sasjs/skills collection (sas, sasjs-core, sasjs-cli) when working on Data Controller SAS code. Covers the repo-specific SAS knowledge that is NOT in those skills — DC test-state conventions (MPE control tables, dctest, %let syscc) and the chunked-deploy strategy for the huge generated build script (sasjsbuild/viya.sas). For general SAS language, @sasjs/core macro, and @sasjs/cli guidance, rely on the sas, sasjs-core and sasjs-cli skills. --- # SAS Development in Data Controller The sas, sasjs-core and sasjs-cli skills cover general SAS language and SASjs conventions (macro quoting, `%mp_assert*` testing style, `sasjs lint`, `sasjs run`, `sasjsbuild/` being generated output). These notes only cover the parts specific to Data Controller. ## Tests must be idempotent A test file must pass when run repeatedly (including after a run that failed partway). - Clean up **all** persistent DC state, not just the obvious one: `MPE_TABLES` registrations, `MPE_LOCKANYTABLE` lock records (a run dying between LOCK and UNLOCK leaves a stale `LOCKED` row), physical tables in `dctest` (`proc datasets ... delete`), and global macro variables created via `select ... into:` (`%symdel`). ## Chunked deploy to Viya The full DC build script (`sasjsbuild/viya.sas`) is very large (11+ MB / 300k+ lines). The Viya compute API can hang or fail when submitting a file this size in a single request. **Chunked deploy.** Split the build script at `%let path=` boundaries — these are clean section breaks between service/test folders (always preceded by blank lines, never inside a data step). Each sub-chunk must be prepended with the shared header (the first ~3827 lines containing macro definitions, `appLoc` setup, and logging options: `options ps=max nonotes nosgen nomprint nomlogic nosource2 nosource noquotelenmax;` Logging is already suppressed in the header — no extra action needed. Keep each chunk under ~1.5 MB. The `tests/macros`, `tests/services`, and streaming-app tail sections are the largest and may need further sub-splitting at `%let service=` boundaries. When splitting mid-folder (between services in the same folder), the sub-chunk that starts mid-folder must re-assert `%let path=;` before its first `%let service=` line — otherwise `&path` is unresolved and the `%mv_createwebservice(path=&appLoc/&path, ...)` call will abort with a recursive reference error. Deploy each chunk in order with `sasjs run .sas -t `. After all chunks are deployed, run `sasjs request services/admin/makedata -d deploy/makeDataViya.json -t ` to create the database. **Non-fatal errors.** `ERROR: Unauthorized` on `/dataSources/providers/Compute/` lines in the log are expected for non-admin Viya users — they come from the Data Sources API during lineage/catalog refresh and do not affect the deploy. ## Repo conventions for .sas files - Test files are named `.test.sas` (or `.test.N.sas`) and run via `npm run 4gl && sasjs test -t 4gl` from `sas/` — see `.agents/docs/testing.md`. - `sas/sasjsbuild/` is generated build output — never hand-edit it; edit sources under `sas/sasjs/` only. ## Temp and scratch files stay out of the repo Transient artifacts from manual test runs against sasjs-server — captured `_webout` JSON responses (e.g. `*_out.json`), request/response logs (e.g. `*.log`), and iteration snapshots (`vd_out2.json`, `stage_check2.json`, etc.) — must not be left in the working tree. They clutter `git status`, are never referenced by source or tests, and easily leak local filesystem paths (the sasjs-server session dir, `/home/.../sasjs_root/sessions/.../`) into committed history. Write them to a gitignored tmp location instead. The repo already provides two: - `tmp/` (gitignored at repo root) — general scratch space. - `sas/tmp/` (gitignored via the root `tmp/` rule) — for SAS-side artifacts. If a helper script dumps captured output for comparison during a debug session, point it at `tmp/` (or `sas/tmp/` for SAS-local paths) rather than alongside the tracked mocks in `sas/mocks/`. The tracked mock fixtures live under `sas/mocks/sas9/` and `sas/mocks/sasjs/services/`; loose `*_out.json` / `*.log` files at the `sas/mocks/` root are not mocks, they are leftover captures — remove them with `git clean -fd sas/mocks/` or write to `tmp/` in the first place.