The async-only direction was already the only one used in production: * create_storage never accepted mode=sync; build_storage_config always emitted mode=async; zero callers referenced StorageBackend / SyncData / S3StorageBackend.sync / LocalStorageBackend.sync anywhere. * Drop the parallel sync base class, the sync concrete classes in backends/local.py and backends/s3.py, and the boto3 dependency. * Drop example_usage.py (zero importers; demonstration code, not part of the public surface). * Rename LocalAsyncStorageBackend -> LocalStorageBackend, S3AsyncStorageBackend -> S3StorageBackend to reflect the single remaining class per type. * Tighten create_storage: any mode=... key now raises StorageConfigError with the new pointer (settings.storage_backend controls behavior). * Cleanup call sites: schedule.application.service.build_object_store no longer passes mode=async to create_storage. * Cosmetic touch-ups in backend/services/storage.py and common/config.py docstrings where they still said "boto3" instead of "S3 client". Public API surface preserved: AsyncStorageBackend / ObjectMeta / create_storage / build_storage_config / register_backend all keep their names and call signatures. backend tests: 136 passed.
Common
后端公共配置、标识、错误模型、日志和基础工具目录。
业务模块不得在本目录外重复定义公共 DTO 或错误码。