6.7 KiB
6.7 KiB
1. Database Schema & Migrations
- 1.1 Add
span_label_typestable to Drizzle schema (id, name, display_name, color, hotkey, is_active, sort_order, created_at) - 1.2 Add
span_annotationstable to Drizzle schema (id, chart_id FK, start_time, end_time, label, confidence, outcome, notes, sub_spans JSON, color, created_at) - 1.3 Run migration to create both tables
- 1.4 Seed
span_label_typeswith default labels: bull_flag, bear_flag, head_and_shoulders, double_bottom, wedge_up, wedge_down, custom (with distinct colors and hotkeys 1-7)
2. Span Label Types API
- 2.1 Create
GET /api/span-label-typesendpoint — return all active label types sorted by sort_order - 2.2 Create
POST /api/span-label-typesendpoint — create a new label type - 2.3 Create
PATCH /api/span-label-types/[id]endpoint — update label type fields - 2.4 Create
DELETE /api/span-label-types/[id]endpoint — delete a label type
3. Span Annotations CRUD API
- 3.1 Create
GET /api/span-annotations?chartId=Xendpoint — return all span annotations for a chart, sorted by start_time desc - 3.2 Create
POST /api/span-annotationsendpoint — create span annotation with start/end time swap validation (start <= end) - 3.3 Create
PATCH /api/span-annotations/[id]endpoint — update label, confidence, outcome, notes, sub_spans - 3.4 Create
DELETE /api/span-annotations/[id]endpoint — delete a span annotation
4. SpanRectanglePrimitive (Chart Rendering)
- 4.1 Create
SpanRectanglePrimitive.tsimplementingISeriesPrimitivewith data-space rectangle coordinates (start_time, end_time, max_high, min_low) - 4.2 Implement
updateAllViews()with a pane renderer that converts time/price to pixel coordinates and draws a filled semi-transparent rectangle usinguseBitmapCoordinateSpace - 4.3 Implement label tag text rendering above the rectangle (pattern name)
- 4.4 Implement
hitTest()to detect clicks within the rectangle bounds - 4.5 Add highlight state (thicker border / increased opacity) for selected spans
- 4.6 Set
zOrder: 'bottom'so rectangles render behind candlesticks
5. Span Tool State & Integration
- 5.1 Extend
activeTooltype inpage.tsxto include'span'tool mode - 5.2 Add span-related state to
page.tsx:spanAnnotations[],selectedSpanId,spanLabelTypes[] - 5.3 Add
fetchSpanAnnotations(chartId)andfetchSpanLabelTypes()data fetching functions - 5.4 Load span annotations and label types when chart changes (alongside existing annotation loading)
- 5.5 Add "Span" tool button to Toolbox component alongside existing tools
6. Two-Click Span Selection & Preview
- 6.1 Create
SpanAnnotationManager.tsxcomponent that manages span interaction state (idle / first-click-done / popover-open) - 6.2 Implement first-click handler: snap to nearest candle, store start candle, render start marker via a preview primitive
- 6.3 Implement mouse-move preview: stretch preview rectangle from start candle to cursor candle, computing price range (min low to max high) of candles in range
- 6.4 Implement second-click handler: snap to nearest candle, finalize span range, swap if end < start, trigger popover
- 6.5 Implement Escape key to cancel span selection and clear preview
7. Label Assignment Popover
- 7.1 Create
SpanPopover.tsxwith shadcn Popover/Dialog: label dropdown (from span_label_types), confidence slider (1-5), outcome select (win/loss/breakeven/none), notes textarea, Save/Cancel buttons - 7.2 Position popover near the end-click position with collision avoidance
- 7.3 Wire Save button: POST to API, attach SpanRectanglePrimitive to chart series, update spanAnnotations state, close popover
- 7.4 Wire Cancel button / Escape: discard span, clear preview, close popover
- 7.5 Disable Save when no label is selected (validation)
8. Span Selection, Editing & Deletion
- 8.1 Implement span click-to-select using hitTest: set selectedSpanId, highlight rectangle, scroll sidebar list to selected item
- 8.2 Implement click-to-deselect (click selected span again or click outside any span)
- 8.3 Implement double-click / Enter to open edit popover pre-populated with current span data
- 8.4 Wire edit Save: PATCH to API, update primitive color/label, update state
- 8.5 Implement Delete/Backspace keyboard shortcut for selected span: DELETE API call, remove primitive, clear selection, update state
- 8.6 Implement delete-tool click on span rectangle: same DELETE flow as keyboard shortcut
9. Span Annotation Sidebar List
- 9.1 Create
SpanAnnotationList.tsxcomponent: scrollable list of span annotations sorted by start_time desc, showing time range, label with colored badge, delete button - 9.2 Add count summary grouped by label type (e.g., "Bull Flag: 3 | Bear Flag: 2")
- 9.3 Implement click-to-select in list: set selectedSpanId, highlight chart rectangle, scroll chart to center on span's time range
- 9.4 Highlight selected span entry in list (background/border)
- 9.5 Wire delete button per list item: DELETE API call, remove primitive, update state
- 9.6 Show empty state message when no span annotations exist
- 9.7 Clear and reload span list when active chart changes
10. Hotkey Label Assignment
- 10.1 Add keydown listener for span label hotkeys (active only when span tool is active and span range is selected)
- 10.2 On hotkey press: save span with mapped label (default confidence/outcome/notes), render rectangle, update sidebar — skip popover
- 10.3 Ignore hotkeys when span tool is inactive or no span range selected
11. Export Endpoints
- 11.1 Create
GET /api/export/spans?chartId=X&format=json— Raw Annotations JSON export with full metadata - 11.2 Create
GET /api/export/spans?chartId=X&format=windowed— Windowed Classification CSV with flattened OHLCV columns and configurablecontext_padding(default 10) - 11.3 Create
GET /api/export/spans?chartId=X&format=bio— BIO-tagged CSV with one row per candle, B-{label}/I-{label}/O tagging, multi-label columns for overlapping spans
12. Integration Testing & Polish
- 12.1 Verify full create flow: activate span tool → two clicks → popover → save → rectangle renders → sidebar updates
- 12.2 Verify edit flow: select span → double-click → edit popover → save → updates reflect
- 12.3 Verify delete flow: select span → Delete key / trash icon → removed from chart and sidebar
- 12.4 Verify chart switch: span annotations and sidebar list reload for new chart
- 12.5 Verify all three export formats produce correct output
- 12.6 Verify hotkey label assignment works end-to-end