docs(06.2-02): complete SHARE-05 + SHARE-03 gap closure — 12 tests pass
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+66
@@ -0,0 +1,66 @@
|
||||
---
|
||||
plan: "06.2-02"
|
||||
phase: "06.2"
|
||||
status: complete
|
||||
started: "2026-05-31"
|
||||
completed: "2026-05-31"
|
||||
requirements:
|
||||
- SHARE-03
|
||||
- SHARE-05
|
||||
---
|
||||
|
||||
# Plan 06.2-02 Summary — SHARE-05 + SHARE-03 Gap Closure
|
||||
|
||||
## What Was Built
|
||||
|
||||
Closed two open v1 requirements in a single vertical slice:
|
||||
|
||||
- **SHARE-05 (badge bug):** DocumentCard.vue fixed — `Shared` pill now reads `doc.is_shared` (boolean from backend) instead of `doc.share_count > 0` (field that doesn't exist in API response).
|
||||
- **SHARE-03 (no permission control):** End-to-end permission flow wired from creation through editing.
|
||||
|
||||
### Backend (Task 1)
|
||||
|
||||
- `ShareCreate` model gained `permission: str = "view"` with `field_validator` enforcing `{"view", "edit"}`.
|
||||
- `SharePermissionPatch` model added (same validator).
|
||||
- `grant_share()` handler updated from hardcoded `permission="view"` to `permission=body.permission`.
|
||||
- New `PATCH /api/shares/{share_id}` endpoint added (placed before DELETE per route-ordering convention). IDOR protection mirrors `revoke_share` exactly: 404 on owner mismatch to prevent enumeration.
|
||||
- 3 xfail stubs from Plan 06.2-01 promoted to real tests.
|
||||
|
||||
### Frontend (Task 2)
|
||||
|
||||
- **DocumentCard.vue:** one-line fix — `v-if="doc.share_count > 0"` → `v-if="doc.is_shared"`.
|
||||
- **ShareModal.vue:** permission `<select>` (`Can view` / `Can edit`) inserted between handle input and submit button; defaults to "view"; resets after successful share.
|
||||
- **ShareModal.vue:** static "view" span replaced with View/Edit toggle group per share row — optimistic update with rollback on error; in-flight state tracked via `updatingPermission` Set.
|
||||
- **documents.js:** `shareDocument` updated to accept `permission` param; `updateSharePermission(shareId, permission)` action added.
|
||||
- **api/client.js:** `createShare` passes `permission` in POST body; `updateSharePermission` PATCH helper added.
|
||||
|
||||
## Test Results
|
||||
|
||||
```
|
||||
backend/tests/test_shares.py — 12 passed, 0 failed, 0 xfailed
|
||||
```
|
||||
|
||||
All pre-existing share tests pass. 3 promoted stubs now pass as real integration tests.
|
||||
|
||||
## Key Files
|
||||
|
||||
### Created
|
||||
- (no new files)
|
||||
|
||||
### Modified
|
||||
- `backend/api/shares.py` — permission field, SharePermissionPatch model, PATCH endpoint
|
||||
- `backend/tests/test_shares.py` — 3 xfail stubs promoted to real tests
|
||||
- `frontend/src/components/documents/DocumentCard.vue` — is_shared badge fix
|
||||
- `frontend/src/components/sharing/ShareModal.vue` — permission dropdown + View/Edit toggle
|
||||
- `frontend/src/stores/documents.js` — shareDocument signature + updateSharePermission action
|
||||
- `frontend/src/api/client.js` — createShare body + updateSharePermission helper
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- [x] POST /api/shares with permission="edit" stores "edit" — confirmed by test_share_create_with_permission
|
||||
- [x] PATCH /api/shares/{id} changes permission — confirmed by test_share_patch_permission
|
||||
- [x] PATCH by wrong owner returns 404 — confirmed by test_share_patch_idor
|
||||
- [x] DocumentCard reads doc.is_shared (not doc.share_count)
|
||||
- [x] ShareModal has permission dropdown with "Permission level" aria-label
|
||||
- [x] ShareModal share rows have View/Edit toggle with handlePermissionChange
|
||||
- [x] 12 tests pass, 0 fail
|
||||
Reference in New Issue
Block a user