feat(rules): portable API schemas and private declarations - #17
Merged
Merged
Conversation
- react-component-architecture/component-folder-structure: a .tsx file that exports nothing is an internal helper of the component beside it and owes no siblings of its own. - audit-log/mutating-service-must-audit: only the public surface is checked; module-private functions and private/protected/#name methods are body of the audited method. includePrivate restores the old scan. - drizzle-conventions/no-raw-sql-outside-allowlist: templates whose text is only arithmetic around column references (the atomic increment) are allowed; allowColumnArithmetic: false disables it. Each ships with rule-tester cases, docs and a changeset.
agjs
added a commit
to boringstack-xyz/boringstack
that referenced
this pull request
Sep 14, 2026
…itself - Session in lib: useMe, IMe, isAuthenticatedMe and SESSION_QUERY_KEYS move to src/lib/session so every feature reads the current user without a cross-feature exception; auth consumes them too, the allow-list keeps only accounts -> auth for the MFA settings section. Reference UI templates follow. - Cache generations: bumpGeneration / readGeneration / generationScopedKey give seeds, publishes and migrations a way to drop a namespace at once; regression proves old keys become unreachable. - Guides: relational row typing and numeric/bigint strings (drizzle), portable API schemas (typescript, api-client), cache namespaces, grouped store selectors, session module (state-management, routing). - Dead-key lint message says which template literals it can follow. - Ledger rows 23, 24, 26, 36, 37, 38, 51, 63, 78, 80 record the fix or the upstream rule (boringstack-xyz/eslint-plugins#17).
Closed
agjs
added a commit
to boringstack-xyz/boringstack
that referenced
this pull request
Sep 14, 2026
* fix: address product setup and agent validation feedback * fix(agent): copy UI dependency patches into the isolated candidate image The isolated evaluation image installs apps/ui from package.json and bun.lock alone. With patchedDependencies present, a frozen install aborts on the missing patch file, which failed the agent verification contract job. Copy the patches directory before installing and assert in a unit test that every patched dependency is copied ahead of the install step. * fix(ui): keep the ESLint cache and invalidate it on dictionary changes Removing --cache made every lint run cold. ESLint keys its result cache on a hash of each file's resolved config, so the config now carries a sha256 digest of every English dictionary in settings; editing a dictionary changes the hash and re-lints every file. A regression runs ESLint twice with --cache against a shrinking dictionary and shows the deleted key is reported with the digest and hidden without it. * fix(ui): drop an unused import and format the ESLint config The cache regression built its digest inside a generated config string, so the createHash import in the test itself was unused; the config edit also missed a Prettier pass. * fix(ui): take the plural-aware i18n lint rule from the released plugin @boring-stack-pkg/eslint-plugin-i18n-keys 0.1.3 resolves i18next count, ordinal and context suffixes upstream (boringstack-xyz/eslint-plugins#10), so the Bun patch of the published dist, its patchedDependencies entry and the COPY patches lines in the three Dockerfiles go away. The installed plugin regression in tests/lint-meta keeps guarding the behaviour. * chore(lint): take three rule fixes from the released plugins react-component-architecture 0.3.1 exempts .tsx files that export nothing from component-folder-structure; audit-log 0.2.0 checks a service's public surface only; drizzle-conventions 0.2.0 accepts column arithmetic such as the atomic increment. Guides describe the accepted shapes and the feedback ledger closes rows 40, 65 and 82 as implemented upstream (boringstack-xyz/eslint-plugins#15). * feat: close the remaining product-feedback rows the template can fix itself - Session in lib: useMe, IMe, isAuthenticatedMe and SESSION_QUERY_KEYS move to src/lib/session so every feature reads the current user without a cross-feature exception; auth consumes them too, the allow-list keeps only accounts -> auth for the MFA settings section. Reference UI templates follow. - Cache generations: bumpGeneration / readGeneration / generationScopedKey give seeds, publishes and migrations a way to drop a namespace at once; regression proves old keys become unreachable. - Guides: relational row typing and numeric/bigint strings (drizzle), portable API schemas (typescript, api-client), cache namespaces, grouped store selectors, session module (state-management, routing). - Dead-key lint message says which template literals it can follow. - Ledger rows 23, 24, 26, 36, 37, 38, 51, 63, 78, 80 record the fix or the upstream rule (boringstack-xyz/eslint-plugins#17). * fix(agent): reference UI needs no auth allow-list entry; Docker errors carry a redacted stderr tail The reference UI generator patched the cross-feature allow-list at the ["dashboard", "auth"] anchor to add projects -> auth; with useMe in @/lib/session the entry is unnecessary and the anchor is gone, which failed the isolated positive control. The isolated Docker helper now appends the last 600 characters of stderr with every argument value redacted, so the next failure of this kind is readable in CI. * chore(lint): enable portable schema types and private declarations from the released plugins elysia 0.2.0 adds portable-schema-types, on for every *.schemas.ts; module-boundaries 0.2.0 adds ignorePrivateDeclarations, on for the UI so private helpers and constants stay next to the hook or component that reads them. Ledger rows 21, 35 and 51 close as implemented upstream.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Findings 21, 24, 35, 37, 38 and 51 from the Tinkercaster build (boringstack-xyz/boringstack#455 ledger) fixed at the rule level.
elysia/portable-schema-types(new, minor). The API's TypeBox schemas are published as OpenAPI and turned into the UI client's types, and three Elysia shapes validate fine but come out wrong on the other side. Reproduced against Elysia 1.4 +@elysiajs/swagger1.3:t.Integer()anyOf [{type:"string",format:"integer"},{type:"integer"}], client typesstring | numberType.Integer()from@sinclair/typeboxt.Tuple([...])items: [...], client widens toT[]t.Array()or a namedt.Object()t.Union(values.map(...))undefinedt.UnionEnum([...values])Scoped to
**/*.schemas.tsby default (optionfileGlob), so env parsing, which wants the coercion, is untouched. Added to the recommended config.module-boundaries/single-semantic-modulegainsignorePrivateDeclarations(default false, minor). When on, only exported declarations are classified: a non-exported config object, render helper or private class next to the hook or component that uses it does not give the module a second category. Two exported categories still conflict, and an exported constant is still a constant.Test plan
pnpm -r build && pnpm -r test: elysia 127 tests (new rule: 4 valid, 4 invalid, plus plugin-shape and recommended-config coverage), module-boundaries 62 tests (option on/off, exported constant still reported, two exported categories still reported). Docs and changesets for both.