fix(05): revise Phase 5 plans based on checker feedback — B1-B4, W1-W4
B1: Mark RESEARCH.md Open Questions as (RESOLVED) with decision text for all 3
B2: Backends now stateless — raise CloudConnectionError(reason=) only; API layer
in cloud.py owns token refresh + DB update via _call_cloud_op helper
B3: Add Task 3 to Plan 05 — cloud connection + object cleanup on account deletion (SEC-09)
B4: Add frontend_url setting to Plan 01 Task 1; Plan 05 uses settings.frontend_url
for OAuth callback redirects
W1: ROADMAP.md Phase 5 now correctly labels Plans 03+04 as Wave 3 (not Wave 2)
W2: Plan 06 invalid_grant test now asserts both 503 HTTP response AND DB REQUIRES_REAUTH
W3: Plan 06 Task 2 split into unit tests (4, cloud_utils.py) and integration tests (11, HTTP)
W4: Plan 07 adds Vitest tests for cloudConnections store (4 tests) and SettingsCloudTab
mount test (2 tests) per CLAUDE.md testing protocol
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -24,7 +24,7 @@ must_haves:
|
||||
- "All 15 Phase 5 test stubs exist in test_cloud.py and xfail with strict=False"
|
||||
- "conftest.py has mock_google_drive_creds, mock_onedrive_creds, mock_webdav_client, cloud_connection_factory fixtures"
|
||||
- "requirements.txt includes all 6 new packages with correct version pins"
|
||||
- "config.py has CLOUD_CREDS_KEY, GOOGLE_CLIENT_ID/SECRET, ONEDRIVE_CLIENT_ID/SECRET/TENANT_ID, BACKEND_URL settings"
|
||||
- "config.py has CLOUD_CREDS_KEY, GOOGLE_CLIENT_ID/SECRET, ONEDRIVE_CLIENT_ID/SECRET/TENANT_ID, BACKEND_URL, FRONTEND_URL settings"
|
||||
- "pytest -v passes with zero failures after Wave 0 (stubs xfail, not fail)"
|
||||
artifacts:
|
||||
- path: "backend/tests/test_cloud.py"
|
||||
@@ -96,7 +96,7 @@ From backend/api/admin.py:
|
||||
</read_first>
|
||||
<behavior>
|
||||
- requirements.txt contains all 6 new packages with their exact version pins
|
||||
- config.py Settings class has: cloud_creds_key (str, default "CHANGEME-32-bytes-padded!!"), google_client_id (str, default ""), google_client_secret (str, default ""), onedrive_client_id (str, default ""), onedrive_client_secret (str, default ""), onedrive_tenant_id (str, default "common"), backend_url (str, default "http://localhost:8000")
|
||||
- config.py Settings class has: cloud_creds_key (str, default "CHANGEME-32-bytes-padded!!"), google_client_id (str, default ""), google_client_secret (str, default ""), onedrive_client_id (str, default ""), onedrive_client_secret (str, default ""), onedrive_tenant_id (str, default "common"), backend_url (str, default "http://localhost:8000"), frontend_url (str, default "http://localhost:5173")
|
||||
- All new settings have empty-string or safe defaults so the app boots without cloud credentials configured
|
||||
</behavior>
|
||||
<action>
|
||||
@@ -113,9 +113,10 @@ From backend/api/admin.py:
|
||||
- onedrive_client_secret: str = "" (ONEDRIVE_CLIENT_SECRET)
|
||||
- onedrive_tenant_id: str = "common" (ONEDRIVE_TENANT_ID — "common" works for personal + org accounts)
|
||||
- backend_url: str = "http://localhost:8000" (BACKEND_URL — used to construct OAuth callback URLs)
|
||||
- frontend_url: str = "http://localhost:5173" (FRONTEND_URL — used to construct OAuth success/error redirect to Vue app; per B4 fix)
|
||||
|
||||
.env.example should have the CLOUD_CREDS_KEY, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET,
|
||||
ONEDRIVE_CLIENT_ID, ONEDRIVE_CLIENT_SECRET, ONEDRIVE_TENANT_ID, BACKEND_URL entries
|
||||
ONEDRIVE_CLIENT_ID, ONEDRIVE_CLIENT_SECRET, ONEDRIVE_TENANT_ID, BACKEND_URL, FRONTEND_URL entries
|
||||
(create .env.example if it doesn't exist, or append if it does).
|
||||
</action>
|
||||
<verify>
|
||||
@@ -123,10 +124,10 @@ From backend/api/admin.py:
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- backend/requirements.txt contains lines matching: cryptography>=41.0.0, google-auth-oauthlib>=1.3.1, google-api-python-client>=2.196.0, msal>=1.36.0, webdavclient3>=3.14.7, cachetools>=5.3.0
|
||||
- backend/config.py contains `cloud_creds_key: str` and `google_client_id: str` and `backend_url: str`
|
||||
- backend/config.py contains `cloud_creds_key: str` and `google_client_id: str` and `backend_url: str` and `frontend_url: str`
|
||||
- `python -c "from config import settings; print(settings.cloud_creds_key)"` prints without ImportError
|
||||
</acceptance_criteria>
|
||||
<done>requirements.txt has all 6 Phase 5 package lines; config.py imports and Settings loads without error; all 7 new cloud settings accessible via settings.{field_name}</done>
|
||||
<done>requirements.txt has all 6 Phase 5 package lines; config.py imports and Settings loads without error; all 8 new cloud settings accessible via settings.{field_name}</done>
|
||||
</task>
|
||||
|
||||
<task type="auto" tdd="true">
|
||||
@@ -278,7 +279,7 @@ cd /Users/nik/Documents/Progamming/document_scanner/backend && python -m pytest
|
||||
- pytest tests/test_cloud.py exits 0; all 15 stubs show xfailed
|
||||
- pytest -v (full suite) exits 0 with zero failures
|
||||
- requirements.txt contains all 6 new package lines
|
||||
- config.py Settings loads without error; cloud_creds_key, google_client_id, backend_url all accessible
|
||||
- config.py Settings loads without error; cloud_creds_key, google_client_id, backend_url, frontend_url all accessible
|
||||
- conftest.py has 4 new fixtures: mock_google_drive_creds, mock_onedrive_creds, mock_webdav_client, cloud_connection_factory
|
||||
</success_criteria>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user