Platform Overview
The Feyenoord digital platform provides fans, members, and partners with access to sports data, membership services, and club content through web and native applications. Client apps are the presentation layer. A federated GraphQL graph and a legacy monolith API form the domain logic layer. PostgreSQL, MongoDB, Redis, and third-party data feeds make up the data layer.
For how requests and events move through these layers, see Data Flow.
The three layers
Presentation
Client applications render UI and orchestrate user interactions. They do not own domain rules or persistent data.
| Application | Stack | Role |
|---|---|---|
| Web | Next.js | Public website |
| Native | Expo / React Native | iOS and Android mobile app |
| Sanity Studio | Sanity | Content management system |
| Storybook | Storybook | Component library |
Domain logic
Backend services enforce domain rules, compose APIs, and coordinate integrations.
| Service | Role |
|---|---|
| API Gateway (Traefik) | Single edge endpoint: path-based routing, TLS, trace propagation |
| GraphQL Router (Apollo Federation) | Composes subgraph schemas into one federated graph |
| Monolith API (deprecated) | v1 REST + GraphQL for most existing domains to be migrated to subgraphs |
| Identity | User identity, authentication, and basic personally identifiable information |
| Notifications | Push and in-app notifications |
| Loyalty | Owns everything related to season cards, memberships, and other loyalty related interactions |
| Match Gateway | Ingests live match events and publishes domain events to the platform |
Data
| Store | Used for |
|---|---|
| PostgreSQL | Relational data within API services |
| MongoDB | Document based data, deployed using CosmosDB |
| Redis | Caching and Dapr pub/sub broker (Redis Streams) |
| External integrations | CMS, sports feeds, ticketing, CRM, and more (see table below) |
INFO
All client apps connect through Traefik. Federated GraphQL queries go to the Apollo Router, which fans out to subgraphs. The legacy monolith serves /api/v1 and /api/graphql. API services also expose OpenAPI REST endpoints at /v2/{service}.
External integrations
Third-party systems the platform reads from or writes to, grouped by category.
| Category | Integration | Purpose | Used by |
|---|---|---|---|
| Identity | Two Circles | OIDC SSO: login, userinfo, account changes | web, native, api, identity, loyalty |
| Content | Sanity | Headless CMS / content lake | sanity, api, match-gateway, notifications, web, native |
| Bynder | Digital asset management picker | sanity | |
| Typeform | Embedded surveys and forms | sanity, web | |
| YouTube | Embedded video | web | |
| Sports data | StatsPerform | Pro match data (SDAPI) + live feed (SDDP) | api, match-gateway, loyalty, match-tools |
| Sportlink | Academy teams, matches, standings | api | |
| Toto | Betting odds and content (feature-flagged) | api | |
| Miscellaneous | Tymes4 | Ticketing platform: mobile tickets, season cards | loyalty, native, api |
| Adyen | Hosted checkout for Legioen and Kameraadjes memberships | api | |
| Easylinq | Membership CRM handoff after payment | api | |
| HubSpot | B2B preferences and transactional email | api | |
| Postcode.eu | Dutch address lookup | api (web/native via GraphQL) | |
| TalentLink | Vacancies and job applications | api | |
| Algolia | Site search indexing and search UI | api, web, native | |
| TriniCo | Supporter-service contact and change forms | web | |
| OneSignal | Push notifications | notifications, match-gateway, web, native | |
| MediaMarkt | Product and deals feed | api | |
| Endeavor | Feyenoord One streaming | native | |
| Azure Blob Storage | Goal-replay video storage | api | |
| Analytics & client tooling | Google Tag Manager | Web analytics and tagging | web |
| Firebase | Analytics, crashlytics, performance | native | |
| Azure Application Insights | Telemetry sink for traces, logs, and exceptions | web, all backend services | |
| Mopinion | In-app feedback surveys | native, web | |
| Cloudflare Turnstile | CAPTCHA on web forms | web |
Observability
Every service emits OpenTelemetry traces, logs, and exceptions through the shared @repo/observability package. Trace context propagates end-to-end from the native app through Traefik, the Apollo Router, and the subgraphs. See Observability for the full pipeline, the Instrumentation guide for how each app is wired in, and Azure Container Apps for how telemetry reaches Application Insights in production.
Related
- Data Flow: request paths, API SDKs, and async event flows
- ADR-001: Microservices Architecture: why Traefik and Apollo Federation
- Docker Compose: local service topology
- Observability: telemetry pipeline