Found while triaging SonarQube S2933 (readonly) on projects/spikersoft/src/app/_components/classes/course.ts. SonarQube flags all 13 fields as "never reassigned → mark readonly", but on inspection 8 of them are never assigned or read anywhere in the class (it's a self-contained 43-line class with only private members, so there is no external access path):
description: string
audience: Array<string>
duration: string
format: Array<string>
assessment: Array<string>
certification: string
objectives: Array<string>
acknowledgements: Array<string>
The constructor only assigns courseCode, title, credits, prerequisites, enrolledStudents (the 5 real fields, each used by a method). The 8 above are declared with a type but no initializer, no constructor assignment, and no reader — under the workspace's strict:false they don't even trip strictPropertyInitialization, so they've sat silently as undefined.
Why not just mark them readonly
That's what a naive S2933 fix would do, but marking dead fields readonly papers over the real problem. This looks like an aspirational data model someone stubbed out and never wired up.
Fix options (needs a human decision)
Delete the 8 fields if Course is meant to be the lightweight enroll/prereq class it currently behaves as — (recommended; simplest, and Course's only live behavior is enrollment + prerequisites), or
Wire them up — add them to the constructor / a builder and the consumers that should populate course metadata, if the richer model was the intent.
Low priority / tech-debt. Filed so the S2933 sweep can skip this file cleanly rather than adding misleading readonly to dead members.
## Context
Found while triaging SonarQube S2933 (readonly) on `projects/spikersoft/src/app/_components/classes/course.ts`. SonarQube flags all 13 fields as "never reassigned → mark readonly", but on inspection 8 of them are **never assigned or read anywhere** in the class (it's a self-contained 43-line class with only `private` members, so there is no external access path):
- `description: string`
- `audience: Array<string>`
- `duration: string`
- `format: Array<string>`
- `assessment: Array<string>`
- `certification: string`
- `objectives: Array<string>`
- `acknowledgements: Array<string>`
The constructor only assigns `courseCode`, `title`, `credits`, `prerequisites`, `enrolledStudents` (the 5 real fields, each used by a method). The 8 above are declared with a type but no initializer, no constructor assignment, and no reader — under the workspace's `strict:false` they don't even trip `strictPropertyInitialization`, so they've sat silently as `undefined`.
## Why not just mark them readonly
That's what a naive S2933 fix would do, but marking dead fields `readonly` papers over the real problem. This looks like an aspirational data model someone stubbed out and never wired up.
## Fix options (needs a human decision)
1. **Delete** the 8 fields if `Course` is meant to be the lightweight enroll/prereq class it currently behaves as — *(recommended; simplest, and `Course`'s only live behavior is enrollment + prerequisites)*, **or**
2. **Wire them up** — add them to the constructor / a builder and the consumers that should populate course metadata, if the richer model was the intent.
Low priority / tech-debt. Filed so the S2933 sweep can skip this file cleanly rather than adding misleading `readonly` to dead members.
Re-verified against origin/master — still present, and the count is right.projects/spikersoft/src/app/_components/classes/course.ts is 43 lines; the constructor assigns only courseCode, title, credits, prerequisites, enrolledStudents.
The 8 fields that are neither assigned nor read, at course.ts:2-9: description, audience, duration, format, assessment, certification, objectives, acknowledgements.
Two additions worth folding into the cleanup while someone is in there:
courseCode (:11) and credits (:13) are write-only — assigned in the constructor, never read. Only title has a reader (getTitle()). So the effective dead surface is 10 of 13 fields, not 8.
That these compile at all means noUnusedLocals-style checking isn't catching unused private class members here. Worth a glance at the tsconfig if you want this class of dead code caught automatically rather than by review.
Notes were accurate; no work has landed.
Re-verified against `origin/master` — **still present, and the count is right.** `projects/spikersoft/src/app/_components/classes/course.ts` is 43 lines; the constructor assigns only `courseCode`, `title`, `credits`, `prerequisites`, `enrolledStudents`.
The 8 fields that are neither assigned nor read, at `course.ts:2-9`: `description`, `audience`, `duration`, `format`, `assessment`, `certification`, `objectives`, `acknowledgements`.
Two additions worth folding into the cleanup while someone is in there:
- `courseCode` (`:11`) and `credits` (`:13`) are **write-only** — assigned in the constructor, never read. Only `title` has a reader (`getTitle()`). So the effective dead surface is 10 of 13 fields, not 8.
- That these compile at all means `noUnusedLocals`-style checking isn't catching unused private class members here. Worth a glance at the tsconfig if you want this class of dead code caught automatically rather than by review.
Notes were accurate; no work has landed.
Verified 2026-08-07 against spikersoft-angular@8e5a404.
Code: Unchanged. projects/spikersoft/src/app/_components/classes/course.ts is still 43 lines. The 8 dead fields are at :2-8 and :10 (description, audience, duration, format, assessment, certification, objectives, acknowledgements); the constructor at :16-22 assigns only courseCode, title, credits, prerequisites, enrolledStudents. The 2026-07-29 comment's addition also holds: courseCode (:11) and credits (:13) are write-only — the only reader in the file is getTitle() at :40-42 — so the effective dead surface is 10 of 13 fields.
Live: Nothing runtime-observable — this is pure dead-code hygiene in a self-contained class with only private members, so master evidence is the bar.
Status: not done — The human decision plus the edit: delete the 8 (recommended) or wire them up. While in there, consider the write-only courseCode/credits, and whether tsconfig should be catching unused private members automatically.
Closing here. Work now lives in the repo that holds the fix, so fixes #644 in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.
— Opus 5 Agent
Migrated to **spikerj/spikersoft-angular#644** as part of the umbrella-tracker breakup.
Verified 2026-08-07 against `spikersoft-angular@8e5a404`.
- **Code:** Unchanged. `projects/spikersoft/src/app/_components/classes/course.ts` is still 43 lines. The 8 dead fields are at `:2-8` and `:10` (`description`, `audience`, `duration`, `format`, `assessment`, `certification`, `objectives`, `acknowledgements`); the constructor at `:16-22` assigns only `courseCode`, `title`, `credits`, `prerequisites`, `enrolledStudents`. The 2026-07-29 comment's addition also holds: `courseCode` (`:11`) and `credits` (`:13`) are write-only — the only reader in the file is `getTitle()` at `:40-42` — so the effective dead surface is 10 of 13 fields.
- **Live:** Nothing runtime-observable — this is pure dead-code hygiene in a self-contained class with only `private` members, so master evidence is the bar.
Status: **not done** — The human decision plus the edit: delete the 8 (recommended) or wire them up. While in there, consider the write-only `courseCode`/`credits`, and whether tsconfig should be catching unused private members automatically.
Closing here. Work now lives in the repo that holds the fix, so `fixes #644` in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.
— Opus 5 Agent
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Context
Found while triaging SonarQube S2933 (readonly) on
projects/spikersoft/src/app/_components/classes/course.ts. SonarQube flags all 13 fields as "never reassigned → mark readonly", but on inspection 8 of them are never assigned or read anywhere in the class (it's a self-contained 43-line class with onlyprivatemembers, so there is no external access path):description: stringaudience: Array<string>duration: stringformat: Array<string>assessment: Array<string>certification: stringobjectives: Array<string>acknowledgements: Array<string>The constructor only assigns
courseCode,title,credits,prerequisites,enrolledStudents(the 5 real fields, each used by a method). The 8 above are declared with a type but no initializer, no constructor assignment, and no reader — under the workspace'sstrict:falsethey don't even tripstrictPropertyInitialization, so they've sat silently asundefined.Why not just mark them readonly
That's what a naive S2933 fix would do, but marking dead fields
readonlypapers over the real problem. This looks like an aspirational data model someone stubbed out and never wired up.Fix options (needs a human decision)
Courseis meant to be the lightweight enroll/prereq class it currently behaves as — (recommended; simplest, andCourse's only live behavior is enrollment + prerequisites), orLow priority / tech-debt. Filed so the S2933 sweep can skip this file cleanly rather than adding misleading
readonlyto dead members.Re-verified against
origin/master— still present, and the count is right.projects/spikersoft/src/app/_components/classes/course.tsis 43 lines; the constructor assigns onlycourseCode,title,credits,prerequisites,enrolledStudents.The 8 fields that are neither assigned nor read, at
course.ts:2-9:description,audience,duration,format,assessment,certification,objectives,acknowledgements.Two additions worth folding into the cleanup while someone is in there:
courseCode(:11) andcredits(:13) are write-only — assigned in the constructor, never read. Onlytitlehas a reader (getTitle()). So the effective dead surface is 10 of 13 fields, not 8.noUnusedLocals-style checking isn't catching unused private class members here. Worth a glance at the tsconfig if you want this class of dead code caught automatically rather than by review.Notes were accurate; no work has landed.
Migrated to spikerj/spikersoft-angular#644 as part of the umbrella-tracker breakup.
Verified 2026-08-07 against
spikersoft-angular@8e5a404.projects/spikersoft/src/app/_components/classes/course.tsis still 43 lines. The 8 dead fields are at:2-8and:10(description,audience,duration,format,assessment,certification,objectives,acknowledgements); the constructor at:16-22assigns onlycourseCode,title,credits,prerequisites,enrolledStudents. The 2026-07-29 comment's addition also holds:courseCode(:11) andcredits(:13) are write-only — the only reader in the file isgetTitle()at:40-42— so the effective dead surface is 10 of 13 fields.privatemembers, so master evidence is the bar.Status: not done — The human decision plus the edit: delete the 8 (recommended) or wire them up. While in there, consider the write-only
courseCode/credits, and whether tsconfig should be catching unused private members automatically.Closing here. Work now lives in the repo that holds the fix, so
fixes #644in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.— Opus 5 Agent