feat(01-04): rewrite services/storage.py as async SQLAlchemy + MinIO orchestrator

- Replaced entire flat-file + filelock implementation with async ORM + MinIO
- All 14 DB-touching functions are async def accepting AsyncSession as first param
- load_settings/save_settings/mask_api_key/settings_masked remain sync (flat-file, Phase 2 will migrate)
- save_upload uses null-user D-03 sentinel; object_key via MinIO put_object
- update_document_topics auto-creates missing topics via create_topic deduplication
- No filelock, no METADATA_DIR/UPLOADS_DIR/TOPICS_FILE references remain
- Added __all__ listing all 18 public functions
- Updated conftest.py: removed filelock patching no longer needed
- Fixed test_object_key_schema: removed unused db_session param (SQLite INET type conflict)
This commit is contained in:
curo1305
2026-05-22 09:39:32 +02:00
parent eaf86a832a
commit 3e4b1f1f91
3 changed files with 410 additions and 127 deletions
+3 -6
View File
@@ -41,14 +41,11 @@ def isolated_data_dir(monkeypatch, tmp_path):
monkeypatch.setattr(config, "TOPICS_FILE", data_dir / "topics.json")
monkeypatch.setattr(config, "SETTINGS_FILE", data_dir / "settings.json")
# Plan 04: services.storage is now async (PostgreSQL + MinIO).
# The flat-file _topics_lock / _settings_lock attributes no longer exist.
# Only SETTINGS_FILE is still used by the sync load_settings/save_settings.
import services.storage as st
from filelock import FileLock
monkeypatch.setattr(st, "UPLOADS_DIR", data_dir / "uploads")
monkeypatch.setattr(st, "METADATA_DIR", data_dir / "metadata")
monkeypatch.setattr(st, "TOPICS_FILE", data_dir / "topics.json")
monkeypatch.setattr(st, "SETTINGS_FILE", data_dir / "settings.json")
monkeypatch.setattr(st, "_topics_lock", FileLock(str(data_dir / "topics.json") + ".lock"))
monkeypatch.setattr(st, "_settings_lock", FileLock(str(data_dir / "settings.json") + ".lock"))
yield data_dir
+1 -1
View File
@@ -20,7 +20,7 @@ import pytest
# Test 1: object key matches STORE-02 regex
# ---------------------------------------------------------------------------
async def test_object_key_schema(db_session):
async def test_object_key_schema():
"""STORE-02: put_object must return a key matching {user_id}/{doc_id}/{uuid4}{ext}."""
try:
from storage.minio_backend import MinIOBackend