Commit 83f0e38
authored
feat(buds): edit impacted_repos from BUD detail (#195)
* feat(buds): per-BUD branch override for UAT / PROD tabs
Lets a BUD opt out of the repo-wide tracking branch and watch its own
pattern instead. Release-train BUDs whose PRs target ``release/*`` can
be tracked without retraining the global repo setting; one-off ad-hoc
release branches can be pointed at directly.
Backend
- New ``branch_overrides`` JSONB column on ``bud_documents``, keyed by
stage (``uat`` / ``prod``) with fnmatch-style values.
- ``BUDUpdate`` accepts ``branch_overrides`` and ``impacted_repos`` on
PATCH. The validator rejects unknown stage keys, empty / whitespace
patterns, and the wrong case (``"UAT"`` / ``"production"``) — typos
surface as 422 at the API edge instead of silently missing in the
filter.
- PATCH handler MERGES branch_overrides per-key so saving a UAT
override doesn't clobber an existing prod override; ``{"uat": null}``
is the clear-this-stage signal and drops the key from the merged
column. Sending ``branch_overrides: null`` wipes both stages.
- ``bud_prs.py::release_stage`` honors ``bud.branch_overrides[stage]``
before falling back to ``repo.uat_branch`` / ``repo.main_branch``.
Reuses the existing ``branch_matches()`` fnmatch utility so wildcard
semantics stay consistent with release detection.
- Editing ``impacted_repos`` after the planning phase logs
``bud_impacted_repos_edited_post_planning`` so an operator can audit
scope changes that may leave PR rows linked to repos that no longer
appear on the stage tab.
Frontend
- New ``BUDStageBranchOverride.vue`` widget rendered inside the shared
``BUDReleaseStagePanel.vue``. Shows the currently-effective pattern
(override or repo default), an Edit affordance opening an inline
dialog, and — for multi-repo BUDs — a one-line "applies to N repos"
disclosure so the per-stage scope is explicit before saving.
- Save → PATCH ``/v1/buds/{id}`` with ``branch_overrides``; on success
the panel re-fetches its stage data and emits ``refresh-bud`` so
``BUDDetail`` pulls the new override into the props feed.
- Empty input on Save and the dedicated Clear button both send
``{[stage]: null}`` — the merge-aware handler drops just that key.
Schema validator covered by 16 new parametrized tests.
Signed-off-by: Arun Rajkumar <mickyarunr@gmail.com>
* docs(buds): tracking-branch hint explains the BUD-number content guard
The override widget previously described only the fnmatch half of the
filter ("Open PRs are matched against this pattern on each impacted
repo. Supports fnmatch wildcards"). After the over-match fix added the
content guard that requires PRs to also reference the BUD by number,
that copy understated what surfaces a PR on a release-stage tab.
Rewrites the in-card hint and the dialog body so both rules are
visible. The example is now per-BUD: BUD-4 sees
``release/bud-001-bud-004``, BUD-12 sees ``release/bud-001-bud-012``.
Threads ``bud_number`` from BUDDetail → BUDReleaseStagePanel → the
override widget so the copy renders the actual reference, not a
placeholder.
Signed-off-by: Arun Rajkumar <mickyarunr@gmail.com>
* refactor(buds): derive branch_overrides allowed keys from ReleaseStage
The validator hardcoded ``{"uat", "prod"}`` next to a comment that
already pointed at the existing ``Literal["uat", "prod"]`` in
``app.schemas.bud_release``. Drop the duplicate and source the
allowed-keys set from ``get_args(ReleaseStage)`` so adding a new
release-stage tab in one place automatically widens the override
contract — no second edit needed, no drift possible.
Behaviour and tests unchanged (16 cases pass).
Signed-off-by: Arun Rajkumar <mickyarunr@gmail.com>
* feat(buds): edit impacted_repos from BUD detail
The tech-arch agent's initial guess at which repos a BUD touches is
often close but not perfect — and scope sometimes drifts mid-build.
This adds an Edit affordance next to the impacted-repos chip row on
``BUDDevelopmentPanel.vue`` so a PM can correct the list without
re-running the agent or hand-editing JSON.
UI
- ``BUDImpactedReposDialog.vue`` multi-select bound to the org's
``active`` tracked repos. Filter-by-name field, in-flight loader,
per-row checkbox, count chip with ``aria-live`` so screen readers
announce selection changes.
- Repos already on the BUD but no longer ``active`` in the tracked
list render as separate "retired" rows, pre-checked. The user
consciously preserves or drops them — never silently erased.
- Always refreshes the tracked-repo list on open (one cheap GET) so
a repo added in another tab shows up in the picker before driving
a destructive PATCH. In-flight ``fetchRepos`` is memoised so
reopen-during-load is safe.
- Save → ``PATCH /v1/buds/{id}`` with the full new list. Clearing
every row when the BUD previously had repos requires a confirm
prompt — release-stage tabs and code-review status both go quiet
on empty, so the consequence is surfaced before the write lands.
- Empty-state copy on the chip row is reworded to read in any phase
(the previous imperative read as tech_arch-only).
Plumbing
- ``BUDDevelopmentPanel`` emits ``refresh-bud`` after a successful
save; ``BUDDetail`` calls ``budStore.fetchBUD`` so the chip row
updates everywhere and any downstream panel relying on
``bud.impacted_repos`` picks up the new list.
- Dialog is non-persistent so Esc and backdrop-click work; the
``persistent`` flag only activates during the in-flight save.
Backend already accepts ``impacted_repos`` on the ``BUDUpdate`` PATCH
schema and logs ``bud_impacted_repos_edited_post_planning`` for
mid-development edits — both landed in the per-BUD branch override PR
this stacks on.
Signed-off-by: Arun Rajkumar <mickyarunr@gmail.com>
* fix(buds): v-if/v-else adjacency in BUDImpactedReposDialog
Vite's Vue compiler rejected the no-matches placeholder because the
literal '.' between the inline v-if span and the v-else span counted
as a text node, breaking the v-if/v-else adjacency rule. Move the
two variants into <template v-if> / <template v-else> wrappers so
the directive pair sits on directly adjacent siblings with no
intervening text. Vue 3 template-compile rule — both branches still
render the same wording, only the wrapping element changes.
Found at runtime while testing the integration branch — would have
blocked the picker from rendering whenever the filter input matched
zero repos or no repos were tracked yet.
Signed-off-by: Arun Rajkumar <mickyarunr@gmail.com>
* fix(buds): expose Impacted Repos Edit on the activity view
The Edit affordance only lived inside the empty-state branch of
``BUDDevelopmentPanel``. Once a BUD had any dev activity (commits,
PRs, todos), the panel switched to the has-activity template and the
button vanished — leaving no way to correct ``impacted_repos`` from
the UI on a BUD that had moved past tech_arch.
Reproduced on BUD-004 after promotion to development.
Adds a compact impacted-repos row at the top of the activity view
with the same Edit button. Mirrors the empty-state semantics —
chip list when the array has entries, "none yet" otherwise — but
slimmer so it sits cleanly above the stats grid.
Signed-off-by: Arun Rajkumar <mickyarunr@gmail.com>
---------
Signed-off-by: Arun Rajkumar <mickyarunr@gmail.com>1 parent 6601034 commit 83f0e38
3 files changed
Lines changed: 378 additions & 3 deletions
File tree
- frontend/src
- components/buds
- views/buds
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
38 | | - | |
39 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
40 | 54 | | |
41 | 55 | | |
42 | 56 | | |
| |||
47 | 61 | | |
48 | 62 | | |
49 | 63 | | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
50 | 68 | | |
51 | 69 | | |
52 | 70 | | |
| |||
95 | 113 | | |
96 | 114 | | |
97 | 115 | | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
98 | 147 | | |
99 | 148 | | |
100 | 149 | | |
| |||
232 | 281 | | |
233 | 282 | | |
234 | 283 | | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
235 | 291 | | |
236 | 292 | | |
237 | 293 | | |
238 | 294 | | |
239 | 295 | | |
| 296 | + | |
240 | 297 | | |
241 | 298 | | |
242 | 299 | | |
| |||
252 | 309 | | |
253 | 310 | | |
254 | 311 | | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
255 | 315 | | |
256 | 316 | | |
| 317 | + | |
| 318 | + | |
257 | 319 | | |
258 | 320 | | |
259 | 321 | | |
| |||
0 commit comments