Files
office_translator/_bmad-output/implementation-artifacts/2-14-stockage-temporaire-metadata.md
Sepehr Ramezani 26bd096a06 feat: production deployment - full update with providers, admin, glossaries, pricing, tests
Major changes across backend, frontend, infrastructure:
- Provider system with model selection (Google, DeepL, OpenAI, Ollama, Google Cloud)
- Admin panel: user management, pricing, settings
- Glossary system with CSV import/export
- Subscription and tier quota management
- Security hardening (rate limiting, API key auth, path traversal fixes)
- Docker compose for dev, prod, and IONOS deployment
- Alembic migrations for new tables
- Frontend: dashboard, pricing page, landing page, i18n (en/fr)
- Test suite and verification scripts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-04-25 15:01:47 +02:00

143 lines
6.3 KiB
Markdown

# Story 2.14: Stockage Temporaire & Métadonnées
Status: done
## Story
As a **system**,
I want **to store uploaded files temporarily with metadata logging**,
so that **files can be processed and tracked efficiently while maintaining security and performance**.
## Acceptance Criteria
1. **Unique Storage**: Every uploaded file is saved to a temporary location (configured via `config.UPLOAD_DIR`) with a unique ID as the filename (FR51).
2. **Metadata Logging**: For every upload, the system logs the following metadata:
- `original_filename`
- `file_size`
- `file_hash` (SHA256)
- `timestamp`
- `user_id` (if available)
3. **No Content Logging**: Ensure that NO actual file content or sensitive internal document data is logged (NFR11, NFR16).
4. **Redis Tracking**: The file path and basic metadata are stored in Redis with a TTL of 60 minutes (Story 2.14).
5. **Job Association**: The metadata is correctly associated with the `job_id` generated during the translation request.
6. **Performance**: Metadata extraction (hashing) must not significantly delay the initial response (NFR1-NFR5).
## Tasks / Subtasks
- [x] **Task 1: Implement Metadata Extraction Utility**
- [x] 1.1 Add `calculate_sha256` method to `utils/file_handler.py`.
- [x] 1.2 Update `FileHandler.get_file_info` or create a new method to include the hash and structured metadata.
- [x] **Task 2: Integrate Redis for Temporary Tracking**
- [x] 2.1 Verify `TierQuotaService`'s Redis client usage for reuse.
- [x] 2.2 Implement a `StorageTracker` service (or extend `ProgressTracker`) to store file paths in Redis with TTL.
- [x] 2.3 Key pattern: `translation:file:{job_id}` with 60 min TTL.
- [x] **Task 3: Update Translation Endpoint**
- [x] 3.1 In `routes/translate_routes.py`, trigger metadata logging after successful file save.
- [x] 3.2 Ensure `user_id` and `timestamp` are captured.
- [x] 3.3 Ensure the `input_path` is correctly pushed to Redis tracking.
- [x] **Task 4: Audit Trail & Logging**
- [x] 4.1 Use `structlog` (or standard logging if `structlog` not yet integrated) to log the metadata in a structured JSON format.
- [x] 4.2 Validate that NO content is logged.
- [x] **Task 5: Verification & Tests**
- [x] 5.1 Add unit tests for SHA256 calculation.
- [x] 5.2 Add integration tests verifying Redis entry creation and TTL.
- [x] 5.3 Verify log output format.
## Dev Notes
### Previous Story Intelligence (2.13)
- `2-13` implemented robust file validation.
- The `translate_document_v1` endpoint already generates a `job_id` and saves the file using `file_handler_util.generate_unique_filename`.
- `2.13` also introduced `CORRUPTED_FILE` and `INVALID_FORMAT` error codes.
### Architecture Compliance
- **Storage**: Use `config.UPLOAD_DIR` and `config.OUTPUT_DIR`.
- **TTL**: `config.FILE_TTL_MINUTES` (60 min).
- **Security**: SHA256 for integrity and collision avoidance in logs.
- **Zero Retention**: TTL in Redis is the first step toward the automated cleanup job (`2-15`).
### Project Structure Notes
- `utils/file_handler.py`: Central place for file operations.
- `routes/translate_routes.py`: Orchestrates the upload flow.
- `middleware/tier_quota.py`: Good example of Redis client usage (`_get_async_redis`).
### References
- [Source: _bmad-output/planning-artifacts/epics.md#Story 2.14]
- [Source: _bmad-output/planning-artifacts/prd.md#NFR11, NFR16]
- [Source: config.py#CLEANUP_ENABLED, FILE_TTL_MINUTES]
## Dev Agent Record
### Agent Model Used
Gemini CLI (Expert Agent)
### Debug Log References
- SHA256 unit tests passed.
- StorageTracker unit tests (including Redis mocking and logging verification) passed.
- Translation endpoint integration tests passed.
### Completion Notes List
- ✅ Implemented `calculate_sha256` in `FileHandler`.
- ✅ Updated `get_file_info` to include SHA256 hash.
- ✅ Created `StorageTracker` service using `redis.asyncio`.
- ✅ Integrated `StorageTracker` into `translate_document_v1` endpoint.
- ✅ Added `structlog`-compatible logging for file uploads (metadata only).
- ✅ Added comprehensive unit and integration tests.
### File List
- `utils/file_handler.py`
- `services/storage_tracker.py`
- `routes/translate_routes.py`
- `tests/test_file_handler.py`
- `tests/test_storage_tracker.py`
- `tests/test_translation_metadata_integration.py`
## Senior Developer Review (AI)
**Reviewer:** Claude (Opencode)
**Date:** 2026-02-21
**Outcome:** ✅ APPROVED (with fixes applied)
### Issues Found & Fixed
| # | Severity | Issue | Fix Applied |
|---|----------|-------|-------------|
| 1 | HIGH | `calculate_sha256` sans gestion d'erreur | Added try/except, returns `None` on failure |
| 2 | HIGH | Pas de cleanup si hash échoue | Added `cleanup_file()` call on hash failure in translate_routes.py |
| 3 | MEDIUM | Fichier orphelin si hash échoue | Fixed with cleanup on error |
| 4 | MEDIUM | `file_hash` pouvait être `None` sans validation | Added validation + raise `CORRUPTED_FILE` error |
| 5 | MEDIUM | Échec Redis silencieux | Added `_log_error("redis_not_available", ...)` and `_log_info("file_tracked_in_redis", ...)` |
| 6 | MEDIUM | TTL hardcodée | Changed to `_get_default_ttl()` using `config.FILE_TTL_MINUTES` |
| 7 | LOW | `print()` au lieu de logger | Changed to `logging.getLogger(__name__)` |
| 8 | LOW | Test mockait le hash | Added real SHA256 calculation test + hash failure test |
### Files Modified in Review
- `utils/file_handler.py` - Error handling in `calculate_sha256`, logging in `cleanup_file`
- `services/storage_tracker.py` - Config-based TTL, improved logging
- `routes/translate_routes.py` - Hash validation + cleanup on failure
- `tests/test_file_handler.py` - Added edge case tests
- `tests/test_translation_metadata_integration.py` - Added hash failure test
### AC Validation
| AC | Status | Evidence |
|----|--------|----------|
| AC1: Unique Storage | ✅ | `file_handler_util.generate_unique_filename()` used |
| AC2: Metadata Logging | ✅ | `_log_info("file_uploaded", ...)` with all fields |
| AC3: No Content Logging | ✅ | Only metadata logged, no file content |
| AC4: Redis Tracking | ✅ | `storage_tracker.track_file()` with TTL |
| AC5: Job Association | ✅ | `job_id` passed to `track_file()` |
| AC6: Performance | ⚠️ | Hash is synchronous (noted for future async improvement) |
### Change Log
- 2026-02-21: Code review completed, 8 issues found and fixed. Status → done.