feat: conflict resolution + remote-contribution review queue (#11) #67
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/v7-conflict-review-queue"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #11 — the final slice of v7 host-inbound-first.
Conflict gate (optimistic lock)
Remote updates now compare the local entry's
updated_atto the activity'spublishedtimestamp (threaded through from the inbox). If the local copy changed more recently, the update is held back as aconflictinstead of overwriting. Non-conflicting updates still apply automatically (last-write-wins) — matching the milestone's "auto-apply, review only conflicts" decision.Review queue (owner only)
GET /api/contributions?project_id=&status=conflict— lists contributions with the proposed payload beside the current entry content + the actor's display name.POST /api/contributions/:id/resolve{ action: 'apply' | 'reject' }— apply forces the remote version over the local entry (re-sanitized, re-embedded, audited); reject discards it. Already-resolved →409; non-owner →403.This is the minimal queue the milestone calls for; v8's moderation layer will later generalize it (the
remote_contributionstable is the shared substrate).Verification (dev server)
remoteContributionReview.test.ts— 7 tests: stale update → conflict (entry untouched); future-dated update → applied; queue lists conflicts with payload+current; resolve(apply) overwrites; resolve(reject) leaves local; double-resolve →409; non-owner →403.Full API suite 203 passed (was 196); app
npm run buildgreen.🤖 Generated with Claude Code
- Optimistic lock on remote updates: if the local entry's updated_at is newer than the activity's published timestamp, the update is queued as a 'conflict' instead of overwriting (last-write-wins otherwise). The inbox now passes the activity's published timestamp through. - Review queue API (routes/contributions.ts, owner only): GET /api/contributions?project_id=&status= lists contributions (with the proposed payload + current entry content); POST /api/contributions/:id/resolve {apply|reject} forces the remote version over the local entry or discards it. - ProjectDetailPage: an owner-only "Remote edit conflicts" panel showing current vs proposed content with Apply remote / Keep mine. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>