Hábito. stores all of its data in three SQLAlchemy ORM models: Usuario, Habito, and RegistroHabito. Each model maps directly to a SQLite table via Flask-SQLAlchemy’sDocumentation 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.
db.Model base class, and uses the modern Mapped / mapped_column annotation syntax introduced in SQLAlchemy 2.0. The three tables form a simple cascade: one user owns many habits, and each habit owns many daily completion records. All models live under app/models/.
Usuario — table usuarios
The Usuario model represents a registered user of the application. It combines SQLAlchemy’s db.Model with Flask-Login’s UserMixin, so every Usuario instance is immediately usable as a Flask-Login principal without any extra wiring.
Usuario inherits from UserMixin (Flask-Login). This automatically provides the is_authenticated, is_active, is_anonymous, and get_id() methods that Flask-Login requires to manage the session cookie.Columns
Primary key. Auto-incremented by the database on every
INSERT. Never set this manually.The user’s email address. Declared
unique=True, nullable=False, and index=True. The index speeds up the login lookup performed by UsuarioRepository.obtener_usuario_por_correo().The bcrypt hash of the user’s password. The plain-text password is never stored.
UsuarioRepository.crear_usuario() calls bcrypt.hashpw() before writing to this column.A unique display name chosen at registration. Declared
unique=True and nullable=False. Violating either the correo or nombre_usuario uniqueness constraint raises SQLAlchemy’s IntegrityError.Timestamp of account creation. Defaults to
datetime.now (Python-side, evaluated at insert time). Not exposed to the user in the current UI.Relationship
| Attribute | Target | Config |
|---|---|---|
habitos | List[Habito] | back_populates="dueno", cascade="all, delete-orphan" |
cascade="all, delete-orphan" setting means that deleting a Usuario will automatically delete all of their Habito rows — and, transitively, all RegistroHabito rows that belong to those habits.
Source
Habito — table habitos
The Habito model represents a single trackable habit belonging to a user. It carries both structural data (which days to perform the habit, what time of day) and running statistics (current streak, best streak). The dias_semana field is stored as a comma-separated string of day-letter codes.
Columns
Primary key. Auto-incremented by the database.
Foreign key referencing
usuarios.id. Not null. Every habit must belong to exactly one user.Short name for the habit (e.g.
"Leer", "Correr"). Not null.Optional longer description of the habit.
nullable=True — omit or pass None if not needed.Comma-separated day-letter codes indicating which days of the week the habit is scheduled. Valid letters are
L (lunes/Monday), M (martes/Tuesday), X (miércoles/Wednesday), J (jueves/Thursday), V (viernes/Friday), S (sábado/Saturday), D (domingo/Sunday). Example value: "L,M,X,J,V".Timestamp of when the habit was created. Defaults to
datetime.now at insert time.Whether the habit is currently active. Defaults to
True. Inactive habits are hidden from the dashboard but preserved in the database, allowing users to “pause” a habit without losing history.The current consecutive-days streak. Defaults to
0. Incremented by HabitoRepository.marcar_completado_hoy() when a completion is marked, and decremented (floor 0) when a completion is unmarked.The all-time best streak for this habit. Defaults to
0. Updated by marcar_completado_hoy() whenever racha_actual exceeds the previous record.Optional suggested time-of-day slot. Typical values:
"Mañana", "Tarde", "Noche". nullable=True.Relationships
| Attribute | Target | Config |
|---|---|---|
dueno | Usuario | back_populates="habitos" |
registros | List[RegistroHabito] | back_populates="habito", cascade="all, delete-orphan" |
Source
RegistroHabito — table registro_habitos
RegistroHabito is the daily completion log. Each row represents one day for one habit, and the table-level UniqueConstraint enforces that the same habit cannot be marked complete more than once on the same calendar date. The fecha column uses SQLAlchemy’s Date type (date only — no time component) to keep the constraint deterministic regardless of the time zone or clock when the request arrives.
The unique constraint
uq_habito_fecha_diaria on (habito_id, fecha) is the database-level guarantee that prevents duplicate completions. HabitoRepository.marcar_completado_hoy() additionally queries for an existing record before inserting, implementing a toggle (mark/unmark) at the application layer.Columns
Primary key. Auto-incremented.
Foreign key referencing
habitos.id. Not null.The calendar date (year, month, day — no time) to which this record belongs. Defaults to
date.today() at insert time.Whether the habit was completed on
fecha. Defaults to False. In practice, the current codebase only inserts rows when completado=True and deletes them to unmark, but the column exists to support future partial-completion states.Table Constraint
uq_habito_fecha_diaria and prevents any habit from accumulating more than one completion record per day at the database level, independently of application logic.
Relationship
| Attribute | Target | Config |
|---|---|---|
habito | Habito | back_populates="registros" |
Source
Entity-Relationship Summary
The three tables form a strict cascade hierarchy. The arrows below show foreign-key direction (child → parent).| Relationship | Type | Cascade |
|---|---|---|
Usuario → Habito | One-to-many | all, delete-orphan |
Habito → RegistroHabito | One-to-many | all, delete-orphan |