Card Types
All canonical card types live in src/card.ts. They mirror the Postgres schema in supabase/migrations/ and are the single source of truth for the card shape across the whole monorepo.
Card
The main card object returned by all API endpoints.
interface Card {
object: "card";
id: string; // Stable UUID (matches Postgres cards.id)
name: string;
name_normalized: string; // Lowercased, punctuation-stripped — used for search
released_at?: string;
collector_number?: string; // e.g. "OGN-001"
external_ids?: CardExternalIds;
set?: CardSet;
rulings?: CardRulings;
attributes?: CardAttributes;
classification?: CardClassification;
text?: CardText;
artist?: string;
artist_id?: string;
metadata?: CardMetadata;
media?: CardMedia;
purchase_uris?: CardPurchaseUris;
prices?: CardPrices;
is_token: boolean;
all_parts: RelatedCard[]; // Tokens or meld parts produced by this card
used_by: RelatedCard[]; // Cards that create or reference this card (populated on tokens)
related_champions: RelatedCard[]; // Champions linked to this legend
related_legends: RelatedCard[]; // Legends linked to this champion
updated_at?: string;
ingested_at?: string;
}
Sub-interfaces
CardAttributes
interface CardAttributes {
energy?: number | null; // Energy cost to play the card
might?: number | null; // Defense-side stat
power?: number | null; // Attack-side stat
}
CardClassification
interface CardClassification {
type?: string; // e.g. "Unit", "Gear", "Spell"
supertype?: string | null;// e.g. "Champion", "Rune", "Battleground"
rarity?: string; // e.g. "Common", "Rare", "Legendary"
tags?: string[]; // e.g. ["Poro"]
domains?: string[]; // e.g. ["Fury"]
}
CardText
interface CardText {
rich?: string; // Rules text with inline symbol tokens (e.g. :rb_exhaust:)
plain?: string; // Rules text with symbols replaced by readable tokens
flavour?: string; // Flavour / lore text if available
}
CardSet
interface CardSet {
set_code: string; // Short code, e.g. "OGN"
set_id?: string;
set_name: string;
set_uri?: string;
set_search_uri?: string;
}
CardMedia
interface CardMedia {
orientation?: string; // "portrait" or "landscape"
accessibility_text?: string;
media_urls?: CardMediaUrls; // { small, normal, large, png }
}
CardMetadata
interface CardMetadata {
finishes?: string[]; // e.g. ["Normal", "Foil"]
signature?: boolean;
overnumbered?: boolean;
alternate_art?: boolean;
}
CardPrices
interface CardPrices {
usd?: number | null;
usd_foil?: number | null;
eur?: number | null;
eur_foil?: number | null;
}
CardExternalIds
interface CardExternalIds {
riftcodex_id?: string;
riftbound_id?: string;
tcgplayer_id?: string;
}
CardRulings
interface CardRulings {
rulings_id?: string;
rulings_uri?: string;
}
CardPurchaseUris
interface CardPurchaseUris {
cardmarket?: string;
tcgplayer?: string;
}
RelatedCard
Referenced inside all_parts, used_by, related_champions, and related_legends:
interface RelatedCard {
object: "related_card";
id: string;
name: string;
component: string; // e.g. "token", "meld_part"
uri?: string; // API URI for the referenced card
}
Request and resolution types
CardRequest
A parsed [[Name|SET-123]] token:
interface CardRequest {
raw: string; // Original text inside [[ ]]
name: string; // Parsed card name
set?: string; // Optional set code
collector?: string; // Optional collector number
}
ResolvedCard
The result of resolving a CardRequest against the provider:
interface ResolvedCard {
request: CardRequest;
card: Card | null;
matchType: "exact" | "fuzzy" | "not-found";
score?: number; // Fuse.js score when matchType === "fuzzy" (lower = better)
}
CardSearchOptions
Options for searchByName:
interface CardSearchOptions {
set?: string;
collector?: string | number;
fuzzy?: boolean; // Default true — set false for exact-only
limit?: number; // Default 10
}
Deck types
SimplifiedDeck
The serialisable, storage-friendly form of a deck. Card quantities are encoded as "cardId:quantity" strings.
interface SimplifiedDeck {
id: string | null;
legendId: string | null;
chosenChampionId: string | null;
mainDeck: string[]; // "cardId:quantity" entries
sideboard: string[]; // "cardId:quantity" entries
runes: string[]; // "cardId:quantity" entries
battlegrounds: string[]; // Card IDs only (always quantity 1)
}
See @riftseer/core — Deck for the richer in-memory Deck class, and @riftseer/core — Serialiser for how SimplifiedDeck is encoded for URL sharing.
Adding a field
If a new field needs to be added to Card:
- Update
packages/types/src/card.ts - Update
packages/ingest-worker/src/riftcodex.ts(rawToCard) - Update the row mapping in
packages/core/src/providers/supabase.ts(dbRowToCard) - Update the field table in
packages/api/docs/cards.md - Check
PrivacyPage.tsxif the field affects what data is stored or shown