refactor(ts-migration): Phase 11 batch 2 — the skills-layer leaves
The eight modules under `src/lib/skills/` that import nothing from their
own layer, plus `uiConfig`, which imports only `surfaces`. Renamed and
annotated; no logic touched.
All eight emit byte-identical minified JavaScript, and the production
bundle still hashes to `74d17e2d…`. Four of them are R100 — not one
character changed beyond the extension.
The annotations are four fixes of the same two kinds:
- `Object.entries<any>` / `Object.values<any>` at three sites. Passing
an `any` value to either yields `unknown`, not `any`, because
inference into the union parameter of their signatures does not
distribute — so `weightsOf`'s entries arrived unsortable and two
`reduce` accumulators arrived un-addable. The explicit type argument
restores what JavaScript had. No cast, no runtime change.
- `FlowReply` as `assignmentPreview`'s return type. Two of its five
branches genuinely return no `followUp` — "already fully staffed"
and "nobody is both qualified and free" are answers with nothing to
offer next — so `followUp` is optional, which is what `headcountSet`
has always passed through.
One inert `/** @param {any} */` in `saveFeedback` became a real
annotation. Left as a comment it would have read as if it still did
something.
Measured against `eaa677f`, all unchanged:
typecheck 20 errors, same files
lint exit 0, 0 errors, 289 warnings
npm test 1684/1691, the same 7 failures verbatim
build exit 0, identical bundle hash
emitted JS 8/8 byte-identical
One number moved and it is a reporting artifact, recorded here so it is
not misread next time: ESLint's file count went 269 -> 261. `src/lib/**`
is in `ignores` for both config blocks and always has been, so no rule
has ever run on these files. A `.js` file there is still walked by
ESLint's default `**/*.js` glob and then ignored, which produces an entry
with zero messages; a `.ts` file matches no `files` pattern, so it is
never walked and produces no entry at all. Confirmed directly: linting
`registry.js` reports nothing, linting `yaml.ts` reports "File ignored
because no matching configuration was supplied." Zero rules applied
before, zero after. The counts that carry signal — 0 errors, 289
warnings — did not move.
No baseline artifact touched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HBG1wnuRfJKCstGB8Fekr8
This commit is contained in:
@@ -228,7 +228,7 @@ export const noDraftReply = () => doc(
|
||||
/** The weights this position actually carries, never a default dressed as one. */
|
||||
export function weightsOf(position) {
|
||||
const criteria = position?.vetting_criteria || {};
|
||||
const entries = Object.entries(criteria).filter(([, value]) => Number.isFinite(Number(value)));
|
||||
const entries = Object.entries<any>(criteria).filter(([, value]) => Number.isFinite(Number(value)));
|
||||
return {
|
||||
entries,
|
||||
total: entries.reduce((sum, [, value]) => sum + Number(value), 0),
|
||||
@@ -298,7 +298,7 @@ export function weightsFromQuestion(question, position) {
|
||||
}
|
||||
|
||||
export const weightsSetReply = (position, next) => {
|
||||
const total = Object.values(next).reduce((sum, value) => sum + Number(value), 0);
|
||||
const total = Object.values<any>(next).reduce((sum, value) => sum + Number(value), 0);
|
||||
|
||||
return doc(
|
||||
heading('Vetting weights updated', position.title),
|
||||
@@ -16,8 +16,7 @@ import { toast } from '@/components/ds';
|
||||
*/
|
||||
export function reportSave(message) {
|
||||
return {
|
||||
/** @param {any} result */
|
||||
onSuccess: (result) => {
|
||||
onSuccess: (result: any) => {
|
||||
if (result?.persisted === false) {
|
||||
toast.error(
|
||||
`${message} — but this browser would not store it, so it will be gone on reload. `
|
||||
@@ -394,4 +394,4 @@ export const sectionsForPage = (skill, page) => {
|
||||
|
||||
/** How many UI sections a definition registers, across every page. */
|
||||
export const countSections = (skill) =>
|
||||
Object.values(skill?.ui || {}).reduce((n, page) => n + (page.sections?.length || 0), 0);
|
||||
Object.values<any>(skill?.ui || {}).reduce((n, page) => n + (page.sections?.length || 0), 0);
|
||||
@@ -580,7 +580,24 @@ export function headcountFailed(position) {
|
||||
* position title, so accepting it goes back through the same resolution path a
|
||||
* typed sentence would — and re-checks the data before writing.
|
||||
*/
|
||||
export function assignmentPreview(position, context) {
|
||||
/**
|
||||
* A reply from this module: a document, and sometimes chips to offer next.
|
||||
*
|
||||
* `followUp` is optional because two of the five branches genuinely omit it —
|
||||
* "already fully staffed" and "nobody is both qualified and free" are answers
|
||||
* with nothing to offer after them. Callers that spread it on, like
|
||||
* `headcountSet`, therefore pass `undefined` through in those cases, which is
|
||||
* what this has always done at run time.
|
||||
*
|
||||
* Both fields are `any`: the blocks are the document format's own structures
|
||||
* and describing them belongs to that format, not here.
|
||||
*/
|
||||
export interface FlowReply {
|
||||
doc: any;
|
||||
followUp?: any;
|
||||
}
|
||||
|
||||
export function assignmentPreview(position, context): FlowReply {
|
||||
const plan = prepareAssignment(position, context);
|
||||
const demand = demandFor(position, context);
|
||||
|
||||
Reference in New Issue
Block a user