- local_converter.py: remove redundant `_default_converter = None` in
except block of `_ensure_default_converter` (variable was already None,
re-raised immediately — dead store)
- test_analysis_service.py: replace bare `await task` with
`await asyncio.gather(task)` to satisfy static analysis
- Replace French mode strings (configurer/verifier/preparer) with English
equivalents (configure/verify/prepare) in StudioPage.vue and tests
- Extract _build_conversion_options, _run_conversion, _finalize_analysis
from _run_analysis_inner to respect Single Responsibility Principle
- Rename _get_default_converter to _ensure_default_converter to reflect
its lazy-init side effect
Closes#136, closes#137, closes#138
Frontend decoupling:
- Create shared/appConfig.ts as reactive bridge (locale, maxFileSizeMb,
maxPageCount) eliminating shared→features and feature→feature imports
- Give history feature its own Pinia store and API layer (was re-export
of analysis store)
- Give chunking feature its own Pinia store and API layer (was importing
from analysis)
- ChunkPanel receives analysis data via props instead of cross-feature
store import
- document/store reads maxFileSizeMb from shared config instead of
importing feature-flags store
- shared/i18n reads locale from shared config instead of importing
settings store
Backend:
- Add HealthResponse Pydantic schema for /api/health endpoint
Closes#140, closes#141, closes#142, closes#143
Add state-machine guard clauses to AnalysisJob transition methods
(mark_running, mark_completed, mark_failed, update_progress) to prevent
invalid status transitions. Make all domain value objects immutable with
frozen=True. Add 11 tests covering guard clause behavior.
Closes#132, closes#133
- Add DocumentRepository and AnalysisRepository protocols in domain/ports.py (#128)
- Refactor persistence repos from module functions to SqliteDocumentRepository
and SqliteAnalysisRepository classes
- Inject repos into AnalysisService and new DocumentService class via
constructor, removing direct imports of persistence and infra.settings (#129)
- Move _merge_results, _classify_error, _extract_html_body to domain/services.py (#130)
- Update main.py composition root to build and wire all dependencies
- Switch api/documents.py to Depends pattern matching api/analyses.py
- Update all tests to use injected mocks instead of module-level patches
Closes#128, closes#129, closes#130
The Release summary job was downloading ALL artifacts (~780 MB)
including Docker images it never uses. The 648 MB docker-image-local
consistently timed out after 5 retries. Now downloads only the 4
small artifacts actually needed (~2 KB total).
Read version from the backend /api/health endpoint instead of
hardcoding from package.json at build time. Add About section
in Settings with link to the DZone design article.
Replace the basic progress bar with a ring percentage indicator,
segmented batch bar with pulse animation, and an inline mini
progress bar in the top banner visible from any tab.
Re-read the job from DB before mark_completed so that
progress_current/progress_total written during batched conversion
are not overwritten by the stale in-memory object.
Add regression unit test and e2e assertion on final progress values.
Force Node.js 24 in all GitHub Actions workflows to suppress the
upcoming Node.js 20 deprecation warnings. Disable vue/html-indent and
vue/html-closing-bracket-newline ESLint rules that conflict with
Prettier formatting.
Closes#122
These env vars were set in the CI workflow step but never passed through
docker-compose to the container, so the backend always used defaults
(100 RPM), causing 429 errors in E2E tests.
The backend container only exposes port 8000 internally (expose, not
ports). The health check and Karate tests must go through the nginx
proxy on port 3000, the only port published to the host.