Last deployment:

Turfi Platform Documentation

Official Turfi documentation portal for users, admins, and developers.

Back to support

Documentation Search

Search only within Turfi documentation pages.

C

Platform Architecture

Cross-engine architecture, shared systems, admin workspace boundaries, and how Turfi is organized as a platform.

Turfi is a multi-engine platform rather than a single app feature set, so the architecture needs a shared map that explains engine boundaries and how systems interact. Product-wide, Turfi acts as a Consensus Engine for Sports Reality: games, events, and performance are reconstructed from media, official feeds (when present), AI, and community input—see Platform Philosophy and Scope.

This document exists to orient developers before they move into deeper domain or data detail. It sits above domain-specific engine documents and shows how platform systems, discovery, identity, recruitment, and other shared capabilities fit together. Over time, it should remain the cross-engine architecture reference (implementation truth emerges from docs/ and schema, not from this paragraph alone).

Shared status legend: [docs/_shared/status-legend.md](./_shared/status-legend.md)


Platform Engine Index

Use this index for quick navigation to architecture engine sections.

Technical Architecture

Quick Architecture Summary

This section is a high-level architecture map of Turfi for new developers and AI assistants.

Identity Engine

Manages authentication, onboarding, and account lifecycle.

Player Engine

Manages athlete identity, player profiles, and player ownership.

Competition Engine

Models competitions as optional context for games, stores canonical match rows and events, and derives standings from game results via full rebuild (never incremental app logic). Games may exist without a competition_id; standings apply only where competition scope exists.

Match Intelligence Engine

Processes game actions, derives statistics, and creates structured play sequences.

Media Engine

Treats video as structured platform input that can produce canonical event review, reusable moments, clips, highlights, and player-facing media feeds.

Video Ingestion and Stats Mapping System

Connects source videos, provider stats, event normalization, player resolution, moment generation, clip extraction, player-highlight outputs, and reusable media services across the Media, Match Intelligence, Broadcast, Player, Admin, and Import systems.

Discovery Engine

Provides search and discovery across players, teams, competitions, and media.

Recruitment Engine

Supports scouting workflows, scouting notes, and talent discovery.

Social Engine

Handles activity feeds, follow relationships, and notifications.

Platform Systems

Shared systems including auditing, imports, moderation, and background processing.

Identity Engine

Status: IMPLEMENTED

The Identity Engine is Turfi's entry point for every user. When someone signs up, signs in, or connects through Google or Facebook, the Identity Engine is what recognizes them and determines what they're allowed to see and do. It answers a simple question: Who is this person, and what can they access?

Without identity, Turfi would have no way to personalize the experience or protect sensitive data. A player's profile, a coach's admin tools, and a recruiter's scouting workspace all depend on knowing who the user is and what role they hold. The Identity Engine was introduced so that authentication and authorization are centralized rather than scattered across every feature.

This engine owns user accounts and authentication (sign-up, sign-in, OAuth), application profile data (display name, avatar, verification status), role assignment (player, coach, club_admin, system_admin, etc.), workspace membership (which Play, Recruit, Compete, or Admin areas a user can access), and session state that the frontend uses to show the right navigation and content.

Identity sits at the foundation of Turfi. Every other engine checks identity before allowing access: admins need system_admin or super_admin, recruiters need recruiter or scout, and player pages may show different content based on whether the viewer owns that profile. The Player Engine uses identity when linking users to player profiles via claims; the Infrastructure Engine enforces access through Row Level Security and edge functions.

As Turfi grows, identity will support federated sign-in (e.g. federation-specific login), parent-managed youth accounts, delegated permissions for agents or scouts, and finer-grained workspace and feature flags.


Purpose

The Identity Engine manages authentication, onboarding, and account lifecycle for Turfi. It provides the foundational user identity layer that all other engines depend on for access control, session hydration, and role resolution.

Architecture Overview

Turfi uses Supabase Auth for authentication with OAuth providers (Google, Facebook, LinkedIn) and email/password. The engine maintains a public.users profile table that mirrors and extends auth identity, synchronized via triggers. Role assignment through user_roles drives workspace visibility and capability-based access. Session context is hydrated in the frontend through SessionProvider and useSession(), which fetch user profile and roles from users and user_roles.

Key Database Models

  • auth.users — Canonical auth identity (Supabase-managed)
  • users — Application profile (display_name, avatar_url, is_email_verified, etc.)
  • roles — Role catalog (system_admin, super_admin, club_admin, coach, player, etc.)
  • user_roles — User-to-role assignment
  • workspaces — Workspace definitions
  • workspace_members — Workspace membership (refreshed from user_roles via trigger)
  • api_user_workspace_summary — Read model for role/workspace context

Key Workflows

  1. Sign-up / OAuth provisioning: New auth user triggers handle_new_auth_user() to create public.users row.
  2. Verification sync: sync_auth_user_verification() keeps users.is_email_verified aligned with auth.
  3. Default role: assign_default_player_role() assigns player role on user creation.
  4. Workspace refresh: trg_refresh_workspace_members_from_user_roles updates workspace membership when roles change.
  5. Session hydration: Frontend fetches profile from users and roles from user_roles joined to roles.

Interactions with Other Engines

  • Platform Systems: Shares users, roles, workspace infrastructure.
  • Infrastructure Engine: Auth and RLS enforce access; edge functions use service-role for privileged ops.
  • Player Engine: User-player linking (user_player_links) connects identity to player profiles.
  • Admin/Data: Role checks (system_admin, super_admin) gate admin navigation.

Discovery Engine

Status: IMPLEMENTED

The Discovery Engine is how users find things on Turfi. When a scout searches for players, when a coach looks up a match, or when the platform surfaces trending or recommended content, Discovery is powering that. It aggregates data from players, games, media, and activity into searchable, ranked views without requiring every feature to build its own lookup logic.

A platform full of players, games, and highlights is only useful if people can find what they need. Discovery exists to provide a consistent, fast way to search and browse—whether for recruitment, competition management, or general exploration. It centralizes retrieval logic so the rest of Turfi doesn't reinvent search in every workspace.

This engine owns player discovery and search index, competition and match retrieval, saved searches (planned) and search templates, rankings, trending signals, and recommendation logic, and API projections optimized for discovery surfaces.

Discovery consumes data from the Player, Competition, Media, and Match Intelligence engines. Recruitment uses it for player discovery; Admin uses it for entity lookup; Broadcast and Social may use discovery signals for trending content. It's the query layer that sits in front of the domain engines.

Future work includes richer search (fuzzy matching, filters by position/age/competition), saved search alerts, recommendation algorithms, and federation or club-scoped discovery views.


Purpose

The Discovery Engine provides query-first retrieval surfaces for player, match, and related domain entities so user-facing and scouting views can locate relevant context quickly.

Architecture Overview

Current discovery behavior is implemented through API views consumed by lib/api/player.ts and lib/api/match.ts, plus schema-level indexing/search support. The UI consumes pre-shaped read models instead of direct raw-table joins for stable retrieval behavior.

Key Database Models

  • players
  • teams
  • competitions
  • games
  • player_search_index
  • saved_player_searches
  • api_player_profiles
  • api_player_competition_analytics
  • api_player_matches
  • api_player_trends
  • api_games
  • api_player_media
  • api_player_activity

Key Workflows

  • Player profile discovery by id
  • Competition analytics retrieval for player context
  • Match-history and trend retrieval for profile context
  • Player media/activity retrieval for entity discovery depth
  • Search/index-backed player retrieval and saved-search lookup

Interactions with Other Engines

  • Player Engine
  • Match Intelligence Engine
  • Media Engine
  • Social Engine
  • Recruitment Engine

Broadcast Engine

Status: IMPLEMENTED (match playback, highlight retrieval); PLANNED (stream ingestion, automated clip generation)

The Broadcast Engine is how video reaches users. When someone watches a full match, clicks through a highlight reel, or navigates to a specific moment in a game, Broadcast is responsible for delivering the right URLs, assembling the right clips, and making playback possible. It's the distribution layer between stored media and the frontend player.

Media and highlights are stored by the Media Engine, but users need a way to consume them. Broadcast exists to bridge that gap—resolving which streams or clips to show, in what order, and with what context. Without it, Turfi would have media assets but no clear path from "watch this game" to actual playback.

This engine owns match playback URL retrieval and assembly, highlight collection and clip delivery, moment-level clip resolution for event-linked playback, stream ingestion and capture pipeline integration (planned), and the logic that turns moment/game references into playable content.

Broadcast consumes Media Engine outputs (video moments, highlight collections) and Match Intelligence timelines. It delivers to the frontend for match and player pages. Discovery may use broadcast metadata for surfacing playable content; the Media Engine stores what Broadcast distributes.

Planned evolution includes live stream ingestion from automated cameras, automated clip generation from event triggers, and multi-quality or adaptive streaming for different devices and connections.


Purpose

The Broadcast Engine governs how match and highlight media is distributed to users across Turfi. It is responsible for distributing video content and live match footage to frontend applications, enabling playback of full matches, event-oriented clips, and curated highlight reels.

Architecture Overview

The conceptual broadcast architecture encompasses:

  • Live match broadcasting: primary stream/recording URLs for full match playback
  • Video clip delivery: moment-level clips for event-oriented playback (goals, assists, key saves)
  • Stream ingestion from automated cameras: capture pipelines (automated or manual) populate media and attach to moments
  • Clip generation for highlights: moment candidates receive clips; highlight collections aggregate into reels
  • Content delivery to frontend applications: match media components and tabbed playback experiences

Current implementation combines game-level media references with moments/highlights for playback surfaces in match pages.

Key Database Models

  • games (api_games with primary_video_url)
  • media_assets
  • video_moments
  • highlight_collections
  • highlight_items
  • api_games

Key Workflows

  • Match playback URL retrieval from game read models
  • Highlight collection retrieval for recap surfaces
  • Moment-level clip retrieval for event-linked playback navigation
  • Assembly of playback-ready highlight sets from moment/group records
  • Stream ingestion: capture pipelines write to media and attach to moments
  • Clip-to-highlight: moment candidates receive clips; collections aggregate into reels

Video Source Ingestion

The Broadcast Engine also participates in source-video normalization, because playback-ready media requires more than simply storing an uploaded file.

Broadcast ingestion inputs include:

  • uploaded video files
  • provider exports
  • livestream archives
  • future RTMP ingest

Normalization stages:

  1. video upload or provider registration
  2. transcoding
  3. streaming format generation
  4. poster frame extraction
  5. clip-safe seek structure generation

Clips and moments are derived from normalized media rather than from raw provider files directly. This keeps source-video ingestion aligned with the Media Engine's storage model and the Match Intelligence Engine's event-normalization layer.

Interactions with Other Engines

  • Media Engine: consumes storage and metadata outputs
  • Highlight Detection System: receives moment candidates; delivers resulting clips and collections
  • Match Intelligence Engine: provides event timelines and moment candidates that drive clip placement
  • Discovery Engine: highlight activity feeds discovery rankings

Video Ingestion and Stats Mapping System

Status: PARTIAL

The Video Ingestion and Stats Mapping System is a cross-engine workflow that connects source video registration, provider event imports, manual/native tagging, player resolution, review, and derived player media. It extends existing Turfi engines rather than introducing a separate standalone engine.

The system supports two ingestion paths:

  • Path A: external provider video with stats such as Veo, XbotGO, and broadcast feeds
  • Path B: video-only sources such as phone uploads, club uploads, player highlights, and livestream recordings

Both paths converge into the same canonical objects:

  • game_events
  • player_game_stats
  • video_moments
  • highlight_collections
  • media_assets

Canonical truth is always approved game_events. Provider data, manual tags, assisted tagging, and future AI detections can all contribute event candidates, but only approved events should drive stats, match timelines, highlights, and player media.

High-level flow:

Video Source
    ↓
Ingestion Jobs
    ↓
Event Imports
    ↓
Canonical Events
    ↓
Moments
    ↓
Clips
    ↓
Highlights
    ↓
Player Media Feeds

Architecture Overview

source videos -> game_videos -> video_ingestion_jobs
-> provider imports or native tagging -> normalization -> player resolution -> approved game_events
-> video_moment_generation_queue -> video_moments
-> video_clip_generation_queue -> highlight_clips
-> player_highlight_items -> v_player_highlights

Platform Media Intelligence Architecture

video ingestion
    ↓
game_videos
    ↓
video_ingestion_jobs + video_event_imports
    ↓
game_events + game_event_sources
    ↓
video_moment_generation_queue
    ↓
video_moments
    ↓
video_clip_generation_queue
    ↓
highlight_clips
    ↓
player_highlight_items
    ↓
v_player_highlights

Key Database Models

  • game_videos
  • video_ingestion_jobs
  • video_event_imports
  • game_event_sources
  • video_player_resolution_queue
  • game_events
  • player_game_stats
  • video_moment_generation_queue
  • video_moments
  • video_clip_generation_queue
  • highlight_clips
  • player_highlight_items
  • v_video_moment_generation_jobs
  • v_video_clip_generation_jobs
  • v_player_highlights
  • highlight_collections
  • media_assets

Key Workflows

  1. Register one or more source videos for a game.
  2. Run ingestion jobs for validation, transcoding, provider import, and clip preparation.
  3. Store raw provider events before canonicalization.
  4. Normalize event types, timestamps, source metadata, and review state.
  5. Resolve players, teams, and unknown labels through governed review queues.
  6. Approve canonical events into game_events.
  7. Enqueue approved events for moment generation.
  8. Generate video_moments, then queue clip extraction.
  9. Create highlight_clips and associate them to players through player_highlight_items.
  10. Expose ranked clips through v_player_highlights for player, recruiter, and league-facing playback surfaces.

Interactions with Other Engines

  • Media Engine: source and derived media storage
  • Match Intelligence Engine: event normalization and stat rebuilds
  • Broadcast Engine: playback-safe source-video preparation
  • Player Engine: player resolution, claims, and player media
  • Admin Operations: ingestion jobs, unresolved players, and provider mapping failures
  • Import System: structured provider payload import workflows
  • Entity Resolution: duplicate cleanup when imported identities conflict with existing platform entities

Media Admin Module

Turfi now exposes a dedicated Admin -> Media module as the operator-facing control center for the media pipeline.

Primary tabs:

  • Overview
  • Videos
  • Moments
  • Highlights
  • Players
  • Processing

This module keeps content objects front and center while moving pipeline-heavy monitoring into the Processing tab. It complements Admin -> Operations rather than replacing it.

Reusable Media Services

Media workflow actions are implemented as reusable platform services rather than embedded admin-only logic.

Representative responsibilities:

  • createVideoSource()
  • startVideoIngestion()
  • importVideoEvents()
  • approveMoment()
  • generateHighlightClip()
  • resolvePlayerIdentity()
  • publishHighlight()

This architecture allows Studio, Club, Player, and Recruiter experiences to reuse the same media operations later without duplicating business rules.

Platform Systems

Status: IMPLEMENTED

Platform Systems are the shared services that every workspace and engine rely on. Session state, workspace membership, notifications, messaging, and feature flags live here. When the app loads and checks what menus to show, when a user gets a notification, or when a feature is gradually rolled out, Platform Systems are coordinating that behind the scenes.

Domain engines (Player, Competition, Media) focus on their own data. But users need a consistent experience across workspaces—the same session, the same notification style, the same way to switch between Play and Recruit. Platform Systems exist so those cross-cutting concerns are solved once and reused everywhere.

This engine owns session bootstrap and re-hydration, user profile sync from auth, role lookup and workspace summary, notifications and notification preferences, messaging and conversation state (planned), and feature flags and background job state.

Platform Systems sit alongside Identity and Infrastructure. Identity answers "who"; Platform Systems answer "what can they access" and "what's their context." Every engine that shows role-based UI or workspace-specific content depends on this layer. Import, Admin, and Audit systems also use it for cross-workspace behavior.

Future work includes richer notification delivery, in-app messaging, feature-flag-driven rollouts, and workspace-level customization so clubs or federations can tailor the experience for their users.


Purpose

Platform Systems provide cross-cutting user/session/role infrastructure used by all implemented domain engines.

Architecture Overview

This layer centralizes shared platform behavior: session context hydration, profile synchronization from auth metadata, role resolution, and workspace summary retrieval. It prevents each engine from implementing separate auth/role logic.

Key Database Models

  • users
  • user_roles
  • roles
  • permissions
  • role_permissions
  • workspaces
  • workspace_members
  • feature_flags
  • background_jobs
  • notifications
  • notification_preferences
  • conversations
  • conversation_participants
  • messages
  • api_user_workspace_summary

Key Workflows

  • Session bootstrap and re-hydration on auth state changes
  • User profile synchronization from auth claims
  • Role lookup and workspace summary loading
  • Workspace-aware access decisions in application routing
  • Shared notification and messaging state retrieval
  • Feature-flag and background job state support for system-wide behavior

Interactions with Other Engines

  • Infrastructure Engine
  • Identity Engine
  • Competition Engine
  • Player Engine
  • Media Engine
  • Social Engine
  • Recruitment Engine

Operations

The Admin Operations workspace is the operator-facing control layer for imports, resolver queues, duplicate review, and registry governance tasks. It complements the Registries by handling workflows that clean or consolidate data rather than simply editing one record at a time.

The Admin workspace is now intentionally split into multiple operator surfaces instead of one monolithic admin menu:

  • Data for registries and governance operations
  • Lookup Registries for canonical lookup metadata and translated option sets
  • Games & Competitions for domain-oriented competition and game workflows
  • Media for video ingestion, diagnostics, processing, and highlight operations

This separation keeps registry CRUD, lookup maintenance, competition context, and media operations from collapsing into one generic grid layer.

The Admin workspace now also includes Media as a dedicated operational surface for video ingestion, extracted moment review, player resolution, highlight publishing, processing queue monitoring, video inventory, and diagnostics. Operations remains the governance-focused surface, while Media is the media-pipeline control surface.

Domain workspace routing

The canonical route family for competition-domain admin work is now /admin/games_competitions/*.

That route family provides:

  • a lightweight hub page at /admin/games_competitions
  • a domain competitions list at /admin/games_competitions/competitions
  • competition detail pages at /admin/games_competitions/competitions/{competitionId}
  • a games list and related detail routes under /admin/games_competitions/games

The older /admin/competitions/* routes remain temporarily as compatibility paths, but current admin navigation points to the new domain workspace.

Entity Resolution System

Status: IMPLEMENTED

Turfi provides a generic duplicate detection and entity merge engine for Data Registry entities through Admin -> Operations -> Entity Resolution.

Its goals are to:

  • maintain clean master data
  • prevent duplicate entities from accumulating during imports and manual admin work
  • allow administrators to safely consolidate records
  • preserve relational integrity across the platform

At a platform level, the Entity Resolution System sits between registry identity management and safe mutation workflows. Duplicate groups are detected by the system, presented to administrators for review, and then resolved through a shared merge engine that keeps one surviving record while consolidating the rest.

Core concept:

  • duplicate groups represent clusters of records that likely describe the same real-world entity
  • administrators review those groups rather than the system auto-merging records blindly
  • one record is selected as the primary record to keep
  • remaining records are merged into the surviving record through the backend merge engine

Architecture flow:

Duplicate Detection
        ↓
Duplicate Groups
        ↓
Admin Review
        ↓
Merge Engine
        ↓
Relationship Rewiring
        ↓
Merge Log

This design lets Turfi clean registry data without sacrificing trust. Operators keep control over identity decisions, while the platform handles the dangerous part: rewiring references, preserving integrity, and recording what changed.

Registry Identity Engine

Turfi registry entities use a standardized identity model so imports, URLs, admin editing, and cross-system references all point at the same conceptual record. This model exists to make imports deterministic, keep URLs stable, preserve human-readable labels, and allow identity reuse across operational workflows.

Registry identity fields:

  • id
  • key
  • slug
  • name
  • normalized_name where duplicate detection or search requires it
  • status
  • created_at
  • updated_at

Identity roles:

  • uuid = database identity
  • key = import identity
  • slug = URL identity
  • name = display identity
  • normalized_name = search and duplicate-detection identity where needed
  • status = lifecycle identity

Registry Identity Automation

Registry identity is enforced by the database rather than generated in application code. Two functions define the behavior:

  • turfi_slugify()
  • turfi_registry_identity()

Behavior enforced by triggers:

  • If slug is missing, generate a slug from name
  • If key is missing, generate a normalized key from name
  • Always update updated_at
  • Registry UIs default to status = active while still supporting inactive and archived filters

Application code must not generate registry keys or slugs anymore. The database is the source of truth for registry identity consistency.

Registry Tables Covered

The generic registry identity trigger applies to:

  • organizations
  • leagues
  • seasons
  • competitions
  • clubs
  • teams
  • venues
  • turfs
  • businesses
  • addresses
  • contacts

Players are intentionally excluded from the generic trigger because they require duplicate detection, merge workflows, claim resolution, and identity snapshots. They still follow the standardized registry lifecycle model and now participate in the shared status contract.

Registry Lifecycle Standard

Core registry entities use the lifecycle states:

  • active
  • inactive
  • archived

This standard exists so the platform can preserve historical records without relying on hard deletes. The players, teams, venues, and turfs registries now explicitly use indexed status fields to support lifecycle-aware registry filtering.

Club Licensing Lookup Standard

Club licensing is handled as centralized lookup metadata rather than a federation-rules engine.

  • club_license_levels stores the canonical keys
  • clubs.license_level_id stores the optional descriptive relationship
  • multilingual labels are resolved through ui_field_labels
  • club_license_level_translations is not part of the target architecture

Licensing may support club profile display, scouting filters, analytics, and discovery, but it must not be used to block league participation, competition access, or team creation.

Centralized Address and Contact Infrastructure

Turfi now separates summary location fields from full contact/address records.

  • Core entity tables such as clubs, organizations, venues, businesses, and users keep summary fields like city, province, country, and website
  • Full postal addresses live in addresses
  • Contact records live in contacts
  • Polymorphic link tables entity_addresses and entity_contacts connect those records back to the owning entity
  • Relationship roles are normalized through address_roles and contact_roles
  • Each entity may have many addresses and many contacts, but only one linked record may be primary in each category
  • venues remain the physical facility layer, while turfs remain child play surfaces attached to venues
  • businesses stay in the entity layer and may link to centralized addresses/contacts without being flattened into the venue model

This architecture keeps registry grids fast because summary fields stay on the main entity row, while detailed address and contact history can grow without bloating every registry table. The primary link is the authoritative source for those summary fields, and database sync logic refreshes the entity summary columns when the primary linked record changes.

Admin editing follows the same split. Registry grids continue to show lightweight summary values, while edit forms manage a primary address/contact plus any number of additional linked records. Standalone addresses and contacts registries exist for direct maintenance and import, but linking remains an explicit operator action in this phase rather than hidden auto-linking during import.

Player Identity Engine

Players use a specialized identity system rather than the generic registry identity trigger. Player identity is designed for athlete-specific workflows such as duplicate review, profile claims, resolver assistance, and merge operations.

Authoritative player triggers:

  • trg_refresh_player_identity_players
  • trg_players_normalized_name
  • players_slug_trigger

This player identity engine supports:

  • duplicate detection
  • identity resolution
  • profile claim workflows
  • player merging

Players are not generic registries and should not be modeled as if they were.

Global Async Activity System

Long-running operations can make the platform appear frozen even when the backend is actively working. Imports, registry loads, and bulk actions therefore participate in a global async activity tracker.

Core concept:

  • activeRequests
  • request start -> activeRequests++
  • request finish -> activeRequests--
  • if activeRequests > 0, show a global working indicator

The indicator appears in the top toolbar near the user avatar. A thin progress bar under the header is a natural extension of the same architecture.

Button Loading Behavior

Global activity must be paired with local action feedback so users know which control is currently processing.

Required behavior:

  • disable the button
  • show a spinner
  • update the text to match the action

Examples:

  • Preview -> Previewing
  • Load -> Loading
  • Execute -> Executing

Shared Loading Button Component

Turfi uses a reusable loading button pattern so asynchronous UI behavior stays consistent across the platform.

Example concept:

  • <Button loading>

Loading state automatically:

  • shows a spinner
  • disables the button
  • updates the button text

Async Request Wrapper

The global async activity system depends on a shared request wrapper so request tracking is not optional.

Example concept:

await trackedRequest(() => supabase.from("players").select());

All API calls should use this wrapper so the global activity system always reflects real platform activity.

Structured Competition Classification

Youth and amateur soccer often names competitions with compact federation-style labels such as MU17 or FU17. Turfi now models those labels as structured data instead of storing the shorthand directly on competitions.

Normalized competition classification:

  • leagues may optionally reference gender_id -> genders.id
  • competitions reference age_group_id -> age_groups.id
  • competitions reference gender_id -> genders.id
  • teams reference age_group_id -> age_groups.id
  • teams reference gender_id -> genders.id
  • players reference gender_id -> genders.id

Example:

  • stored data: age_group_id -> u17, gender_id -> male
  • UI rendering: MU17

Category model:

  • League: may be mixed or category-specific
  • Competition: category-aware for age group and gender
  • Team: category-specific for age group and gender
  • Player: gender-specific

Transition note:

  • teams.age_group and teams.gender still exist as temporary compatibility fields
  • teams.age_group_id and teams.gender_id are now the source of truth
  • a database sync trigger keeps the text fields aligned during the transition window

This change keeps the database normalized, keeps lookup values multilingual-compatible, and allows the UI to present familiar shorthand without collapsing structured competition data back into one text field.

Recruitment Engine

Status: IMPLEMENTED (workspace and navigation); PLANNED (saved searches, scouting playlists, talent pipelines)

The Recruitment Engine is built for scouts, recruiters, and club staff who need to find and evaluate talent. It provides a dedicated workspace with player discovery, saved searches, scouting notes, and player reports. When a recruiter logs in, the Recruitment Engine defines what they see and how they work with player data.

Recruitment is a distinct workflow. Coaches manage teams; admins manage data. Recruiters and scouts need to search across many players, save criteria for recurring checks, annotate players with evaluation notes, and generate reports. The Recruitment Engine exists so that workflow has a home instead of being scattered across generic search and admin tools.

This engine owns Recruit workspace navigation and access (role-gated), player discovery surfaces and filters, saved searches and scouting notes (planned), player reports and evaluation outputs (planned), and shared models with Discovery and Player Engine for search and profile context.

Recruitment leans heavily on Discovery (for finding players) and Player Engine (for profile and performance data). It may consume Match Intelligence for stats and Media for highlights when evaluating players. The engine is the recruitment-specific layer on top of those shared capabilities.

Planned evolution includes full saved search persistence, scouting playlists, talent pipeline stages, report templates, and deeper integration with club and federation workflows so recruiting is more than discovery—it becomes a structured process.


Purpose

The Recruitment Engine supports scouting workflows, talent discovery, and recruiter-centric experiences. It enables users with recruiter, scout, club_admin, or association_admin roles to discover players, save searches, and maintain scouting notes.

Architecture Overview

The Recruit workspace is exposed through role-based navigation (recruiter, scout, club_admin, association_admin, system_admin). Menu items include Dashboard, Player Discovery, Saved Searches, Scouting Notes, and Player Reports. Discovery surfaces consume api_player_profiles, api_player_competition_analytics, and search-index views. The engine shares infrastructure with the Discovery Engine for player lookup and with the Player Engine for profile context.

Key Database Models

  • player_search_index — Search-optimized player index (if implemented)
  • saved_player_searches — Stored search criteria for recruiters (PLANNED)
  • api_player_profiles — Player discovery read model
  • api_player_competition_analytics — Performance context for scouting
  • api_player_matches — Match history for evaluation

Recruitment-specific tables are not fully confirmed in the current schema; the workspace and navigation are implemented with placeholder routes.

Key Workflows

  1. Player Discovery: Recruiters browse/filter players via Discovery surfaces.
  2. Saved Searches: (PLANNED) Save filter criteria for recurring discovery.
  3. Scouting Notes: (PLANNED) Annotate players with evaluation notes.
  4. Player Reports: (PLANNED) Generate or export player evaluation reports.

Interactions with Other Engines

  • Player Engine: Profile and identity data for discovery.
  • Discovery Engine: Shared search and retrieval infrastructure.
  • Match Intelligence Engine: Stats and match context for evaluation.
  • Media Engine: Highlight and clip context for scouting.

Social Engine

Status: IMPLEMENTED (activity feed); PLANNED (follows, notifications, messaging)

The Social Engine brings a feed-style experience to Turfi. When a player page shows "recent activity" or when users might follow athletes and get updates, the Social Engine is powering that. It turns events—goals, new highlights, competition updates—into a stream of activity that keeps users engaged and informed.

Sports platforms thrive on engagement. A static profile or a one-off match view doesn't encourage return visits. The Social Engine exists to create an ongoing narrative: what's new, what's notable, and what's relevant to the people and teams a user cares about. It gives Turfi a social layer on top of the data.

This engine owns player-scoped activity feeds, activity event generation from games and highlights, follow relationships (planned), notifications and preferences (planned), messaging and conversations (planned), and engagement signals for discovery and trending.

Social consumes events from Match Intelligence (goals, assists), Media (new highlights), and Competition (game results). It surfaces activity on player pages and may power discovery trends. Platform Systems will handle notification delivery; Discovery may use social signals for ranking.

Planned evolution includes full follow/subscribe flows, push notifications, in-app messaging, comment and like features on activity, and federation or club-scoped social feeds so users can stay connected within their community.


Purpose

The Social Engine handles activity feeds, follow relationships, and social context around players and matches. It surfaces event-driven activity to player pages, feeds, and discovery surfaces.

Architecture Overview

Activity is exposed through api_player_activity, keyed by player_id. The Player API (lib/api/player.ts) fetches activity for player profile surfaces. Event sources include game events, highlight collections, and administrative actions. The schema references activity_feed, activity_comments, and activity_likes for extended social features; current implementation focuses on player-scoped activity projection.

Key Database Models

  • api_player_activity — Player-scoped activity read model (IMPLEMENTED)
  • activity_feed — Base activity events (schema-dependent)
  • activity_comments — (PLANNED)
  • activity_likes — (PLANNED)
  • player_follows — (PLANNED) Follow relationships
  • conversations, conversation_participants, messages — (PLANNED) Messaging
  • notifications, notification_preferences — (PLANNED)

Key Workflows

  1. Activity feed retrieval: Player pages fetch api_player_activity for the selected player.
  2. Feed event generation: Game events and highlight activity drive feed population (trigger-backed where implemented).
  3. Follow/notify: (PLANNED) Follow players; receive notifications on new activity.

Interactions with Other Engines

  • Player Engine: Activity is player-scoped; profile context for feed display.
  • Match Intelligence Engine: Game events feed activity.
  • Media Engine: Highlight and moment activity.
  • Discovery Engine: Activity signals for trending/engagement.

Development Roadmap

Future Feature: Event Driven Editorial Drafts

Turfi will introduce an automated editorial drafting system that generates article drafts when important platform events occur.

These drafts will appear inside the Studio editorial environment and will allow editors to rapidly produce match reports, competition coverage, and player feature stories.

Example trigger events:

  • Game completed
  • Game scheduled
  • Competition finals scheduled
  • Player milestone events

Status: Planned