Two pre-existing issues noticed while converting marks-site off ngModel (epic #722 wave-2 batch 7, PR spikersoft-angular#492 — neither introduced there):
Duplicate track keys: the address list iterates @for (entry of ... ; track entry.addressId) and newCustomerAddress() creates entries with addressId: "". Add a second address before saving the first → two entries share the "" key → Angular duplicate-track-key runtime error (NG0955 class) and broken row identity. Track by $index or mint a temp id.
saveAddresses() is a console.warn/console.log stub — the Addresses tab has no persistence path at all (only verifyAddress() touches the service, and only for addresses[0]). Related smell in the same area: marks-service-contract renders a large hard-coded demo contracts array, and day-scheduler declares public hours: ["12:00am", ...] as a type annotation with no initializer (the property is undefined at runtime and unused).
Worth deciding whether marks-site's address/contract tabs are demo scaffolding to finish or to prune.
Two pre-existing issues noticed while converting marks-site off ngModel (epic #722 wave-2 batch 7, PR spikersoft-angular#492 — neither introduced there):
1. **Duplicate track keys:** the address list iterates `@for (entry of ... ; track entry.addressId)` and `newCustomerAddress()` creates entries with `addressId: ""`. Add a second address before saving the first → two entries share the `""` key → Angular duplicate-track-key runtime error (NG0955 class) and broken row identity. Track by `$index` or mint a temp id.
2. **`saveAddresses()` is a `console.warn`/`console.log` stub** — the Addresses tab has no persistence path at all (only `verifyAddress()` touches the service, and only for `addresses[0]`). Related smell in the same area: `marks-service-contract` renders a large hard-coded demo `contracts` array, and `day-scheduler` declares `public hours: ["12:00am", ...]` as a *type annotation with no initializer* (the property is `undefined` at runtime and unused).
Worth deciding whether marks-site's address/contract tabs are demo scaffolding to finish or to prune.
Board-sweep verification (2026-07-22): still live — marks-address.component.html line 30 still tracks @for by entry.addressId, which is exactly the reported duplicate-key collision for unsaved addresses (no id yet). No fix commit references this file.
Board-sweep verification (2026-07-22): still live — marks-address.component.html line 30 still tracks @for by entry.addressId, which is exactly the reported duplicate-key collision for unsaved addresses (no id yet). No fix commit references this file.
Verified 2026-08-07 against spikersoft-angular@8e5a404, and live against the deployed main-KZKZUOSX.js bundle on learn.spikersoft.com.
Code: Both items unchanged. projects/spikersoft/src/app/_components/marks-site/marks-address/marks-address.component.html:30 — @for (entry of _selectedCustomer?.addresses; track entry.addressId; let index = $index), i.e. still tracking by an id that is "" for unsaved rows. marks-address.component.ts:106-116 — saveAddresses(form: any) is still nothing but console.warn + two console.group/console.log pairs; no service call.
Live: Not user-reachable: marks-site is unrouted (rg marks over app-routing.module.ts → 0 hits, no marks* route in prod main-KZKZUOSX.js), and MarksAddressComponent's only non-spec reference in the repo is its own marks-address.component.stories.ts. So neither defect can bite a user today — which is exactly the finish-or-prune decision the ticket asks for.
Status: not done — Everything. The decision the ticket names is now the whole ticket: marks-site is dead code, so either prune the address/contract tabs or finish them (temp id or $index tracking + a real persistence path in saveAddresses(), plus the marks-service-contract hard-coded demo array and day-scheduler's uninitialised hours annotation).
Closing here. Work now lives in the repo that holds the fix, so fixes #646 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#646** as part of the umbrella-tracker breakup.
Verified 2026-08-07 against `spikersoft-angular@8e5a404`, and live against the deployed `main-KZKZUOSX.js` bundle on learn.spikersoft.com.
- **Code:** Both items unchanged. `projects/spikersoft/src/app/_components/marks-site/marks-address/marks-address.component.html:30` — `@for (entry of _selectedCustomer?.addresses; track entry.addressId; let index = $index)`, i.e. still tracking by an id that is `""` for unsaved rows. `marks-address.component.ts:106-116` — `saveAddresses(form: any)` is still nothing but `console.warn` + two `console.group`/`console.log` pairs; no service call.
- **Live:** Not user-reachable: marks-site is unrouted (`rg marks` over `app-routing.module.ts` → 0 hits, no `marks*` route in prod `main-KZKZUOSX.js`), and `MarksAddressComponent`'s only non-spec reference in the repo is its own `marks-address.component.stories.ts`. So neither defect can bite a user today — which is exactly the finish-or-prune decision the ticket asks for.
Status: **not done** — Everything. The decision the ticket names is now the whole ticket: marks-site is dead code, so either prune the address/contract tabs or finish them (temp id or `$index` tracking + a real persistence path in `saveAddresses()`, plus the `marks-service-contract` hard-coded demo array and `day-scheduler`'s uninitialised `hours` annotation).
Closing here. Work now lives in the repo that holds the fix, so `fixes #646` 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.
Two pre-existing issues noticed while converting marks-site off ngModel (epic #722 wave-2 batch 7, PR spikersoft-angular#492 — neither introduced there):
Duplicate track keys: the address list iterates
@for (entry of ... ; track entry.addressId)andnewCustomerAddress()creates entries withaddressId: "". Add a second address before saving the first → two entries share the""key → Angular duplicate-track-key runtime error (NG0955 class) and broken row identity. Track by$indexor mint a temp id.saveAddresses()is aconsole.warn/console.logstub — the Addresses tab has no persistence path at all (onlyverifyAddress()touches the service, and only foraddresses[0]). Related smell in the same area:marks-service-contractrenders a large hard-coded democontractsarray, andday-schedulerdeclarespublic hours: ["12:00am", ...]as a type annotation with no initializer (the property isundefinedat runtime and unused).Worth deciding whether marks-site's address/contract tabs are demo scaffolding to finish or to prune.
Board-sweep verification (2026-07-22): still live — marks-address.component.html line 30 still tracks @for by entry.addressId, which is exactly the reported duplicate-key collision for unsaved addresses (no id yet). No fix commit references this file.
Migrated to spikerj/spikersoft-angular#646 as part of the umbrella-tracker breakup.
Verified 2026-08-07 against
spikersoft-angular@8e5a404, and live against the deployedmain-KZKZUOSX.jsbundle on learn.spikersoft.com.projects/spikersoft/src/app/_components/marks-site/marks-address/marks-address.component.html:30—@for (entry of _selectedCustomer?.addresses; track entry.addressId; let index = $index), i.e. still tracking by an id that is""for unsaved rows.marks-address.component.ts:106-116—saveAddresses(form: any)is still nothing butconsole.warn+ twoconsole.group/console.logpairs; no service call.rg marksoverapp-routing.module.ts→ 0 hits, nomarks*route in prodmain-KZKZUOSX.js), andMarksAddressComponent's only non-spec reference in the repo is its ownmarks-address.component.stories.ts. So neither defect can bite a user today — which is exactly the finish-or-prune decision the ticket asks for.Status: not done — Everything. The decision the ticket names is now the whole ticket: marks-site is dead code, so either prune the address/contract tabs or finish them (temp id or
$indextracking + a real persistence path insaveAddresses(), plus themarks-service-contracthard-coded demo array andday-scheduler's uninitialisedhoursannotation).Closing here. Work now lives in the repo that holds the fix, so
fixes #646in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.— Opus 5 Agent