candle-annotator/openspec/specs/input-validation/spec.md
Marko Djordjevic 925e7284e3 Archive code-review-fix change and sync specs to main
- Synced 14 capability delta specs to main specs
- Created 6 new main specs: api-authentication, error-boundary, input-validation, security-headers, shared-types
- Updated 8 existing specs with security, validation, and performance requirements
- Archived change to openspec/changes/archive/2026-02-20-code-review-fix/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 08:54:59 +01:00

3.9 KiB

ADDED Requirements

Requirement: Zod validation on proxy routes

All Next.js proxy routes SHALL validate request bodies using Zod schemas before forwarding to the ML service. If validation fails, the route SHALL return HTTP 400 with { "error": "<zod error message>" } without contacting the ML service.

Scenario: Valid predict request

  • WHEN POST /api/predict receives { pair: "EURUSD", timeframe: "1H", candles: [{time: 1, open: 1, high: 2, low: 0.5, close: 1.5}] }
  • THEN the request passes validation and is forwarded to the ML service

Scenario: Invalid predict request

  • WHEN POST /api/predict receives { pair: 123, candles: "not-an-array" }
  • THEN the route returns HTTP 400 with a Zod validation error message

Scenario: Valid training start request

  • WHEN POST /api/training/start receives { model_type: "random_forest" }
  • THEN the request passes validation and is forwarded

Scenario: Valid model load request

  • WHEN POST /api/model/load receives { run_id: "abc-123" }
  • THEN the request passes validation and is forwarded

Scenario: Valid pattern detection request

  • WHEN POST /api/patterns/detect receives { candles: [...], patterns: ["CDLENGULFING"] }
  • THEN the request passes validation and is forwarded

Requirement: run_id format validation

All routes and endpoints that accept a run_id parameter SHALL validate that the value matches the pattern /^[a-zA-Z0-9_-]+$/. If validation fails, the route SHALL return HTTP 400 with { "error": "Invalid run_id format" }.

Scenario: Valid run_id in URL path

  • WHEN DELETE /api/training/runs/abc-123_v2 is called
  • THEN the request proceeds normally

Scenario: Path traversal attempt in run_id

  • WHEN DELETE /api/training/runs/../../admin/delete-all is called
  • THEN the route returns HTTP 400 with { "error": "Invalid run_id format" }

Scenario: Python service run_id validation

  • WHEN POST /model/load receives { run_id: "../../../etc/passwd" }
  • THEN the FastAPI endpoint returns HTTP 400 with { "detail": "Invalid run_id format" }

Requirement: File upload size limit

The POST /api/upload route SHALL reject files larger than 10MB. The route SHALL check file.size before processing and return HTTP 413 with { "error": "File too large. Maximum size is 10MB." } if exceeded. The route SHALL also limit the number of rows inserted to 500,000.

Scenario: File within size limit

  • WHEN a 5MB CSV file is uploaded
  • THEN the upload proceeds normally

Scenario: File exceeds size limit

  • WHEN a 15MB CSV file is uploaded
  • THEN the route returns HTTP 413 with { "error": "File too large. Maximum size is 10MB." }

Scenario: Row count limit

  • WHEN a CSV file contains 600,000 rows
  • THEN the route returns HTTP 400 with { "error": "Too many rows. Maximum is 500,000." }

Requirement: Batch prediction input size limit

The FastAPI /predict/batch endpoint SHALL validate that the requested date range does not exceed 1 year. If exceeded, the endpoint SHALL return HTTP 400.

Scenario: Date range within limit

  • WHEN POST /predict/batch requests a 6-month range
  • THEN the request proceeds normally

Scenario: Date range exceeds limit

  • WHEN POST /predict/batch requests a 2-year range
  • THEN the endpoint returns HTTP 400 with { "detail": "Date range exceeds maximum of 1 year" }

Requirement: File type validation on upload

The POST /api/upload route SHALL validate that the uploaded file has a .csv extension and a text-based MIME type. Other file types SHALL be rejected with HTTP 400.

Scenario: Valid CSV upload

  • WHEN a file named data.csv with MIME type text/csv is uploaded
  • THEN the upload proceeds normally

Scenario: Invalid file type

  • WHEN a file named model.pkl is uploaded
  • THEN the route returns HTTP 400 with { "error": "Only CSV files are accepted" }