Files
signal-platform/.kiro/specs/ux-improvements/tasks.md
Dennis Thiessen 181cfe6588
Some checks failed
Deploy / lint (push) Failing after 8s
Deploy / test (push) Has been skipped
Deploy / deploy (push) Has been skipped
major update
2026-02-27 16:08:09 +01:00

125 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Implementation Plan: UX Improvements
## Overview
Implement four UX improvements: balanced S/R zone selection in the backend, visible levels filtering (backend + frontend), Trade Scanner explainer banner and R:R analysis columns, and Rankings weight slider form. Backend changes use Python (FastAPI/Pydantic), frontend changes use TypeScript (React).
## Tasks
- [x] 1. Implement balanced S/R zone selection in `cluster_sr_zones()`
- [x] 1.1 Refactor `cluster_sr_zones()` to use interleave-based balanced selection
- In `app/services/sr_service.py`, after clustering and computing zones, split zones into `support_zones` and `resistance_zones` pools sorted by strength descending
- Implement round-robin interleave picking: alternate strongest from each pool until `max_zones` is reached or both pools exhausted
- If one pool is exhausted, fill remaining slots from the other pool
- Sort final selected zones by strength descending before returning
- _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6_
- [ ]* 1.2 Write property test: balanced zone selection guarantees both types
- **Property 1: Balanced zone selection guarantees both types**
- **Validates: Requirement 1.1**
- In `tests/unit/test_cluster_sr_zones.py`, use Hypothesis to generate sets of levels with at least one support and one resistance zone, verify output contains at least one of each type when `max_zones >= 2`
- [ ]* 1.3 Write property test: interleave selection correctness
- **Property 2: Interleave selection correctness**
- **Validates: Requirements 1.2, 1.3**
- Verify the selected zones match the expected round-robin interleave from support and resistance pools
- [ ]* 1.4 Write property test: zone output sorted by strength
- **Property 3: Zone output is sorted by strength**
- **Validates: Requirement 1.4**
- For any input, verify returned zones are sorted by strength descending
- [x] 1.5 Update existing unit tests for balanced selection behavior
- Update `tests/unit/test_cluster_sr_zones.py` to add tests for: mixed support/resistance input produces balanced output, all-support input fills from support only, all-resistance input fills from resistance only, single zone edge case
- _Requirements: 1.1, 1.2, 1.3, 1.5, 1.6_
- [x] 2. Implement `visible_levels` filtering in backend
- [x] 2.1 Add `visible_levels` field to `SRLevelResponse` schema
- In `app/schemas/sr_level.py`, add `visible_levels: list[SRLevelResult] = []` to `SRLevelResponse`
- _Requirements: 2.1, 2.3_
- [x] 2.2 Compute `visible_levels` in the SR levels router
- In `app/routers/sr_levels.py`, after computing zones, filter `level_results` to only those whose `price_level` falls within the `[low, high]` range of at least one zone
- Set the filtered list as `visible_levels` on the `SRLevelResponse`
- When zones list is empty, `visible_levels` should be empty
- _Requirements: 2.1, 2.2, 2.4_
- [ ]* 2.3 Write property test: visible levels subset within zone bounds
- **Property 4: Visible levels are a subset within zone bounds**
- **Validates: Requirements 2.1, 2.2**
- Verify every entry in `visible_levels` appears in `levels` and has a price within at least one zone's `[low, high]` range
- [x] 2.4 Update router unit tests for `visible_levels`
- In `tests/unit/test_sr_levels_router.py`, add tests verifying: `visible_levels` is present in response, `visible_levels` contains only levels within zone bounds, `visible_levels` is empty when zones are empty
- _Requirements: 2.1, 2.2, 2.4_
- [x] 3. Checkpoint - Ensure all backend tests pass
- Ensure all tests pass, ask the user if questions arise.
- [x] 4. Update frontend types and S/R levels table filtering
- [x] 4.1 Add `visible_levels` to frontend `SRLevelResponse` type
- In `frontend/src/lib/types.ts`, add `visible_levels: SRLevel[]` to the `SRLevelResponse` interface
- _Requirements: 2.1_
- [x] 4.2 Update `TickerDetailPage` to use `visible_levels` for the S/R table
- In `frontend/src/pages/TickerDetailPage.tsx`, change `sortedLevels` to derive from `srLevels.data.visible_levels` instead of `srLevels.data.levels`
- Keep sorting by strength descending
- Hide the S/R Levels Table section when `visible_levels` is empty
- Maintain existing color coding (green for support, red for resistance)
- _Requirements: 3.1, 3.2, 3.3, 3.4_
- [x] 5. Add Trade Scanner explainer banner and R:R analysis columns
- [x] 5.1 Add explainer banner to `ScannerPage`
- In `frontend/src/pages/ScannerPage.tsx`, add a static informational banner above the filter controls
- Banner text: describe that the scanner identifies asymmetric risk-reward trade setups using S/R levels as targets and ATR-based stops
- Banner should be visible on initial page load without user interaction
- _Requirements: 4.1, 4.2, 4.3_
- [x] 5.2 Add R:R analysis columns to `TradeTable`
- In `frontend/src/components/scanner/TradeTable.tsx`, add computed columns: Risk $ (`|entry_price - stop_loss|`), Reward $ (`|target - entry_price|`), % to Stop (`risk / entry * 100`), % to Target (`reward / entry * 100`)
- Color-code the existing R:R ratio column: green for ≥ 3.0, amber for ≥ 2.0, red for < 2.0
- Update the `SortColumn` type and `columns` array to include the new columns
- Update `sortTrades` in `ScannerPage.tsx` to handle sorting by new computed columns
- _Requirements: 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8_
- [ ]* 5.3 Write property test: trade analysis computation correctness
- **Property 5: Trade analysis computation correctness**
- **Validates: Requirements 5.2, 5.3, 5.4, 5.5**
- Using fast-check, for any trade with positive entry_price, stop_loss, and target, verify `risk_amount == |entry_price - stop_loss|`, `reward_amount == |target - entry_price|`, `stop_pct == risk_amount / entry_price * 100`, `target_pct == reward_amount / entry_price * 100`
- [x] 6. Convert Rankings weight inputs to sliders
- [x] 6.1 Replace number inputs with range sliders in `WeightsForm`
- In `frontend/src/components/rankings/WeightsForm.tsx`, replace `<input type="number">` with `<input type="range" min={0} max={100} step={1}>`
- On mount, convert API decimal weights to 0100 scale: `Math.round(w * 100)`
- Display current whole-number value next to each slider
- Show humanized label (replace underscores with spaces)
- _Requirements: 6.1, 6.2, 6.3, 6.4_
- [x] 6.2 Implement weight normalization on submit
- On submit, normalize slider values: divide each by the sum of all values
- Disable submit button when all sliders are zero
- Show validation message "At least one weight must be greater than zero" when all are zero
- Send normalized decimal weights via existing `useUpdateWeights` mutation
- _Requirements: 7.1, 7.2, 7.3, 7.4_
- [ ]* 6.3 Write property test: weight conversion round-trip
- **Property 6: Weight conversion round-trip**
- **Validates: Requirement 6.3**
- Using fast-check, verify that converting decimal weights to slider scale and normalizing back preserves relative proportions within floating-point tolerance
- [ ]* 6.4 Write property test: normalized weights sum to one
- **Property 7: Normalized weights sum to one**
- **Validates: Requirement 7.1**
- Using fast-check, for any set of slider values (integers 0100) where at least one > 0, verify normalized weights sum to 1.0 within ±1e-9
- [x] 7. Final checkpoint - Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
## Notes
- Tasks marked with `*` are optional and can be skipped for faster MVP
- Backend uses Python (Hypothesis for property tests), frontend uses TypeScript/React (fast-check for property tests)
- Each task references specific requirements for traceability
- Checkpoints ensure incremental validation after backend and full implementation phases
- Property tests validate universal correctness properties from the design document