Add game category and region metadata for genlocke presets
Add `category` field (original/remake/enhanced/sequel/spinoff) to the Game model and tag all 38 games. Create regions.json with generation mapping, ordering, and genlocke preset defaults per region. Add GET /games/by-region endpoint returning games grouped by region. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
# nuzlocke-tracker-glh8
|
# nuzlocke-tracker-glh8
|
||||||
title: Gather generation metadata (games, regions)
|
title: Gather generation metadata (games, regions)
|
||||||
status: todo
|
status: in-progress
|
||||||
type: task
|
type: task
|
||||||
priority: normal
|
priority: normal
|
||||||
created_at: 2026-02-08T19:20:49Z
|
created_at: 2026-02-08T19:20:49Z
|
||||||
updated_at: 2026-02-09T07:45:21Z
|
updated_at: 2026-02-09T08:05:52Z
|
||||||
parent: nuzlocke-tracker-25mh
|
parent: nuzlocke-tracker-25mh
|
||||||
blocking:
|
blocking:
|
||||||
- nuzlocke-tracker-kz5g
|
- nuzlocke-tracker-kz5g
|
||||||
@@ -27,11 +27,17 @@ Collect and store metadata about each Pokemon generation to support genlocke fea
|
|||||||
- However, a dedicated generations reference would be useful for UI purposes (showing all generations even if not all games are seeded yet)
|
- However, a dedicated generations reference would be useful for UI purposes (showing all generations even if not all games are seeded yet)
|
||||||
- Check if `backend/src/app/seeds/data/generations.json` already exists or if this needs to be created from scratch
|
- Check if `backend/src/app/seeds/data/generations.json` already exists or if this needs to be created from scratch
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
- Legends games (Hisui, Lumiose) are excluded from genlocke presets — available via Custom only
|
||||||
|
- Black 2/White 2 are grouped with Black/White in the same Unova slot (category: sequel)
|
||||||
|
- Normal Genlocke defaults use best mainline remake: FireRed, HeartGold, Alpha Sapphire, Platinum, Ultra Sun
|
||||||
|
- Metadata stored as `category` field on Game model + standalone `regions.json` seed file
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
- [ ] Define the generation-to-region mapping (Gen 1 = Kanto, Gen 2 = Johto, ..., Gen 9 = Paldea)
|
- [x] Define the generation-to-region mapping (Gen 1 = Kanto, Gen 2 = Johto, ..., Gen 9 = Paldea)
|
||||||
- [ ] Determine how to group games by region (use `region` field on existing Game model, or create a dedicated lookup)
|
- [x] Determine how to group games by region (use `region` field on existing Game model, or create a dedicated lookup)
|
||||||
- [ ] Create a `generations.json` seed file (or equivalent) with: generation number, region name, region order, and which games belong to each region
|
- [x] Create a `regions.json` seed file (or equivalent) with: generation number, region name, region order, and which games belong to each region
|
||||||
- [ ] Categorize each game as "original", "remake", or "enhanced" so presets can filter appropriately
|
- [x] Categorize each game as "original", "remake", "enhanced", "sequel", or "spinoff" so presets can filter appropriately
|
||||||
- [ ] Define which game is the "default" pick per region for the Normal Genlocke preset (e.g., FireRed for Kanto, HeartGold for Johto)
|
- [x] Define which game is the "default" pick per region for the Normal Genlocke preset (e.g., FireRed for Kanto, HeartGold for Johto)
|
||||||
- [ ] Add an API endpoint or extend the games endpoint to return games grouped by region with generation metadata
|
- [x] Add an API endpoint or extend the games endpoint to return games grouped by region with generation metadata
|
||||||
- [ ] Verify all seeded games are correctly tagged with their region
|
- [x] Verify all seeded games are correctly tagged with their region
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
"""add category to games
|
||||||
|
|
||||||
|
Revision ID: a1b2c3d4e5f8
|
||||||
|
Revises: f6a7b8c9d0e1
|
||||||
|
Create Date: 2026-02-09 12:00:00.000000
|
||||||
|
|
||||||
|
"""
|
||||||
|
from typing import Sequence, Union
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision: str = 'a1b2c3d4e5f8'
|
||||||
|
down_revision: Union[str, Sequence[str], None] = 'f6a7b8c9d0e1'
|
||||||
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
op.add_column(
|
||||||
|
'games',
|
||||||
|
sa.Column('category', sa.String(20), nullable=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
op.drop_column('games', 'category')
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, HTTPException
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from sqlalchemy import delete, select
|
from sqlalchemy import delete, select
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
@@ -14,6 +17,7 @@ from app.schemas.game import (
|
|||||||
GameDetailResponse,
|
GameDetailResponse,
|
||||||
GameResponse,
|
GameResponse,
|
||||||
GameUpdate,
|
GameUpdate,
|
||||||
|
RegionResponse,
|
||||||
RouteCreate,
|
RouteCreate,
|
||||||
RouteReorderRequest,
|
RouteReorderRequest,
|
||||||
RouteResponse,
|
RouteResponse,
|
||||||
@@ -46,6 +50,38 @@ async def list_games(session: AsyncSession = Depends(get_session)):
|
|||||||
return result.scalars().all()
|
return result.scalars().all()
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/by-region", response_model=list[RegionResponse])
|
||||||
|
async def list_games_by_region(session: AsyncSession = Depends(get_session)):
|
||||||
|
"""Return games grouped by region with generation metadata and genlocke preset defaults."""
|
||||||
|
regions_path = Path(__file__).parent.parent / "seeds" / "data" / "regions.json"
|
||||||
|
with open(regions_path) as f:
|
||||||
|
regions_data = json.load(f)
|
||||||
|
|
||||||
|
result = await session.execute(select(Game).order_by(Game.release_year, Game.name))
|
||||||
|
all_games = result.scalars().all()
|
||||||
|
|
||||||
|
games_by_region: dict[str, list[Game]] = {}
|
||||||
|
for game in all_games:
|
||||||
|
games_by_region.setdefault(game.region, []).append(game)
|
||||||
|
|
||||||
|
response = []
|
||||||
|
for region in regions_data:
|
||||||
|
region_games = games_by_region.get(region["name"], [])
|
||||||
|
defaults = region["genlocke_defaults"]
|
||||||
|
response.append({
|
||||||
|
"name": region["name"],
|
||||||
|
"generation": region["generation"],
|
||||||
|
"order": region["order"],
|
||||||
|
"genlocke_defaults": {
|
||||||
|
"true_genlocke": defaults["true"],
|
||||||
|
"normal_genlocke": defaults["normal"],
|
||||||
|
},
|
||||||
|
"games": region_games,
|
||||||
|
})
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{game_id}", response_model=GameDetailResponse)
|
@router.get("/{game_id}", response_model=GameDetailResponse)
|
||||||
async def get_game(game_id: int, session: AsyncSession = Depends(get_session)):
|
async def get_game(game_id: int, session: AsyncSession = Depends(get_session)):
|
||||||
game = await _get_game_or_404(session, game_id)
|
game = await _get_game_or_404(session, game_id)
|
||||||
@@ -66,6 +102,7 @@ async def get_game(game_id: int, session: AsyncSession = Depends(get_session)):
|
|||||||
"slug": game.slug,
|
"slug": game.slug,
|
||||||
"generation": game.generation,
|
"generation": game.generation,
|
||||||
"region": game.region,
|
"region": game.region,
|
||||||
|
"category": game.category,
|
||||||
"box_art_url": game.box_art_url,
|
"box_art_url": game.box_art_url,
|
||||||
"release_year": game.release_year,
|
"release_year": game.release_year,
|
||||||
"color": game.color,
|
"color": game.color,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ class Game(Base):
|
|||||||
slug: Mapped[str] = mapped_column(String(100), unique=True)
|
slug: Mapped[str] = mapped_column(String(100), unique=True)
|
||||||
generation: Mapped[int] = mapped_column(SmallInteger)
|
generation: Mapped[int] = mapped_column(SmallInteger)
|
||||||
region: Mapped[str] = mapped_column(String(50))
|
region: Mapped[str] = mapped_column(String(50))
|
||||||
|
category: Mapped[str | None] = mapped_column(String(20)) # original, remake, enhanced, sequel, spinoff
|
||||||
box_art_url: Mapped[str | None] = mapped_column(String(500))
|
box_art_url: Mapped[str | None] = mapped_column(String(500))
|
||||||
release_year: Mapped[int | None] = mapped_column(SmallInteger)
|
release_year: Mapped[int | None] = mapped_column(SmallInteger)
|
||||||
color: Mapped[str | None] = mapped_column(String(7)) # Hex color e.g. #FF0000
|
color: Mapped[str | None] = mapped_column(String(7)) # Hex color e.g. #FF0000
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ class GameResponse(CamelModel):
|
|||||||
slug: str
|
slug: str
|
||||||
generation: int
|
generation: int
|
||||||
region: str
|
region: str
|
||||||
|
category: str | None = None
|
||||||
box_art_url: str | None
|
box_art_url: str | None
|
||||||
release_year: int | None
|
release_year: int | None
|
||||||
color: str | None
|
color: str | None
|
||||||
@@ -39,6 +40,7 @@ class GameCreate(CamelModel):
|
|||||||
slug: str
|
slug: str
|
||||||
generation: int
|
generation: int
|
||||||
region: str
|
region: str
|
||||||
|
category: str | None = None
|
||||||
box_art_url: str | None = None
|
box_art_url: str | None = None
|
||||||
release_year: int | None = None
|
release_year: int | None = None
|
||||||
color: str | None = None
|
color: str | None = None
|
||||||
@@ -49,11 +51,25 @@ class GameUpdate(CamelModel):
|
|||||||
slug: str | None = None
|
slug: str | None = None
|
||||||
generation: int | None = None
|
generation: int | None = None
|
||||||
region: str | None = None
|
region: str | None = None
|
||||||
|
category: str | None = None
|
||||||
box_art_url: str | None = None
|
box_art_url: str | None = None
|
||||||
release_year: int | None = None
|
release_year: int | None = None
|
||||||
color: str | None = None
|
color: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
class GenlockeDefaultsResponse(CamelModel):
|
||||||
|
true_genlocke: str # game slug for true genlocke default
|
||||||
|
normal_genlocke: str # game slug for normal genlocke default
|
||||||
|
|
||||||
|
|
||||||
|
class RegionResponse(CamelModel):
|
||||||
|
name: str
|
||||||
|
generation: int
|
||||||
|
order: int
|
||||||
|
genlocke_defaults: GenlockeDefaultsResponse
|
||||||
|
games: list[GameResponse] = []
|
||||||
|
|
||||||
|
|
||||||
class RouteCreate(CamelModel):
|
class RouteCreate(CamelModel):
|
||||||
name: str
|
name: str
|
||||||
order: int
|
order: int
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
"slug": "alpha-sapphire",
|
"slug": "alpha-sapphire",
|
||||||
"generation": 6,
|
"generation": 6,
|
||||||
"region": "hoenn",
|
"region": "hoenn",
|
||||||
|
"category": "remake",
|
||||||
"release_year": 2014,
|
"release_year": 2014,
|
||||||
"color": "#26649C"
|
"color": "#26649C"
|
||||||
},
|
},
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
"slug": "black",
|
"slug": "black",
|
||||||
"generation": 5,
|
"generation": 5,
|
||||||
"region": "unova",
|
"region": "unova",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2010,
|
"release_year": 2010,
|
||||||
"color": "#444444"
|
"color": "#444444"
|
||||||
},
|
},
|
||||||
@@ -20,6 +22,7 @@
|
|||||||
"slug": "black-2",
|
"slug": "black-2",
|
||||||
"generation": 5,
|
"generation": 5,
|
||||||
"region": "unova",
|
"region": "unova",
|
||||||
|
"category": "sequel",
|
||||||
"release_year": 2012,
|
"release_year": 2012,
|
||||||
"color": "#424B50"
|
"color": "#424B50"
|
||||||
},
|
},
|
||||||
@@ -28,6 +31,7 @@
|
|||||||
"slug": "blue",
|
"slug": "blue",
|
||||||
"generation": 1,
|
"generation": 1,
|
||||||
"region": "kanto",
|
"region": "kanto",
|
||||||
|
"category": "original",
|
||||||
"release_year": 1996,
|
"release_year": 1996,
|
||||||
"color": "#1111FF"
|
"color": "#1111FF"
|
||||||
},
|
},
|
||||||
@@ -36,6 +40,7 @@
|
|||||||
"slug": "brilliant-diamond",
|
"slug": "brilliant-diamond",
|
||||||
"generation": 8,
|
"generation": 8,
|
||||||
"region": "sinnoh",
|
"region": "sinnoh",
|
||||||
|
"category": "remake",
|
||||||
"release_year": 2021,
|
"release_year": 2021,
|
||||||
"color": "#44BAE5"
|
"color": "#44BAE5"
|
||||||
},
|
},
|
||||||
@@ -44,6 +49,7 @@
|
|||||||
"slug": "crystal",
|
"slug": "crystal",
|
||||||
"generation": 2,
|
"generation": 2,
|
||||||
"region": "johto",
|
"region": "johto",
|
||||||
|
"category": "enhanced",
|
||||||
"release_year": 2000,
|
"release_year": 2000,
|
||||||
"color": "#4FD9FF"
|
"color": "#4FD9FF"
|
||||||
},
|
},
|
||||||
@@ -52,6 +58,7 @@
|
|||||||
"slug": "diamond",
|
"slug": "diamond",
|
||||||
"generation": 4,
|
"generation": 4,
|
||||||
"region": "sinnoh",
|
"region": "sinnoh",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2006,
|
"release_year": 2006,
|
||||||
"color": "#AAAAFF"
|
"color": "#AAAAFF"
|
||||||
},
|
},
|
||||||
@@ -60,6 +67,7 @@
|
|||||||
"slug": "emerald",
|
"slug": "emerald",
|
||||||
"generation": 3,
|
"generation": 3,
|
||||||
"region": "hoenn",
|
"region": "hoenn",
|
||||||
|
"category": "enhanced",
|
||||||
"release_year": 2005,
|
"release_year": 2005,
|
||||||
"color": "#00A000"
|
"color": "#00A000"
|
||||||
},
|
},
|
||||||
@@ -68,6 +76,7 @@
|
|||||||
"slug": "firered",
|
"slug": "firered",
|
||||||
"generation": 3,
|
"generation": 3,
|
||||||
"region": "kanto",
|
"region": "kanto",
|
||||||
|
"category": "remake",
|
||||||
"release_year": 2004,
|
"release_year": 2004,
|
||||||
"color": "#FF7327"
|
"color": "#FF7327"
|
||||||
},
|
},
|
||||||
@@ -76,6 +85,7 @@
|
|||||||
"slug": "gold",
|
"slug": "gold",
|
||||||
"generation": 2,
|
"generation": 2,
|
||||||
"region": "johto",
|
"region": "johto",
|
||||||
|
"category": "original",
|
||||||
"release_year": 1999,
|
"release_year": 1999,
|
||||||
"color": "#DAA520"
|
"color": "#DAA520"
|
||||||
},
|
},
|
||||||
@@ -84,6 +94,7 @@
|
|||||||
"slug": "heartgold",
|
"slug": "heartgold",
|
||||||
"generation": 4,
|
"generation": 4,
|
||||||
"region": "johto",
|
"region": "johto",
|
||||||
|
"category": "remake",
|
||||||
"release_year": 2010,
|
"release_year": 2010,
|
||||||
"color": "#B69E00"
|
"color": "#B69E00"
|
||||||
},
|
},
|
||||||
@@ -92,6 +103,7 @@
|
|||||||
"slug": "leafgreen",
|
"slug": "leafgreen",
|
||||||
"generation": 3,
|
"generation": 3,
|
||||||
"region": "kanto",
|
"region": "kanto",
|
||||||
|
"category": "remake",
|
||||||
"release_year": 2004,
|
"release_year": 2004,
|
||||||
"color": "#00DD00"
|
"color": "#00DD00"
|
||||||
},
|
},
|
||||||
@@ -100,6 +112,7 @@
|
|||||||
"slug": "legends-arceus",
|
"slug": "legends-arceus",
|
||||||
"generation": 8,
|
"generation": 8,
|
||||||
"region": "hisui",
|
"region": "hisui",
|
||||||
|
"category": "spinoff",
|
||||||
"release_year": 2022,
|
"release_year": 2022,
|
||||||
"color": "#36597B"
|
"color": "#36597B"
|
||||||
},
|
},
|
||||||
@@ -108,6 +121,7 @@
|
|||||||
"slug": "legends-z-a",
|
"slug": "legends-z-a",
|
||||||
"generation": 9,
|
"generation": 9,
|
||||||
"region": "lumiose",
|
"region": "lumiose",
|
||||||
|
"category": "spinoff",
|
||||||
"release_year": 2025,
|
"release_year": 2025,
|
||||||
"color": "#3A7BDB"
|
"color": "#3A7BDB"
|
||||||
},
|
},
|
||||||
@@ -116,6 +130,7 @@
|
|||||||
"slug": "lets-go-eevee",
|
"slug": "lets-go-eevee",
|
||||||
"generation": 7,
|
"generation": 7,
|
||||||
"region": "kanto",
|
"region": "kanto",
|
||||||
|
"category": "remake",
|
||||||
"release_year": 2018,
|
"release_year": 2018,
|
||||||
"color": "#D4924B"
|
"color": "#D4924B"
|
||||||
},
|
},
|
||||||
@@ -124,6 +139,7 @@
|
|||||||
"slug": "lets-go-pikachu",
|
"slug": "lets-go-pikachu",
|
||||||
"generation": 7,
|
"generation": 7,
|
||||||
"region": "kanto",
|
"region": "kanto",
|
||||||
|
"category": "remake",
|
||||||
"release_year": 2018,
|
"release_year": 2018,
|
||||||
"color": "#F5DA00"
|
"color": "#F5DA00"
|
||||||
},
|
},
|
||||||
@@ -132,6 +148,7 @@
|
|||||||
"slug": "moon",
|
"slug": "moon",
|
||||||
"generation": 7,
|
"generation": 7,
|
||||||
"region": "alola",
|
"region": "alola",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2016,
|
"release_year": 2016,
|
||||||
"color": "#5599CA"
|
"color": "#5599CA"
|
||||||
},
|
},
|
||||||
@@ -140,6 +157,7 @@
|
|||||||
"slug": "omega-ruby",
|
"slug": "omega-ruby",
|
||||||
"generation": 6,
|
"generation": 6,
|
||||||
"region": "hoenn",
|
"region": "hoenn",
|
||||||
|
"category": "remake",
|
||||||
"release_year": 2014,
|
"release_year": 2014,
|
||||||
"color": "#CF3025"
|
"color": "#CF3025"
|
||||||
},
|
},
|
||||||
@@ -148,6 +166,7 @@
|
|||||||
"slug": "pearl",
|
"slug": "pearl",
|
||||||
"generation": 4,
|
"generation": 4,
|
||||||
"region": "sinnoh",
|
"region": "sinnoh",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2006,
|
"release_year": 2006,
|
||||||
"color": "#FFAAAA"
|
"color": "#FFAAAA"
|
||||||
},
|
},
|
||||||
@@ -156,6 +175,7 @@
|
|||||||
"slug": "platinum",
|
"slug": "platinum",
|
||||||
"generation": 4,
|
"generation": 4,
|
||||||
"region": "sinnoh",
|
"region": "sinnoh",
|
||||||
|
"category": "enhanced",
|
||||||
"release_year": 2008,
|
"release_year": 2008,
|
||||||
"color": "#999999"
|
"color": "#999999"
|
||||||
},
|
},
|
||||||
@@ -164,6 +184,7 @@
|
|||||||
"slug": "red",
|
"slug": "red",
|
||||||
"generation": 1,
|
"generation": 1,
|
||||||
"region": "kanto",
|
"region": "kanto",
|
||||||
|
"category": "original",
|
||||||
"release_year": 1996,
|
"release_year": 1996,
|
||||||
"color": "#FF1111"
|
"color": "#FF1111"
|
||||||
},
|
},
|
||||||
@@ -172,6 +193,7 @@
|
|||||||
"slug": "ruby",
|
"slug": "ruby",
|
||||||
"generation": 3,
|
"generation": 3,
|
||||||
"region": "hoenn",
|
"region": "hoenn",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2002,
|
"release_year": 2002,
|
||||||
"color": "#A00000"
|
"color": "#A00000"
|
||||||
},
|
},
|
||||||
@@ -180,6 +202,7 @@
|
|||||||
"slug": "sapphire",
|
"slug": "sapphire",
|
||||||
"generation": 3,
|
"generation": 3,
|
||||||
"region": "hoenn",
|
"region": "hoenn",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2002,
|
"release_year": 2002,
|
||||||
"color": "#0000A0"
|
"color": "#0000A0"
|
||||||
},
|
},
|
||||||
@@ -188,6 +211,7 @@
|
|||||||
"slug": "scarlet",
|
"slug": "scarlet",
|
||||||
"generation": 9,
|
"generation": 9,
|
||||||
"region": "paldea",
|
"region": "paldea",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2022,
|
"release_year": 2022,
|
||||||
"color": "#F93C3C"
|
"color": "#F93C3C"
|
||||||
},
|
},
|
||||||
@@ -196,6 +220,7 @@
|
|||||||
"slug": "shield",
|
"slug": "shield",
|
||||||
"generation": 8,
|
"generation": 8,
|
||||||
"region": "galar",
|
"region": "galar",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2019,
|
"release_year": 2019,
|
||||||
"color": "#EF3B6E"
|
"color": "#EF3B6E"
|
||||||
},
|
},
|
||||||
@@ -204,6 +229,7 @@
|
|||||||
"slug": "shining-pearl",
|
"slug": "shining-pearl",
|
||||||
"generation": 8,
|
"generation": 8,
|
||||||
"region": "sinnoh",
|
"region": "sinnoh",
|
||||||
|
"category": "remake",
|
||||||
"release_year": 2021,
|
"release_year": 2021,
|
||||||
"color": "#E18AAA"
|
"color": "#E18AAA"
|
||||||
},
|
},
|
||||||
@@ -212,6 +238,7 @@
|
|||||||
"slug": "silver",
|
"slug": "silver",
|
||||||
"generation": 2,
|
"generation": 2,
|
||||||
"region": "johto",
|
"region": "johto",
|
||||||
|
"category": "original",
|
||||||
"release_year": 1999,
|
"release_year": 1999,
|
||||||
"color": "#C0C0C0"
|
"color": "#C0C0C0"
|
||||||
},
|
},
|
||||||
@@ -220,6 +247,7 @@
|
|||||||
"slug": "soulsilver",
|
"slug": "soulsilver",
|
||||||
"generation": 4,
|
"generation": 4,
|
||||||
"region": "johto",
|
"region": "johto",
|
||||||
|
"category": "remake",
|
||||||
"release_year": 2010,
|
"release_year": 2010,
|
||||||
"color": "#C0C0E0"
|
"color": "#C0C0E0"
|
||||||
},
|
},
|
||||||
@@ -228,6 +256,7 @@
|
|||||||
"slug": "sun",
|
"slug": "sun",
|
||||||
"generation": 7,
|
"generation": 7,
|
||||||
"region": "alola",
|
"region": "alola",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2016,
|
"release_year": 2016,
|
||||||
"color": "#F1912B"
|
"color": "#F1912B"
|
||||||
},
|
},
|
||||||
@@ -236,6 +265,7 @@
|
|||||||
"slug": "sword",
|
"slug": "sword",
|
||||||
"generation": 8,
|
"generation": 8,
|
||||||
"region": "galar",
|
"region": "galar",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2019,
|
"release_year": 2019,
|
||||||
"color": "#00D4E7"
|
"color": "#00D4E7"
|
||||||
},
|
},
|
||||||
@@ -244,6 +274,7 @@
|
|||||||
"slug": "ultra-moon",
|
"slug": "ultra-moon",
|
||||||
"generation": 7,
|
"generation": 7,
|
||||||
"region": "alola",
|
"region": "alola",
|
||||||
|
"category": "enhanced",
|
||||||
"release_year": 2017,
|
"release_year": 2017,
|
||||||
"color": "#204E8C"
|
"color": "#204E8C"
|
||||||
},
|
},
|
||||||
@@ -252,6 +283,7 @@
|
|||||||
"slug": "ultra-sun",
|
"slug": "ultra-sun",
|
||||||
"generation": 7,
|
"generation": 7,
|
||||||
"region": "alola",
|
"region": "alola",
|
||||||
|
"category": "enhanced",
|
||||||
"release_year": 2017,
|
"release_year": 2017,
|
||||||
"color": "#E95B2B"
|
"color": "#E95B2B"
|
||||||
},
|
},
|
||||||
@@ -260,6 +292,7 @@
|
|||||||
"slug": "violet",
|
"slug": "violet",
|
||||||
"generation": 9,
|
"generation": 9,
|
||||||
"region": "paldea",
|
"region": "paldea",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2022,
|
"release_year": 2022,
|
||||||
"color": "#A96EEC"
|
"color": "#A96EEC"
|
||||||
},
|
},
|
||||||
@@ -268,6 +301,7 @@
|
|||||||
"slug": "white",
|
"slug": "white",
|
||||||
"generation": 5,
|
"generation": 5,
|
||||||
"region": "unova",
|
"region": "unova",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2010,
|
"release_year": 2010,
|
||||||
"color": "#E1E1E1"
|
"color": "#E1E1E1"
|
||||||
},
|
},
|
||||||
@@ -276,6 +310,7 @@
|
|||||||
"slug": "white-2",
|
"slug": "white-2",
|
||||||
"generation": 5,
|
"generation": 5,
|
||||||
"region": "unova",
|
"region": "unova",
|
||||||
|
"category": "sequel",
|
||||||
"release_year": 2012,
|
"release_year": 2012,
|
||||||
"color": "#E3CED0"
|
"color": "#E3CED0"
|
||||||
},
|
},
|
||||||
@@ -284,6 +319,7 @@
|
|||||||
"slug": "x",
|
"slug": "x",
|
||||||
"generation": 6,
|
"generation": 6,
|
||||||
"region": "kalos",
|
"region": "kalos",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2013,
|
"release_year": 2013,
|
||||||
"color": "#025DA6"
|
"color": "#025DA6"
|
||||||
},
|
},
|
||||||
@@ -292,6 +328,7 @@
|
|||||||
"slug": "y",
|
"slug": "y",
|
||||||
"generation": 6,
|
"generation": 6,
|
||||||
"region": "kalos",
|
"region": "kalos",
|
||||||
|
"category": "original",
|
||||||
"release_year": 2013,
|
"release_year": 2013,
|
||||||
"color": "#EA1A3E"
|
"color": "#EA1A3E"
|
||||||
},
|
},
|
||||||
@@ -300,6 +337,7 @@
|
|||||||
"slug": "yellow",
|
"slug": "yellow",
|
||||||
"generation": 1,
|
"generation": 1,
|
||||||
"region": "kanto",
|
"region": "kanto",
|
||||||
|
"category": "enhanced",
|
||||||
"release_year": 1998,
|
"release_year": 1998,
|
||||||
"color": "#FFD733"
|
"color": "#FFD733"
|
||||||
}
|
}
|
||||||
|
|||||||
83
backend/src/app/seeds/data/regions.json
Normal file
83
backend/src/app/seeds/data/regions.json
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "kanto",
|
||||||
|
"generation": 1,
|
||||||
|
"order": 1,
|
||||||
|
"genlocke_defaults": {
|
||||||
|
"true": "red",
|
||||||
|
"normal": "firered"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "johto",
|
||||||
|
"generation": 2,
|
||||||
|
"order": 2,
|
||||||
|
"genlocke_defaults": {
|
||||||
|
"true": "gold",
|
||||||
|
"normal": "heartgold"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "hoenn",
|
||||||
|
"generation": 3,
|
||||||
|
"order": 3,
|
||||||
|
"genlocke_defaults": {
|
||||||
|
"true": "ruby",
|
||||||
|
"normal": "alpha-sapphire"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sinnoh",
|
||||||
|
"generation": 4,
|
||||||
|
"order": 4,
|
||||||
|
"genlocke_defaults": {
|
||||||
|
"true": "diamond",
|
||||||
|
"normal": "platinum"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unova",
|
||||||
|
"generation": 5,
|
||||||
|
"order": 5,
|
||||||
|
"genlocke_defaults": {
|
||||||
|
"true": "black",
|
||||||
|
"normal": "black"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "kalos",
|
||||||
|
"generation": 6,
|
||||||
|
"order": 6,
|
||||||
|
"genlocke_defaults": {
|
||||||
|
"true": "x",
|
||||||
|
"normal": "x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "alola",
|
||||||
|
"generation": 7,
|
||||||
|
"order": 7,
|
||||||
|
"genlocke_defaults": {
|
||||||
|
"true": "sun",
|
||||||
|
"normal": "ultra-sun"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "galar",
|
||||||
|
"generation": 8,
|
||||||
|
"order": 8,
|
||||||
|
"genlocke_defaults": {
|
||||||
|
"true": "sword",
|
||||||
|
"normal": "sword"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "paldea",
|
||||||
|
"generation": 9,
|
||||||
|
"order": 9,
|
||||||
|
"genlocke_defaults": {
|
||||||
|
"true": "scarlet",
|
||||||
|
"normal": "scarlet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -51,6 +51,7 @@ async def upsert_games(
|
|||||||
"slug": game["slug"],
|
"slug": game["slug"],
|
||||||
"generation": game["generation"],
|
"generation": game["generation"],
|
||||||
"region": game["region"],
|
"region": game["region"],
|
||||||
|
"category": game.get("category"),
|
||||||
"release_year": game.get("release_year"),
|
"release_year": game.get("release_year"),
|
||||||
"color": game.get("color"),
|
"color": game.get("color"),
|
||||||
}
|
}
|
||||||
@@ -58,6 +59,7 @@ async def upsert_games(
|
|||||||
"name": game["name"],
|
"name": game["name"],
|
||||||
"generation": game["generation"],
|
"generation": game["generation"],
|
||||||
"region": game["region"],
|
"region": game["region"],
|
||||||
|
"category": game.get("category"),
|
||||||
"release_year": game.get("release_year"),
|
"release_year": game.get("release_year"),
|
||||||
"color": game.get("color"),
|
"color": game.get("color"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,31 @@
|
|||||||
|
export type GameCategory = 'original' | 'remake' | 'enhanced' | 'sequel' | 'spinoff'
|
||||||
|
|
||||||
export interface Game {
|
export interface Game {
|
||||||
id: number
|
id: number
|
||||||
name: string
|
name: string
|
||||||
slug: string
|
slug: string
|
||||||
generation: number
|
generation: number
|
||||||
region: string
|
region: string
|
||||||
|
category: GameCategory | null
|
||||||
boxArtUrl: string | null
|
boxArtUrl: string | null
|
||||||
releaseYear: number | null
|
releaseYear: number | null
|
||||||
color: string | null
|
color: string | null
|
||||||
versionGroupId: number | null
|
versionGroupId: number | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GenlockeDefaults {
|
||||||
|
trueGenlocke: string // game slug
|
||||||
|
normalGenlocke: string // game slug
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Region {
|
||||||
|
name: string
|
||||||
|
generation: number
|
||||||
|
order: number
|
||||||
|
genlockeDefaults: GenlockeDefaults
|
||||||
|
games: Game[]
|
||||||
|
}
|
||||||
|
|
||||||
export interface Route {
|
export interface Route {
|
||||||
id: number
|
id: number
|
||||||
name: string
|
name: string
|
||||||
|
|||||||
Reference in New Issue
Block a user