Files
teamwallet/.superpowers/sdd/admin-user-management/task-1-report.md
2026-07-31 22:12:53 +02:00

3.6 KiB

Task 1 implementation report: backend directory contract and query

Files changed

  • myteamwallet_backend/src/users/dto/user-directory-query.dto.ts — page, limit, and optional search input validation.
  • myteamwallet_backend/src/users/dto/user-directory-response.dto.ts — explicit safe directory, admin, assignment, team, and reference response DTOs.
  • myteamwallet_backend/src/users/users.service.ts — scoped directory query, search, pagination, deduplication, and explicit entity-to-DTO mapping.
  • myteamwallet_backend/src/users/users.controller.ts — authenticated GET /api/v1/users/directory endpoint, declared before :id.
  • myteamwallet_backend/src/users/users.service.spec.ts — focused contract coverage.

RED test evidence

Command:

npm test -- users/users.service.spec.ts --runInBand

Result: failed as expected, 7/7 tests failed with TypeError: service.findDirectory is not a function. This proved the missing directory-query behavior before implementation.

GREEN verification

Commands and results:

npm test -- users/users.service.spec.ts --runInBand

Passed: 1 suite, 7 tests. Covers cross-team isolation, non-admin email/secret redaction, inactive visibility, admin visibility, deduplication before pagination, search, and pagination metadata.

.\node_modules\.bin\eslint.cmd src\users\users.service.ts src\users\users.controller.ts src\users\users.service.spec.ts src\users\dto\user-directory-query.dto.ts src\users\dto\user-directory-response.dto.ts --max-warnings=0

Passed with no warnings or errors.

npm run build

Passed: Nest build completed successfully.

git diff --check

Passed with no whitespace errors.

Design notes

  • findDirectory(requester, query) returns { data, page, limit, total, hasNextPage }.
  • A non-admin's shared-team set is derived from their active player assignments. Only users with an assignment in that set are included, and each returned assignment is filtered to that same set.
  • Inactive target users and inactive assignments remain visible when their team is shared.
  • Admins receive all non-deleted users and every linked player assignment. Their records extend the safe base summary with email and the existing { id, name } role shape.
  • The query maps selected DTO fields explicitly. It never serializes a User or Player entity, so passwords, hashes, social IDs, providers, and other authentication fields cannot leak through this endpoint.
  • User IDs are ordered before search/pagination for deterministic pages. Users are the primary result set, which guarantees deduplication before pagination even when they have multiple player assignments.

Self-review

  • Confirmed GET directory is registered before GET :id.
  • Confirmed non-admin searches only operate after visibility filtering and do not include email.
  • Confirmed admin search may include email and admin mapping includes role/status using the backend's existing { id, name } shapes.
  • Confirmed an admin with no player assignment is included and an unassigned non-admin is not exposed to other non-admins.
  • Confirmed assignment mapping includes team/team-role summary fields only, never its linked user entity.

Concerns

  • The service intentionally fetches the user and player directory sets and applies the authorization filter in memory. Task 2's planned foreign-key index work can support a future query-builder optimization without changing this safe response contract.
  • The repository-wide Jest suite has documented pre-existing placeholder dependency failures in the SDD ledger; this task verified its focused suite, lint, build, and whitespace check.