Includes planning artifacts (03-CONTEXT, 03-DISCUSSION-LOG, 03-02-SUMMARY), integration test script, MinIO/auth/docker fixes, and local dev account reference. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add generate_presigned_put_url and stat_object abstract methods to StorageBackend ABC - Extend MinIOBackend with dual client (self._client internal + self._public_client public) - MinIOBackend.__init__ accepts optional public_endpoint param (RESEARCH.md Finding 3) - generate_presigned_put_url uses self._public_client for browser-resolvable URLs - stat_object uses self._client.stat_object and returns .size (authoritative, T-03-05) - get_storage_backend() passes public_endpoint=settings.minio_public_endpoint - config.py adds minio_public_endpoint field (RESEARCH.md Finding 3) - docker-compose.yml: MINIO_API_CORS_ALLOW_ORIGIN on minio service (T-03-09) - docker-compose.yml: MINIO_PUBLIC_ENDPOINT on backend service - docker-compose.yml: new celery-beat service (RESEARCH.md Finding 10)
- backend/storage/base.py: StorageBackend ABC with 5 abstract methods mirroring ai/base.py - backend/storage/minio_backend.py: MinIOBackend wrapping all sync Minio SDK calls in asyncio.to_thread(); STORE-02 key schema: {user_id}/{document_id}/{uuid4()}{ext} - backend/storage/__init__.py: get_storage_backend() factory mirroring ai/__init__.py - backend/tests/test_storage.py: remove xfail markers (plan 04 implements the module)