Files
psp_api/Agents.md
T
ahasani 62b659246f feat: implement Redis caching for business activities and consumers
- Added Redis caching to BusinessActivitiesService for findAll and findOne methods.
- Integrated Redis caching in BusinessActivityComplexesService for findAll and findOne methods.
- Enhanced ConsumersService with Redis caching for findAll and findOne methods.
- Introduced cache invalidation for partner consumers and business activities.
- Created RedisKeyMaker utility for generating cache keys for consumers, partners, and POS.
- Implemented cache invalidation services for partners and POS.
- Added Redis service methods for JSON handling and key deletion by patterns.
- Updated goods service to include caching and invalidation for goods list.
- Introduced DTO for updating goods.
2026-05-19 15:40:45 +03:30

8.5 KiB

AGENT.md

Operational guide for AI/coding agents working in consumer_api.

Scope

  • Applies to the whole repository.
  • Stack: NestJS + Prisma + TypeScript.

Primary Goals

  • Deliver minimal, safe, and focused changes.
  • Preserve existing API behavior unless explicitly requested.
  • Keep Prisma schema/data operations forward-safe.

Project Conventions

  • Keep module layering consistent: controller -> service -> prisma/shared service.
  • Reuse shared services for cross-module business logic (for example, sales invoice create flow).
  • Keep DTO validation at API boundaries; avoid unchecked any in new code.
  • Keep response shaping aligned with existing ResponseMapper usage.
  • Prefer explicit Prisma select/include to control payload shape.

Sales Invoice / TSP Rules

  • originalSend, correctionSend, and revoke flows should be consistent and auditable.
  • For correction/revoke creation, prepare data from the related invoice when required.
  • Persist attempt records with clear status transitions (QUEUED -> final status).
  • Store request/response payloads for traceability.
  • Avoid changing fiscal/tax status semantics without explicit approval.

Prisma and Migration Safety

  • Treat committed migrations as immutable history.
  • Prefer forward migrations; avoid destructive resets unless explicitly requested.
  • For data-affecting changes:
    • use transactions,
    • verify expected row scope,
    • keep logic idempotent where possible.

Editing Principles

  • Do not modify unrelated files.
  • Do not revert user changes unless asked.
  • Keep functions cohesive; extract shared logic when duplication appears.
  • Remove debug leftovers (console.log, dead code) before finishing unless explicitly needed.

Validation Checklist (before handoff)

  1. Read target module/service/DTO end-to-end before edits.
  2. Apply minimal patch with consistent naming.
  3. Run typecheck: pnpm -s tsc --noEmit.
  4. If behavior changed, run targeted checks/tests where possible.
  5. Summarize changed files and behavior impact clearly.

Useful Commands

  • Typecheck: pnpm -s tsc --noEmit
  • Migration status: pnpm prisma migrate status
  • Create migration: pnpm prisma migrate dev --name <name>
  • Deploy migrations: pnpm prisma migrate deploy

Communication Style

  • Be concise and implementation-focused.
  • Call out assumptions/risk before risky steps.
  • Provide practical next actions after task completion.

Do / Don't (Repo-Specific)

Do

  • Do derive correction/revoke invoice creation data from relatedInvoice when the flow requires historical consistency.
  • Do keep TSP attempt lifecycle explicit (QUEUED, then update with provider result and timestamps).
  • Do use shared invoice-creation service instead of duplicating create logic across modules.
  • Do normalize numeric DB values (Decimal) with Number(...) before DTO/payload composition.
  • Do keep Prisma queries tight with select/include only for fields you actually use.

Don't

  • Don't pass undefined/out-of-scope variables in TSP flows (common regressions: invoice_id, attemptId, pos_id mismatches).
  • Don't leave placeholder query blocks (for example empty select: {}) in production code.
  • Don't mix method semantics (send vs originalSend) across services without verifying signatures.
  • Don't leave debug logs (console.log) in critical invoice/tax paths unless explicitly requested.
  • Don't change invoice type semantics (ORIGINAL, CORRECTION, REVOKE) implicitly.

Common Pitfalls To Recheck

  • Incorrect relation field names (tax_id on wrong model, missing relation selects).
  • Building payloads from the wrong invoice (must match the expected new/ref invoice in each flow).
  • Creating attempts without persisting request payload and final response payload.
  • Mismatch between DTO shapes and shared service input contracts.

Thread Notes (May 2026)

  • Shared sale-invoice creation was introduced and must be injected/exported correctly in consuming modules (example failure: UnknownDependenciesException for SharedSaleInvoiceCreateService).
  • In SalesInvoiceTspService.revoke, prepare all creation/update data from relatedInvoice (no external dataToUpdate argument expected).
  • Prisma client is generated to src/generated/prisma via:
    • provider = "prisma-client"
    • output = "../../src/generated/prisma"
    • moduleFormat = "cjs"
  • Docker/runtime must include generated Prisma artifacts and @prisma/client runtime; missing @prisma/client/runtime/client indicates build/copy/install mismatch.
  • Seeder commands that use tsx require dev dependencies/runtime tools; if running in slim production container, use a dedicated seed target/container or run seed from build/dev image.
  • pnpm invocation in containers should use executable form (pnpm ...), not node /app/pnpm.
  • Added SQL/Prisma error normalization utility: src/common/utils/prisma-error.util.ts; prefer mapping duplicate/constraint DB errors to domain-friendly messages.
  • Partner-module list endpoints were standardized toward ResponseMapper.paginate where pagination response contract is expected.
  • For heavy license provisioning (100+), request path should not synchronously insert all licenses; queue/background + batching is required.

Migration Drift Playbook (Prisma/MySQL)

  • If Prisma reports modified after applied, never edit an already-applied migration in-place for shared environments; create a new forward migration instead.
  • If migration history and DB drift mismatch:
    1. Verify local migration folders are complete and ordered.
    2. Check _prisma_migrations for missing/applied names.
    3. Use prisma migrate resolve only to reconcile history state, then apply a forward fix migration.
  • Duplicate FK error seen in this repo: sales_invoices_ref_id_fkey (MySQL 1826). Recheck migration SQL for repeated ADD CONSTRAINT statements before rerun.
  • Drift that repeatedly showed in this project: missing FK/unique on sale_invoice_tsp_attempts.invoice_id. Validate both schema and migration SQL produce the same final state.
  • prisma migrate status may show up-to-date while migrate dev still detects drift (shadow DB/application history issue); treat migrate dev output as source of truth for fixing local history.

Redis Cache Conventions (May 2026)

  • Use RedisKeyMaker in src/common/utils/redis-key-maker.util.ts for all cache keys and wildcard patterns; do not inline key strings in services.
  • Keep invalidation domain-based (for example src/modules/admin/guilds/cache/*, src/modules/admin/partners/cache/*, src/modules/pos/cache/*) and avoid duplicating delete logic across modules.
  • For list APIs that are expensive or frequently read, prefer read-through cache with TTL and invalidation on every related write path.
  • For entity endpoints, use list + detail split:
    • list key(s): invalidated broadly on writes,
    • detail key(s): invalidated per entity id.
  • Partner domain rules:
    • Shared partner cache namespace is partners:* (not admin-prefixed) because writes occur in both admin/partners and partners modules.
    • Use shared invalidation service src/modules/partners/cache/partners-cache-invalidation.service.ts from both admin and partner write paths.
    • Invalidate partners:list and partners:{id}:detail on partner create/update/delete and license-affecting writes.
    • Invalidate partner license caches (activated-licenses list, charge-transactions list/detail) via the shared invalidation service.
  • POS goods rules:
    • Cache key shape is BA + guild scoped (pos:ba:{businessActivityId}:guild:{guildId}:goods:list) because results combine guild-default and BA-owned goods.
    • Invalidate POS goods cache by guild when admin guild goods/category/sku changes.
    • Invalidate POS goods cache by business activity when consumer BA goods create/update/delete.
  • Consumer/Partner hierarchy rules:
    • Consumer profile cache key: consumers:{consumerId}:info.
    • Partner-consumer profile cache key: partners:{partnerId}:consumers:{consumerId}:info.
    • On partner-consumer single read, write both keys when practical to share warm cache across modules.
    • On consumer info update or partner-consumer update, invalidate both consumer and partner-consumer profile keys.
    • For business activities, invalidate both list and detail layers; child updates may invalidate parent single cache when parent aggregates depend on child state.
  • Wildcard invalidation implementation:
    • Use RedisService.deleteByPattern / RedisService.deleteByPatterns for all pattern deletes.
    • Do not implement ad-hoc scan/delete loops inside domain services.
    • Pattern deletion uses SCAN + pipelined DEL; multi-pattern deletes run in parallel.