feat(projects): expose snapshot config across API, CLI, and dashboard#1045
feat(projects): expose snapshot config across API, CLI, and dashboard#1045
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
nhopeatall
left a comment
There was a problem hiding this comment.
Summary
The dashboard form has a correctness bug: unchecking the snapshot checkbox sends null instead of false, making it impossible for users to explicitly disable snapshots via the UI. The API, CLI, repository, and test changes all look correct.
Code Issues
Should Fix
-
web/src/components/projects/project-general-form.tsx:146 —
snapshotEnabled: snapshotEnabled || nullcoercesfalsetonull. When a user unchecks the "Enable container snapshots" checkbox,snapshotEnabledstate isfalse, andfalse || nullevaluates tonull. This sendsnullto the API — which means "clear the per-project override / use default" rather than "explicitly disable snapshots for this project."Compare with
runLinksEnabledon the line directly above (line 145), which is passed as a bare boolean without|| null. The fix is to do the same:snapshotEnabled,
instead of:
snapshotEnabled: snapshotEnabled || null,
🕵️ claude-code · claude-opus-4-6 · run details
`snapshotEnabled || null` coerced `false` to `null`, meaning unchecking the checkbox sent "clear override / use default" instead of "explicitly disable". Pass the bare boolean, matching the pattern used by `runLinksEnabled` on the line above. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nhopeatall
left a comment
There was a problem hiding this comment.
LGTM — Clean, mechanical addition of snapshotEnabled and snapshotTtlMs across all three surfaces (API, CLI, dashboard). The implementation follows the exact same patterns established by runLinksEnabled and maxInFlightItems: conditional-spread in CLI flags, .nullish() Zod validators, nullable DB columns, and useState + dirty-state tracking in the React form. Nullable semantics are correctly maintained end-to-end (three-state: true/false/null-inherit). Test coverage is solid with 12 new tests spanning create, update, null-override, and absent-field scenarios. All CI checks pass.
🕵️ claude-code · claude-opus-4-6 · run details
Summary
Exposes container snapshot configuration (
snapshotEnabledandsnapshotTtlMs) across all operator-facing surfaces so each project can opt in with its own TTL.snapshotEnabled(boolean, nullable) andsnapshotTtlMs(integer, nullable) toprojects.createandprojects.updatetRPC inputs, flowing through tocreateProject/updateProjectrepository calls.projects.getByIdandprojects.listFullalready return all columns from theprojectstable (including the DB fields added in the prior story).--snapshot-enabled/--no-snapshot-enabled(allowNo boolean) and--snapshot-ttl(integer ms) flags to bothprojects createandprojects update, following the same conditional-spread pattern used by--run-links-enabled.project-general-form.tsxwith a checkbox toggle and a TTL input (visible only when snapshots are enabled). Dirty-state tracking and reset handler updated to include both fields. Submit handler sendssnapshotEnabledandsnapshotTtlMs(null when blank).Closes: https://trello.com/c/69c291f7b55f7af775fffca6
Test plan
npm testpasses (6888 tests, 12 new)npm run lintcleannpm run typecheckcleansnapshotEnabledandsnapshotTtlMs, passing them to the repositorynullvalues (clears per-project override)projects update --snapshot-enabled/--no-snapshot-enabledpasses correct booleanprojects update --snapshot-ttl 3600000passes integer TTLprojects createaccepts same snapshot flagsuseProjectUpdate🤖 Generated with Claude Code
🕵️ claude-code · claude-sonnet-4-6 · run details