From 652d80736069ada01073f912818b6ae6fdeab2aa Mon Sep 17 00:00:00 2001 From: HAL9000 Date: Thu, 7 May 2026 07:02:22 +0000 Subject: [PATCH] fix(changeset_repository): preserve per-changeset granularity in get_for_plan Previously get_for_plan() collapsed all ChangeEntry rows from a plan into a single SpecChangeSet, losing the ability to distinguish between separate changeset scopes. This restores per-changeset grouping by querying raw DB rows and partitioning them by changeset_id before constructing individual SpecChangeSet objects. --- .../database/changeset_repository.py | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/src/cleveragents/infrastructure/database/changeset_repository.py b/src/cleveragents/infrastructure/database/changeset_repository.py index 847d837f4..1faa054ef 100644 --- a/src/cleveragents/infrastructure/database/changeset_repository.py +++ b/src/cleveragents/infrastructure/database/changeset_repository.py @@ -452,17 +452,50 @@ class SqliteChangeSetStore: self, plan_id: str, ) -> list[SpecChangeSet]: - """Return all ChangeSets associated with *plan_id*.""" + """Return all ChangeSets associated with *plan_id*. + + Returns one ``SpecChangeSet`` per distinct changeset, preserving + per-changeset granularity instead of collapsing every entry into a + single container. Entry ordering is by timestamp within each + changeset. + """ if not plan_id: return [] - entries = self._entry_repo.get_entries_for_plan(plan_id) - if not entries: + session = self._entry_repo._session() + try: + rows = ( + session.query(ChangeSetEntryModel) + .filter_by(plan_id=plan_id) + .order_by(ChangeSetEntryModel.timestamp) + .all() + ) + except (OperationalError, SQLAlchemyDatabaseError) as exc: + raise DatabaseError(f"Failed to get entries for plan: {exc}") from exc + + if not rows: return [] - return [ - SpecChangeSet(plan_id=plan_id, entries=entries), - ] + # Group raw DB rows by their original changeset_id so each + # SpecChangeSet represents one logical chunk of work. + groups: dict[str, list[ChangeSetEntryModel]] = {} + for row in rows: + cs_id = cast(str, row.changeset_id) + groups.setdefault(cs_id, []).append(row) + + result: list[SpecChangeSet] = [] + for cs_id in sorted(groups): + group_rows = groups[cs_id] + entries = [self._entry_repo._to_domain(r) for r in group_rows] + plan_id_from_entries = entries[0].plan_id if entries else plan_id + result.append( + SpecChangeSet( + changeset_id=cs_id, + plan_id=plan_id_from_entries or plan_id, + entries=entries, + ) + ) + return result def summarize( self, -- 2.52.0