Quality cleanup refactoring

Made-with: Cursor
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-04-13 06:21:26 +03:00
parent 8f7deb3fca
commit 4eaf218f09
33 changed files with 957 additions and 207 deletions
@@ -0,0 +1,97 @@
# Baseline Metrics
## Run Info
- **Run**: 01-quality-cleanup
- **Mode**: Automatic
- **Date**: 2026-04-13
## Source Metrics
| Metric | Value |
|--------|-------|
| Source files | 11 |
| Source LOC | 785 |
| Test files | 6 |
| Test LOC | 295 |
| Endpoints | 7 |
### Source File Breakdown
| File | LOC | Type |
|------|-----|------|
| api_client.pyx | 222 | Cython |
| main.py | 187 | Python |
| hardware_service.pyx | 100 | Cython |
| binary_split.py | 69 | Python |
| security.pyx | 68 | Cython |
| cdn_manager.pyx | 44 | Cython |
| constants.pyx | 44 | Cython |
| setup.py | 27 | Python |
| unlock_state.py | 11 | Python |
| credentials.pyx | 9 | Cython |
| user.pyx | 6 | Cython |
## Test Results (Last Run)
| Metric | Value |
|--------|-------|
| Total tests | 18 |
| Passed | 18 |
| Failed | 0 |
| Skipped | 0 |
| Errors | 0 |
| Duration | 12.87s |
## Endpoint Inventory
| Endpoint | Method | Tested | Notes |
|----------|--------|--------|-------|
| /health | GET | Yes | AC-1 |
| /status | GET | Yes | AC-2 partial |
| /login | POST | Yes | AC-2, AC-3 |
| /load/{filename} | POST | Yes | AC-4 |
| /upload/{filename} | POST | Yes | AC-5 |
| /unlock | POST | Yes | AC-6, AC-7, AC-10 |
| /unlock/status | GET | Yes | AC-8 |
## Identified Issues
| # | Issue | Location | Severity | Category |
|---|-------|----------|----------|----------|
| 1 | ApiClient singleton not thread-safe | main.py:20-25 | Medium | Race condition |
| 2 | Global mutable unlock state | main.py:48-50 | Medium | Testability / thread safety |
| 3 | Manual PKCS7 unpadding (incomplete validation) | security.pyx:38-44, binary_split.py:46-53 | Medium | Security / correctness |
| 4 | Hardcoded log file path | constants.pyx:20 | Low | Configurability |
| 5 | `os.remove` error silently swallowed | main.py:143-146 | Low | Error handling |
| 6 | Dead code: 5 orphan methods + 5 orphan constants | api_client.pyx, constants.pyx | Low | Dead code |
### Issue Details
**Issue 1 — ApiClient singleton race condition**: `get_api_client()` checks `if api_client is None` and assigns without a lock. Under concurrent requests, two threads could create separate instances, the second overwriting the first.
**Issue 2 — Global mutable unlock state**: `unlock_state` and `unlock_error` are module-level globals in `main.py`. They are protected by `unlock_lock` for writes, but the pattern of global state makes reasoning about state transitions harder and prevents running multiple unlock sequences.
**Issue 3 — Manual PKCS7 unpadding**: `security.pyx:38-44` manually reads the last byte to determine padding length, but does not validate that all N trailing bytes equal N (as PKCS7 requires). Corrupted or tampered ciphertext silently produces garbage. If the last byte is outside 1-16, data is returned as-is with no error. The library's `padding.PKCS7(128).unpadder()` is already imported (line 8) and used for encryption — the same should be used for decryption. The same manual pattern exists in `binary_split.py:46-53` for archive decryption.
**Issue 4 — Hardcoded log path**: `constants.pyx:20` writes to `"Logs/log_loader_{time:YYYYMMDD}.txt"` with no environment variable override. Works in Docker where `/app/Logs/` is the implicit path, but breaks or creates unexpected directories in other environments.
**Issue 5 — Silent error swallowing**: `main.py:143-146` catches `OSError` on `os.remove(tar_path)` and passes silently. Per project rules, errors should not be silently suppressed.
**Issue 6 — Dead code**: 5 orphan methods in `api_client.pyx` (`get_user`, `list_files`, `check_resource`, `upload_to_cdn`, `download_from_cdn`) — defined and declared in `.pxd` but never called from any source file. 5 orphan constants in `constants.pyx` (`CONFIG_FILE`, `QUEUE_CONFIG_FILENAME`, `AI_ONNX_MODEL_FILE`, `MODELS_FOLDER`, `ALIGNMENT_WIDTH`) — declared but never referenced outside their own file. Git history preserves them if ever needed again.
## Dependencies
| Package | Version | Used In |
|---------|---------|---------|
| fastapi | latest | main.py |
| uvicorn[standard] | latest | server |
| Cython | 3.1.3 | build |
| requests | 2.32.4 | api_client, binary_split |
| pyjwt | 2.10.1 | api_client |
| cryptography | 44.0.2 | security, binary_split |
| boto3 | 1.40.9 | cdn_manager |
| loguru | 0.7.3 | constants |
| pyyaml | 6.0.2 | api_client |
| psutil | 7.0.0 | hardware_service |
| python-multipart | latest | main.py (file upload) |