lumnik. / scenarios All scenarios · Français

NestJS: a ticket deleted mid-read no longer costs its neighbour

Goal Read every ticket of a NestJS service through its API, even while the support team works in it.

A NestJS service on nestjs-paginate and 130 tickets, 97 of them open.

manifests/lab-docker-compose.yml
name: lumnik-scenario-nestjsservices:  tickets:    build: ../lab    ports: ["127.0.0.1:${NESTJS_PORT:-9350}:3000"]
manifests/10-tickets.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-nestjs-a  connector_type: rest-generic  scopes: [support]spec:  base_url: http://host.docker.internal:9350  endpoints:    - id: tickets      path: "/tickets?limit=50"      method: GET      pagination: { kind: nestjs }                    # follows $.links.next, reads $.data      target:        kind: hybrid        table: ext.scenario_nestjs_a        unique_key: $.id        promote:          - { name: subject, path: $.subject, type: text }          - { name: status, path: $.status, type: text }
manifests/20-open-tickets.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-nestjs-open-a  connector_type: rest-generic  scopes: [support]spec:  base_url: http://host.docker.internal:9350  endpoints:    - id: tickets      path: "/tickets?limit=50&filter.status=$eq:open"      method: GET      pagination: { kind: nestjs }                    # the next link keeps the filter      target:        kind: hybrid        table: ext.scenario_nestjs_open_a        unique_key: $.id        promote:          - { name: subject, path: $.subject, type: text }          - { name: status, path: $.status, type: text }
manifests/30-tickets-watched.yaml
apiVersion: connectors.lumnik.io/v1kind: Connectormetadata:  name: scenario-nestjs-watched-a  connector_type: rest-generic  scopes: [support]spec:  base_url: http://host.docker.internal:9350  default_rate_limit: 1/s                              # a gentle reader: thirteen pages take thirteen seconds  endpoints:    - id: tickets      path: "/tickets?limit=10"      method: GET      pagination: { kind: nestjs }                    # checks $.meta.totalItems on every page (#1794)      target:        kind: hybrid        table: ext.scenario_nestjs_watched_a        unique_key: $.id        promote:          - { name: subject, path: $.subject, type: text }          - { name: status, path: $.status, type: text }

Limits

  • A deleted ticket stays in the hub's table: a full read adds and updates, it does not erase.
  • The second read counts the rows read twice in IN; the upsert keeps one.
  • 130 fictional tickets, in the service's memory.

Support · tickets

The tickets live in the support service.

Every one must be read, through the API.

NestJS 11, nestjs-paginate, 130 tickets

The problem

The API hands the list out in pages.

  • Each page gives the link to the next.
  • Meanwhile, support works.

What is not changed

The service stays as it is.

  • Its API, as the team wrote it.
  • No module, no setting.

The trap

A deletion shifts the pages.

  • A ticket on page 1 disappears.
  • Another one lands on no page.

What had to be written

pagination: { kind: nestjs }

One line.

  • The next link is followed.
  • Each page's total is checked.
  • A 21-line connector.

A filter

Open tickets only.

  • The filter is written in the path.
  • Every next link keeps it: 97 read.

What was fixed

One gap found, one fix.

  • Before: Completed, a ticket missing.
  • Now: the list is read again (#1794).

Try it

The scenario replays locally.

Every step is published with its output.

This scenario runs on lumnik Open, free and open source.

Try lumnik Open →