Skip to content

System Requirements

This page defines what the system must do (functional), how it must behave (non-functional), what constraints it operates under, and what it explicitly does not try to solve.


Project Vision

SoccerPredictAI is a dual-purpose project:

  1. Portfolio / hiring asset — an end-to-end MLOps system that demonstrates production-style discipline (reproducible pipelines, registry-backed serving, observability, contract validation, runbooks) at a level relevant to applied-ML / MLOps engineering interviews.
  2. A working football match-prediction service — a real, read-only public deployment that produces 1x2 predictions for past, current, and upcoming matches and exposes historical model-quality metrics for transparency.

These two purposes are aligned: the portfolio narrative is credible only if the service actually works end-to-end. They do not make the project a betting product or a multi-user platform — see Non-Goals.


Definition of Done — v1.0 ("demo-ready")

v1.0 is the minimum state at which the system can be shown to a technical interviewer and used by a non-operator visitor without the operator's intervention. The criteria are deliberately small and verifiable:

# Criterion Verification
DoD-01 Public read-only Streamlit UI lists past, current, and upcoming matches and shows the champion-model 1x2 prediction for each Visit deployed UI; predictions render without operator action
DoD-02 UI also shows historical quality metrics (accuracy, log-loss, calibration, historical ROI) for the champion and any registered challenger models, side by side, as information only UI page renders metrics from MLflow / evaluation reports
DoD-03 The champion model in MLflow Registry was trained with production-scale parameters (classification.fracs_for_train and tuning.n_trials are not in smoke mode) params.yaml review + MLflow run tags
DoD-04 docs/status.md and the code agree: every component marked ✅ Operational is actually wired and reachable; the contract test in tests/contract/test_pipeline_contracts.py is green pytest tests/contract/ -q + manual cross-check
DoD-05 Public deployment carries a visible "demo only — not betting advice" disclaimer and has nginx-level rate limiting on the public surface Inspect rendered UI footer + nginx config
DoD-06 Quickstart can be executed end-to-end from a clean checkout by a reader who has not seen the code before docs/quickstart.md dry-run

Everything outside this list is explicitly post-v1 and lives in Roadmap.


Functional Requirements

# Requirement Status
FR-01 Automatically ingest football match data from WhoScored.com on a configurable schedule ✅ Implemented
FR-02 Version and reproduce all training datasets — any historical model must be traceable to its exact data ✅ Implemented
FR-03 Run an end-to-end ML training pipeline (preprocessing → feature engineering → training → evaluation → registration) reproducibly ✅ Implemented
FR-04 Track all experiments: parameters, metrics, and artifacts, with model versioning and promotion lifecycle ✅ Implemented
FR-05 Serve match outcome predictions synchronously (p95 < 30 s) via a versioned REST API ✅ Implemented
FR-06 Accept long-running inference jobs asynchronously and return results via a polling endpoint ✅ Implemented
FR-07 Expose service health and operational metrics for scraping by Prometheus ✅ Implemented
FR-08 Validate data contracts at every major pipeline stage boundary (raw / finished / future / features) ✅ Implemented
FR-09 Provide a public read-only Streamlit UI that lists matches and renders the champion-model prediction for each 🚧 Partial — livescores page only; predictions page is the v1.0 deliverable
FR-10 Display historical model-quality metrics (accuracy, log-loss, calibration, historical ROI) for champion and challenger models, as information only — the UI must not present strategy advice 📋 Planned — v1.0 deliverable
FR-11 Apply nginx-level rate limiting on the public UI / API surface and render a "demo only — not betting advice" disclaimer in the UI 📋 Planned — v1.0 deliverable

Quality Attributes

These attributes describe how the system must behave — independent of specific thresholds or configurations.

Attribute Statement
Reproducibility Any historical model must be reproducible from a clean checkout. Training, evaluation, and inference paths are independent and cannot contaminate each other's logic. All randomness is explicitly seeded.
Traceability Every deployed model is traceable to its git commit, dataset version, experiment run, and dependency lock. Predictions are traceable to the model version that produced them.
Contract validation Data schema violations at pipeline stage boundaries must fail fast and block downstream processing. API requests violating the input schema must be rejected with a structured error.
Reliability The serving layer must degrade gracefully under partial infrastructure failure (e.g., cache unavailability). Non-critical components must not take down the core prediction path.
Observability Service health, request metrics, and infrastructure state must be accessible to an operator without reading source code.
Maintainability All runbooks must be executable by a single operator. No operational step should require undocumented tribal knowledge.
Security No credential or secret appears in plaintext in the repository, Docker images, or CI logs. All external-facing endpoints validate input schemas. Kubernetes namespace isolation limits blast radius of any single compromised service.

Operational Targets

Concrete targets for the current single-VPS deployment. These are implementation-level targets and may evolve as the system scales. They are listed here for operational reference, not as architectural invariants.

Target Value Notes
Sync inference latency (p95) < 30 s Celery ml queue timeout enforced by FastAPI
Cache-hit latency Sub-second Redis in-cluster; no inference or feature assembly
Data freshness Within 24 h Of match completion; Airflow schedule-driven
Infrastructure cost < €30 / month Single-VPS, fully self-hosted
Full redeployment time Within 2 h Using documented runbooks from a clean state

Constraints

Constraint Impact
Portfolio + production-style project No HA, no multi-region, but realistic tooling and discipline
Self-hosted single VPS (healserver) Single point of failure; no automated failover
External data source (WhoScored) Unstable, may change layout or rate-limit without notice
One maintainer Runbooks must be self-sufficient; on-call automation is limited
Limited budget (< €30/month) No managed Kubernetes, no SaaS ML platform, no cloud object storage
External Selenoid host Browser automation runs outside the K8s cluster; separate operational concern

Non-Goals

The following are explicitly outside the scope of this system:

  • Guaranteed betting profitability: the system produces probabilistic predictions; edge and profitability are not system-level guarantees.
  • Betting strategy advice: the UI and API surface model outputs and historical quality metrics as information only. The system never returns prescriptive recommendations of the form "bet on X" / "stake N units". A visible "demo only — not betting advice" disclaimer is part of the v1.0 deliverable.
  • Authenticated multi-user access: the public surface is intentionally read-only and unauthenticated. Abuse protection is provided by nginx rate limiting and the read-only nature of the API, not by per-user accounts. RBAC, per-user quotas, and account management are out of scope.
  • Online model selection from the UI: v1.0 serves a single champion model. Comparison of challenger models is offline-only (historical metrics rendered in the UI). A user-facing model switch on the prediction endpoint is post-v1 and would require multi-alias serving conventions in MLflow Registry that the project does not currently adopt.
  • General sports analytics platform: the system is purpose-built for football 1x2 outcome prediction; other sports or bet types are out of scope.
  • Large-scale multi-tenant serving: designed for a single operator; no multi-tenancy, RBAC, or per-user quotas.
  • Real-time streaming ingestion: data is ingested in batches on a schedule; event-streaming architecture is a future consideration.
  • Automated model retraining on drift: drift detection is planned; fully automated retraining trigger is a future goal.
  • Player-level or market-level modeling: current scope is match-level 1x2 outcome only.

Requirements → Architectural Consequences

This table makes explicit how system requirements and constraints directly shaped architectural decisions. It exists to prevent revisiting settled choices without understanding what drove them.

Requirement / Constraint Architectural consequence
Single maintainer Avoid distributed systems (Kafka, Spark, managed queues) that require specialized operational expertise. Prefer tools with clear runbooks and local debugging.
Limited budget (< €30/month) Self-hosted MinIO instead of S3. Self-hosted MLflow instead of W&B or Neptune. Single-VPS K8s instead of managed EKS/GKE. No SaaS dependencies in the critical path.
Reproducibility required DVC for artifact-driven pipeline versioning. MLflow for run tracking and model registry. Explicit dependency locking (conda environment, pdm). All randomness seeded.
No HA requirement Single-node Kubernetes is acceptable. No replicated RabbitMQ, no Redis Sentinel, no MLflow HA. These are known limitations, not omissions.
External unstable data source (WhoScored) Dedicated validation layer: Great Expectations gates at raw, interim, and features boundaries. Fail fast on schema drift rather than silently corrupt the pipeline.
Batch retraining acceptable No streaming architecture required. DVC artifact-driven pipeline is sufficient. No Kafka, no Flink, no real-time feature store.
Portfolio + production-style project Real K8s, real Helm, real secrets management (SOPS + age), real CI/CD — but without the scale or HA requirements of a true production system. Discipline over complexity.