Skip to content

Comments

feat: new FastAPI v3 API wrapping Analyticom KSI REST API#131

Open
sindrig wants to merge 27 commits intomasterfrom
new-api
Open

feat: new FastAPI v3 API wrapping Analyticom KSI REST API#131
sindrig wants to merge 27 commits intomasterfrom
new-api

Conversation

@sindrig
Copy link
Owner

@sindrig sindrig commented Feb 16, 2026

Summary

Replace the fragile SOAP + HTML scraping Lambda functions with a clean FastAPI v3 API wrapping the Analyticom KSI REST API. Consolidates match data and weather into a single Lambda deployed behind API Gateway.

  • New FastAPI application in clock-api/v3/ with 6 endpoints (health, matches, lineups, events, match info, weather)
  • Terraform infrastructure for Lambda + API Gateway route at /v3/{proxy+}
  • TypeScript type generation from OpenAPI spec for future frontend migration
  • 35 passing tests with TDD approach (unit, integration, handler tests)

What's New

API Endpoints

Method Path Description
GET /v3/health Health check
GET /v3/{team_id}/matches/{date} Matches for team on date
GET /v3/{team_id}/matches/{match_id}/lineups Match lineups
GET /v3/{team_id}/matches/{match_id}/events Match events (goals, cards, subs)
GET /v3/{team_id}/matches/{match_id}/info Detailed match info
GET /v3/weather?lat=&lon= Weather with vedur.is → OpenWeatherMap fallback

Key Design Decisions

  • One API key per team stored in SSM (/vikes-match-clock/ksi-api-key/{team_id})
  • Weather fallback chain: vedur.is (free, Iceland-specific) → OpenWeatherMap (global, paid)
  • Mangum adapter for Lambda deployment (no uvicorn in prod)
  • Pydantic v2 models with auto-generated OpenAPI spec

What's NOT Changed

  • No changes to existing Lambda functions (match-report, match-report-v2, weather)
  • No frontend changes (except generate-api-types script + generated types for future use)
  • Old APIs continue to work as-is — deprecation happens in a separate PR

Pre-merge Checklist

  • Set up SSM parameters for team API keys before first deploy
  • Consider adding sandbox-deploy label to test in staging first

Test Results

35 passed, 1 skipped

@codecov
Copy link

codecov bot commented Feb 16, 2026

Codecov Report

❌ Patch coverage is 73.68421% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.38%. Comparing base (f70fe01) to head (3d1e7d3).

Files with missing lines Patch % Lines
clock/src/controller/asset/team/TodaysMatches.tsx 65.51% 10 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #131      +/-   ##
==========================================
- Coverage   86.86%   86.38%   -0.49%     
==========================================
  Files          33       33              
  Lines        1599     1579      -20     
  Branches      467      458       -9     
==========================================
- Hits         1389     1364      -25     
- Misses        210      215       +5     
Flag Coverage Δ
unittests 86.38% <73.68%> (-0.49%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
clock/src/controller/asset/team/Team.tsx 100.00% <ø> (ø)
.../src/controller/asset/team/TeamAssetController.tsx 98.75% <100.00%> (-0.01%) ⬇️
clock/src/controller/asset/team/TodaysMatches.tsx 72.00% <65.51%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

sindrig and others added 21 commits February 19, 2026 23:13
Implement matches endpoint that converts YYYY-MM-DD date to yyyyMMdd
format, looks up team API key, and delegates to KsiClient. Router
included in main app. TDD: tests written first, all 15 pass.
- Create tests/test_handler.py with 7 Mangum handler tests
- Test Lambda event handling, response format, routing, and error cases
- Validate OpenAPI spec completeness (6 endpoints present)
- All 35 tests pass, no LSP errors
- Evidence: task-8-handler-tests.txt, task-8-openapi-validation.txt, task-8-openapi-spec.json
Create clock-api/v3/AGENTS.md with full API documentation including
endpoints, architecture, development setup, and testing patterns.
Update root AGENTS.md to reference v3 and mark legacy APIs.
Update infra/AGENTS.md with clock-api-v3 Lambda entry.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Remove the .sisyphus internal tracking folder from the repository while
keeping it locally. Update .gitignore to prevent it from being tracked
in the future.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Remove nested .sisyphus from clock-api/v3/ and update .gitignore to
recursively ignore any .sisyphus directories found in the project.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
- Migrate weather.ts to use v3 fetchWeather endpoint
- Migrate getAvailableMatches action to use v3 adapter with team_id
- Add teamId field to screen config in ListenersState
- Update reducer to handle new data shape
- Migrate MatchesOnPitch component (all 3 methods) to v3 API
- Remove search-for-player feature from Team.tsx

All API calls now use v3 endpoints with team_id parameter.
Fallback to team_id 2492 (Víkingur in Analyticom API).
- Fix TypeScript types in v3-api.ts (use ListenersState['screens'])
- Update lambda-example.ts to match new AvailableMatches shape
- Add numeric id fields to all debug players
- Replace 'as any' with proper type assertion

All ESLint errors resolved, build and lint pass cleanly.
…olution

- KsiClient now accepts api_key in constructor
- All methods use self.api_key (no per-method parameter)
- get_ksi_client dependency resolves key automatically
- Router endpoints no longer manually call get_ksi_api_key
- Tests updated to match new dependency pattern

Eliminates repetitive api_key = get_ksi_api_key(team_id) in every endpoint.
All 33 tests pass.
@github-actions
Copy link

Deployed to staging: https://staging.irdn.is

@github-actions
Copy link

Deployed to staging: https://staging.irdn.is

@github-actions
Copy link

Deployed to staging: https://staging.irdn.is

@github-actions
Copy link

Deployed to staging: https://staging.irdn.is

@github-actions
Copy link

Deployed to staging: https://staging.irdn.is

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant