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édex Web App exposes 9 Flask routes in application.py. All routes serve HTML via Jinja2 templates — there is no JSON API. Routes that require authentication check for usuario_id in the Flask session and redirect to /login if no session is present.
Session data is signed with application.secret_key. See the Configuration Reference for details on rotating this value before deploying to production.

Route Overview

MethodPathAuth RequiredReturns
GET/Noindex.html
GET/pokemon/<nombre>Nodetalle.html
GET/mi-pokedexYesmi-pokedex.html
GET/registroNoregistro.html
POST/registroNoRedirect to /login
GET/loginNologin.html
POST/loginNoRedirect to /
GET/logoutNoRedirect to /
GET/equipoYesequipo.html
GET/equipo/agregar/<int:pokemon_id>/<nombre>/<path:imagen>/<tipos>YesRedirect to /pokemon/<nombre>
GET/equipo/eliminar/<int:pokemon_id>YesRedirect to /equipo

Route Details

GET /

The application’s home page. Displays the full Pokédex listing with optional search and type-filter capabilities. Auth required: No
busqueda
string
Optional. Filters the Pokémon list by name using a substring match. Applied via Pokedex.buscar_por_nombre().
tipo
string
Optional. Filters the Pokémon list by type (e.g. fire, water). Applied via PokeAPI.obtener_por_tipo().
Template rendered: index.html Behavior: On every request the route calls PokeAPI.validacion() to check whether the local cache_pokemon table already contains data. If the cache is empty the app fetches all 1 025 Pokémon from the PokéAPI and stores them; otherwise it reads directly from SQLite via PokeAPI.cargar_desde_db(). After loading, busqueda and tipo filters are applied in that priority order (only one filter is active at a time).

GET /pokemon/<nombre>

Displays the detail page for a single Pokémon identified by name or National Pokédex ID. Auth required: No — but view is silently logged when a user is logged in.
nombre
string
required
The Pokémon’s name (e.g. pikachu) or its National Pokédex ID as a string (e.g. 25). Passed directly to PokeAPI.obtener_pokemon().
tipo
string
Optional. Passed through to the template unchanged — used by the breadcrumb navigation to link back to the correct type filter on the index page.
Template rendered: detalle.html Behavior: Calls PokeAPI.obtener_pokemon(nombre) to retrieve Pokémon data (from cache or live API). If usuario_id is present in the session, calls PokedexUsuario.registrar_visto() to record the view in the pokedex_usuario table — the UNIQUE constraint means duplicate views are silently ignored.

GET /mi-pokedex

Displays a list of every Pokémon the authenticated user has ever viewed. Auth required: Yes — redirects to /login if usuario_id is not in the session. Template rendered: mi-pokedex.html Behavior: Calls PokedexUsuario.obtener_vistos(session['usuario_id']) and passes the result set to the template. Each row includes pokemon_id, pokemon_nombre, and fecha_visto (the timestamp of the first view).

GET /registro

Renders the registration form. Auth required: No Template rendered: registro.html

POST /registro

Processes a new user registration form submission. Auth required: No
username
string
required
Desired username. Must be unique — Usuario.crear() returns False if the username already exists, which triggers an error flash message.
password
string
required
Plain-text password. Hashed with Werkzeug’s generate_password_hash before being stored in the usuarios table.
Behavior: Calls Usuario.crear(username, password). On success, flashes a "success" message and redirects to /login. On failure (duplicate username), flashes an "Error" message and re-renders registro.html.

GET /login

Renders the login form. Auth required: No Template rendered: login.html

POST /login

Authenticates a user and establishes a session. Auth required: No
username
string
required
The registered username.
password
string
required
The plain-text password to verify against the stored hash via check_password_hash.
Behavior: Calls Usuario.login(username, password). On success, writes usuario_id and username into the Flask session and redirects to /. On failure, flashes an "error" message and re-renders login.html.

GET /logout

Destroys the current session and returns the user to the home page. Auth required: No Template rendered: None Behavior: Calls session.clear() and issues a redirect to /. No flash message is shown.

GET /equipo

Displays the authenticated user’s current Pokémon team (up to 6 members). Auth required: Yes — redirects to /login if usuario_id is not in the session. Template rendered: equipo.html Behavior: Calls Equipo.obtener_equipo(session['usuario_id']) to load the team from the equipos table and passes the rows to the template.

GET /equipo/agregar/<int:pokemon_id>/<nombre>/<path:imagen>/<tipos>

Adds a Pokémon to the authenticated user’s team. Auth required: Yes — redirects to /login if usuario_id is not in the session.
pokemon_id
integer
required
The Pokémon’s National Pokédex ID.
nombre
string
required
The Pokémon’s name. Used for the flash message and the post-add redirect back to /pokemon/<nombre>.
imagen
string
required
URL of the Pokémon’s sprite image. Uses Flask’s <path:> converter so that forward slashes inside the URL are preserved correctly.
tipos
string
required
A JSON-encoded array of type strings (e.g. ["fire","flying"]). Stored as-is in equipos.pokemon_tipos and decoded in templates with the parse_tipos filter.
Template rendered: None Behavior: Calls Equipo.agregar_pokemon(). If the team already has 6 members (Equipo.MAX_POKEMONES), the call returns (False, message) and an error flash is shown. On success, a "success" flash is shown. Either way, the response redirects to /pokemon/<nombre>.
This route is a GET request that mutates state. Do not bookmark or share these URLs — revisiting them will attempt to add the Pokémon to the team again. Equipo.agregar_pokemon() checks for duplicate entries before inserting, and the 6-member cap (Equipo.MAX_POKEMONES) prevents adding to a full team; both guards are enforced in application logic, not at the database level.

GET /equipo/eliminar/<int:pokemon_id>

Removes a Pokémon from the authenticated user’s team by its Pokédex ID. Auth required: Yes — redirects to /login if usuario_id is not in the session.
pokemon_id
integer
required
The Pokémon’s National Pokédex ID. Used to identify the row in the equipos table for the current user.
Template rendered: None Behavior: Calls Equipo.eliminar_pokemon(session['usuario_id'], pokemon_id). Flashes a "success" or "Error" message depending on the result, then redirects to /equipo.

Template Filter: parse_tipos

The app registers a custom Jinja2 filter named parse_tipos that converts the JSON-encoded tipos string stored in the database into a Python list for use in templates.
@application.template_filter('parse_tipos')
def parse_tipos(value):
    import ast
    import json
    try:
        return json.loads(value)
    except:
        return ast.literal_eval(value)
Usage in templates:
{% for tipo in pokemon.pokemon_tipos | parse_tipos %}
  <span class="badge">{{ tipo }}</span>
{% endfor %}
The filter first attempts json.loads(). If the string is formatted as a Python literal instead of strict JSON (e.g. uses single quotes), it falls back to ast.literal_eval() for safe evaluation.
When storing Pokémon types via the /equipo/agregar/ route, ensure the tipos path segment is a valid JSON array string. The filter handles minor formatting inconsistencies, but malformed input will raise an unhandled exception.

Build docs developers (and LLMs) love