Conversation
…recto ProfessorCard y tema duplicados sin uso, tests generados con package com.utp.studyplanner que nunca coincidio con com.example.studyplanner.
…shboard Completa el UseCase Map de PROJECT_SETUP.md: RF-007 (UpdateSubject), RF-011 (UpdateTask), RF-013 (MarkTaskComplete), RF-022 (GetPendingTasksBySubject), RF-023 (GetTaskStats). Incluye tests con MockK.
…completado
TaskListScreen era un stub ("Pendiente implementar"). Agrega AddTaskDialog
(materia/prioridad/tipo/deadline), TaskFilterBar (materia/prioridad/estado),
checkbox de completado y boton para iniciar sesion de enfoque por tarea.
Cubre RF-009 a RF-013.
…profesor FAB y edicion quedaban como TODO. Agrega AddSubjectDialog (dropdown de profesor, selector de color) y SubjectCard con contador de tareas pendientes. Cubre RF-005 a RF-008.
…oardViewModel
DashboardScreen calculaba todo ad-hoc desde TaskViewModel y mostraba
"Materia {id}" en vez del nombre real. Ahora usa DashboardViewModel con
GetTaskStatsUseCase y GetPendingTasksBySubjectUseCase (RF-022, RF-023).
RF-017 exigia iniciar focus atado a una tarea especifica, pero no habia
forma de llegar a FocusScreen con un taskId: la pestana Enfoque solo
mostraba "No hay sesion activa" sin entrada posible. Agrega ruta
focus/{taskId} y guarda contra iniciar dos sesiones si ya hay una activa.
Agrega provideDashboardUseCases/provideDashboardViewModel y registra UpdateTaskUseCase, MarkTaskCompleteUseCase y UpdateSubjectUseCase en sus respectivos wrappers.
RNF-3.3 pide DB indexada por deadline/materia/estado; Room advertia de full table scans en cada FK sin indice (professorId, subjectId, taskId). Agrega los indices y desactiva exportSchema (no se versiona el schema en este proyecto).
Los tests existentes usaban org.mockito sin la dependencia declarada, no compilaban. RNF-3.5 pide JUnit4 + MockK, asi que se reescriben con MockK y se agrega kotlinx-coroutines-test. De paso alinea minSdk=30/targetSdk=36 con RNF-3.4 (estaban en 24/35).
… con icono FAB extendido (Box+align) reemplaza Scaffold en Materias/Tareas/Profesores, bottom sheets abren a altura completa, padding de listas consistente (top 8dp, bottom 88dp para el FAB), y TaskFilterBar muestra icono de estado.
…acion Room.Callback.onCreate inserta los 7 cursos del semestre (referencia: CLAUDE.md del vault) con su profesor y horario, solo se ejecuta una vez cuando la BD se crea por primera vez, asi cualquiera que instale el APK ve datos reales en vez de una app vacia.
DeleteConfirmDialog (compartido) y DeleteConfirmationDialog (solo profesor) eran dos componentes casi identicos con estilos distintos (Button relleno vs TextButton plano). Se elimina el duplicado, Profesores ahora usa el dialogo compartido con TextButton, igual que el resto. TaskCard tenia un containerColor explicito que lo desviaba del color por defecto que usan Materia y Profesor, se quita para que las tres cards se vean iguales.
resumeTimer() llamaba a startTimer() que siempre arrancaba con timeRemaining = WORK_DURATION y cyclesCompleted = session.cyclesCompleted (el valor original de creacion, nunca actualizado), asi que pausar y reanudar volvia a 25:00 y ciclo 1 sin importar cuanto llevaba corriendo. Ahora runCountdown() recibe el ciclo, fase y tiempo restante actuales desde el estado en vivo. De paso: la UI mostraba el boton de pausa y el de reanudar al mismo tiempo siempre, ahora alterna segun timerRunning.
bottomBarRoute compara contra el route pattern exacto (focus/{taskId}),
que nunca coincide con item.route (focus), asi que ningun tab quedaba
seleccionado al iniciar el enfoque desde el icono de una tarea.
Si se elimina la materia (o tarea) de un timer que esta corriendo, el cascade delete borra la fila de FocusSession en la BD, pero la coroutine del countdown no estaba enlazada a esa fila y seguia contando en segundo plano. loadActiveSession ahora cancela el timerJob cuando el Flow reporta que ya no hay sesion activa.
Las cards de Materia, Profesor y Tarea mostraban los botones de accion directo en la fila (icono lapiz + icono basura, y en Tarea tambien timer), ocupando espacio y sin lugar para crecer. CardActionsMenu (componente compartido) reemplaza eso por un boton de 3 puntos que abre un bottom sheet con las opciones (Editar, Eliminar, y en Tarea tambien Iniciar enfoque si no esta completada).
Icon() con tint=Color.Unspecified no hereda LocalContentColor como Text, directamente desactiva el tinte y muestra el color crudo del vector (negro), por eso el icono de Editar se veia negro sin importar el tema. Se usa LocalContentColor.current explicito. De paso se quita el tint = colorScheme.error en Eliminar, no hay razon para que ese boton sea rojo distinto al resto, CardAction ya no tiene el parametro tint.
Contador de ciclos sumaba por fase (trabajo o descanso) en vez de por par completo, entregando solo 2 sesiones de 25min en vez de 4. La sesion se guardaba en BD al iniciar el timer y quedaba huerfana si el usuario abandonaba o rechazaba la validacion. Duracion del pomodoro movida a domain/model/PomodoroPolicy (regla de negocio, no de UI).
El calculo solo contaba el largo de la ultima racha consecutiva en la BD sin comparar contra la fecha actual, mostrando rachas viejas de forma indefinida aunque el usuario no estudiara mas.
Deadline en el pasado y titulo/tiempo estimado invalidos solo se frenaban en el Composable, sin garantia a nivel de dominio. Borrar una tarea cascadeaba su historial de sesiones sin avisar. Prioridad, tipo y limite de tareas urgentes centralizados en domain/model (antes duplicados entre AddTaskDialog y TaskFilterBar, o numero magico en SQL).
Se podian crear dos materias con el mismo codigo. Borrar una materia cascadeaba sus tareas y el historial de sesiones asociado sin avisar.
Nombre/email/departamento solo se validaban en el Composable, sin garantia a nivel de dominio; regla movida a domain/model/ProfessorPolicy y aplicada en Add/UpdateProfessorUseCase. Borrar un profesor cascadeaba sus materias, tareas y sesiones sin avisar. AddProfessorDialog recibia el ViewModel completo (unico caso asi en el proyecto); ahora recibe editingProfessor/onSave/onDismiss como el resto de dialogos.
El card de progreso por materia solo mostraba conteo de pendientes, sin desglose de completadas (ese dato solo existia de forma global).
Double-checked locking incompleto: no volvia a comprobar INSTANCE dentro del bloque synchronized antes de construir la base de datos.
StreakCard y PointsCard existian pero no estaban conectados a ningun ViewModel ni renderizados. Reutilizan GetStreakUseCase/CalculatePointsUseCase ya existentes (no se duplica logica de negocio).
…rminar Abandonar una sesion ahora guarda los ciclos realmente completados en vez de descartar todo (0 ciclos si no se completo ninguno). abandonSession y validateSession dejaban timerMs/currentCycle/isWorkPhase/phaseIndex con valores viejos tras terminar, mostrando un timer congelado si el estado se resucitaba. loadActiveSession ya no muestra sesiones huerfanas de la BD como activas, solo las limpia (ninguna deberia poder resumirse segun el diseño original de la app).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.