Skip to content

feat(merge_requests): save private replies on existing discussions - #623

Merged
sjungwon03 merged 2 commits into
devfrom
feat/622-private-review-replies
Oct 5, 2026
Merged

sjungwon03 merged 2 commits into
devfrom
feat/622-private-review-replies

Conversation

@sjungwon03

@sjungwon03 sjungwon03 commented Oct 5, 2026 •

Copy link
Copy Markdown
Member

Summary

Existing public MR discussion groups now offer Save private reply. A shared dialog displays the captured discussion and saves exact private Markdown without publishing or resolving it. Unsent public comments and thread replies remain intact.

A fresh selected-discussion comparison joins account/client/repository and authoritative MR identity checks before one private POST. Uncertain results block private writes until the actual request settles and a complete private-note traversal plus the original public target are visibly inspected. Missing targets stay missing; scoped reply inspection cannot clear uncertain publication/reviewer state. Changed context requires new consent for explicit retry, and obsolete sessions/origins discard input and outcomes.

Closes #622

Validation

  • dart format .: 951 Dart files, zero outstanding changes
  • flutter analyze: no issues
  • 7,246 full tests: app 4,211; design system 127; API 2,719; models 184; secure storage 5
  • 139 new behavior tests: API 49; repository 6; controller 61; widgets 23. Missing API/repository/controller/UI behavior and a review-found obsolete preflight read reproduced before their fixes
  • Seven new localization messages translated into all five locales; generated delegates included; existing 109-message untranslated baseline unchanged
  • Three widths, both themes, 1.8 text scale with a 280-pixel keyboard, resize/theme preservation, twelve synthetic captures visually inspected
  • Live GitLab/device manual validation (unit/widget tests and synthetic captures only)
  • Models unchanged; no build-runner regeneration needed

Checklist

  • Linked issue, feature branch into dev, Conventional Commit and DCO
  • Test-first behavior and updated flow/parity documentation
  • Shared responsive UI; Mobile/Desktop and Light/Dark verification
  • No dependencies, disk persistence or telemetry added
  • Dummy users/credentials/notes only; source/docs/review in English with localized translations

Screenshots

All twelve synthetic captures

Mobile composition, light Desktop recovery, dark
Composition Recovery

Notes for reviewers

Uses documented in_reply_to_discussion_id and the primary draft creation service. Strict HTTP 201 confirms exact discussion/body, captured author/global MR, false resolution and absent unexpected anchor/commit. No position reconstruction, redirect, authentication replay, fallback or automatic retry is introduced. Existing non-individual groups with non-system origins are eligible; individual notes retain their separate public reply behavior.

The stable conversation parent owns the modal so missing-target recovery can remain visible after its row disappears. Same-account repository replacement recovery waits for actual write settlement. Scoped inspection preserves publication/reviewer uncertainty, and retry requires fresh visible context/notes and acknowledgement. GitLab can implicitly mark review started during private creation; the client sends no reviewer-state command here.

Read-then-write checks are not atomic or conditional-write guarantees; recovery remains in memory and an explicit retry can duplicate a server-accepted write. Server permissions/capabilities remain authoritative. Commit/image/file draft creation remains separate; MW-07 stays in progress. No live-instance/device validation is claimed.

Confirm fresh discussion context before private writes and require complete pending-note and original-target inspection after uncertain saves.

Signed-off-by: sjungwon03 <sjungwon03@gmail.com>
@sjungwon03
sjungwon03 marked this pull request as ready for review October 5, 2026 16:56
@github-actions github-actions Bot added area:api packages/gitlab_api — GitLab REST/GraphQL client area:ui Screens and feature UI area:docs AGENTS.md, .agents/, README and friends feat New feature labels Oct 5, 2026

@sjungwon03-ai sjungwon03-ai left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P2] Recheck the captured origin/session before starting the fresh discussion read. In savePendingReply, awaiting the already resolved comments repository introduces an asynchronous boundary after _pendingReview validates detail. If the origin becomes inactive at that boundary, comments.discussion still dispatches before current() is checked. A regression test that schedules origin cancellation while the authoritative detail ID is validated reproduces one obsolete target read, although the later private POST is correctly prevented. Add a current() check after obtaining the comments repository and before this GET; keep the same pre-dispatch discipline in scoped reply inspection. Re-run the regression and quality gates before approval.

Recheck the captured origin after awaiting repositories so final detail-validation cancellation cannot dispatch another discussion read.

Signed-off-by: sjungwon03 <sjungwon03@gmail.com>

@sjungwon03-ai sjungwon03-ai left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Review of commit aa2f4b4: Reviewed the API, repository, shared controller, modal/thread integration, generated localization, tests and documentation on this commit. The obsolete preflight-read finding from review 5417994710 is addressed: a reproduced final-detail cancellation now rechecks the captured origin before any target GET, with the same guard in scoped recovery. Both boundary regression cases and the full quality gates pass.

One strict-201 private POST preserves exact Markdown and the existing discussion ID with false resolution, captured author/global MR confirmation, and no unexpected anchor/commit. Fresh full selected-context comparison and shared reservations prevent stale writes; no redirect/authentication replay/public fallback/automatic retry is introduced. Recovery waits for actual write settlement and stages all private pages plus the original target before adoption, retains missing targets and publication/reviewer uncertainty, and requires renewed visible consent.

Account/client/repository/origin replacement discards private input and stale outcomes. Stable conversation ownership preserves public comments/replies through own detail refresh and target removal. Seven messages are translated in five locales; 1.8 text with keyboard, resize/theme preservation, integrated MR screen and twelve synthetic light/dark captures are covered. Local validation: clean analysis, 951 formatted Dart files with zero changes, and 7,246 full tests (139 new: API 49, repository 6, controller 61, widgets 23).

No blocking findings remain in the reviewed changes. Reads are not atomic or conditional writes; recovery is in memory and a conscious retry can duplicate a server-accepted request. The documented individual/system-origin and creation-type boundaries remain explicit, with no live GitLab/device guarantee. Approval covers this exact commit; all four required CI checks remain a separate merge prerequisite.

@sjungwon03
sjungwon03 merged commit ae819b7 into dev Oct 5, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:api packages/gitlab_api — GitLab REST/GraphQL client area:docs AGENTS.md, .agents/, README and friends area:ui Screens and feature UI feat New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Save private review reply drafts on existing MR discussions

2 participants