To upload files, navigate into a cloud folder first.
```
The hint must be a sibling of the connections list `
`, not nested inside it. Keep both inside the single `v-else` block so the hint is only visible when connections exist.
- CloudStorageView.vue contains `To upload files, navigate into a cloud folder first.` in a `` element inside the `v-else` block
- The `
` is NOT inside the `v-else-if="connections.length === 0"` empty state block
- `cd frontend && npm run build` exits 0 with no errors
- No DropZone or UploadProgress imported or rendered in CloudStorageView.vue
cd /Users/nik/Documents/Progamming/document_scanner/frontend && npm run build 2>&1 | tail -5
Upload hint added below connections list. Build passes. No DropZone added. Existing connection click behavior unchanged.
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| oauth_initiate preflight | User-supplied provider string already validated; new checks only inspect server-side settings values — no user input involved |
| 502 error message | Static string, no user data reflected in the error detail |
| volume mount | Read-only to container — same bind mount pattern as backend service |
## STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-05-12-01 | Information Disclosure | 400 error message for missing creds | mitigate | Message names env vars (server config), not any user data or secret values — safe to expose |
| T-05-12-02 | Information Disclosure | 502 error message | mitigate | Static string "Cloud backend unreachable" — no stack trace, no exception detail leaked to client |
| T-05-12-03 | Tampering | celery-worker volume mount | accept | Bind mount is same as backend service; only developer-controlled source files are mounted; production deployments use image builds, not bind mounts |
| T-05-12-SC | Tampering | npm/pip installs | mitigate | No new packages installed in this plan |
After all tasks complete:
- `cd backend && python -m pytest tests/test_cloud_api.py::test_oauth_initiate_google_drive_not_configured tests/test_cloud_api.py::test_oauth_initiate_onedrive_not_configured -v` — 2 tests pass
- `cd backend && python -m pytest tests/test_documents_api.py::test_stream_document_content_cloud_backend_error -v` — 1 test passes
- `cd backend && python -m pytest -v` — zero new failures
- `cd frontend && npm run build` — zero errors
- Manual: docker-compose.yml celery-worker service has `volumes: - ./backend:/app`
- Manual: open CloudStorageView at /cloud — upload hint visible below connections list
- Manual: curl -H "Authorization: Bearer " http://localhost:8000/api/cloud/oauth/initiate/onedrive (with empty OneDrive creds) → 400 with "ONEDRIVE_CLIENT_ID" in detail
- oauth_initiate returns 400 with descriptive env-var hint for unconfigured google_drive and onedrive
- stream_document_content returns 502 (not 500) for non-CloudConnectionError cloud exceptions
- celery-worker has volume mount so `docker compose restart celery-worker` picks up code changes
- CloudStorageView shows upload hint directing users to navigate into a folder
- 3 new backend tests pass; full pytest suite has zero new failures; frontend build clean