Files
kite/.planning/phases/12-cloud-resource-foundation/12-PATTERNS.md
T
2026-06-18 22:30:07 +02:00

104 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 12: Cloud Resource Foundation - Pattern Map
**Mapped:** 2026-06-18
**Status:** Complete
## Purpose
Map Phase 12 files and data flow to existing DocuVault patterns so implementation extends established architecture without duplicating helpers, grids, or provider-specific UI logic.
## Backend Pattern Map
| New/changed area | Closest analog | Pattern to preserve |
|------------------|----------------|---------------------|
| `backend/migrations/versions/0006_cloud_resource_foundation.py` | `0005_system_settings.py` | Typed Alembic table creation, named constraints/indexes, timezone timestamps, exact `down_revision="0005"`, reversible downgrade |
| `CloudItem` and connection fields in `backend/db/models.py` | `CloudConnection`, `Document`, `Folder` | UUID PKs, explicit owner FKs with cascade, compound owner/navigation indexes, human names in DB only |
| `backend/storage/cloud_base.py` | `backend/storage/base.py`, `backend/ai/base.py` | Small abstract interface; normalized domain values; provider adapters own translation |
| Provider capability/metadata normalization | Existing Google/OneDrive/Nextcloud adapters | Keep SDK/HTTP details inside provider files, wrap synchronous SDK calls with `asyncio.to_thread()`, preserve canonical `CloudConnectionError` import |
| `backend/services/cloud_items.py` | Owner-scoped query patterns in `api/folders.py`, service exception policy in AGENTS.md | Filter by owner in every statement; service raises `ValueError`/domain exceptions, never `HTTPException`; use shared `deps.utils.parse_uuid` at router boundary |
| `backend/api/cloud/` package | `backend/api/documents/` and `backend/api/admin/` | One aggregator owns `/api/cloud`; sub-routers have no prefix; root empty-path routes register on parent if FastAPI requires it |
| Cloud response schemas | `CloudConnectionOut` in `backend/api/schemas.py` | Explicit field whitelist with `from_attributes`; never serialize ORM objects or `credentials_enc` directly |
| Metadata refresh/backoff | Celery retry conventions in document tasks | Bounded exponential retry, idempotent upsert/reconciliation, no retry around ownership/validation failures |
### Required Backend Corrections
- Current `_upsert_cloud_connection()` and `_get_active_connection()` use `(user_id, provider)` and must not be copied. Phase 12 uses connection UUID as identity to support multiple same-provider accounts.
- Current listing cache key `{user_id}:{provider}:{folder_id}` is insufficient. Any transitional key includes connection UUID; durable metadata belongs in PostgreSQL.
- Current provider listing dictionaries contain only `id`, `name`, `is_dir`, `size`. New adapters normalize parent, MIME/type, mtime, etag/version, per-item capabilities, and completeness/pagination.
- `api/folders.py` contains a private `_parse_uuid`; new cloud routers must import `parse_uuid` from `backend/deps/utils.py` under the projects shared-helper rule.
## Frontend Pattern Map
| New/changed area | Closest analog | Pattern to preserve |
|------------------|----------------|---------------------|
| Capability-aware rows | `frontend/src/components/storage/StorageBrowser.vue` | This remains the only grid; props drive layout/state and generic events travel upward |
| Sync indicator | `frontend/src/components/ui/BreadcrumbBar.vue` | Extend shared breadcrumb rather than adding cloud-only breadcrumb markup |
| Connection roots | Current `CloudStorageView.vue` plus `StorageBrowser.vue` | View owns store/router only; feed normalized root rows into shared browser |
| Cloud folder route | `CloudFolderView.vue`, `FileManagerView.vue` | Thin data provider; no duplicated toolbar, row, action, or tooltip layout |
| API functions | `frontend/src/api/cloud.js` + `client.js` barrel | Change route arguments behind the domain module; consumers retain barrel imports |
| Connection state | `frontend/src/stores/cloudConnections.js` | Pinia owns connection/folder state and errors; components stay store-agnostic |
| Shared formatting | `frontend/src/utils/formatters.js` | Reuse `formatDate`, `formatSize`, and provider helpers; do not redefine locally |
| Icons | `frontend/src/components/ui/AppIcon.vue` | Add registry entries only when an existing icon name cannot express status/action |
### UI Contract Patterns
- Unsupported actions use `aria-disabled="true"`, remain focusable/tappable, and suppress action emission while surfacing explanation.
- Permanent unsupported state is gray; temporary unavailable state is amber. Do not hide actions based on `mode === "local"`.
- `StorageBrowser` receives capabilities, folder freshness, connection root, last refresh time, and byte availability as props.
- Local storage supplies a supported capability set so local/cloud share one rendering path.
- Minimum touch target stays 36x36 px and all controls use existing indigo focus-ring utilities.
- Session-only last folder state uses `sessionStorage` keyed by connection UUID; JWT tokens remain Pinia-memory-only.
## Testing Pattern Map
| Coverage | Existing analog | Phase 12 use |
|----------|-----------------|--------------|
| API/ownership | `backend/tests/test_cloud.py` | Multiple same-provider accounts, foreign connection/item 404, admin rejection, credential exclusion |
| Adapter contracts | `backend/tests/test_cloud_backends.py` | Shared normalized fixtures, async methods, pagination/completeness, no destructive probes |
| DB/service | async fixtures in `backend/tests/conftest.py` | Fast SQLite unit loop plus marked real-PostgreSQL constraint/index/cascade tests |
| Pinia | `frontend/src/stores/__tests__/cloudConnections.test.js` | Connection UUID routes, duplicate providers, freshness/error transitions |
| Storage browser | `StorageBrowser.dragmove/showSearch/skeleton.test.js` | Capability rendering, action suppression, focus/tap explanations, local regression |
| Breadcrumb | `components/ui/__tests__/BreadcrumbBar.test.js` | Refreshing/fresh/warning labels, timestamps, fade behavior |
| Thin views | `views/__tests__/FileManagerView.test.js` | Cloud views pass props/handle events without grid duplication |
## Data Flow
1. Router authenticates regular user and parses `connection_id` with shared request helpers.
2. Service resolves `(connection_id, user_id)` and reads durable children by connection/parent.
3. Provider adapter normalizes a complete paginated listing and capability states.
4. Service upserts metadata using `(connection_id, provider_item_id)` and reconciles only after complete success.
5. Explicit Pydantic schemas return rows, capability messages, freshness, and connection identity without credentials.
6. Pinia/view maps API data into `StorageBrowser`; the browser renders shared rows/actions and emits generic commands.
7. Browse never calls provider byte download, writes MinIO, or changes quota.
## Files Likely Modified
### Backend
- `backend/migrations/versions/0006_cloud_resource_foundation.py`
- `backend/db/models.py`
- `backend/storage/cloud_base.py`
- `backend/storage/cloud_backend_factory.py`
- provider backend modules
- `backend/services/cloud_items.py`
- `backend/api/cloud/__init__.py`, `connections.py`, `browse.py`, `schemas.py`
- `backend/main.py` only if aggregator import changes
- focused backend tests and PostgreSQL integration coverage
### Frontend
- `frontend/src/api/cloud.js`
- `frontend/src/stores/cloudConnections.js`
- `frontend/src/router/index.js`
- `frontend/src/views/CloudStorageView.vue`
- `frontend/src/views/CloudFolderView.vue`
- `frontend/src/components/storage/StorageBrowser.vue`
- `frontend/src/components/ui/BreadcrumbBar.vue`
- focused component/store/view tests
### Documentation/Versioning
- `AGENTS.md`, `README.md`, `backend/main.py`, and `frontend/package.json` per the project documentation/version protocol after user-facing plan completion.
## PATTERN MAPPING COMPLETE