ad06fe7de4
Consolidate backend modules/tests under the backend package while syncing Supabase compose/env config and related plans.
6.0 KiB
6.0 KiB
Plan: Base Service for Redis and Qdrant
Date: 2026-02-05 Author: AI Assistant Status: Draft
Overview
Create a reusable base service module under backend/src/services/base that standardizes Redis and Qdrant client creation, lifecycle management, and error handling. Align the design with the DIVA-backend equivalent (once provided) and integrate configuration through existing SOCIAL_REDIS__* and SOCIAL_QDRANT__* settings.
Requirements
Functional
- Provide a base service abstraction that exposes Redis and Qdrant clients to other services.
- Use async client implementations compatible with FastAPI async execution.
- Support connection lifecycle hooks (initialize, health check, close).
- Centralize error handling and translate connection failures to consistent HTTP errors.
- Mirror DIVA-backend base service features and naming conventions where applicable.
Non-Functional
- Performance: reuse client instances; avoid per-request connection creation.
- Security: never log secrets (API keys/passwords); enforce TLS settings when enabled.
- Reliability: implement timeouts and retry policy where supported by client libraries.
Technical Approach
Introduce a services/base package that provides a small, composable base class plus Redis/Qdrant client factories. Configuration will be sourced from core/config/settings.py using the existing .env keys. The base service will accept injected clients to keep testability high and avoid global state, while a module-level factory will handle creation and cleanup.
Key Decisions
| Decision | Rationale |
|---|---|
| Use async Redis and Qdrant clients | Matches FastAPI async usage and avoids blocking the event loop. |
| Constructor injection with factories | Keeps services testable and avoids hidden global state. |
| Centralized error mapping in base service | Ensures consistent HTTP 503 responses and logging. |
Implementation Steps
Phase 1: DIVA-backend Parity Review (1-2 hours)
- Locate DIVA-backend base service module (path or repo) and document its responsibilities, public API, and lifecycle behavior.
- Produce a parity checklist to map DIVA behaviors to this repo (naming, error types, retry policy, health checks).
Phase 2: Configuration and Client Factories (3 hours)
- Add
RedisSettingsandQdrantSettingssections tobackend/src/core/config/settings.pyusing existingSOCIAL_REDIS__*andSOCIAL_QDRANT__*env keys. - Create
backend/src/services/base/redis_client.pyandbackend/src/services/base/qdrant_client.pywith async client factory functions and close helpers. - Add structured logging for client initialization, connection failures, and shutdown paths.
Phase 3: Base Service Class (3 hours)
- Create
backend/src/services/base/service.pywith aBaseServicethat accepts optional Redis/Qdrant clients (dependency injection). - Add helper methods (e.g.,
require_redis(),require_qdrant()) that raise HTTP 503 on unavailable clients. - Define error translation utilities for Redis/Qdrant exceptions with consistent messages and logging.
Phase 4: Tests (TDD) and Minimal Integration (4 hours)
- Unit tests for settings parsing and default values (RED/GREEN).
- Unit tests for base service behavior: missing client errors, exception mapping, and logging context.
- Integration tests using running Redis/Qdrant containers to verify client factories can connect and execute a simple command.
- E2E test that exercises a minimal endpoint using the base service (e.g.,
/health/infra), or record an explicit exception if no API integration is allowed.
Files to Modify
| File | Changes |
|---|---|
| backend/src/core/config/settings.py | Add Redis/Qdrant settings models and defaults. |
| backend/src/app.py | (If needed) register startup/shutdown hooks for client lifecycle. |
| backend/src/v1/router.py | (If needed) add an infra health endpoint to support E2E. |
Files to Create
| File | Purpose |
|---|---|
| backend/src/services/base/__init__.py | Package export surface for base services. |
| backend/src/services/base/service.py | Base service class for Redis/Qdrant access. |
| backend/src/services/base/redis_client.py | Redis client factory and teardown helpers. |
| backend/src/services/base/qdrant_client.py | Qdrant client factory and teardown helpers. |
| backend/tests/unit/services/base/test_service.py | Unit tests for base service error handling. |
| backend/tests/unit/services/base/test_clients.py | Unit tests for client factory behavior. |
| backend/tests/integration/services/base/test_clients.py | Integration tests with Redis/Qdrant containers. |
| backend/tests/e2e/test_infra_health.py | E2E test for an endpoint using base service. |
Dependencies
redis(async client) for Redis connectivity.qdrant-clientfor Qdrant connectivity (async/GRPC as configured).- No additional infra services required (Redis/Qdrant already in Docker compose).
Testing Strategy
- Unit Tests: Base service behavior, missing client errors, exception translation, settings parsing.
- Integration Tests: Connect to Redis and Qdrant, run minimal ping/health operations.
- E2E Tests: Call a minimal endpoint that uses the base service to validate wiring and error handling.
Risks & Mitigations
| Risk | Impact | Likelihood | Mitigation |
|---|---|---|---|
| DIVA-backend module not available | Medium | High | Add a parity checklist and update plan once module location is provided. |
| Client library mismatch (sync vs async) | Medium | Medium | Select async-supported libraries and verify compatibility in unit tests. |
| Lack of API integration for E2E | High | Medium | Add a minimal infra health endpoint or record a documented exception. |
| Connection config mismatches | Medium | Medium | Validate settings with integration tests and mirror .env.example. |
Estimated Effort
| Phase | Effort |
|---|---|
| Phase 1 | 2 hours |
| Phase 2 | 3 hours |
| Phase 3 | 3 hours |
| Phase 4 | 4 hours |
| Total | 12 hours |