Skip to main content
Petanque Life
← Back to all features
03

Membership & Licensing

101 features · 8 subsystems

Complete lifecycle management of player licenses, club memberships, federation affiliations, and inter-federation transfers. This is the backbone of the petanque administrative system.

License Management

F03.01
Planned
How it works
  • F03.01.01 Shipped

    Configurable license types per tenant — each federation defines its own types (e.g., Sweden: 1 type; France: compétition, loisir, jeune, découverte). Each type has: competition eligibility, insurance inclusion, age limits, duration, renewability

    ✅ PL-F0301a
  • F03.01.02 Shipped

    License application workflow (club applies on behalf of player → federation reviews → approves → issues)

    ✅ PL-F0301a
  • F03.01.03 Shipped

    License numbering system (federation prefix + sequential, configurable format per tenant)

    ✅ PL-F0301a
  • F03.01.04 Shipped

    Annual license renewal (individual and bulk), season configurable per tenant (calendar year default)

    ✅ PL-F0301a
  • F03.01.05 Shipped

    Composite license fee calculation — fee = sum of configurable components (e.g., part fédérale + part ligue/region + part comité/district + assurance). Each component set at its OrgNode level. Supports regional price variation (France, Spain)

    ✅ PL-F0301a
  • F03.01.06 Shipped

    License card generation (digital + physical), with FIPJP symbol where required — PL-F0301b

    ✅ PL-F0301b
  • F03.01.07 Shipped

    License verification — QR code scan at events, public API for cross-tenant verification — PL-F0301b

    ✅ PL-F0301b
  • F03.01.08 Shipped

    License history tracking (all clubs, all federations, all years) — PL-F0301b

    ✅ PL-F0301b
  • F03.01.09 Shipped

    License suspension and revocation — only federation can decide (not club/district). Administrative fee configurable. — PL-F0301b

    ✅ PL-F0301b
  • F03.01.10 Shipped

    Time-limited license type — e.g., France's "licence découverte" (max 3 months, one-time only per player) — PL-F0301b

    ✅ PL-F0301b
  • F03.01.11 Shipped

    Grace period management for late renewals — PL-F0301c

    ✅ PL-F0301c
  • F03.01.12 Shipped

    Bulk license import from legacy systems — PL-F0301c

    ✅ PL-F0301c
  • F03.01.13 Shipped

    Audit trail on all license changes — PL-F0301c

    ✅ PL-F0301c
  • F03.01.14 Shipped

    One-license-per-nation-per-season enforcement (system-level constraint) — PL-F0301c

    ✅ PL-F0301c
  • F03.01.15 Shipped

    Season management (configurable per federation — calendar year, split year, etc.) — PL-F0301c

    ✅ PL-F0301c
  • F03.01.16 Shipped

    Medical certificate management — configurable per tenant: required at first license (France), renewal cycle (every 3 years), digital attestation sur l'honneur for annual renewal, upload/expiry tracking — PL-F0301d

    ✅ PL-F0301d
  • F03.01.17 Shipped

    License insurance declaration (licensförsäkran) — allows unlicensed player to participate if club has fulfilled obligations and player signs declaration (Sweden-specific but configurable) — PL-F0301d

    ✅ PL-F0301d
  • F03.01.18 Shipped

    International license issuance — member can request international license + health certificate for play abroad (required in France etc.) — PL-F0301d

    ✅ PL-F0301d
  • F03.01.19 Shipped

    Foreign license verification — player with foreign license can participate in national events by presenting valid license from issuing federation — PL-F0301d

    ✅ PL-F0301d
  • F03.01.20 Shipped

    Unauthorized player enforcement — configurable penalties per tenant (e.g., Sweden: 13-0 forfeit + 5000 SEK fine + exclusion from next year's equivalent event) — PL-F0301d

    ✅ PL-F0301d
  • F03.01.21 Shipped

    Multi-discipline license support — License.discipline field scopes each license to one discipline (petanque, jeu_provencal, sport_boules, bocce, raffa). Unique index (tenant, license_number, discipline). LicenseType.discipline determines which discipline a license type covers. Auto-propagation: discipline copied from LicenseType to License on creation, auto-added to PlayerProfile.disciplines. Duplicate check scoped by discipline — same player can hold licenses for different disciplines in same season. — PL-T013

    ✅ PL-T013
  • F03.01.22 Shipped

    Admin UI för licenshantering — LicenseList med filter (säsong, typ, status, klubb, fritext), massoperationer (godkänn/avslå/påminnelse), CSV-export (UTF-8 BOM), LicenseDetail med audit-tidslinje, bulk-renewal för nästa säsong, massutskick via BulkEmailComposer — PL-T058

    ✅ PL-T058

Club Membership

F03.02
Platform+
How it works
  • F03.02.01 Shipped

    Membership application (player applies to join club) — PL-F0302a

    ✅ PL-F0302a
  • F03.02.02 Shipped

    Club acceptance/rejection workflow — PL-F0302a

    ✅ PL-F0302a
  • F03.02.03 Shipped

    Membership categories — configurable per tenant (full, associate, honorary, youth, family, support, etc.) — PL-F0302a

    ✅ PL-F0302a
  • F03.02.04 Shipped

    Membership fee management per category — PL-F0302a

    ✅ PL-F0302a
  • F03.02.05 Shipped

    Membership card generation — PL-F0302a

    ✅ PL-F0302a
  • F03.02.06 Shipped

    Member directory per club (with privacy controls) — PL-F0302a

    ✅ PL-F0302a
  • F03.02.07 Shipped

    Membership start/end dates and status tracking — status transition history, auto-expire endpoint, activated_at/expired_at timestamps — PL-F0302b

    ✅ PL-F0302b
  • F03.02.08 Shipped

    License club vs support membership — player has exactly one license club (competition rights) but can be support member in other clubs (no competition rights). System enforces single license club constraint. Categories with grants_competition_rights require is_license_club=true. Player summary endpoint. — PL-F0302b

    ✅ PL-F0302b
  • F03.02.09 Shipped

    Family membership grouping — FamilyGroup model, family discount for 2nd+ member, family membership overview endpoint — PL-F0302b

    ✅ PL-F0302b
  • F03.02.10 Shipped

    Automatic membership renewal reminders — bulk reminder endpoint with max_reminders threshold, per-club filtering, reminder count tracking — PL-F0302b

    ✅ PL-F0302b
  • F03.02.11 Shipped

    Club-bound competition enforcement — enhanced validation with expected club_id, per-player club mapping, club name resolution — PL-F0302b

    ✅ PL-F0302b
  • F03.02.12 Shipped

    ClubInquiry inbox — shared inbox for prospect/visitor inquiries, status-FSM new/assigned/awaiting_reply/responded/converted/closed_no_response/spam, indices för (tenant_id, club_id, status) + (tenant_id, assigned_to, status) + (follow_up_due) — PL-T222

    ✅ PL-T222
  • F03.02.13 Shipped

    InquiryAssignment — event-log per (re-)assignment, role-gated på role:club_secretary / role:membership_secretary, dispatchar inquiry.assigned-notification via F09.02 — PL-T222

    ✅ PL-T222
  • F03.02.14 Shipped

    InquiryResponseTemplate — Jinja-style {{contact.name}}-substitution, per (club_id, inquiry_type, language)-default, okända variabler collapsar till tomt — PL-T222

    ✅ PL-T222
  • F03.02.15 Shipped

    Inquiry follow-up reminder — 5-dagars default-SLA, inquiry_follow_up_tick (1 h-cron), single-fire via follow_up_reminder_sent_at-marker — PL-T222

    ✅ PL-T222
  • F03.02.16 Shipped

    Convert-to-member — skapar ClubMember från inquiry, sätter inquiry.converted_to_member_id + status=converted, 409 vid email-kollision — PL-T222

    ✅ PL-T222
  • F03.02.17 Shipped

    Public CMS inquiry-form-endpoint — POST /public/clubs/{id}/inquiries med rate-limit 10/h per IP, honeypot-fält website (left:-9999px), 5-min dedup på (email, subject), email lower-normaliserad — PL-T222

    ✅ PL-T222

Transfers

F03.03
Planned

### Transfer Rules — Vary Per Nation

How it works
  • F03.03.01 Shipped

    Intra-national club transfer (OrgNode change within same tenant) — PL-F0303a

    ✅ PL-F0303a
  • F03.03.02 Shipped

    International transfer (cross-tenant, nation to nation via public APIs) — PL-F0303a

    ✅ PL-F0303a
  • F03.03.03 Shipped

    Configurable transfer window per tenant — open period (Germany: Nov-Dec), free period before deadline (Sweden), or always open (Denmark). Tenant admin configures. — PL-F0303a

    ✅ PL-F0303a
  • F03.03.04 Shipped

    Configurable transfer approval workflow per tenant — who must approve (player, old club, new club, federation, district/region). Each step configurable. — PL-F0303a

    ✅ PL-F0303a
  • F03.03.05 Shipped

    Max transfers per season — configurable limit per tenant (Sweden: 2, others: unlimited) — PL-F0303a

    ✅ PL-F0303a
  • F03.03.06 Shipped

    Transfer quarantine during active league — configurable: player cannot transfer while league season is active (Denmark Landsturneringen). Tenant-scoped league check. — PL-F0303b

    ✅ PL-F0303b
  • F03.03.07 Shipped

    Cross-region/cross-district transfer — additional approval required when transferring between OrgNode subtrees (Spain: autonomous federation approval, France: inter-comité mutation). Configurable approval type per tenant. — PL-F0303b

    ✅ PL-F0303b
  • F03.03.08 Shipped

    Outstanding obligations check — system blocks transfer if player has unpaid fees/active sanctions. Configurable blocking period (Sweden: max 2 years). Sanctions always checked. — PL-F0303b

    ✅ PL-F0303b
  • F03.03.09 Shipped

    Carta de libertad / release letter — some nations require formal release document from departing club. Configurable per tenant. Submit/verify/reject workflow. — PL-F0303b

    ✅ PL-F0303b
  • F03.03.10 Shipped

    ITC generation and verification via public API (peer-to-peer between tenants). Verify endpoint validates authenticity and status. — PL-F0303b

    ✅ PL-F0303b
  • F03.03.11 Shipped

    ITC workflow: player requests in new nation → new nation verifies license status via public API → sends ITC request → old nation reviews and approves/rejects → license marked "transferred out" → new nation issues license — PL-F0303c

    ✅ PL-F0303c
  • F03.03.12 Shipped

    Transfer fee handling — configurable per tenant (who pays, amount) — PL-F0303c

    ✅ PL-F0303c
  • F03.03.13 Shipped

    Transfer history per player (all clubs, all nations, all seasons) — PL-F0303c

    ✅ PL-F0303c
  • F03.03.14 Shipped

    One-nation-per-season validation on international transfer — PL-F0303c

    ✅ PL-F0303c
  • F03.03.15 Shipped

    Post-transfer competition eligibility delay — configurable per tenant (France: délai de carence ~30 days after mutation before player is competition-eligible in new club). Distinct from transfer quarantine (F03.03.06). — PL-F0303c

    ✅ PL-F0303c
  • F03.03.16 Shipped

    Transfer refusal appeal/escalation — when a step in the transfer workflow is rejected (e.g., old club refuses), player can escalate to higher OrgNode level (France: appeal to comité départemental). Configurable escalation path per tenant. — PL-F0303d

    ✅ PL-F0303d
  • F03.03.17 Shipped

    Transfer exception conditions — configurable per tenant: allow transfer outside normal window if specific conditions are met (Germany: Wohnsitzwechsel/residence change). Exception must be documented and approved by federation. — PL-F0303d

    ✅ PL-F0303d
  • F03.03.18 Shipped

    Multi-club membership toggle — configurable per tenant: some nations allow support membership in multiple clubs (Sweden), others forbid all multi-club affiliation (France: double appartenance interdit). — PL-F0303d

    ✅ PL-F0303d
  • F03.03.19 Shipped

    Audit trail on all transfers — embedded TransferAuditEntry list with action, performer, timestamp, status transitions. Audit endpoint GET /transfers/{id}/audit. — PL-F0303d

    ✅ PL-F0303d

Federation Affiliation

F03.04
Planned
How it works
  • F03.04.01 Shipped

    Club affiliation to regional/national federation — PL-F0304a

    ✅ PL-F0304a
  • F03.04.02 Shipped

    Annual affiliation renewal — PL-F0304a

    ✅ PL-F0304a
  • F03.04.03 Shipped

    Affiliation fee calculation (based on member count) — PL-F0304a

    ✅ PL-F0304a
  • F03.04.04 Shipped

    Affiliation document management (statutes, insurance proof, etc.) — PL-F0304a

    ✅ PL-F0304a
  • F03.04.05 Shipped

    New federation/club application process — AffiliationApplication model with full workflow (draft → submitted → under_review → approved/rejected). Club applications auto-create Club entity on approval. CRUD + status filtering, parent org validation, audit trail. — PL-F0304b

    ✅ PL-F0304b
  • F03.04.06 Shipped

    Affiliation status (active, suspended, withdrawn) — Enhanced suspend/reinstate/terminate endpoints with 409 conflict codes, structured audit logging. Proper status transition enforcement. — PL-F0304b

    ✅ PL-F0304b
  • F03.04.07 Shipped

    Federation member count reporting (upward to parent) — MemberCountReport model with club/district/federation-level aggregation. Counts active members and licensed members. Persisted snapshots for FIPJP/CEP annual reporting. — PL-F0304b

    ✅ PL-F0304b

Insurance

F03.05
Planned
How it works
  • F03.05.01 Shipped

    Insurance integration with license (mandatory liability) — InsurancePolicy model tied to License with auto-generated policy numbers, per-tenant provider config, coverage amounts, group policy linkage. Tenant InsuranceConfig extended with coverage_type, default_coverage_amount, provider_contact_email, provider_api_endpoint — PL-F0305

    ✅ PL-F0305
  • F03.05.02 Shipped

    Optional insurance add-ons (equipment, travel, accident) — InsuranceAddonSubscription model with addon_code validated against tenant's InsuranceConfig.optional_addons, premium tracking from InsuranceAddon.premium_amount, subscribe/cancel workflow, one active subscription per player/addon/season — PL-F0305

    ✅ PL-F0305
  • F03.05.03 Shipped

    Insurance certificate generation — Enhanced /insurance/certificate/{player_id}/{season_id} with policy_number, addon_coverages list, group_policy_number, coverage_amount from policy or tenant default. Comprehensive certificate data for PDF rendering — PL-F0305

    ✅ PL-F0305
  • F03.05.04 Shipped

    Claim submission workflow — InsuranceClaim model with full status workflow (submitted→under_review→approved/rejected→paid), ClaimDocument attachments, ClaimStatusChange audit trail, per-tenant claims_enabled gating, valid transition enforcement (409 on invalid), review endpoint with approved_amount/paid_amount/provider_claim_reference — PL-F0305

    ✅ PL-F0305
  • F03.05.05 Shipped

    Insurance provider integration (API/file exchange) — InsuranceProviderExport model tracking batch exports (policies/claims/renewals/cancellations) in csv/xml/json, export generation with record counting, provider acknowledgement workflow, file_url generation, provider_reference tracking — PL-F0305

    ✅ PL-F0305
  • F03.05.06 Shipped

    Group insurance management for clubs/federations — GroupInsurancePolicy model for club/district/federation-level policies, member count tracking (auto-incremented when individual policies linked), coverage per member, renewal management, member listing endpoint, per-tenant group_policies_enabled gating — PL-F0305

    ✅ PL-F0305

Per-nationella licensregler

F03.06
Planned
How it works
  • F03.06.01 Shipped

    France — 4 licenstyper (Compétition, Loisir, Jeune, Découverte) — Konfigurerbara via LicenseType-modellen med allows_competition, time_limited/max_duration_days (90d för découverte), one_time_only, max_age (17 för jeune), requires_medical_certificate med 3-årscykel, includes_insurance. Seed-template i NATIONAL_TEMPLATES["FR"]. 53 tester inkl. France-fixture — PL-F0306a

    ✅ PL-F0306a
  • F03.06.02 Shipped

    France — ligue+comité+club godkännandekedja — LicenseRuleConfig.approval_chain med 3 steg: comité départemental (org_level 1) → ligue régionale (org_level 0) → FFPJP (org_level -1). ApprovalChainRecord spårar varje steg med status/reviewer/timestamp/kommentar. Kedjan initieras vid submit, steg måste godkännas i ordning, avslag i vilket steg som helst avbryter hela ansökan. Fullständig chain-approve endpoint /license-applications/{id}/approval-chain/{step}/approve

    reject — PL-F0306a | ✅ PL-F0306a
  • F03.06.03 Shipped

    Sverige — en licenstyp utfärdad av klubben — LicenseRuleConfig med issuer_type="club", tom approval_chain, max_license_types=1. Ansökan går direkt till "submitted" utan godkännandekedja. requires_insurance_declaration=True (licensförsäkran). Seed-template NATIONAL_TEMPLATES["SE"] — PL-F0306a

    ✅ PL-F0306a
  • F03.06.04 Shipped

    Deutschland — DPV-licens med Landesverband-godkännande — LicenseRuleConfig med issuer_type="org_node", issuer_org_level=0 (Landesverband), 1-stegs approval_chain (org_level 0). Verein ansöker → Landesverband godkänner → licens skapas. Seed-template NATIONAL_TEMPLATES["DE"] — PL-F0306a

    ✅ PL-F0306a
  • F03.06.05 Shipped

    Norge — inget licenssystem — LicenseRuleConfig med competition_requires_license=False, membership_only_competitions=True. Rekryteringsturneringar (LF) kräver bara medlemskap, ranking/NM kräver lisens. validate_competition_entry_allowed() hanterar båda fallen. Competition entry check endpoint — PL-F0306a

    ✅ PL-F0306a
  • F03.06.06 Shipped

    Espana — FEP-licens med autonom region-koppling — LicenseRuleConfig med autonomous_regions_manage_licenses=True, license_photo_required=True, autonomous_region_stamp_required=True. 1-stegs approval av federación autonómica (org_level 0). 3 licenstyper (deportiva, técnica, árbitro). Seed-template NATIONAL_TEMPLATES["ES"] — PL-F0306a

    ✅ PL-F0306a
  • F03.06.07 Shipped

    Danmark — DPF-licens — NATIONAL_TEMPLATES["DK"] med issuer_type="federation", tom approval_chain, max_license_types=1, flat struktur (org_hierarchy_depth=0). 1 licenstyp (standard) med base_fee=350 DKK. Inget medicinsk intyg-krav. Competition requires license. — PL-F0306b

    ✅ PL-F0306b
  • F03.06.08 Shipped

    FIPJP — ingen direktlicens — NATIONAL_TEMPLATES["FIPJP"] med license_system_enabled=False, verification_only=True. Världsförbundet utfärdar inga licenser — verifierar nationella licenser vid VM/World Games. LicenseRuleConfig utökad med verification_only-fält och validator. — PL-F0306b

    ✅ PL-F0306b
  • F03.06.09 Shipped

    CEP — kontinentala spelartillstånd — NATIONAL_TEMPLATES["CEP"] med continental_permit_enabled=True, continental_permit_validity_days=30, continental_permit_requires_national_license=True. Utfärdar tidsbegränsade tillstånd (30 dagar) för EM-deltagande. continental_permit-licenstyp. POST /license-rules/continental-permit-check validerar att spelaren har aktiv nationell licens. LicenseRuleConfig utökad med continental_permit_*-fält och validators. — PL-F0306b

    ✅ PL-F0306b
  • F03.06.10 Shipped

    Per-tenant pris och giltighetstid — LicenseType utökad med base_fee (Decimal), fee_currency (ISO 4217), reduced_fee_pct (rabatt%). calculate_license_fee() beräknar effective_fee med rabatt. calculate_license_validity() beräknar giltighetsperiod (season vs fixed_days). GET /license-rules/fee-info/{id} returnerar avgifts- och giltighetsdetaljer. Alla nationella templates uppdaterade med fee-data (FR: 80€ competition/35€ loisir/20€ jeune/5€ découverte, SE: 300 SEK, DE: 40€, NO: 400 NOK, DK: 350 DKK). — PL-F0306b

    ✅ PL-F0306b
  • F03.06.11 Shipped

    Per-tenant medicinska intyg-krav — validate_medical_certificate_requirement() kombinerar LicenseType.requires_medical_certificate med TenantConfig.medical_certificate_config (required, renewal_cycle_years, allows_self_declaration). Returnerar required/valid/reason/self_declaration_allowed/next_certificate_due. Alla nationella templates inkluderar medical_certificate_config. POST /license-rules/medical-certificate-check endpoint. Frankrike: 3-årscykel med självdeklaration. Sverige/DK/DE/NO: ej krav. — PL-F0306b

    ✅ PL-F0306b
  • F03.06.12 Shipped

    Per-tenant ungdomslicens-regler (under 18) — LicenseType utökad med requires_parental_consent (bool, kräver max_age), reduced_fee_pct (rabatt%, kräver base_fee). validate_youth_license_eligibility() kontrollerar ålder (min_age/max_age), föräldrasamtycke, returnerar eligible/reason/player_age. POST /license-rules/youth-eligibility-check endpoint. Frankrike licence jeune: max_age=17, requires_parental_consent=True, reduced_fee_pct=75 (75% rabatt). Modell-validators: parental_consent kräver max_age, reduced_fee kräver base_fee. — PL-F0306b

    ✅ PL-F0306b

Spelartransfer mellan klubbar och nationer

F03.07
Planned

### Transfer Rules — Vary Per Nation

How it works
  • F03.07.01 Shipped

    Per-tenant transferfönster (datum) — Konfigurerbart via TransferConfig.window_type (always_open / deadline / strict_period), window_start/window_end (MonthDay) för strict_period, deadline (MonthDay) för deadline-typ. Stöder årsövergripande fönster (t.ex. Nov–Jan). Undantagsvillkor (exception_conditions) kringgår fönsterrestriktion. Verifierat med 9 integrationstester (always_open, strict_period in/out/wrap, deadline before/after, exception override, per-tenant isolation) — PL-F0307a

    ✅ PL-F0307a
  • F03.07.02 Shipped

    France — 1 transfer per säsong — TransferConfig.max_per_season=1 för franska federationen. Begränsningen är per spelare per säsong. Cancelled/rejected transfers räknas inte mot gränsen. Annan spelare i samma säsong påverkas inte. Verifierat med 6 integrationstester (first allowed, second blocked, cancelled/rejected don't count, config stored, per-player isolation) — PL-F0307a

    ✅ PL-F0307a
  • F03.07.03 Shipped

    Sverige — fri transfer utan fönster — TransferConfig.window_type="always_open" utan max_per_season-begränsning. Ingen competition eligibility delay. Spelare kan genomföra flera godkända transfers under samma säsong. Verifierat med 5 integrationstester (always_open config, no max, transfer succeeds, multiple allowed, no delay) — PL-F0307a

    ✅ PL-F0307a
  • F03.07.04 Shipped

    Avgivande klubb-godkännande — old_club i required_approvals-kedjan. Godkännande avancerar workflow till nästa steg (pending_new_club). Avslag terminerar transfern (status=rejected). Registrerar approver user ID, beslutsdatum och kommentar. Konfigurerbart — kan utelämnas i tenants som inte kräver det. Verifierat med 5 integrationstester (in chain, approve advances, reject blocks, optional in minimal config, user ID recording) — PL-F0307a

    ✅ PL-F0307a
  • F03.07.05 Shipped

    Mottagande klubb-godkännande — new_club i required_approvals-kedjan. I Sverige: sista steget → transfer godkänns, gammal ClubMembership→EXPIRED, ny ACTIVE skapad, License.club_id uppdaterat. I Frankrike: avancerar till pending_federation. Avslag terminerar transfern. Verifierat med 6 integrationstester (in chain, advances to federation in FR, final step in SE, reject blocks, membership updated, license updated) — PL-F0307a

    ✅ PL-F0307a
  • F03.07.06 Shipped

    Federation-godkännande för internationell transfer — TransferConfig.itc_federation_approval_required (opt-in, default false). När aktivt: ITC startar i pending_federation_approval-status. PATCH /itc/{itc_number}/federation-approve godkänner/avvisar internt. Godkännande → pending_release. Avslag → rejected. Release-endpoint blockeras medan federation-godkännande saknas. Audit trail inkluderar federation_approved/federation_rejected. Verifierat med 7 integrationstester (approval required/not required, approve advances, reject blocks, release blocked, double approve rejected, audit trail) — PL-F0307b

    ✅ PL-F0307b
  • F03.07.07 Shipped

    Karantänsperiod för internationell transfer — TransferConfig.itc_competition_eligibility_delay_days (t.ex. France: 30 dagar, Deutschland: 15 dagar). Sätts vid ITC-komplettering baserat på MOTTAGANDE federationens config. competition_eligible_from datum lagras på ITC. GET /itc/{itc_number}/eligibility kontrollerar tävlingsbehörighet med valfritt check_date. Verifierat med 4 integrationstester (quarantine set, no quarantine, during quarantine, after quarantine) — PL-F0307b

    ✅ PL-F0307b
  • F03.07.08 Shipped

    ITC via FIPJP (interkontinentala transfers) — Konfederationsmappning för ~50 länder (CEP, COPAB, CAP, CAPP). is_intercontinental auto-detekteras när konfederationer skiljer sig. Interkontinentala transfers: release → pending_fipjp istället för released. PATCH /itc/{itc_number}/fipjp-approve — FIPJP godkänner/avvisar med referensnummer. Kontinentala (samma konfederation) transfers släpps direkt. Verifierat med 8 integrationstester (confederation lookup, intercontinental detection, FIPJP required, approve/reject, non-intercontinental blocked, continental skip) — PL-F0307b

    ✅ PL-F0307b
  • F03.07.09 Shipped

    Transferhistorik och spårbarhet — GET /itc/history/{player_id} med komplett ITC-historik inkl. alla spårbarhetsfält (is_intercontinental, confederation_code, federation_approval_status, fipjp_reference, competition_eligible_from, fee). Valfri include_audit=true för full audit trail per ITC. GET /itc/{itc_number}/audit för dedikerad audit trail. Enhetlig GET /transfers/history/{player_id} utökad med ITC-spårbarhetsfält. Verifierat med 6 integrationstester (history, traceability fields, audit trail, unified history, pagination) — PL-F0307b

    ✅ PL-F0307b
  • F03.07.10 Shipped

    Avgift per transfer (per tenant konfigurerbar) — TransferConfig.itc_fee_amount/itc_fee_currency/itc_fee_payer. Avgift fångas från avgivande federationens config vid ITC-förfrågan. PATCH /itc/{itc_number}/fee/pay markerar betald. GET /itc/{itc_number}/fee returnerar avgiftsdetaljer. FIPJP förbjuder avgifter på själva ITC-certifikatet men nationella förbund kan ta interna handläggningsavgifter. Verifierat med 7 integrationstester (fee captured, no fee, mark paid, no fee 400, idempotent, audit trail, DE config) — PL-F0307b

    ✅ PL-F0307b

Global Player Passport (FIPJP)

F03.08

Cross-tenant spelaridentitet i FIPJP-tenanten. Kopplar auth-identity till alla nationella licenser.

How it works
  • F03.08.01 Shipped

    GlobalPassport datamodell — Beanie-dokument med passport_id (FIPJP-YYYY-NNNNNN), auth_identity_id (unik), personuppgifter, linked_licenses (embedded lista med tenant_code, license_number, season, status, last_verified_at). Tenant-scoped till FIPJP. — PL-T009

    ✅ PL-T009
  • F03.08.02 Shipped

    FIPJPTenantConfig — Singleton per FIPJP-tenant: passport_number_format, next_passport_sequence (atomärt via $inc), photo_required, photo_max_size_kb. — PL-T009

    ✅ PL-T009
  • F03.08.03 Shipped

    FIPJP admin endpoints — POST /fipjp/passports (skapa), GET /fipjp/passports/{id} (hämta), POST /link-license (koppla licens), POST /verify-license (verifiera mot nationell tenant, 24h cache), PATCH /status (suspendera/återkalla). — PL-T009

    ✅ PL-T009
  • F03.08.04 Shipped

    Publika verifierings-endpoints — GET /public/passports/{id} (privacy-safe: namn, nationalitet, licensstatus — ingen DoB/foto), GET /public/passports/by-license?tenant_code&license_number (lookup). — PL-T009

    ✅ PL-T009
  • F03.08.05 Shipped

    Automatisk onboarding — passport_sync.py: link_local_license_to_passport() skapar passport vid första licens, lägger till licens vid ytterligare. Fire-and-forget (licensutfärdande misslyckas inte vid sync-fel). — PL-T009

    ✅ PL-T009
  • F03.08.06 Shipped

    TenantConfig passport sync — fipjp_passport_sync_enabled (default true), fipjp_passport_sync_endpoint, fipjp_m2m_credentials_secret_ref på alla national tenants. — PL-T009

    ✅ PL-T009
  • F03.08.07 Shipped

    Backfill-jobb — backfill_global_passports(): itererar alla aktiva licenser över alla national tenants, skapar passport per auth_identity, länka licens. Idempotent. — PL-T009

    ✅ PL-T009
  • F03.08.08 Shipped

    Cross-tenant suspension-koppling till passport — CrossTenantSuspensionEntry.subject_passport_id länkar varje global suspension till sitt FIPJP-pass. Subscriber-tenants matchar på subject_passport_id (O(1)) först, sen fallback på subject_full_name_normalized + birth_year när passport saknas. Aktiv ban blockerar licens-issuance och event-inscription via LocalSuspensionCache-uppslag. Se docs/domain/discipline/cross-tenant-suspension.md. — PL-T213

    ✅ PL-T213