62b659246f
- 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.
8.5 KiB
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
anyin new code. - Keep response shaping aligned with existing
ResponseMapperusage. - Prefer explicit Prisma
select/includeto control payload shape.
Sales Invoice / TSP Rules
originalSend,correctionSend, andrevokeflows 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)
- Read target module/service/DTO end-to-end before edits.
- Apply minimal patch with consistent naming.
- Run typecheck:
pnpm -s tsc --noEmit. - If behavior changed, run targeted checks/tests where possible.
- 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
relatedInvoicewhen 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) withNumber(...)before DTO/payload composition. - Do keep Prisma queries tight with
select/includeonly for fields you actually use.
Don't
- Don't pass undefined/out-of-scope variables in TSP flows (common regressions:
invoice_id,attemptId,pos_idmismatches). - Don't leave placeholder query blocks (for example empty
select: {}) in production code. - Don't mix method semantics (
sendvsoriginalSend) 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_idon 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:
UnknownDependenciesExceptionforSharedSaleInvoiceCreateService). - In
SalesInvoiceTspService.revoke, prepare all creation/update data fromrelatedInvoice(no externaldataToUpdateargument expected). - Prisma client is generated to
src/generated/prismavia:provider = "prisma-client"output = "../../src/generated/prisma"moduleFormat = "cjs"
- Docker/runtime must include generated Prisma artifacts and
@prisma/clientruntime; missing@prisma/client/runtime/clientindicates build/copy/install mismatch. - Seeder commands that use
tsxrequire dev dependencies/runtime tools; if running in slim production container, use a dedicated seed target/container or run seed from build/dev image. pnpminvocation in containers should use executable form (pnpm ...), notnode /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.paginatewhere 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:
- Verify local migration folders are complete and ordered.
- Check
_prisma_migrationsfor missing/applied names. - Use
prisma migrate resolveonly 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 repeatedADD CONSTRAINTstatements 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 statusmay show up-to-date whilemigrate devstill detects drift (shadow DB/application history issue); treatmigrate devoutput as source of truth for fixing local history.
Redis Cache Conventions (May 2026)
- Use
RedisKeyMakerinsrc/common/utils/redis-key-maker.util.tsfor 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 bothadmin/partnersandpartnersmodules. - Use shared invalidation service
src/modules/partners/cache/partners-cache-invalidation.service.tsfrom both admin and partner write paths. - Invalidate
partners:listandpartners:{id}:detailon partner create/update/delete and license-affecting writes. - Invalidate partner license caches (activated-licenses list, charge-transactions list/detail) via the shared invalidation service.
- Shared partner cache namespace is
- 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.
- Cache key shape is BA + guild scoped (
- 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.
- Consumer profile cache key:
- Wildcard invalidation implementation:
- Use
RedisService.deleteByPattern/RedisService.deleteByPatternsfor all pattern deletes. - Do not implement ad-hoc scan/delete loops inside domain services.
- Pattern deletion uses
SCAN+ pipelinedDEL; multi-pattern deletes run in parallel.
- Use