Frozen domain/data contracts for issues, pull requests, reviews, and
comments so TASK-008's UI can be built without touching shared layers.
- Separate immutable IssueSummary/Detail and PullRequestSummary/Detail
models; WorkItemAuthor.Unavailable instead of inventing an identity
for deleted/null authors.
- PullRequestState derived from Gitea's merged flag + open/closed
state (no single field already encodes "merged").
- listIssues drops entries with a non-null pull_request field so
Gitea's issue-list endpoint (which also returns PRs) never
duplicates listPullRequests, done client-side rather than trusting
an unverified query parameter.
- Reuses existing Page<T> and ApiFailure rather than new parallel
types. Read-only: no put/delete/postForm call anywhere in the file.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
TASK-018, human product owner priority-1 request. Adds write:user
OAuth scope (ADR-004) and relaxes OAuthClientConfig's read-only guard
to an explicit, hard-coded write-scope allow-list rather than a
general write-scope allowance. GiteaRepositoryBrowserApi gains star/
unstar/listStarred via a new RepositoryFavorites interface, reusing
its existing repository mapping. RepositoryListViewModel tracks an
ALL/FAVORITES mode; toggling favorite confirms against the server
before updating UI state rather than acting optimistically.
No create/edit/merge/close/comment endpoint is introduced. Favorite
state is never cached locally.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
TASK-017, human product owner priority-1 request. Repository list now
requests sort=updated&order=desc from Gitea, loads 5 repositories per
page with explicit prev/next navigation, and each visible row
independently fetches and shows its most recently committed branch.
Removes the legacy eager-loading RepositoryListApi in favor of the
existing paged GiteaRepositoryBrowser.listRepositories. Fixes two
issues found in self-review: missing error handling on page
navigation, and repositories with no default branch (empty repos)
previously failing the whole page instead of just that row.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Independent read-only review of 8a47d30/bbbff77/16c46a5 per
handoff/claude-master-handoff.md's review-and-freeze step. Verified
build/test/lint independently rather than trusting recorded evidence.
Fixed P2: requireSuccess() collapsed HTTP 409/422 into the generic
InvalidResponse, which would have blocked TASK-007's planned
conflict/unprocessable error states. Added ApiFailure.Conflict and
ApiFailure.Unprocessable with test coverage.
Recorded a P3 (CPU-bound work on the Main dispatcher in
CodeBrowserViewModel) for TASK-016 rather than fixing it now. Closed
TASK-005/006's mutual contract-freeze checkboxes. No P0/P1 found.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Pure-Kotlin classifier for feature/codebrowser/content/ that turns
already-loaded SourceContent bytes into bounded text, binary, Git LFS
pointer, unsupported-encoding, or oversized results with caller-supplied
positive byte/character/line limits, per handoff/task-006a-ready.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>