Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/BrandonCVale/SISTEMA-HABITOS/llms.txt

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

Hábito. organises its HTTP surface into three Flask Blueprints, each registered inside create_app() in app/__init__.py. The auth_bp blueprint (prefix /auth) handles registration, login, and logout. The pag_principal_bp blueprint (prefix /pagina_principal) owns the main dashboard. The habito_bp blueprint (prefix /habitos) manages the full habit CRUD lifecycle. There is also a bare root route (/) that immediately redirects every visitor to the login page.

Root Route

PathMethodAuth RequiredBehaviour
/GETNoRedirects to /auth/inicio_sesion
@app.route('/')
def index():
    return redirect(url_for('auth.inicio_sesion'))

Auth Blueprint

Blueprint name: auth_bp · URL prefix: /auth · Source: app/routes/auth.py The auth blueprint is registered as 'auth', so all internal url_for() calls use the auth. namespace (e.g. url_for('auth.inicio_sesion')).

Endpoints

Method: GET
Auth required: No
Description: Renders the registro.html registration form. If the user already has an active session (current_user.is_authenticated), they are redirected to the dashboard instead with a "success" flash.
Redirect on already-authenticated:pag_principal.inicio

Auth route summary table

RouteMethodsLogin RequiredSuccess Redirect
/auth/registroGET, POSTNoauth.registro (POST)
/auth/inicio_sesionGET, POSTNopag_principal.inicio (POST)
/auth/cerrar_sesionGETYesauth.inicio_sesion

Dashboard Blueprint

Blueprint name: pag_principal_bp · URL prefix: /pagina_principal · Source: app/routes/pagina_principal.py The dashboard is a single, read-only view. It aggregates data from several repository calls and passes everything to the pagina_principal.html template.

Endpoints

Method: GET
Auth required: Yes (@login_required)
Description: Builds and renders the main dashboard. Performs the following work before rendering:
  1. Fetches all active habits for current_user via HabitoRepository.obtener_habitos_por_usuario(current_user.id).
  2. Determines today’s day-letter (LD) and filters habits that are both activo=True and scheduled for today.
  3. Annotates each habit with a transient completado_hoy attribute (bool) by scanning habito.registros.
  4. Queries HabitoRepository.obtener_dias_activos_mes() to produce the set of calendar day-numbers used by the heat-map.
  5. Computes three KPIs: habits completed today, current best streak, all-time best streak.
Template variables passed:
VariableTypeDescription
usuarioUsuarioThe logged-in user object
habitoslist[Habito]Today’s active habits (with completado_hoy)
mes_actualstrSpanish month name (e.g. "Julio")
num_diasintNumber of days in current month
dia_semana_iniciointWeekday of the 1st of the month (0=Mon)
dias_completadosset[int]Day numbers with ≥1 completion this month
habitos_completados_hoyintCount of today’s completed habits
racha_actualintHighest current streak across all habits
mejor_rachaintHighest all-time streak across all habits

Habits Blueprint

Blueprint name: habito_bp · URL prefix: /habitos · Source: app/routes/habito.py All routes in this blueprint require an authenticated session. Routes that operate on a specific habit by id additionally check that habito.usuario_id == current_user.id before proceeding — see Ownership Security below.
All POST routes in this blueprint modify database state and are not idempotent. Refreshing the browser after a POST will resubmit the form. The app does not implement CSRF protection beyond Flask’s signed session cookie.

Endpoints

Method: GET
Auth required: Yes
Description: Renders habitos.html with the full list of the user’s habits. Accepts an optional ?estado= query parameter.
estado valueEffect
activos (default)Only habits with activo=True
inactivosOnly habits with activo=False
todosAll habits regardless of status
GET /habitos/mis_habitos?estado=inactivos

Habits route summary table

RouteMethodsLogin RequiredOwnership Check
/habitos/mis_habitosGETYesNo
/habitos/crearPOSTYesNo
/habitos/editar/<id>GET, POSTYesYes
/habitos/eliminar/<id>POSTYesYes
/habitos/completar/<id>POSTYesYes
/habitos/visualizar_progreso/<id>GETYesYes

Ownership Security Checks

Any route that targets a specific habit by ID applies the following guard before doing any work:
habito = HabitoRepository.obtener_habito_por_id(id_habito)
if not habito or habito.usuario_id != current_user.id:
    flash("...", "error")
    return redirect(url_for('habitos.mis_habitos'))
This pattern protects the edit, delete, completar, and visualizar_progreso routes. If the habit does not exist (None returned by the repository) or belongs to a different user, the request is silently rejected with an error flash and a redirect — no habit data is leaked to the requester.

Flash Messages

Hábito. uses Flask’s flash() function throughout all three blueprints to communicate outcomes to the user. Flash messages are stored in the session for one request and rendered by the template on the next page load. Two categories are used:
CategoryWhen used
"success"Operation completed successfully (login, registration, habit created, etc.)
"error"Validation failure, wrong credentials, ownership violation, or missing resource
Example flash calls from the source:
flash("¡Registro exitoso! Ahora puedes iniciar sesión.", "success")
flash("Este correo electrónico o nombre de usuario ya está registrado.", "error")
flash(f"¡Genial! Has completado '{habito.nombre}' hoy. 🔥", "success")
flash("No tienes permiso para modificar este hábito.", "error")
Flask-Login itself also emits a flash when it redirects an unauthenticated user, using the category configured in app/__init__.py:
login_manager.login_message = 'Por favor inicia sesión para acceder.'
login_manager.login_message_category = 'error'

Build docs developers (and LLMs) love