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