Skip to main content
Petanque Life

Localization & Federation Customization

F16.03 20 features In progress

At a glance

Per-tenant configurability and 43-language localisation in one layer: every federation defines its own competition classes, game formats, levels, fee structures, license types, transfer rules, ranking algorithms, OrgNode hierarchy, branding and terminology — and every screen renders in the user's language with locale-aware formatting and full RTL support.

How it works

The customisation surface is exposed as a TenantConfig document with typed sub-registries: competition classes, game formats, competition levels, license types, fee structures with OrgNode-level components, transfer rules, ranking algorithms, OrgNode hierarchies (depth, type names and capabilities), umpire grades, discipline rules, medical-certificate requirements, branding (logos, colour palette, fonts, custom CSS), terminology mapping (26 standard keys), game variants (Pétanque, Jeu Provençal, Sport-Boules) and per-branch hierarchy overrides for non-uniform federations. Each registry has dedicated GET/PUT endpoints under /tenant-config/, validation that prevents code collisions and a delegated-admin flag so sub-federations can run autonomously with their own admin and CMS while inheriting parent branding.

Localisation is the second axis. The platform ships a single source of truth for translatable strings authored in source language, processed through a DeepL-backed translation pipeline and cached per language. The framework wraps gettext (.po) on the API side and react-intl on the frontend, with lazy-loaded message bundles keyed on locale. Locale detection picks from URL prefix, user preference, tenant default and Accept-Language in that order. Date, number, time and currency formatting use a LocaleFormattingConfig with built-in defaults for en/sv/fr/de/es/ar that tenants can override. Pluralisation goes through ICU MessageFormat. Right-to-left support flips layouts for Arabic, Hebrew, Persian and Urdu via I18nManager on React Native and dir="rtl" on web.

Localised content (rules, news, documents) lives in a LocalizedContent collection with per-language title/body/summary, slug-lookup and per-language translation management — so a federation can publish a rule change in French and Spanish on the same record without forking the document. Tenants pick their launch languages, see completeness reporting against the master string set, and can commission DeepL fills for missing keys.

Key capabilities

  • Configurable registries per tenant: competition classes, game formats, levels, license types, fees, transfer rules, ranking algorithms
  • Configurable OrgNode hierarchy with per-level capabilities and per-branch depth overrides
  • Tenant branding (logo, palette, fonts, custom CSS) plus terminology mapping for 26 standard keys
  • Game-variant support for Pétanque, Jeu Provençal and Sport-Boules with per-variant rules
  • 43+ languages via gettext / react-intl with DeepL pipeline, lazy-loaded bundles and ICU pluralisation
  • Locale-aware date / number / currency formatting and full RTL layout support
  • Per-language localised content collection for rules, news and documents with slug lookup
  • Delegated admin and CMS per OrgNode level for autonomous sub-federations

In practice

A new continental confederation onboards. On day one their platform admin opens /tenant-config and configures a three-level OrgNode hierarchy (continental → national → club), defines five license types matching their statute, sets a ranking algorithm with three-year validity weighted 3×/2×/1×, uploads logo and brand colours, and toggles Jeu Provençal as an enabled game variant. Their localisation officer commissions French and Italian translations through DeepL, reviews the auto-generated strings for sport-specific terminology, and publishes.

Within an hour the admin app, the player app, the federation CMS and the marketing site are live in two languages, with locale-correct dates, federation branding throughout and rule documents available in both languages from the same slug.

Features in this subsystem

20
ID Status Features
F16.03.01 Shipped Configurable competition class registry — each tenant defines its own age/gender classes with: code, name, type (age/gender/open), min/max age, gender filter, ranking eligibility. Examples: Sweden (M/YJ/J/Ö/D/V55/V65), France (Poussin/Benjamin/Minime/Cadet/Junior/Sénior/Vétéran), Spain (Benjamín→Veterano+Sub-23). Implemented (PL-F1603a): PlayerClass model med class_type-fält (age/gender/open), CompetitionClass = PlayerClass + GameFormat. CRUD-endpoints med unik kodvalidering per tenant. ✅ PL-F1603a
F16.03.02 Shipped Configurable game format registry — each tenant defines: code, name, players per team, boules per player, mixed gender required. Standard formats (s/d/t/Mxd/Mxt) pre-seeded, tenants can add variants. Implemented (PL-F1603a): GameFormat model med mixed_gender_required. CRUD-endpoints med unik kodvalidering per tenant. ✅ PL-F1603a
F16.03.03 Shipped Configurable competition level registry — each tenant defines its levels with: code, name, who can sanction, ranking eligibility, ranking coefficient, required referee grade, venue requirements, sanction deadline, quota. Not hardcoded. Implemented (PL-F1603a): CompetitionLevel med sanction_deadline_days och quota. CRUD-endpoints med unik kodvalidering per tenant. ✅ PL-F1603a
F16.03.04 Shipped Configurable fee structure with OrgNode-level components — license fee can be split across multiple OrgNode levels (federation + region + district + insurance). Each level sets its own component. Supports regional price variation. Implemented (PL-F1603a): LicenseFeeConfig med FeeComponent[], LicenseFeeOverride per OrgNode, beräkningsendpoint som resolver OrgNode-hierarkin. ✅ PL-F1603a
F16.03.05 Shipped Configurable license type registry — each tenant defines its license types with: code, name, competition eligibility, insurance inclusion, age limits, duration (annual/time-limited), medical certificate requirement, renewability. Implemented (PL-F1603a): LicenseType med alla fält inkl. renewable, includes_insurance, base_fee, fee_currency, requires_parental_consent, reduced_fee_pct. Fullständig validering. ✅ PL-F1603a
F16.03.06 Shipped Configurable transfer rules — per tenant: transfer window dates, max transfers per season, required approvals (player/old club/new club/federation/district), cross-region extra approval, outstanding debt blocking, quarantine during league. Implemented (PL-F1603b): Dedikerade GET/PUT-endpoints under /tenant-config/transfer-config/. Full TransferConfig med alla fält inkl. ITC-inställningar. ✅ PL-F1603b
F16.03.07 Shipped Configurable ranking algorithm — per tenant: point scale per level × placement × participant count, validity period (1/2/3 years), weighting across years (Germany: 3×/2×/1×), max competitions counted, separate per class/format/gender. Implemented (PL-F1603b): RankingAlgorithmConfig i TenantConfig med ParticipantThreshold-stöd. Dedikerade GET/PUT-endpoints under /tenant-config/ranking-algorithm/. ✅ PL-F1603b
F16.03.08 Shipped Configurable OrgNode hierarchy — per tenant: number of levels (0-3+), type names per level, capabilities per level (can_sanction, can_set_license_price, has_discipline_body, can_issue_licenses). Implemented (PL-F1603b): Dedikerade GET/PUT-endpoints under /tenant-config/org-hierarchy/ med validering av djup och sekventiella nivåer. ✅ PL-F1603b
F16.03.09 Shipped Configurable umpire grade registry — per tenant: grade names, count, progression path, playing-umpire allowed per level. Implemented (PL-F0501a, verifierat PL-F1603b): Befintliga endpoints under /tenant-config/umpire-grades/ med full progression, multi-part exam och recertification. ✅ PL-F1603b
F16.03.10 Shipped Configurable discipline rules — per tenant: penalty amounts, suspension rules, who can decide (only federation vs also district). Implemented (PL-F1603b): Utökad DisciplinaryConfigSchema med sanction_catalog (straffkatalog med belopp, typ, varaktighet) och adr_config (alternativ tvistlösning). Beslutsmyndighet konfigureras via levels[].org_node_level. ✅ PL-F1603b
F16.03.11 Shipped Configurable medical requirements — per tenant: medical certificate required (yes/no), at first license only, renewal cycle, attestation sur l'honneur, health certificate for international play. Implemented (PL-F1603c): MedicalCertificateConfig med required_at_first_license_only och health_certificate_for_international. Dedikerad config-endpoint GET /medical-certificates/config. ✅ PL-F1603c
F16.03.12 Shipped Multi-language UI — architected for 43+ FIPJP-member-nation languages, with 5 launch languages delivered (en, sv, fr, es, it) and additional languages activated per nation via tools/translate/translate.py. Implemented (PL-1701, refined under PL-T328): i18n framework, language picker, per-tenant default language, translation management API, completeness reporting (CI gate i18n-coverage enforces ≥ 80% Tier-1 coverage). See specs/shared/i18n.md and docs/engineering/i18n-strategy.md. ✅ PL-F1603c
F16.03.13 Shipped Multi-language content management (rules, news, documents). Implemented (PL-F1603c): LocalizedContent modell med per-språk title/body/summary, CRUD-endpoints under /content, slug-lookup, per-language translation management (PUT/DELETE /content/{id}/translations/{lang}). ✅ PL-F1603c
F16.03.14 Shipped Locale-aware formatting (dates, numbers, currency). Implemented (PL-F1603c): LocaleFormattingConfig i TenantConfig med date/time/number/currency-format. Endpoints GET /i18n/locale-formats/{locale} och GET /i18n/locale-formats. Inbyggda defaults för en/sv/fr/de/es/ar. ✅ PL-F1603c
F16.03.15 Shipped Right-to-left language support. Implemented (PL-1701): RTL detection and layout mirroring for Arabic, Hebrew, Persian, Urdu via I18nManager (React Native) and dir="rtl" (web). ✅ PL-F1603c
F16.03.16 Shipped Tenant-level branding — logo, colors, terminology per federation. Implemented (PL-F1603d): BrandingConfig embedded i TenantConfig med logo_url, logo_dark_url, favicon_url, primary/secondary/accent/background/text colors (hex-validerade), font_heading, font_body, custom_css. Dedikerade endpoints GET/PUT /tenant-config/branding/. ✅ PL-F1603d
F16.03.17 Shipped Federation-specific terminology mapping — each tenant maps generic terms to local equivalents. Implemented (PL-F1603d): STANDARD_TERMINOLOGY_KEYS (26 standardtermer), dedikerade endpoints GET/PUT /tenant-config/terminology/ som returnerar terminology dict + standard_keys lista. ✅ PL-F1603d
F16.03.18 Shipped Game variant support — Jeu Provençal, Pétanque, Sport-Boules. Implemented (PL-F1603d): GameVariantConfig med variant, enabled, name i18n, court_dimensions (CourtDimensions), boules_per_player, max_points, team size, competition_class_codes, rules_document_url. Dedikerade endpoints GET/PUT /tenant-config/game-variants/ med unik variant-validering. ✅ PL-F1603d
F16.03.19 Shipped Variable OrgNode depth per branch within tenant — non-uniform hierarchy depth. Implemented (PL-F1603d): BranchHierarchyOverride med region_code, region_name i18n, extra_levels (list[OrgNodeTypeConfig]), description. Dedikerade endpoints GET/PUT /tenant-config/branch-hierarchy/ med unik region_code-validering. ✅ PL-F1603d
F16.03.20 Shipped Delegated admin and CMS per OrgNode level — autonomous sub-federations. Implemented (PL-F1603d): has_own_admin och has_own_cms boolean-fält i OrgNodeTypeConfig. Dedikerad read-endpoint GET /tenant-config/delegated-admin/ som returnerar delegated_levels + parent_branding. ✅ PL-F1603d