Chore/remove dead safe hash compare - #17
Closed
FranciscoPerezRamos wants to merge 117 commits into
Closed
FranciscoPerezRamos wants to merge 117 commits into
FranciscoPerezRamos wants to merge 117 commits into
Conversation
…guration for development
…nt deletion logic
…s for task recommendations
* feat: add badge query param, log enrichment, and community stats aggregation by area/interval/taskType * refactor: support query filters in project community stats endpoint * refactor: extract helpers and type communityStats return - Split AnalyticsDao.communityStats into buildCommunityStatsFilter, applyGeoRadiusFilter and buildCommunityStatsResult, with a JSDoc block documenting the method and where the query comes from. - Replace the Promise<any> return and the 'any' Mongo filter typings with the new CommunityStats/AreaStat/TaskTypeStat/IntervalStat interfaces and FilterQuery<CheckInDocument>. - Push the task-name filter down to Mongo (escaped, case-insensitive regex) instead of loading all project tasks and matching in memory. - Type AdminCheckinPage.items as CheckInDocument[] and drop the 'any' casts in CheckinService check-in enrichment.
Introduce TaskTypeValue (string | TaskType) and a getTaskTypeName helper to replace the loosely-typed any[] used during the task-type migration. The legacy string form is kept for retrocompatibility with existing projects that still store task types as bare names. Propagate the union through the DTO, builder, entity and schema, and centralize the legacy/object resolution in one helper. Add unit tests for the helper. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat: add task type description support with external link
… su sesion es infinita aunque exista un refresh de tokens
…ification engine (#56) Co-authored-by: Lucas Matwiejczuk <lucasmatwiejczuk@MacBook-Pro-de-Lucas.local>
…en saving badges (#57) * feat: replace bipartite matching with recursive DAG evaluation in gamification engine * fix(gamification): handle validation errors and auto-create templates when saving badges --------- Co-authored-by: Lucas Matwiejczuk <lucasmatwiejczuk@MacBook-Pro-de-Lucas.local>
… una medalla para poder mostrar en la UI
Ahora se guarda un expiresAt y mas data sobre porque se puse en faded una medalla
…tegies (#62) * docs: add badge fading documentation under adaptive gamification strategies * docs: add visual walkthrough and mobile UI examples to badge fading documentation
…nto docsify (#68) Add interactive Vanishing Badges simulator to docsify documentation with dedicated markdown page, iframe integration, sidebar navigation, and links from badge fading documentation.
Feature/badge fading
Refresh-token comparison now happens inside the Mongo query
({ _id: userId, refreshTokenHash: hash }) rather than in JS, so the
constant-time compare has had no caller since that refactor. Dead
code triggers a lint failure (no-unused-vars) on any PR against main.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
It introduces blocking issues (committed credentials, invalid npm dependency version, and a likely-broken Docker runtime CMD) that should be fixed before merge.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR significantly expands the backend with new admin capabilities (task/check-in/admin analytics), media storage support (S3/Garage), and authentication/session improvements (Google auth + refresh-token sessions), plus supporting infrastructure and documentation updates.
Changes:
- Adds S3-compatible storage module + Garage local dev setup, and extends check-ins to support imageRefs + multipart uploads + idempotency.
- Introduces badge-fading lifecycle support across gamification (schema/DAO/service/controller/engines) and normalizes strategy handling/validation.
- Adds admin-oriented endpoints (checkins listing/stats, analytics dashboard endpoints) and a lightweight
/healthprobe excluded from/v1.
File summaries
| File | Description |
|---|---|
| src/module/task/task.service.ts | Adds findForAdmin mapping tasks to JSON. |
| src/module/task/task.service.spec.ts | Tests findForAdmin. |
| src/module/task/task.controller.ts | Adds admin-only task listing endpoint. |
| src/module/task/task.controller.spec.ts | Tests new controller method wiring. |
| src/module/task/persistence/task.dao.ts | Refactors task mapping with project prefetch + null-safe lookups. |
| src/module/storage/storage.service.ts | New S3 client wrapper for upload/get. |
| src/module/storage/storage.service.spec.ts | Unit tests for storage service behavior. |
| src/module/storage/storage.module.ts | Registers storage controller/service. |
| src/module/storage/storage.controller.ts | Adds file retrieval endpoint. |
| src/module/storage/storage.controller.spec.ts | Tests streaming/not-found behavior. |
| src/module/project/project.service.ts | Adds badge status resolution, checkin fetching, strategy validation, task type migration support. |
| src/module/project/project.module.ts | Registers CheckIn model for ProjectService queries. |
| src/module/project/project.controller.ts | Sets ownerId from request user on create. |
| src/module/project/project.controller.spec.ts | Updates controller test for new signature. |
| src/module/project/project.builder.ts | Updates builder to use TaskTypeValue union. |
| src/module/project/project-service.spec.ts | Adds strategy validation tests + checkin model mocking. |
| src/module/project/persistence/project.schema.ts | Migrates taskTypes schema to Mixed union type. |
| src/module/project/entities/task-type.ts | Introduces TaskTypeValue union + display-name helper. |
| src/module/project/entities/task-type.spec.ts | Tests getTaskTypeName. |
| src/module/project/entities/project.ts | Updates Project entity taskTypes type. |
| src/module/project/dto/create-project.dto.ts | Adds BADGE_FADING strategy + leaderboardStrategy + TaskTypeValue typing. |
| src/module/health/health.module.ts | New health module. |
| src/module/health/health.controller.ts | Adds GET/HEAD /health (no-store) reachability probe. |
| src/module/health/health.controller.spec.ts | Tests health controller responses. |
| src/module/gamification/persistence/gamification.schema.ts | Adds badge lifecycle fields (status/fadedSince/expiresAt/fadeReason). |
| src/module/gamification/persistence/gamification-dao.service.ts | Adds lifecycle-aware badge status update + improves error handling + ensures gamification rows exist. |
| src/module/gamification/persistence/gamification-dao.service.spec.ts | Tests updateBadgeStatus behavior and error cases. |
| src/module/gamification/gamificationController.ts | Adds guarded PATCH route to update badge status with ParseEnumPipe. |
| src/module/gamification/gamificationController.spec.ts | Tests controller forwarding for status updates. |
| src/module/gamification/gamification.spec.ts | Tests service-side fading window parsing/validation. |
| src/module/gamification/gamification.service.ts | Adds badge status update path + fading window validation. |
| src/module/gamification/entities/gamification.entity.ts | Adds BadgeStatus + effective status derivation + awardable predicate + extends BadgeRule fields. |
| src/module/gamification/entities/gamification.entity.spec.ts | Tests effective status derivation and awardability. |
| src/module/gamification/entities/engine/recommendation/adaptive-recomendation-engine.spec.ts | Stabilizes test by controlling env var K. |
| src/module/gamification/entities/engine/gamification/gamification-strategy-factory.ts | Adds BADGE_FADING handling in engine factory. |
| src/module/gamification/entities/engine/gamification/gamification-strategy-factory.spec.ts | Tests factory routing for BADGE_FADING. |
| src/module/gamification/entities/engine/gamification/basic-points-engine.ts | Makes basic points engine assignable to BADGE_FADING. |
| src/module/gamification/entities/engine/gamification/basic-points-engine.spec.ts | Tests assignability for BADGE_FADING vs ELASTIC. |
| src/module/gamification/entities/engine/gamification/basic-badge-engine.ts | Adds fading-aware awarding + prerequisite DAG satisfaction logic + TaskTypeValue support. |
| src/module/gamification/entities/engine/gamification/basic-badge-engine.spec.ts | Extensive tests for fading windows and prerequisite satisfaction. |
| src/module/gamification/entities/engine/gamification/badge-first-leaderboard-engine.ts | Fixes assignability to use leaderboard strategy (not gamification strategy). |
| src/module/gamification/entities/engine/gamification/badge-first-leaderboard-engine.spec.ts | Updates tests to validate correct strategy routing. |
| src/module/gamification/dto/update-badge-status.dto.ts | Adds DTO for fading window body. |
| src/module/checkin/persistence/move.dao.ts | Adds query helpers for analytics/admin filtering. |
| src/module/checkin/persistence/CheckinMapper.ts | Maps imageRefs + legacy imageRef migration support. |
| src/module/checkin/persistence/CheckinMapper.spec.ts | Tests imageRefs + legacy imageRef migration mapping. |
| src/module/checkin/persistence/checkin.schema.ts | Adds imageRefs array to schema/constructor. |
| src/module/checkin/persistence/checkin.dao.ts | Adds admin query model, geo filtering, per-user stats aggregation, and new find helpers. |
| src/module/checkin/persistence/checkin.dao.spec.ts | Tests new admin query filtering/pagination/geo filtering and imageRefs mapping. |
| src/module/checkin/persistence/checkin-idempotency.schema.ts | Adds TTL-backed idempotency key collection. |
| src/module/checkin/persistence/checkin-idempotency.dao.ts | Adds DAO for recording/looking up idempotency keys with collision handling. |
| src/module/checkin/entities/game.entity.ts | Updates in-memory user list after points assignment to keep leaderboard build consistent. |
| src/module/checkin/entities/checkin.entity.ts | Adds imageRefs field to Checkin entity. |
| src/module/checkin/dto/create-checkin.dto.ts | Adds optional imageRefs to DTO. |
| src/module/checkin/dto/admin-checkin-query.dto.ts | Adds typed admin query DTO for checkin listing filters. |
| src/module/checkin/checkin.module.ts | Wires Storage + Idempotency DAO and schema into module. |
| src/module/checkin/checkin.controller.ts | Adds multipart upload handling + idempotency header + admin listing + my stats endpoint. |
| src/module/checkin/checkin.controller.spec.ts | Tests create/idempotency header behavior + admin listing wiring. |
| src/module/checkin/checkin.constants.ts | Centralizes upload/idempotency constants. |
| src/module/auth/users/UserMapper.ts | Maps new user fields (googleId, createdAt, refresh token fields, description) and ratings default. |
| src/module/auth/users/UserMapper.spec.ts | Updates tests for new mapped fields and googleId behavior. |
| src/module/auth/users/user.service.ts | Adds profile patching + refresh session helpers + googleId lookup. |
| src/module/auth/users/user.service.spec.ts | Tests updateProfile and googleId lookup delegation. |
| src/module/auth/users/user.schema.ts | Adds googleId index + createdAt/description + refresh session fields. |
| src/module/auth/users/user.entity.ts | Extends User entity with googleId/createdAt/refresh token legacy fields/description. |
| src/module/auth/users/user.entity.spec.ts | Updates tests for new entity fields. |
| src/module/auth/users/user.dao.ts | Adds googleId lookup + atomic refresh session helpers + fixes reset-token null handling. |
| src/module/auth/users/user.dao.spec.ts | Adds tests for googleId lookup and reset-token null case. |
| src/module/auth/users/user.controller.ts | Adds profile PATCH endpoint for self-editable fields. |
| src/module/auth/mail.templates.ts | Introduces reusable HTML email templates for verification/reset. |
| src/module/auth/mail.templates.spec.ts | Tests template rendering and email option builders. |
| src/module/auth/auth.service.ts | Adds refresh-token sessions (SHA-256), Google auth flow, structured mail sending/logging, refresh/logout endpoints logic. |
| src/module/auth/auth.module.ts | Aligns JWT expiry config with constants. |
| src/module/auth/auth.controller.ts | Adds Google auth, refresh, and logout endpoints. |
| src/module/auth/auth.controller.spec.ts | Tests new endpoints and updated login response shape. |
| src/module/auth/auth.constants.ts | Centralizes access/refresh TTLs and refresh token format/cap. |
| src/module/analytics/analytics.types.ts | Adds analytics response types. |
| src/module/analytics/analytics.service.ts | Adds service façade over analytics DAO queries. |
| src/module/analytics/analytics.module.ts | Wires analytics controller/service/DAO with required models. |
| src/module/analytics/analytics.controller.ts | Adds admin-only analytics endpoints. |
| src/main.ts | Excludes /health from /v1 prefix + installs Multer exception filter. |
| src/common/middleware/logger.middleware.ts | Adds HTTP status-based logging middleware. |
| src/common/filters/multer-exception.filter.ts | Normalizes Multer errors to clean HTTP responses. |
| src/app.module.ts | Registers new modules + applies logger middleware globally. |
| README.md | Updates local run steps + adds Google auth setup note. |
| package.json | Adds S3 SDK + switches bcrypt lib + adds multer types. |
| init-garage.sh | Adds Garage bootstrap script for local dev. |
| garage.toml | Adds Garage config file. |
| docs/README.md | Adds documentation landing page. |
| docs/mobile/workflows.md | Documents mobile check-in flow. |
| docs/mobile/ui-dissection.md | Adds detailed UI/architecture doc for check-in screen. |
| docs/mobile/technical-details.md | Documents mobile startup/network/auth flows. |
| docs/mobile/reference.md | Adds mobile dependency/reference summary. |
| docs/mobile/README.md | Adds mobile architecture overview. |
| docs/mobile/offline-sync.md | Documents offline sync/idempotency architecture. |
| docs/mobile/architecture.md | Documents feature-first/clean architecture layout. |
| docs/index.html | Adds docsify-based docs site entry point. |
| docs/gamification-badges.md | Adds gamification architecture doc page. |
| docs/deployment.md | Adds deployment/infrastructure documentation. |
| docs/analytics-queries.md | Adds analytics aggregation/query documentation. |
| docs/adaptive-gamification/simulator.md | Adds simulator documentation page. |
| docs/.nojekyll | Disables Jekyll processing for docs site. |
| docs/_sidebar.md | Adds docs navigation sidebar. |
| Dockerfile | Switches to multi-stage build + production runtime image. |
| docker-compose.yml | Adds Garage service + env wiring for local dev. |
| AGENTS.md | Adds unified agent guidance for the project. |
| .gitignore | Broadens env ignore rules + ignores agent scratch files. |
| .env.test | Removes committed test env file. |
Review details
- Files reviewed: 113/126 changed files
- Comments generated: 9
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+40
to
+41
| # Comando de inicio: ejecuta el archivo principal compilado | ||
| CMD ["node", "dist/src/main"] |
Comment on lines
+6
to
+8
| rpc_bind_addr = "0.0.0.0:3901" | ||
| rpc_secret = "f0f1352d3244af9b9d8d596df6945f81e0d8e2d94128cff373310c70c8264511" | ||
|
|
Comment on lines
+18
to
+20
| [admin] | ||
| api_bind_addr = "0.0.0.0:3903" | ||
| admin_token = "GK565f128362694b2605389657" |
Comment on lines
+21
to
+22
| # Import key (matching .env defaults) | ||
| docker exec garage /garage key import GKeb4b3ddceb7b51753a68f6ea 65cbf335e26752e15e0d3d88c3479d273b7355af1e8102007e7b27e4a0475150 -n rayuela --yes |
Comment on lines
+30
to
+34
| static toEntity(template: any, user: User): Checkin { | ||
| // Handle migration from imageRef to imageRefs | ||
| let imageRefs = template.imageRefs || []; | ||
| if (imageRefs.length === 0 && template.imageRef) { | ||
| imageRefs = [template.imageRef]; |
Comment on lines
+26
to
+28
| export function getTaskTypeName(value: TaskTypeValue): string { | ||
| return typeof value === 'string' ? value : value?.name; | ||
| } |
Comment on lines
38
to
43
| const tasks: TaskDocument[] = await this.taskModel | ||
| .find({ projectId }) | ||
| .exec(); | ||
| if (!tasks) { | ||
| throw new NotFoundException('No tasks found for this project'); | ||
| } |
Comment on lines
20
to
24
| "test:e2e": "jest --config ./test/jest-e2e.json" | ||
| }, | ||
| "dependencies": { | ||
| "@aws-sdk/client-s3": "^3.999.0", | ||
| "@nestjs-modules/mailer": "^2.0.2", |
Comment on lines
90
to
93
| private mapTimeRestriction( | ||
| timeIntervalId: string, | ||
| project: Project, | ||
| ): TimeInterval { |
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.
safeHashCompare quedó huérfana tras el refactor que movió la comparación del refresh token a la query de Mongo ({ _id: userId, refreshTokenHash: hash } en user.dao.ts). Ya no hay ningún caller.
El unused-var que dispara safeHashCompare (y su import de timingSafeEqual) rompe npm run lint en cualquier PR contra main, porque el script lintea todo el árbol ({src,apps,libs,test}/**/*.ts), no solo lo que cada PR toca.
Este PR no tiene relación con ningún feature en curso — es limpieza de código muerto para desbloquear CI