Skip to Content
Game ImportersGrand Archive TCGAdrStatic TCGPlayer Expansion Mapping

Static TCGPlayer Expansion Mapping

Date2026-04-12
StatusAccepted
Decision Makers@GaultierRomon

Context and Problem Statement

The Grand Archive API has 54 sets, TCGPlayer has 44 groups. Set names and abbreviations differ between the two platforms in several ways:

  • Re:Collections: GA API uses Re:Collection Aurelian Regent, TCGPlayer uses Mordred Re: Collection, Aurelian Regent (character name prefix)
  • First Editions: GA API has separate sets (e.g., HVN 1st), TCGPlayer merges them into the base set
  • Promos: GA API splits by year (P22-P26), TCGPlayer has one “Promotional Cards” group
  • Event Packs: GA API consolidates old event packs into one EVP set, TCGPlayer splits per-set
  • Abbreviations: Some sets have different codes (DTR vs DTR1E, AMB vs AMB1E)

We need a reliable way to map GA set codes to TCGPlayer group IDs for product-level matching.

Decision Drivers

  • Expansion mapping errors cause wrong prices on all products in that expansion
  • Grand Archive has only 54 sets — small enough for a complete manual mapping
  • The mapping must be verifiable (every entry can be checked against both APIs)
  • New sets should fall back gracefully (fuzzy matching) rather than silently fail

Considered Options

  1. Static deterministic map: Manually map every GA set code → TCGPlayer groupId
  2. Fuzzy-only matching: Use Levenshtein name similarity for all sets
  3. Abbreviation matching: Match by set code/abbreviation automatically

Decision Outcome

Chosen option: Static deterministic map with a fuzzy fallback for unmapped sets. All 55 GA set codes are mapped in GA_CODE_TO_TCGPLAYER_GROUP with verified groupIds.

Mapping Confidence (Tested Against Real Data)

TierSetsTested Match RateRisk
EXACT (same code + name)26100%None
VERIFIED (different code, verified name)11100%None
INFERRED (1st ed → base set)7~95%Low
RISKY (event packs, promos)693-97%Medium
NONE (no TCGPlayer)50%N/A

Key Mapping Patterns

One-to-one (most sets):

"HVN": [24070] // Abyssal Heaven → Abyssal Heaven

One-to-many (GA API consolidates, TCGPlayer splits):

"EVP": [23125, 23436, 23784, 24252] // Event Packs → 4 TCGPlayer groups

Many-to-one (GA API splits, TCGPlayer consolidates):

"P22": [23133] // All yearly promo sets → single "Promotional Cards" group "P23": [23133] "P24": [23133]

Redirect (1st edition → base set):

"HVN 1st": [24070] // Same group as base Abyssal Heaven

Absent (no TCGPlayer equivalent):

"FTCA": [] // Empty array = known absent, don't search

Product-Level Matching

Within mapped groups, products match by:

  1. Print number — zero-padded 3 digits on both sides (e.g., "001")
  2. Card name — exact match after normalization (strip parenthesized suffixes, lowercase)
  3. Finish — "Normal" → Standard, "Foil" → Foil via TCGPlayer subTypeName

Tested at 100% match rate on standard sets, 97% on promos (after parenthesis stripping).

Consequences

Positive

  • 100% verifiable — every mapping was checked against both GA API and TCGPlayer data
  • No false positives — deterministic lookup prevents wrong-expansion matches
  • Explicit absent sets — [] clearly marks sets without TCGPlayer data
  • Fuzzy fallback — new future sets not in the map get fuzzy matching automatically

Negative

  • Manual maintenance — new sets require adding a mapping entry
  • 55 entries to maintain — though most won’t change once verified
  • Promo collisions — different promo cards can share print numbers within TCGPlayer’s single promo group (1 known case: Apotheosis Rite vs Sacramental Rite at #000)

Impacted Files

FileRole
grand-archive-tcgplayer.utils.tsStatic GA_CODE_TO_TCGPLAYER_GROUP map
grand-archive-tcgplayer.service.tsMatching service with deterministic + fuzzy tiers
Last updated on