Add ARG CACHEBUST=1 after FROM nginx:alpine to invalidate stale build cache.
HuggingFace was executing old Dockerfile instructions despite correct commit.
This forces a complete rebuild without cached layers.
refactor: restructure views into mixin-based architecture
- Convert monolithic views.py (226 lines) into focused components
- Create SimulationMixin and ReportingMixin following Django pattern
- Compose ProfileViewSet with mixins for single-ViewSet-per-resource
- Extract ReportingQueries service to eliminate code duplication
- Fix exception handling with proper DRF exceptions (ValidationError, NotFound, APIException)
- Add exception chaining with 'from e' to preserve stack traces
- Update test assertions for DRF exception response format
- Fix router registrations (one ViewSet per resource path)
- All 73 tests passing
feat: add per-section breakdown to ice usage endpoint and remove redundant ruff config
- Fix total_sections assertion to expect int not string
- Fix DailyProgress count in test_simulate_simple_profile (3 not 4)
- Fix ice_amount assertion to match actual Decimal serialization
All 107 tests now passing with 96% coverage.
feat: migrate from TypedDict to Pydantic for type safety
- Add pydantic>=2.10.6 dependency
- Replace all TypedDict classes with Pydantic BaseModel in simulator.py
- Update ConfigParser to return list[ProfileConfig] instead of list[dict]
- Update views.py to mutate Pydantic model attributes
- Update all test files to use Pydantic models
- Fix StopIteration exception handling in _update_state
- Add type annotation for progress_by_day dict
- Disable ruff SIM108 rule (conflicts with explicit if/else requirement)
This provides runtime validation in addition to static type checking,
fixing all 21 MyPy type errors without using Any or type: ignore.