Skip to content

feat(projects): expose snapshot config across API, CLI, and dashboard#1045

Merged
aaight merged 2 commits intodevfrom
feature/snapshot-config-api-cli-dashboard
Mar 24, 2026
Merged

feat(projects): expose snapshot config across API, CLI, and dashboard#1045
aaight merged 2 commits intodevfrom
feature/snapshot-config-api-cli-dashboard

Conversation

@aaight
Copy link
Copy Markdown
Collaborator

@aaight aaight commented Mar 24, 2026

Summary

Exposes container snapshot configuration (snapshotEnabled and snapshotTtlMs) across all operator-facing surfaces so each project can opt in with its own TTL.

  • API: Added snapshotEnabled (boolean, nullable) and snapshotTtlMs (integer, nullable) to projects.create and projects.update tRPC inputs, flowing through to createProject / updateProject repository calls. projects.getById and projects.listFull already return all columns from the projects table (including the DB fields added in the prior story).
  • CLI: Added --snapshot-enabled / --no-snapshot-enabled (allowNo boolean) and --snapshot-ttl (integer ms) flags to both projects create and projects update, following the same conditional-spread pattern used by --run-links-enabled.
  • Dashboard: Added a dedicated Container Snapshots card to project-general-form.tsx with 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 sends snapshotEnabled and snapshotTtlMs (null when blank).
  • Tests: Added API round-trip tests (enable, null override, absent-field cases) and CLI flag tests (enable/disable/TTL for both create and update, no-flag cases).

Closes: https://trello.com/c/69c291f7b55f7af775fffca6

Test plan

  • npm test passes (6888 tests, 12 new)
  • npm run lint clean
  • npm run typecheck clean
  • API create/update accept snapshotEnabled and snapshotTtlMs, passing them to the repository
  • API create/update accept null values (clears per-project override)
  • CLI projects update --snapshot-enabled / --no-snapshot-enabled passes correct boolean
  • CLI projects update --snapshot-ttl 3600000 passes integer TTL
  • CLI projects create accepts same snapshot flags
  • Absent flags are not included in the tRPC payload (preserves default fallback)
  • Dashboard checkbox toggle and TTL input save via useProjectUpdate

🤖 Generated with Claude Code

🕵️ claude-code · claude-sonnet-4-6 · run details

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Collaborator

@nhopeatall nhopeatall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:146snapshotEnabled: snapshotEnabled || null coerces false to null. When a user unchecks the "Enable container snapshots" checkbox, snapshotEnabled state is false, and false || null evaluates to null. This sends null to the API — which means "clear the per-project override / use default" rather than "explicitly disable snapshots for this project."

    Compare with runLinksEnabled on 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>
Copy link
Copy Markdown
Collaborator

@nhopeatall nhopeatall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@aaight aaight merged commit 75a8544 into dev Mar 24, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants