Repository navigation
Seed a new machine's service card from the farm's own interval table, instead of from a literal - #116
Merged
Merged
Conversation
… instead of from a literal (#29) The maintenance-intervals row of #29, and the one of its six tables with a consumer waiting: a printer was registered with an empty service card, and every operation an engineer then added defaulted to 500 hours from a literal in `CreateServiceOperation`. `service.maintenance_defaults` is now the fifth Kind.TABLE field - rows of {code, interval_hours}, one per MaintenanceKind, default every kind at 500 so an untouched table changes nothing. The shape, its validation and the seeding live in fleet (`maintenance.py`): the consumer owns what a valid row is, as pricing owns ZoneTariffs. Settings stores, audits and resolves it. Two readers, both at the API edge: POST /printers seeds the card from the table, and POST /printers/{id}/services gives an operation sent without a periodicity its kind's row - told apart from an explicit 500 by model_fields_set. A kind removed from the table is not seeded on a new machine; the editor draws it with a dash and a way back. The kit's «Простой» and «Расход» columns are deliberately not stored: ServiceOperation carries neither and nothing prices a service, so they would be rows nothing reads (CLAUDE.md §1). Verified: 15 unit + 4 API tests; the six backend gates each exit=0; the editor's screen test saves exactly the rows the server keys by code; frontend from the lockfile - tsc --build --force, lint, test (33 files, 320 passed), build, and a regenerated API client - each exit=0. Mutating either router reading to ignore the table fails the API tests (3 and 1). The zones test's table-list guard now names the fifth table. Co-Authored-By: Claude Fable 5.1 <[email protected]>
dimmus
force-pushed
the
claude/maintenance-defaults
branch
from
September 24, 2026 15:38
4cfe514 to
ecbc6b1
Compare
…st reads them `tests/unit/test_docs_screen_inventory.py` checks §1 and §2.1 against `len(FIELDS)` and the per-kind counts, and both moved by one with `service.maintenance_defaults`: 105 parameters, five tables. §2.1's status of #29 now lists the maintenance table among the built ones and names the two columns it does not store, so the document says what the code does rather than what the issue said was missing (CLAUDE.md §4). Verified: the docs tests, 32 passed, 1 skipped. Co-Authored-By: Claude Fable 5.1 <[email protected]>
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.
Issue #29, the maintenance intervals row (the kit's «Периодичность по умолчанию»). Stacked on #115 because both touch the same HANDOFF section; merge #115 first and this diff shrinks to its own commit.
What it is.
service.maintenance_defaults, the fifthKind.TABLEfield: rows of{code, interval_hours}, one perMaintenanceKind. Default: every kind at the 500 hoursCreateServiceOperationalways assumed, so an untouched table changes nothing (the settings context's rule).Who reads it — the part the issue says must not be missing.
POST /printersseeds the new machine's service card from the table. A machine used to be registered with an empty card.POST /printers/{id}/servicesgives an operation sent without a periodicity its kind's row; an explicit500is told apart from an omitted one bymodel_fields_set. A kind the table does not carry keeps the schema's default rather than being refused.What is deliberately not stored. The kit's «Простой» and «Расход» columns:
ServiceOperationcarries neither and nothing prices a service, so they would be settings rows nothing reads (CLAUDE.md §1). They arrive with whatever reads them.Where the shape lives.
contexts/fleet/maintenance.py— validation (error.fleet.maintenance_kind_unknown,…_duplicate,…_interval_invalid), default, JSON shape and the seeding — because the consumer owns what a valid row is, the way pricing ownsZoneTariffs. Settings stores, audits and resolves (resolve_maintenance_defaults).Verified
exit=0. Mutations, run and reverted: register ignoring the table (3 API tests fail), the services route ignoring it (1).tsc --build --force,lint,test(33 files, 320 passed) andbuildeachexit=0; the API client regenerated from the new schema. The settings screen test edits an interval, drops a kind and asserts the exact PUT body.Left on #29 after this: the event matrix, API keys and webhooks. Each needs a channel or a credential store that does not exist yet.
🤖 Generated with Claude Code