Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Navi-27/Proyecto-UPC/llms.txt

Use this file to discover all available pages before exploring further.

The Pokémon detail page (GET /pokemon/<nombre>) is the richest view in the application. It presents a full profile card for a single Pokémon — sprite, National Dex number, types, physical measurements, and a complete base-stat breakdown rendered as progress bars. Logged-in users also see an Add to Team button, and the visit is silently recorded in their personal Pokédex history the moment the page loads.

Example URL

http://localhost:5000/pokemon/charizard
The <nombre> segment is the lowercase slug used by PokéAPI (e.g. charizard, bulbasaur, mr-mime).

Data Lookup and Cache Fallback

When the route is hit, PokeAPI.obtener_pokemon(nombre_o_id) is called. It follows a two-step lookup:
  1. SQLite cache first — queries cache_pokemon with WHERE nombre = ? OR id = ?. If a matching row is found, a Pokemon object is constructed from it and returned immediately, with no network call.
  2. Live PokéAPI fallback — if the Pokémon is not in the cache (for example, a Pokémon above 1025 or one that wasn’t bulk-loaded), the app calls https://pokeapi.co/api/v2/pokemon/<nombre_o_id>. A successful response is parsed, returned, and also saved to cache_pokemon via INSERT OR IGNORE so future lookups are instant.

Pokémon Data Fields

The Pokemon class exposes the following attributes, all of which are rendered on the detail page:
FieldTypeDescription
idintNational Pokédex number (e.g. 6 for Charizard)
nombrestrPokémon name in lowercase (e.g. charizard)
tiposlist[str]Ordered list of type slugs (e.g. ["fire", "flying"])
alturaintHeight in decimeters — divide by 10 for metres (e.g. 17 → 1.7 m)
pesointWeight in hectograms — divide by 10 for kilograms (e.g. 905 → 90.5 kg)
imagenstrAbsolute URL to the official front sprite from the PokéAPI sprites CDN
statsdictBase stats keyed by stat name (see table below)

Base Stats

The stats dictionary contains six entries corresponding to the standard competitive stat set:
KeyStat
hpHit Points
attackPhysical Attack
defensePhysical Defense
special-attackSpecial Attack
special-defenseSpecial Defense
speedSpeed
Each value is an integer in the range 1–255. The detail template renders each stat as a proportional progress bar using (value / 255) * 100 as the bar width percentage.

Viewed Tracking

Every time a logged-in user visits a detail page, the application automatically records that Pokémon in the user’s personal history — no button click required. This happens at the top of the route handler, before the template is rendered:
# application.py
@application.route("/pokemon/<nombre>")
def detalle(nombre):
    pokemon = api.obtener_pokemon(nombre)
    tipo = request.args.get("tipo", "")

    if "usuario_id" in session:
        PokedexUsuario.registrar_visto(
            session["usuario_id"],
            pokemon.id,
            pokemon.nombre,
        )
    return render_template("detalle.html", pokemon=pokemon, tipo=tipo)
PokedexUsuario.registrar_visto() inserts a row into pokedex_usuario using INSERT OR IGNORE, so repeated visits to the same Pokémon never create duplicate entries — only the first visit is recorded.

Add to Team Button

When a user is logged in, a green ➕ Agregar a mi equipo button appears at the bottom of the stat card. Clicking it navigates to:
/equipo/agregar/<pokemon_id>/<nombre>/<imagen>/<tipos>
All the data the team builder needs (ID, name, sprite URL, and types) is passed directly in the URL path so no additional database lookup is required in the add route. If the user is not logged in, the button is replaced with a secondary link prompting them to log in first. The add action can fail gracefully in two scenarios:
  • Team is full (6 Pokémon already in the roster) → flash message: El equipo ya esta completo (6 Pokemones)
  • Pokémon already in team → flash message: El pokemon ya se encuentra en tu equipo
In both cases the user is redirected back to the detail page, where the flash message is displayed in a dismissible alert banner.
The tipos field is stored as a JSON string (e.g. '["fire", "flying"]') in both the cache_pokemon and equipos database tables. The detail template accesses pokemon.tipos as a native Python list (already parsed by PokeAPI.obtener_pokemon()), but other templates that read tipos directly from database rows use the custom parse_tipos Jinja2 filter — registered in application.py — to deserialise the string back into a list before iterating over it.

Build docs developers (and LLMs) love