Commit graph

46 commits

Author SHA1 Message Date
Marko Djordjevic
9a5e325632 feat(auth): add POST /api/auth/register endpoint (task 4.1)
Validates email presence and password length (8+ chars), checks email
uniqueness with 409 on conflict, hashes password with bcryptjs (cost 12),
inserts user into the users table and returns 201 with id/email/name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 10:14:55 +01:00
Marko Djordjevic
45b6366861 Create nextauth route handler exporting GET/POST from auth.ts (task 3.4) 2026-02-20 10:13:32 +01:00
Marko Djordjevic
328476a581 Fix predict proxy schema and error messages 2026-02-18 23:38:17 +01:00
Marko Djordjevic
07064fbf40 fix(training): use selected chart and include TA-Lib span sources 2026-02-18 23:21:23 +01:00
Marko Djordjevic
b2129ad626 security: add CSV injection protection to all export routes
Add sanitizeCsvCell() helper to both export routes that prefixes cell
values starting with =, +, @, or - with a single quote to prevent CSV
formula injection attacks.

Applied to:
- src/app/api/export/route.ts: timestamp and label_type columns
- src/app/api/span-annotations/export/route.ts: start_time, end_time,
  label, and outcome columns

Closes task 4.10.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:20:36 +01:00
Marko Djordjevic
15adf09b73 fix: add parseInt(value, 10) with isNaN() guards to all integer query param parsing
- Add radix 10 to all parseInt() calls parsing integer query/path parameters
- Add isNaN() guards returning HTTP 400 with descriptive error messages
- Updated routes: annotations, candles, export, export/spans, annotation-types/[id], span-annotations, span-annotations/[id], span-label-types/[id]
- Ensures strict integer parsing and prevents invalid parameter values from reaching database queries
2026-02-18 11:19:26 +01:00
Marko Djordjevic
1678da2d9d fix: wrap chart cascade delete in db.transaction() and add spanAnnotations deletion
- Import spanAnnotations from schema
- Wrap all delete operations in db.transaction() for atomicity
- Delete spanAnnotations first to satisfy FK constraints, then annotations, candles, chart
- Mark task 4.8 as done in tasks.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:17:19 +01:00
Marko Djordjevic
103bfa89cb fix: require chartId for bulk delete in annotations route (task 4.7)
Reject DELETE ?all=true without chartId with HTTP 400 to prevent
accidental deletion of annotations across all charts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:16:37 +01:00
Marko Djordjevic
aace19b7f4 fix: replace error.message with generic "Internal server error" in all API catch blocks
Prevents leaking internal error details to clients across 7 route files:
health, candles, annotations, annotations/[id], upload, export, span-annotations/export.
Server-side console.error logging preserved for debugging.

Closes task 4.6.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:16:02 +01:00
Marko Djordjevic
81e3554d82 feat: add Zod schema validation to patterns/detect route
- Import z from zod
- Add CandleSchema validating time, open, high, low, close (number), volume (optional number)
- Add PatternDetectRequestSchema validating candles array and patterns array of non-empty strings
- Use safeParse() and return HTTP 400 with error details on validation failure
- Forward only validated data to the inference service
- Mark task 4.5 as completed in tasks.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:14:36 +01:00
Marko Djordjevic
2e02d155af feat: add Zod schema validation to training/start route (task 4.4)
Validates model_type as a non-empty string using .safeParse(); returns
HTTP 400 with error details on invalid input. Marks task 4.4 as done.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:14:00 +01:00
Marko Djordjevic
4cffc223b3 feat: add Zod schema validation to model/load route
Validate run_id in POST /api/model/load using Zod:
- run_id must be a non-empty string matching /^[a-zA-Z0-9_-]+$/
- Returns HTTP 400 with error details if validation fails
- Validated data is forwarded to the inference service

Marks task 4.3 as complete in tasks.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:13:13 +01:00
Marko Djordjevic
5c399037c3 feat: add Zod validation to predict/batch route (task 4.2)
Add BatchPredictRequestSchema with Zod to validate pair, timeframe,
start_date, and end_date fields. Returns HTTP 400 with flattened error
details on invalid input. Forward only validated data to the inference
service.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:12:38 +01:00
Marko Djordjevic
3361236d3f feat: add Zod schema validation to predict API route
- Add CandleSchema validating time, open, high, low, close (number) and optional volume
- Add PredictRequestSchema validating pair (non-empty string), timeframe (non-empty string), candles array
- Use safeParse() and return HTTP 400 with error details on invalid input
- Forward only validated data to the inference service
- Mark task 4.1 as done in tasks.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:11:58 +01:00
Marko Djordjevic
4a3e4a48ba feat: forward X-API-Key header from Next.js proxy routes to ML service
All 12 Next.js API routes that proxy requests to the ML service
(INFERENCE_API_URL / localhost:8001) now include the X-API-Key header
read from process.env.API_KEY. Affected routes:
- /api/predict
- /api/predict/batch
- /api/model/info
- /api/model/load
- /api/training/start
- /api/training/runs
- /api/training/runs/[run_id] (DELETE)
- /api/training/dataset-info
- /api/training/active
- /api/training/build-dataset
- /api/patterns/available
- /api/patterns/detect

Marks task 3.3 as complete in openspec/changes/code-review-fix/tasks.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:06:18 +01:00
Marko Djordjevic
94bc5768d1 feat: add file type validation to upload endpoint
- Validate filename ends with .csv (case-insensitive)
- Validate MIME type is text/* or application/csv or text/csv
- Return HTTP 400 with error message if validation fails
- Mark task 2.4 as complete
2026-02-18 11:01:28 +01:00
Marko Djordjevic
0e239dc3da security: add file size (10MB) and row count (500k) limits to upload route
- Reject uploads larger than 10MB before reading file content
- Reject CSVs with more than 500,000 data rows after parsing
- Checks placed as early as possible in the handler flow
- Mark task 2.3 as done in tasks.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-18 11:01:02 +01:00
Marko Djordjevic
870f92d208 feat: add run_id format validation in DELETE training/runs endpoint
Validate that run_id matches /^[a-zA-Z0-9_-]+$ regex before interpolating into the API URL.
Returns HTTP 400 with 'Invalid run_id format' error if validation fails.
This prevents potential URL injection attacks and invalid identifier usage.
2026-02-18 10:58:54 +01:00
Marko Djordjevic
d3dcfcea7d feat: auto-build training dataset from DB annotations before training
- Add build_dataset_from_db() that exports candles from DB, runs feature
  engineering, and ingests span annotations into labeled CSV
- Call it automatically in _run_training_background before training starts
- Add POST /training/build-dataset endpoint for standalone use
- Add Next.js proxy route /api/training/build-dataset
- Update TrainingPanel: remove dataset-missing block on Start Training,
  show informational message that dataset builds automatically
2026-02-18 00:24:39 +01:00
Marko Djordjevic
69634909d1 fix: correct timestamp/boolean types for PostgreSQL schema (Date not int, bool not 0/1) 2026-02-17 22:50:31 +01:00
Marko Djordjevic
e00bd4d804 fix: await params in DELETE route for Next.js 15 async params 2026-02-17 22:33:38 +01:00
Marko Djordjevic
6ef102cf21 fix: training panel stuck button, stale runs on startup, add delete model 2026-02-17 22:23:50 +01:00
Marko Djordjevic
c404e79678 fix: normalize span annotation timestamps to Unix epoch seconds in all API responses 2026-02-17 20:02:14 +01:00
Marko Djordjevic
900443d078 fix: convert Unix epoch seconds to Date for span annotation start_time/end_time on insert 2026-02-17 20:01:09 +01:00
Marko Djordjevic
3a114cccd0 fix: convert Unix epoch seconds to Date before inserting annotation timestamp 2026-02-17 19:46:24 +01:00
Marko Djordjevic
04a8303f4f fix: convert timestamp columns to Unix epoch seconds in candles and annotations API 2026-02-17 19:40:48 +01:00
Marko Djordjevic
2a02669222 feat: add FastAPI model/load endpoint and all Next.js proxy routes (tasks 2-4) 2026-02-17 18:47:04 +01:00
Marko Djordjevic
bfe437857b feat: add Python migration script and successfully test SQLite to PostgreSQL data migration
- Created scripts/migrate-sqlite-to-postgres.py as alternative to TypeScript version
- Handles all type conversions: timestamps, booleans, and JSONB fields
- Successfully migrated all 2,836 rows from SQLite to PostgreSQL
- Verified data integrity: all 6 tables migrated correctly
- Charts: 1, Candles: 2,592, Annotations: 4, Span annotations: 223
2026-02-17 14:01:21 +01:00
Marko Djordjevic
5f70f13da3 feat: migrate from SQLite to PostgreSQL - complete schema and API updates
- Remove better-sqlite3, add pg driver
- Convert schema to PostgreSQL types (serial, timestamp, boolean, jsonb)
- Generate fresh PostgreSQL migrations
- Update database connection layer with pg.Pool
- Fix all API routes: remove JSON.parse/stringify, use native timestamps and booleans
- Update drizzle.config.ts and .env.example for PostgreSQL
2026-02-17 13:43:06 +01:00
Marko Djordjevic
f850728d44 fix(api): add GET /api/charts/[id] and fix batch prediction
- Add GET handler to /api/charts/[id] route to fetch chart metadata
- Fix batch prediction to use regular /predict endpoint with database candles
- Remove /predict/batch usage (was designed for file-based predictions)
- Make volume field optional in CandleData model (database candles don't have volume)
- Convert timestamps to ISO dates for batch requests

Known issue: TA-Lib indicators failing with 'input array type is not double'
- May need to ensure candle data is float64/double type before processing
2026-02-15 21:49:22 +01:00
Marko Djordjevic
bb1b6d573f feat(api): add span annotation export and feedback loop support
- Add GET /api/span-annotations/export endpoint for ML pipeline JSON/CSV export
- Add source and model_prediction fields to span_annotations schema
- Update POST endpoint to accept source (human/model/human_correction) and model_prediction metadata
- Support negative annotations (label 'O' for user corrections to model predictions)
- Create migration 0005 for new schema fields

Completes tasks 8.1-8.4 of candle-backend change
2026-02-15 14:35:31 +01:00
Marko Djordjevic
205021e810 feat(api): add Next.js proxy routes for ML inference service 2026-02-15 14:30:09 +01:00
Marko Djordjevic
4b5cc2f174 fix: install missing shadcn/ui components and fix TypeScript build errors
- Install missing shadcn/ui components: dialog, select, label, slider, textarea
- Fix import paths in export API endpoint (@/lib/db instead of @/db)
- Fix CandleChart activeChartId type (handle undefined with nullish coalescing)
- Fix SpanRectanglePrimitive renderer to use proper lightweight-charts v4 API:
  - Implement ISeriesPrimitivePaneRenderer interface
  - Use useBitmapCoordinateSpace for HiDPI rendering
  - Add proper scaling factor for coordinates and dimensions
  - Fix hitTest to return PrimitiveHoveredItem with required zOrder property
- Mark all section 12 integration testing tasks as completed
2026-02-14 10:43:10 +01:00
Marko Djordjevic
842a58f12b feat: implement section 11 - span export endpoints (JSON, windowed CSV, BIO-tagged CSV) 2026-02-14 10:14:58 +01:00
Marko Djordjevic
dadf515406 feat: add database schema, migrations, and API endpoints for span annotations
- Add span_label_types and span_annotations tables to schema
- Seed default span label types (bull_flag, bear_flag, etc.)
- Implement CRUD API endpoints for span label types
- Implement CRUD API endpoints for span annotations
- Add time swap validation in POST endpoint (start_time <= end_time)
2026-02-14 05:56:28 +01:00
Marko Djordjevic
90e1e179cc feat: scope candles/annotations/export APIs by chartId query param
- GET /api/candles accepts ?chartId= with fallback to most recent chart
- GET /api/annotations accepts ?chartId= with fallback to most recent chart
- POST /api/annotations now requires chart_id in request body
- GET /api/export accepts ?chartId= to scope exported annotations
- DELETE /api/annotations supports optional chartId scoping
2026-02-13 00:14:22 +01:00
Marko Djordjevic
98e91b047a feat: upload creates new chart from filename with duplicate handling
- POST /api/upload now creates a chart named from the CSV filename
- Duplicate names get numeric suffix (e.g., btc-daily-2)
- Candles inserted with chart_id instead of replacing all data
- Response includes chart id and name
2026-02-13 00:13:23 +01:00
Marko Djordjevic
b53cb1b7d1 feat: add charts API endpoints (GET list, DELETE with cascade) 2026-02-13 00:12:53 +01:00
Marko Djordjevic
011bea2350 feat: delete old candles on CSV upload before inserting new ones 2026-02-12 18:47:11 +01:00
Marko Djordjevic
974d9f5598 feat: add annotation types management system
- Created annotation_types table with name, display_name, color, category, icon
- Implemented CRUD API endpoints for annotation types management
- Built annotation types management UI page at /annotation-types
- Updated Toolbox component to dynamically load and display annotation types
- Updated CandleChart component to use dynamic annotation types for markers
- Added seed functionality for default types (break_up, break_down, line)
- Cleaned up duplicate migration files
2026-02-12 18:17:44 +01:00
Marko Djordjevic
957663e29a fix: use proper Drizzle query syntax in health endpoint instead of execute() 2026-02-12 15:19:50 +01:00
Marko Djordjevic
a1fa86fe55 feat: implement label management with sidebar, hacker theme, and Docker support
- Add label selection on chart with visual highlight (size 2x, color change)
- Implement keyboard delete handler (Delete/Backspace keys)
- Add comprehensive label management sidebar with:
  - Collapsible label annotations section
  - Search by timestamp
  - Filter by type (Break Up, Break Down, All)
  - Individual delete buttons
  - Count display
  - Click to select/highlight on chart
- Transform UI with hacker theme:
  - Matrix green (#00ff41) on dark background (#0a0e0a)
  - Monospace font (JetBrains Mono)
  - Glow effects on button hover and active states
  - Custom scrollbar styling
  - Terminal-inspired aesthetic
- Add Docker deployment:
  - Multi-stage Dockerfile with standalone output
  - docker-compose.yml with volume persistence
  - Non-root user (nextjs) for security
  - Health check endpoint integration
- Tailwind and CSS enhancements:
  - Custom colors (matrix, matrixDim, neonRed, etc.)
  - Glow box shadows and animations
  - Selection and scrollbar styling
2026-02-12 15:12:59 +01:00
Marko Djordjevic
37c3adf42f feat: implement Phase 4 endpoint dragging with visual handles 2026-02-12 14:32:00 +01:00
Marko Djordjevic
006e95c266 feat: add color support for line annotations
- Add color field to annotations schema with default blue (#3b82f6)
- Add color picker UI with 5 preset colors (red, green, blue, yellow, white)
- Pass selected color through component hierarchy (Page -> Toolbox, CandleChart -> SvgOverlay)
- Store color when creating line annotations
- Render lines with their stored color
- Update database with color column
- Preview lines show selected color during drawing

Phase 1 of LINE_DRAWING_IMPROVEMENTS.md complete
2026-02-12 14:04:51 +01:00
Marko Djordjevic
23f18f405a feat: complete candle annotator implementation
- Created CandleChart component with lightweight-charts integration
- Implemented SvgOverlay component for line drawing
- Integrated all components in main page
- Fixed TypeScript and Tailwind CSS compatibility issues
- Added comprehensive README.md with project documentation
- Created DEPLOYMENT.md with setup and troubleshooting guide
- Downgraded to stable versions (Tailwind v3, lightweight-charts v4)
- All 59 tasks from OpenSpec completed
2026-02-12 11:20:29 +01:00
Marko Djordjevic
096a80b229 feat: implement backend API endpoints
- CSV upload with papaparse (handles date strings and Unix timestamps)
- Annotations CRUD (GET, POST, DELETE)
- Candles GET endpoint
- Export annotations as CSV
2026-02-12 10:24:03 +01:00