Files
psp_api/Agents.md
T
ahasani 9aa12184a1 refactor: streamline Redis caching logic across services
- Implemented a unified `getAndSet` method in RedisService to handle caching for single, list, and paginated responses.
- Removed redundant cache checks and writes in various services, simplifying the code and improving readability.
- Updated GoodsService, StockKeepingUnitsService, PartnerActivatedLicensesService, and others to utilize the new caching mechanism.
- Adjusted Prisma connection limit for better resource management.
2026-05-21 17:27:37 +03:30

11 KiB

GapCode Agent Instructions

AGENTS.md

Operational guide for AI/coding agents working in consumer_api.


RTK LOW-TOKEN EXECUTION POLICY (MANDATORY)

This repository uses RTK (Rust Token Killer).

All shell interactions MUST prefer RTK wrappers to reduce token usage.

If an RTK equivalent exists, never use the raw command.

This repository can be large; uncontrolled shell output will quickly exhaust model context.


COMMAND REWRITE RULES (STRICT)

Always rewrite commands using RTK:

git status → rtk git status git diff → rtk git diff git log → rtk git log ls → rtk ls tree → rtk ls cat → rtk read grep → rtk grep rg → rtk grep find → rtk find

Never run:

  • raw git commands for inspection
  • raw cat
  • raw grep
  • raw ls
  • raw tree

📂 CODE NAVIGATION WORKFLOW (MANDATORY)

When working in this repository follow this order:

1️⃣ Discover structure

rtk ls

2️⃣ Search before opening files

rtk grep <symbol | class | function | DTO | service>

3️⃣ Read only the necessary files

rtk read

4️⃣ For large files (>300 lines)

rtk read -l aggressive

5️⃣ For quick understanding

rtk smart

Never open many files blindly.

Never read entire modules without searching first.


🧠 DIFF INSPECTION RULES

For reviewing repository changes:

Use:

rtk git diff

For large diffs:

rtk git diff -l aggressive

Never run raw git diff.


📁 FORBIDDEN PATHS

Never inspect or read these directories unless explicitly required:

node_modules/ dist/ build/ coverage/ .prisma/ prisma/migrations/

These folders produce extremely large outputs and waste tokens.


📄 FILE READING POLICY

Preferred:

rtk read file.ts

Large file:

rtk read file.ts -l aggressive

Quick overview:

rtk smart file.ts

Never use cat for source code inspection.


🔎 SEARCH POLICY

Always search before opening files.

Use:

rtk grep

Avoid raw recursive searches.


🎯 TOKEN SAFETY RULES

  • Never scan the entire repository.
  • Never dump full logs.
  • Never output entire large files.
  • Prefer targeted inspection.

Token preservation is mandatory for this project.


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.