Agregar documentación completa del MVP de KinderTrack - JEK#93
Agregar documentación completa del MVP de KinderTrack - JEK#93juankuja wants to merge 5 commits intoLIDR-academy:mainfrom
Conversation
📝 WalkthroughWalkthroughAdds extensive documentation: a complete OpenAPI spec, architecture and data-model docs, PRD, multiple ticket dossiers, user stories, prompts rework, README expansion, and guidance for exports/security—centralizing design, API surface, and implementation plans. Changes
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~30 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 19
🤖 Fix all issues with AI agents
In `@docs/api-spec/api-kindertrack.yaml`:
- Around line 470-491: The schema currently lists pickedUpByName and
pickedUpByRelation as optional text but requires them in the description when
pickedUpBy == "OTHER"; update the OpenAPI schema to enforce this conditional
requirement using JSON Schema conditional keywords: add an if/then block for the
object (if: properties.pickedUpBy.const == "OTHER") with then: required:
["pickedUpByName","pickedUpByRelation"] and appropriate property validations
(maxLength) so those fields are validated when pickedUpBy is OTHER; apply the
same pattern for reasonDescription in the /attendance/absent schema (use if
properties.reason == "OTHER" then require reasonDescription).
- Around line 1299-1308: The example values under the user example (fields id
and assignedClassRoomIds, and any other example UUID-like fields across the
spec) use non-UUID formats (e.g., prefixes like "u-" or "att-" and non-hex
characters); replace those with valid RFC 4122 UUID strings (32 hex chars with
hyphens) so they conform to the schema's format: uuid (e.g.,
"123e4567-e89b-12d3-a456-426614174000"), and apply this change consistently for
all example properties that declare format: uuid such as id,
assignedClassRoomIds entries, attachment IDs, etc., ensuring no extra prefixes
or invalid characters remain.
In `@docs/arquitectura/arquitectura.md`:
- Around line 101-121: The doc is inconsistent about the static assets path:
update all references so they use a single canonical deployment path (choose
either frontend/build/web or backend/public) and make the change everywhere the
symbols appear — e.g., replace the express.static call string
app.use(express.static('frontend/build/web')) and the unified flow line "Flutter
Web build --> backend/public" (and any other mentions of "backend/public" or
"frontend/build/web" or "Flutter Web build") so they match the chosen canonical
path and accompanying instructions (build command, serve path, and examples for
hosting) across the file.
In `@docs/data-model/data-model.md`:
- Around line 81-90: The doc currently says users can have multiple roles but
the schema shows User.role as a single ENUM and the ER diagram uses
RolePermission ||--|| USER; reconcile by choosing one model and updating
text/diagram: either change User.role to a roles relation (e.g., UserRoles join
table / User.roles ARRAY or a many-to-many between User and RolePermission) and
update the narrative and ER diagram to N:N (RolePermission <-> User via
UserRoles), or keep User.role as a single ENUM and change the narrative to state
each user has one role and adjust the ER diagram to show many users per role
(RolePermission 1:N User). Update references to User.role, RolePermission, and
the ER diagram entries so they consistently reflect the chosen model.
In `@docs/good-practices/ticket.md`:
- Around line 124-125: The example history uses ambiguous dates ("* 01/10/2023:
Creado por [nombre]" and "* 05/10/2023: Prioridad actualizada a Alta por
[nombre]"); update those entries to ISO‑8601 format (YYYY‑MM‑DD), e.g.
"2023-10-01" and "2023-10-05", keeping the rest of the text identical so the
timeline is unambiguous for a global team.
In `@docs/product/prd.md`:
- Around line 79-80: Replace the cipher label "AES256" with the normalized form
"AES-256" in the product requirements copy so the line "Datos cifrados en
repositorio local (AES256)." becomes "Datos cifrados en repositorio local
(AES-256)."; ensure any other occurrences in the same document use "AES-256" for
consistency.
- Around line 7-15: TOC links use accented characters that may not match
generated heading IDs; update each fragment (e.g., links for "Breve descripción
del producto", "Valor agregado y ventajas competitivas", "Descripción general de
las funcionalidades", "Registro de Asistencias", "Registro de Incidentes",
"Requisitos clave del MVP", "Consideraciones de seguridad", "Escalabilidad y
visión futura") to use ASCII-only anchors (e.g., remove accents and replace
spaces with hyphens) or add explicit HTML anchors in the headings themselves so
the fragments reliably match the generated IDs and navigation works.
In `@docs/tickets/ticket-gestion-usuarios.md`:
- Around line 232-235: Update the ticket's "Respuestas estandarizadas" section
to match the OpenAPI contract: change the success response to include token,
refreshToken and expiresIn alongside user, and change the error response schema
to { error, message, details } instead of { error, code }; also update the
"Documentación OpenAPI/Swagger" checklist entry and any examples in this doc
(the Respuestas estandarizadas block) so BE/FE implementers use the exact
OpenAPI shapes.
In `@docs/tickets/ticket-registro-asistencias.md`:
- Around line 26-33: La discrepancia entre el campo status (PRESENT/ABSENT) y el
uso de "checkedOut" se corrige de dos formas: en el modelo Attendance decide si
quieres un valor explícito o derivado; o bien añade un miembro CHECKED_OUT al
enum status (actualiza cualquier uso de status en lógica y documentación) o deja
status como PRESENT/ABSENT y documenta/implementa checkedOut como un valor
derivado (booleano calculado) basado en la presencia de check_out_time (p. ej.
checkedOut = check_out_time != null) y ajusta las consultas y validaciones que
actualmente esperan checkedOut para usar esa derivación; busca las ocurrencias
del modelo Attendance, el campo status, el campo check_out_time y cualquier
referencia a checkedOut para aplicar el cambio consistente.
- Around line 81-87: En la sección "Criterios de aceptación" reemplaza el ítem
"TSLint sin warnings" por un enunciado que haga referencia a ESLint con soporte
TypeScript; por ejemplo indica "ESLint sin warnings usando
`@typescript-eslint/parser` y `@typescript-eslint/eslint-plugin`" para asegurar que
el criterio apunte al linter moderno y a los paquetes `@typescript-eslint/parser`
y `@typescript-eslint/eslint-plugin`.
In `@docs/tickets/ticket-registro-incidentes.md`:
- Around line 171-176: The ticket defines a mismatch: it asks for a PATCH
/api/incidents/:id/visibility route but the OpenAPI spec defines PATCH
/incidents/{incidentId} and has no visibility endpoint; update the ticket to
match the API spec by replacing the proposed `PATCH
/api/incidents/:id/visibility` with `PATCH /incidents/{incidentId}` (handled by
IncidentController) or, if the dedicated visibility route is required, add the
new route to the OpenAPI spec and document `PATCH
/incidents/{incidentId}/visibility` (or `/api/incidents/:id/visibility`) so
IncidentController and the routes list remain consistent.
- Around line 24-26: The Prisma Incident schema currently uses fields and enums
named type, tags and shared_with_family with development enums (FINE_MOTOR,
GROSS_MOTOR, CREATIVITY); update the schema to match the OpenAPI spec by
renaming fields to category, developmentAreas and visibility and replace the
enum definitions to the API's values (e.g., category enum values,
developmentAreas options, and visibility values INTERNAL/SHAREABLE), keeping the
same FK relations to Child, ClassRoom and User and preserving
created_at/updated_at semantics; ensure model names and enum identifiers (e.g.,
Incident, CategoryEnum, DevelopmentAreasEnum, VisibilityEnum) align with the API
to avoid mismatch.
In `@docs/use-cases/use-cases.md`:
- Around line 146-148: Remove the conversational prompt "¿Quieres que haga eso?"
from the use-cases document (the Spanish block that offers to generate a UML
use-case diagram) and either delete it or move it into a non-interactive "Next
steps" or "Optional follow-up" section; if moved, reword it as a neutral
actionable item such as "Opcional: generar un diagrama de casos de uso UML para
KinderTrack (roles, acciones y dependencias) para integrar en el PRD." Ensure
the original paragraph's content is kept as documentation or task item rather
than an assistant-style question.
In `@docs/user-stories/user-stories.md`:
- Around line 22-26: The fenced code block example for the user story template
is missing a language tag which triggers markdownlint MD040; update the
triple-backtick fence that contains the template "Como [tipo de
usuario],\nquiero [acción que desea realizar],\npara [beneficio que espera
obtener]." to include a language label (e.g., use ```text) so the block is
explicitly tagged and MD040 is satisfied.
- Around line 752-760: La cabecera "Historias de Alta Prioridad (MVP Completo -
5 historias)" no coincide con la lista que contiene solo US-006, US-008, US-011
y US-012; corrige esto editando la cabecera a "(... - 4 historias)" o añadiendo
la historia faltante al listado (mantén el formato de las entradas como US-XXX)
y actualiza cualquier total de planificación relacionado en el documento para
que los conteos queden consistentes.
In `@readme.md`:
- Around line 287-307: The README currently references two different static
asset directories ("frontend/build/web" in the text and "backend/public" in the
deployment flow); choose one canonical path (e.g., frontend/build/web) and
update both the static-serving example (express.static('frontend/build/web'))
and the flow diagram's node ("Flutter Web build --> backend/public") to use that
same path string so the deployment guidance is consistent across the document.
- Line 36: Replace the bare URL
"https://github.com/juankuja/AI4Devs-finalproject" in the README with a Markdown
link using the [text](url) syntax (e.g.,
[AI4Devs-finalproject](https://github.com/juankuja/AI4Devs-finalproject)) to
satisfy MD034; update the single occurrence of that URL so the README uses the
linked text instead of a bare URL.
- Around line 361-363: Replace the bolded line "**Enfoque: TDD (Test-Driven
Development)**" with an actual Markdown heading (e.g., prefix with one or more
'#' such as "## Enfoque: TDD (Test-Driven Development)") so the section is a
proper heading instead of emphasized text; update any adjacent formatting to
match heading level and run markdownlint to confirm MD036 is resolved.
- Line 842: Update the README line "Implementar en modo offline-first (SQLite
local)" to explicitly state the web strategy: either SQLite via WASM (e.g.,
Drift + sqlite3.wasm/sqlite3_flutter_libs with drift_web or sqlite3_wasm)
including the build and initialization steps, or recommend a web-native store
(IndexedDB via idb_shim, Hive, or Isar) with brief pros/cons and a short setup
note; mention the chosen package names (drift, sqlite3_wasm, idb_shim,
hive_flutter, isar) so readers know which implementation and config to follow.
🧹 Nitpick comments (3)
docs/good-practices/user-story.md (1)
13-15: Optional: add a language tag to fenced examples for lint consistency.
If markdownlint is enabled elsewhere, label these blocks (e.g.,text) to avoid MD040.Also applies to: 36-38
docs/arquitectura/arquitectura.md (1)
52-84: Add language identifiers to fenced blocks (MD040).The structure and deployment flow code blocks are missing a language tag. Please use
text(orbashfor commands) to satisfy markdownlint.✅ Example fix
-``` +```text kindertrack/ ... -``` +``` -``` +```text Flutter Web build --> backend/public Backend Node.js sirve frontend + API Backend <--> PostgreSQL (Supabase) Backend <--> Storage Multimedia -``` +``` </details> Also applies to: 116-121 </blockquote></details> <details> <summary>readme.md (1)</summary><blockquote> `237-269`: **Add language identifiers to fenced blocks (MD040).** Use `text` for the repo tree and deployment flow blocks to satisfy markdownlint. <details> <summary>✅ Example fix</summary> ```diff -``` +```text kindertrack/ ... -``` +``` -``` +```text Flutter Web build --> backend/public Backend Node.js sirve frontend + API Backend <--> PostgreSQL (Supabase) Backend <--> Storage Multimedia -``` +``` </details> Also applies to: 302-307 </blockquote></details> </blockquote></details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In `@docs/api-spec/api-kindertrack.yaml`:
- Around line 253-270: The request body schema for the checkout endpoint
currently defines properties childId and notes (schema properties childId,
notes) but the tickets (US-004) require classRoomId and pickupNote; update the
OpenAPI schema so the payload matches the tickets by replacing or augmenting
properties: add classRoomId (string, format: uuid) and pickupNote (string,
maxLength: 100) and adjust the required array to list childId, classRoomId,
pickupNote (or remove/rename notes to pickupNote) and update the example
accordingly so frontend and backend contracts align.
- Around line 305-325: The OpenAPI schema for the /attendance/absent request is
missing the notes field in the required array; update the schema by adding
"notes" to the required list alongside "childId", "classRoomId", and "date" so
the properties.notes (type: string, maxLength: 200) is enforced as mandatory;
ensure the description and maxLength remain unchanged and validate the updated
spec against the API validator.
- Around line 460-475: El campo pickedUpBy está declarado en el PATCH request
body pero no existe en el modelo Attendance; either add pickedUpBy to the
Attendance schema or remove it from the PATCH operation to keep the API contract
consistent. To fix, update the components.schemas.Attendance definition to
include a pickedUpBy property (type: string, enum: [FATHER, MOTHER, AUTHORIZED,
OTHER]) matching the PATCH, or remove the pickedUpBy property from the PATCH
request body definition so both places match; ensure the symbol names
"pickedUpBy" and "Attendance" are the targets you modify.
- Around line 978-1064: The export endpoints currently (operationId
exportAttendances and exportIncidents) only accept classRoomId and dates but the
ticket US‑013 requires classRoomIds (array) plus additional filters (childId,
types, tags) for incidents; update the requestBody schemas for
/export/attendances and /export/incidents to replace classRoomId with
classRoomIds: type array of uuid, keep startDate and endDate as required, and
add optional properties childId (uuid), types (array of strings or enum matching
IncidentType), and tags (array of strings) for the incidents endpoint (and add
childId/tags to attendances if ticket requires), then update the example objects
to show classRoomIds and the new filters so the spec matches US‑013.
In `@docs/tickets/ticket-registro-asistencias.md`:
- Around line 26-52: Update the Attendance schema so the notes column uses 200
chars instead of 100 (e.g., Attendance model: notes String `@db.VarChar`(200));
regenerate the migration and update any seeds to use the new size; keep the
business rule that check-in/check-out notes are limited to 100 by enforcing that
in the input/validation logic (wherever checkIn/checkOut or attendance
creation/update handlers validate input), not in the DB schema; ensure
check_in_time/check_out_time remain timestamptz and date remains DATE as before
and run migrations/tests to verify no truncation of absence reasons.
♻️ Duplicate comments (1)
docs/api-spec/api-kindertrack.yaml (1)
219-223: Ejemplos con UUID inválido en requestsEn Line 220 el ejemplo contiene caracteres no hexadecimales (
7g8h...). Esto no cumpleformat: uuidy puede romper validadores/generadores. Actualiza estos ejemplos y el resto de UUIDs similares.✏️ Ejemplo de corrección
- childId: "c1a2b3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6" + childId: "c1a2b3d4-e5f6-4a8b-9c0d-1e2f3a4b5c6d"
🧹 Nitpick comments (6)
docs/user-stories/user-stories.md (1)
22-26: Optional: Consider more specific language tag for the template.The user story template code block uses the generic
textlanguage tag. While this resolves the markdownlint warning, you could usemarkdownorgherkinfor syntax highlighting if the template format warrants it.docs/arquitectura/arquitectura.md (3)
52-84: Add language tag to directory structure code block.The directory structure visualization lacks a language identifier, triggering markdownlint MD040. Consider adding a language tag like
treeortextto the opening fence.♻️ Proposed fix
-``` +```text kindertrack/ │
116-121: Add language tag to deployment flow diagram.The deployment flow block is missing a language identifier. Add
textormermaiddepending on whether you want to keep it as ASCII art or convert to Mermaid syntax.♻️ Proposed fix
-``` +```text Flutter Web build --> frontend/build/web Backend Node.js sirve frontend + API
205-207: Remove conversational prompt from committed documentation.The closing question "¿Quieres que haga eso?" reads as an interactive assistant prompt rather than finalized documentation. Consider either removing it or rephrasing as a neutral note about available follow-up materials.
♻️ Proposed rewording
-Si quieres, puedo generar **una guía paso a paso de desarrollo TDD para este mono-repo**, con **tests por dominio**, **Flutter Web + backend TS**, y **despliegue gratuito en Supabase o Render**, lista para empezar a codificar KinderTrack. - -¿Quieres que haga eso? +**Próximos pasos opcionales**: Se puede generar una guía paso a paso de desarrollo TDD para este mono-repo, con tests por dominio, Flutter Web + backend TS, y despliegue gratuito en Supabase o Render, lista para empezar a codificar KinderTrack.Based on learnings from past reviews, conversational prompts should be rephrased or moved to separate planning sections.
readme.md (2)
237-237: Specify language for fenced code blocks.Markdownlint flags these code blocks without language specifiers. Consider adding a language identifier (e.g.,
textor leave empty string) to satisfy linting rules.🔧 Suggested fix
-``` +```textApply to both occurrences at lines 237 and 302.
Also applies to: 302-302
361-361: Convert bold text to proper heading.This line uses bold emphasis instead of a markdown heading, which affects document structure and navigation. Convert to a proper heading.
🔧 Suggested fix
-#### Enfoque: TDD (Test-Driven Development) +#### **Enfoque: TDD (Test-Driven Development)**
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@docs/tickets/ticket-registro-asistencias.md`:
- Around line 368-405: The codebase mixes "notes" and "pickupNote" in the
check-out flow; unify to pickupNote across the API, service, event and tests:
update the CheckOutDto to use pickupNote (required), change the
AttendanceController POST /api/attendance/check-out handler to read pickupNote
from the request and pass it to AttendanceService.checkOut(dto, userId), adjust
AttendanceService.checkOut to validate and append pickupNote to attendance notes
and set checkOutTime, include pickupNote in the ChildCheckedOut domain event
payload, and update any unit tests and frontend notifier references to use
pickupNote so the naming is consistent end-to-end.
♻️ Duplicate comments (2)
docs/api-spec/api-kindertrack.yaml (2)
219-221: Replace non‑UUID example values with valid UUIDs.Several examples still include non‑hex characters, which will fail validators and mislead integrators. Please update these and apply the fix consistently across the spec.
✏️ Example adjustments
- childId: "c1a2b3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6" + childId: "c1a2b3d4-e5f6-4a8b-9c0d-1e2f3a4b5c6d" ... - childId: "c1a2b3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6" + childId: "c1a2b3d4-e5f6-4a8b-9c0d-1e2f3a4b5c6d" ... - childId: "c1a2b3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6" + childId: "c1a2b3d4-e5f6-4a8b-9c0d-1e2f3a4b5c6d" ... - classRoomIds: ["a123b456-c789-0d12-e345-f67890123456", "b234c567-d890-1e23-f456-g78901234567"] + classRoomIds: ["a123b456-c789-0d12-e345-f67890123456", "b234c567-d890-1e23-f456-678901234567"] ... - childId: "c1a2b3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6" + childId: "c1a2b3d4-e5f6-4a8b-9c0d-1e2f3a4b5c6d"Also applies to: 275-277, 333-335, 1019-1020, 1087-1089
258-278: Align check‑out payload naming with tickets (pickupNote).The tickets use
pickupNote, but the OpenAPI spec usesnotes. This will cause DTO drift between BE/FE and the contract.✏️ Suggested contract alignment
required: - childId - classRoomId - - notes + - pickupNote properties: childId: type: string format: uuid description: ID del niño classRoomId: type: string format: uuid description: ID del aula - notes: + pickupNote: type: string maxLength: 100 description: Información sobre quién recoge al niño y observaciones de la salida example: childId: "c1a2b3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6" classRoomId: "a123b456-c789-0d12-e345-f67890123456" - notes: "Recogido por su madre a tiempo" + pickupNote: "Recogido por su madre a tiempo"
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@docs/tickets/ticket-gestion-usuarios.md`:
- Around line 141-145: The AuthService contract is out of sync with the API:
update the signatures so login and token refresh return the full API response
shape. Change login(email, password) to return Promise<{ user, token,
refreshToken, expiresIn }>, and change refreshToken(oldToken) to return
Promise<{ token, refreshToken, expiresIn }> (instead of Promise<string>); keep
logout(userId), validateToken(token), and trackFailedAttempt(email) unchanged.
Adjust any implementations and the docs references (the other occurrence
mentioned) to match these updated types.
- Line 84: Replace the outdated phrase "TSLint/ESLint sin warnings" with "ESLint
(with `@typescript-eslint/`*) without warnings" in the document; locate the exact
string "TSLint/ESLint sin warnings" (appears on the current line 84) and update
it to reflect using ESLint with the `@typescript-eslint` plugins.
In `@docs/tickets/ticket-registro-asistencias.md`:
- Around line 76-79: The docs (and implementation) have conflicting limits for
the notes field: the domain Value Object (VO) currently caps notes at 100 chars
while the absence registration use-case allows 200, causing valid absence
reasons to be rejected; update the domain/VO notes limit to 200 characters to
match the absence use-case (or vice‑versa if you prefer domain stricter rules),
and then enforce a 100‑char input/UI/validation constraint only for the
check‑in/check‑out paths (i.e., keep a 100‑char check‑in/check‑out input
validation rule but relax the core domain/VO validation for notes to 200) so
both the "notes" field and the "absence registration" use-case are consistent.
♻️ Duplicate comments (1)
docs/tickets/ticket-registro-asistencias.md (1)
369-405: UnifypickupNotevsnotesin the check‑out flow.The BE ticket/DTO uses
notes, while FE usespickupNote. This mismatch will leak into DTOs and APIs. Please align naming end‑to‑end.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@docs/tickets/ticket-gestion-usuarios.md`:
- Around line 141-170: Decide whether refreshToken is required for MVP and make
the ticket consistent: if choosing mandatory, mark refreshToken as required in
the contract (keep login(email, password): Promise<{ user, token, refreshToken,
expiresIn }> and refreshToken(oldToken): Promise<{ token, refreshToken,
expiresIn }>) and update acceptance criteria to require refresh token behavior
and tests; if choosing optional, remove refreshToken from the login/refreshToken
signatures (or mark them nullable/optional) and update acceptance criteria,
notes and tests to state refresh token is out of scope for MVP; ensure the doc
references (functions login, logout, validateToken, refreshToken,
trackFailedAttempt, lockAccount) and the acceptance criteria, technical notes
and tests are all updated to match the chosen posture.
♻️ Duplicate comments (2)
docs/tickets/ticket-registro-asistencias.md (1)
368-405: UnifypickupNotevsnotesnaming in check‑out flow to avoid DTO/API drift.The check‑out tickets still use
notes, but the intended naming across layers ispickupNote. Please align all check‑out DTOs, service args, and FE method signatures topickupNoteto prevent mismatches.✏️ Suggested doc tweak
- - Validar notes no vacío + - Validar pickupNote no vacío ... - - `CheckOutDto`: { childId, classRoomId, notes } - - Validar notes requerido (información sobre quién recoge) + - `CheckOutDto`: { childId, classRoomId, pickupNote } + - Validar pickupNote requerido (información sobre quién recoge) ... - - [ ] Agregar método `checkOut(childId, notes)` a `AttendanceNotifier` + - [ ] Agregar método `checkOut(childId, pickupNote)` a `AttendanceNotifier`Also applies to: 432-435
docs/tickets/ticket-gestion-usuarios.md (1)
501-510:ALL_PERMISSIONSno está definido en el enum.El mapa usa
ALL_PERMISSIONS, pero el enumPermissionno lo declara. Eso deja el rol DIRECTOR sin definición concreta y puede bloquear la implementación.✅ Propuesta de alineación
- - CREATE_ATTENDANCE, VIEW_ALL_CLASSROOMS, CREATE_INCIDENT, VIEW_INCIDENT, EXPORT_DATA, MANAGE_USERS, EDIT_ATTENDANCE, etc. + - CREATE_ATTENDANCE, VIEW_ALL_CLASSROOMS, CREATE_INCIDENT, VIEW_INCIDENT, EXPORT_DATA, MANAGE_USERS, EDIT_ATTENDANCE, etc. + - ALL_PERMISSIONS (si quieres un wildcard explícito)o bien expandir la lista para DIRECTOR:
- DIRECTOR: [ALL_PERMISSIONS], + DIRECTOR: [CREATE_ATTENDANCE, VIEW_ALL_CLASSROOMS, CREATE_INCIDENT, VIEW_INCIDENT, EXPORT_DATA, MANAGE_USERS, EDIT_ATTENDANCE],
🧹 Nitpick comments (1)
docs/tickets/ticket-registro-asistencias.md (1)
372-375: Clarify hownotesis composed to avoid data loss/ambiguity.
notesis used for check‑in notes, check‑out pickup info, and absence reason. Document a clear format (e.g., structured JSON or prefix tags) or split into dedicated fields (e.g.,checkInNote,pickupNote,absenceReason) to prevent overwriting and ambiguous history.Also applies to: 459-463, 673-676
| - `login(email, password): Promise<{ user, token, refreshToken, expiresIn }>` | ||
| - `logout(userId): Promise<void>` | ||
| - `validateToken(token): Promise<User | null>` | ||
| - `refreshToken(oldToken): Promise<{ token, refreshToken, expiresIn }>` | ||
| - `trackFailedAttempt(email): Promise<void>` | ||
| - `lockAccount(userId, duration): Promise<void>` | ||
| - [ ] Implementar generación de JWT con claims: | ||
| - userId, role, email, exp (8 horas) | ||
| - [ ] Implementar verificación de password con bcrypt | ||
| - [ ] Lógica de bloqueo tras 5 intentos fallidos (15 minutos) | ||
| - [ ] Limpieza de sesiones expiradas (cron job) | ||
| - [ ] Tests unitarios con mocks del repositorio | ||
|
|
||
| #### Criterios de aceptación | ||
| - JWT generado correctamente con secret de env | ||
| - Password hasheado con bcrypt rounds=12 | ||
| - Bloqueo funciona tras 5 intentos fallidos | ||
| - Token expira a las 8 horas correctamente | ||
| - Sesiones expiradas se limpian automáticamente | ||
| - Tests unitarios >85% coverage | ||
|
|
||
| #### Dependencias | ||
| - TICKET-001-BE-01 | ||
| - TICKET-001-BE-02 | ||
|
|
||
| #### Notas técnicas | ||
| - Usar librerías: `jsonwebtoken`, `bcrypt` | ||
| - Secret JWT debe venir de variable de entorno | ||
| - Implementar refresh token pattern (opcional para MVP) | ||
|
|
There was a problem hiding this comment.
Aclara si refreshToken es obligatorio en MVP.
Aquí se define refreshToken como parte del contrato (login, refreshToken), pero más abajo se indica que el patrón es “opcional para MVP”. Eso crea ambigüedad para BE/FE y QA. Elige una sola postura y refleja el contrato en todo el ticket.
✅ Propuesta de ajuste (elige una)
Opción A: hacerlo obligatorio en MVP (recomendado si el endpoint ya existe)
- - Implementar refresh token pattern (opcional para MVP)
+ - Implementar refresh token pattern (obligatorio para MVP)Opción B: hacerlo opcional en MVP (ajustar contrato)
- - `login(email, password): Promise<{ user, token, refreshToken, expiresIn }>`
+ - `login(email, password): Promise<{ user, token, expiresIn }>`
...
- - `refreshToken(oldToken): Promise<{ token, refreshToken, expiresIn }>`
+ - `refreshToken(oldToken): Promise<{ token, expiresIn }>`📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - `login(email, password): Promise<{ user, token, refreshToken, expiresIn }>` | |
| - `logout(userId): Promise<void>` | |
| - `validateToken(token): Promise<User | null>` | |
| - `refreshToken(oldToken): Promise<{ token, refreshToken, expiresIn }>` | |
| - `trackFailedAttempt(email): Promise<void>` | |
| - `lockAccount(userId, duration): Promise<void>` | |
| - [ ] Implementar generación de JWT con claims: | |
| - userId, role, email, exp (8 horas) | |
| - [ ] Implementar verificación de password con bcrypt | |
| - [ ] Lógica de bloqueo tras 5 intentos fallidos (15 minutos) | |
| - [ ] Limpieza de sesiones expiradas (cron job) | |
| - [ ] Tests unitarios con mocks del repositorio | |
| #### Criterios de aceptación | |
| - JWT generado correctamente con secret de env | |
| - Password hasheado con bcrypt rounds=12 | |
| - Bloqueo funciona tras 5 intentos fallidos | |
| - Token expira a las 8 horas correctamente | |
| - Sesiones expiradas se limpian automáticamente | |
| - Tests unitarios >85% coverage | |
| #### Dependencias | |
| - TICKET-001-BE-01 | |
| - TICKET-001-BE-02 | |
| #### Notas técnicas | |
| - Usar librerías: `jsonwebtoken`, `bcrypt` | |
| - Secret JWT debe venir de variable de entorno | |
| - Implementar refresh token pattern (opcional para MVP) | |
| - `login(email, password): Promise<{ user, token, refreshToken, expiresIn }>` | |
| - `logout(userId): Promise<void>` | |
| - `validateToken(token): Promise<User | null>` | |
| - `refreshToken(oldToken): Promise<{ token, refreshToken, expiresIn }>` | |
| - `trackFailedAttempt(email): Promise<void>` | |
| - `lockAccount(userId, duration): Promise<void>` | |
| - [ ] Implementar generación de JWT con claims: | |
| - userId, role, email, exp (8 horas) | |
| - [ ] Implementar verificación de password con bcrypt | |
| - [ ] Lógica de bloqueo tras 5 intentos fallidos (15 minutos) | |
| - [ ] Limpieza de sesiones expiradas (cron job) | |
| - [ ] Tests unitarios con mocks del repositorio | |
| #### Criterios de aceptación | |
| - JWT generado correctamente con secret de env | |
| - Password hasheado con bcrypt rounds=12 | |
| - Bloqueo funciona tras 5 intentos fallidos | |
| - Token expira a las 8 horas correctamente | |
| - Sesiones expiradas se limpian automáticamente | |
| - Tests unitarios >85% coverage | |
| #### Dependencias | |
| - TICKET-001-BE-01 | |
| - TICKET-001-BE-02 | |
| #### Notas técnicas | |
| - Usar librerías: `jsonwebtoken`, `bcrypt` | |
| - Secret JWT debe venir de variable de entorno | |
| - Implementar refresh token pattern (obligatorio para MVP) |
🧰 Tools
🪛 LanguageTool
[grammar] ~147-~147: Cambia la palabra o signo.
Context: ...mplementar generación de JWT con claims: - userId, role, email, exp (8 horas) - [ ]...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_OTHER)
[grammar] ~148-~148: Cambia la palabra o signo.
Context: ...: - userId, role, email, exp (8 horas) - [ ] Implementar verificación de password...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_SPACE)
[grammar] ~149-~149: Cambia la palabra o signo.
Context: ...ntar verificación de password con bcrypt - [ ] Lógica de bloqueo tras 5 intentos fa...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_SPACE)
[grammar] ~150-~150: Cambia la palabra o signo.
Context: ...eo tras 5 intentos fallidos (15 minutos) - [ ] Limpieza de sesiones expiradas (cron...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_SPACE)
[grammar] ~151-~151: Cambia la palabra o signo.
Context: ...impieza de sesiones expiradas (cron job) - [ ] Tests unitarios con mocks del reposi...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_SPACE)
[grammar] ~152-~152: Aquí puede haber un error.
Context: ...ests unitarios con mocks del repositorio #### Criterios de aceptación - JWT generado c...
(QB_NEW_ES)
[grammar] ~154-~154: Agrega un signo de puntuación.
Context: ...ocks del repositorio #### Criterios de aceptación - JWT generado correctamente con secret...
(QB_NEW_ES_OTHER_ERROR_IDS_MISSING_PUNCTUATION)
[grammar] ~155-~155: Agrega un signo de puntuación.
Context: ...WT generado correctamente con secret de env - Password hasheado con bcrypt rounds=1...
(QB_NEW_ES_OTHER_ERROR_IDS_MISSING_PUNCTUATION)
[grammar] ~156-~156: Agrega un signo de puntuación.
Context: ...t de env - Password hasheado con bcrypt rounds=12 - Bloqueo funciona tras 5 intentos fall...
(QB_NEW_ES_OTHER_ERROR_IDS_MISSING_PUNCTUATION)
[grammar] ~157-~157: Agrega un signo de puntuación.
Context: ...s=12 - Bloqueo funciona tras 5 intentos fallidos - Token expira a las 8 horas correctame...
(QB_NEW_ES_OTHER_ERROR_IDS_MISSING_PUNCTUATION)
[grammar] ~158-~158: Agrega un signo de puntuación.
Context: ...s fallidos - Token expira a las 8 horas correctamente - Sesiones expiradas se limpian automát...
(QB_NEW_ES_OTHER_ERROR_IDS_MISSING_PUNCTUATION)
[grammar] ~159-~159: Agrega un signo de puntuación.
Context: ...tamente - Sesiones expiradas se limpian automáticamente - Tests unitarios >85% coverage #### D...
(QB_NEW_ES_OTHER_ERROR_IDS_MISSING_PUNCTUATION)
[grammar] ~160-~160: Aquí puede haber un error.
Context: ...icamente - Tests unitarios >85% coverage #### Dependencias - TICKET-001-BE-01 - TICKET...
(QB_NEW_ES)
[grammar] ~162-~162: Elimina la palabra o signo.
Context: ...itarios >85% coverage #### Dependencias - TICKET-001-BE-01 - TICKET-001-BE-02 ###...
(QB_NEW_ES_OTHER_ERROR_IDS_UNNECESSARY_SPACE)
[grammar] ~163-~163: Elimina la palabra o signo.
Context: ...ge #### Dependencias - TICKET-001-BE-01 - TICKET-001-BE-02 #### Notas técnicas - ...
(QB_NEW_ES_OTHER_ERROR_IDS_UNNECESSARY_SPACE)
[grammar] ~166-~166: Cambia la palabra o signo.
Context: ...01-BE-01 - TICKET-001-BE-02 #### Notas técnicas - Usar librerías: jsonwebtoken, bcrypt...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_OTHER)
[grammar] ~167-~167: Cambia la palabra o signo.
Context: ...écnicas - Usar librerías: jsonwebtoken, bcrypt - Secret JWT debe venir de variable de ent...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_SPACE)
[grammar] ~168-~168: Cambia la palabra o signo.
Context: ...et JWT debe venir de variable de entorno - Implementar refresh token pattern (opcio...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_OTHER)
[grammar] ~169-~169: Aquí puede haber un error.
Context: ...efresh token pattern (opcional para MVP) --- ### TICKET-001-BE-04: Implementación de midd...
(QB_NEW_ES)
🤖 Prompt for AI Agents
In `@docs/tickets/ticket-gestion-usuarios.md` around lines 141 - 170, Decide
whether refreshToken is required for MVP and make the ticket consistent: if
choosing mandatory, mark refreshToken as required in the contract (keep
login(email, password): Promise<{ user, token, refreshToken, expiresIn }> and
refreshToken(oldToken): Promise<{ token, refreshToken, expiresIn }>) and update
acceptance criteria to require refresh token behavior and tests; if choosing
optional, remove refreshToken from the login/refreshToken signatures (or mark
them nullable/optional) and update acceptance criteria, notes and tests to state
refresh token is out of scope for MVP; ensure the doc references (functions
login, logout, validateToken, refreshToken, trackFailedAttempt, lockAccount) and
the acceptance criteria, technical notes and tests are all updated to match the
chosen posture.
Descripción
🎯 Qué cambia
Este PR introduce la documentación completa del producto y arquitectura técnica de KinderTrack:
Documentación de Producto:
prd.md): Product Requirements Document con valor agregado, funcionalidades MVP y visión futurause-cases.md): 5 casos de uso principales con roles, flujos y dependenciasuser-stories.md): 14 historias de usuario con criterios de aceptación, priorizadas en 3 niveles (Crítica: 8, Alta: 4, Media: 2)Documentación Técnica:
arquitectura.md): Diseño DDD con mono-repo, estructura de proyecto Backend (Node.js/TypeScript) y Frontend (Flutter Web), infraestructura con Supabasedata-model.md): Entidades principales (Child, ClassRoom, User, Attendance, Incident) con atributos, relaciones y diagrama ERapi-kindertrack.yaml): Especificación OpenAPI 3.0 con 40+ endpoints para autenticación, usuarios, asistencias, incidentes y reportesuser-stories-tech.md): Análisis arquitectónico detallado de las 14 user stories con código de ejemplo en TypeScript/Dart, 50+ riesgos identificados con mitigaciones, y stack tecnológico completoTickets de Implementación:
Buenas Prácticas:
💡 Por qué
Necesidad de documentación estructurada:
Facilitar la planificación:
🔍 Impacto
Positivo:
Archivos del PR:
Checklist del PR
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.