pr-lens

Draw code changes as animated architecture/data-flow SVGs.

  • diagrams
  • pull-requests
  • code-review
  • svg

Declared platforms: linux · macos

Install
npx skills add 'https://github.com/NousResearch/hermes-agent/tree/main/optional-skills/software-development/pr-lens'
Download bundle ↓
main · 24fd22bScanned 2026-09-15

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗

references/example.graph.json

references/example.graph.jsonBrowse 5 files
View on GitHub
← Back to SKILL.md
{  "schemaVersion": "0.1.1",  "kind": "graph",  "generatedAt": "2026-08-19T18:24:00.000Z",  "title": "Batch broadcast sending through Postmark",  "summary": "Broadcast delivery moves from one Postmark request per recipient to batched requests of 500, with suppression filtering pulled in front of the send and the payload builder extracted into a shared library.",  "lenses": [    "architecture",    "data-flow"  ],  "provenance": {    "repo": {      "owner": "ohansemmanuel",      "name": "bestregards",      "host": "github.com"    },    "base": {      "sha": "3f5c1ab9d24e7f08c6b1a5d3e9074c2b8a6f1d40",      "ref": "main"    },    "head": {      "sha": "b71e0d4c8a92f5361de7c0b4a8f2593d6c1e8a77",      "ref": "batch-broadcast-send"    },    "pullRequest": {      "number": 128,      "title": "Send broadcasts in batches of 500",      "url": "https://github.com/ohansemmanuel/bestregards/pull/128"    },    "generator": {      "name": "pr-lens-examples",      "version": "0.1.0"    }  },  "lanes": [    {      "id": "web",      "label": "Next.js",      "subtitle": "Vercel",      "order": 0    },    {      "id": "functions",      "label": "Cloud Functions",      "subtitle": "Firebase",      "order": 1    },    {      "id": "external",      "label": "External",      "subtitle": "Postmark",      "order": 2    }  ],  "nodes": [    {      "id": "broadcast-composer",      "label": "Broadcast composer",      "kind": "ui",      "delta": "unchanged",      "lane": "web",      "subtitle": "app/broadcasts/new",      "summary": "Where an author writes a broadcast and hits send. Untouched by this change.",      "files": [        {          "path": "app/broadcasts/new/page.tsx"        }      ],      "badges": []    },    {      "id": "queue-route",      "label": "POST /api/broadcasts/queue",      "kind": "route",      "delta": "modified",      "lane": "web",      "summary": "Writes the queue document. Now stamps the recipient count and batch size the sender will use instead of leaving batching to the worker.",      "files": [        {          "path": "app/api/broadcasts/queue/route.ts",          "startLine": 24,          "endLine": 96        }      ],      "badges": [        "+38 / -12"      ]    },    {      "id": "broadcast-queue",      "label": "broadcastQueue",      "kind": "datastore",      "delta": "modified",      "lane": "functions",      "subtitle": "Firestore collection",      "summary": "Queue documents gained batchSize and suppressedCount fields, and results are now written back per batch rather than per recipient.",      "files": [        {          "path": "functions/src/broadcast/schema.ts",          "startLine": 12,          "endLine": 48        }      ],      "badges": []    },    {      "id": "send-broadcast-bulk",      "label": "sendBroadcastBulk",      "kind": "function",      "delta": "added",      "lane": "functions",      "subtitle": "onWrite trigger",      "summary": "New trigger handler. Fetches suppressions once, builds batched payloads, and posts them to Postmark in chunks of 500.",      "files": [        {          "path": "functions/src/broadcast/sendBroadcastBulk.ts",          "startLine": 1,          "endLine": 142        }      ],      "badges": [        "new"      ]    },    {      "id": "build-bulk-payload",      "label": "buildBulkPayload",      "kind": "function",      "delta": "added",      "lane": "functions",      "summary": "Turns a broadcast and its recipient slice into a Postmark batch request body.",      "files": [        {          "path": "packages/broadcast-lib/src/buildBulkPayload.ts",          "startLine": 1,          "endLine": 74        }      ],      "badges": []    },    {      "id": "get-suppressed-emails",      "label": "getSuppressedEmails",      "kind": "function",      "delta": "added",      "lane": "functions",      "summary": "Pulls the Postmark suppression dump once per broadcast so suppressed addresses are filtered before any batch is sent.",      "files": [        {          "path": "packages/broadcast-lib/src/getSuppressedEmails.ts",          "startLine": 1,          "endLine": 58        }      ],      "badges": []    },    {      "id": "broadcast-lib",      "label": "broadcast-lib",      "kind": "package",      "delta": "added",      "lane": "functions",      "subtitle": "packages/broadcast-lib",      "summary": "New shared package so the queue route and the sender agree on payload shape and batch size.",      "files": [        {          "path": "packages/broadcast-lib/src/index.ts"        }      ],      "badges": [        "new package"      ]    },    {      "id": "process-broadcast",      "label": "processBroadcast",      "kind": "function",      "delta": "removed",      "lane": "functions",      "subtitle": "onWrite trigger",      "summary": "The per-recipient loop this change replaces.",      "files": [        {          "path": "functions/src/broadcast/processBroadcast.ts",          "startLine": 1,          "endLine": 118,          "revision": "base"        }      ],      "badges": []    },    {      "id": "send-single-email",      "label": "sendSingleEmail",      "kind": "function",      "delta": "removed",      "lane": "functions",      "summary": "One Postmark request per recipient. Gone with the loop that called it.",      "files": [        {          "path": "functions/src/broadcast/sendSingleEmail.ts",          "startLine": 1,          "endLine": 46,          "revision": "base"        }      ],      "badges": []    },    {      "id": "postmark",      "label": "Postmark",      "kind": "external",      "delta": "modified",      "lane": "external",      "subtitle": "Email API",      "summary": "Same provider, different endpoints: the batch endpoint and the suppression dump replace repeated single sends.",      "files": [],      "badges": []    }  ],  "edges": [    {      "id": "composer-to-queue",      "from": "broadcast-composer",      "to": "queue-route",      "kind": "http",      "delta": "unchanged",      "label": "send broadcast",      "emphasis": "normal",      "animated": false,      "files": []    },    {      "id": "queue-to-firestore",      "from": "queue-route",      "to": "broadcast-queue",      "kind": "data",      "delta": "modified",      "label": "enqueue job",      "emphasis": "normal",      "animated": false,      "files": []    },    {      "id": "queue-to-lib",      "from": "queue-route",      "to": "broadcast-lib",      "kind": "dependency",      "delta": "added",      "label": "batch size",      "emphasis": "normal",      "animated": false,      "files": []    },    {      "id": "firestore-to-bulk",      "from": "broadcast-queue",      "to": "send-broadcast-bulk",      "kind": "event",      "delta": "added",      "label": "onWrite",      "emphasis": "normal",      "animated": false,      "files": []    },    {      "id": "firestore-to-process",      "from": "broadcast-queue",      "to": "process-broadcast",      "kind": "event",      "delta": "removed",      "label": "onWrite",      "emphasis": "normal",      "animated": false,      "files": []    },    {      "id": "process-to-single",      "from": "process-broadcast",      "to": "send-single-email",      "kind": "call",      "delta": "removed",      "label": "per recipient",      "emphasis": "normal",      "animated": false,      "files": []    },    {      "id": "single-to-postmark",      "from": "send-single-email",      "to": "postmark",      "kind": "http",      "delta": "removed",      "label": "POST /email · 1 msg/call",      "emphasis": "normal",      "animated": false,      "files": []    },    {      "id": "bulk-to-payload",      "from": "send-broadcast-bulk",      "to": "build-bulk-payload",      "kind": "call",      "delta": "added",      "emphasis": "normal",      "animated": false,      "files": []    },    {      "id": "bulk-to-suppressions",      "from": "send-broadcast-bulk",      "to": "get-suppressed-emails",      "kind": "call",      "delta": "added",      "emphasis": "normal",      "animated": false,      "files": []    },    {      "id": "bulk-to-lib",      "from": "send-broadcast-bulk",      "to": "broadcast-lib",      "kind": "dependency",      "delta": "added",      "emphasis": "normal",      "animated": false,      "files": []    },    {      "id": "suppressions-to-postmark",      "from": "get-suppressed-emails",      "to": "postmark",      "kind": "http",      "delta": "added",      "label": "GET suppression dump",      "emphasis": "normal",      "animated": true,      "files": []    },    {      "id": "bulk-to-postmark",      "from": "send-broadcast-bulk",      "to": "postmark",      "kind": "http",      "delta": "added",      "label": "500 msgs/call",      "emphasis": "hero",      "animated": true,      "summary": "The change in one edge: a broadcast to 10,000 recipients drops from 10,000 requests to 20.",      "files": []    },    {      "id": "bulk-to-firestore",      "from": "send-broadcast-bulk",      "to": "broadcast-queue",      "kind": "data",      "delta": "added",      "label": "write results",      "emphasis": "normal",      "animated": false,      "files": []    }  ],  "flows": [    {      "id": "send-pipeline",      "title": "Sending a broadcast",      "summary": "The path a queued broadcast takes now, from enqueue to per-message results.",      "delta": "modified",      "participants": [        {          "node": "queue-route",          "label": "queue route"        },        {          "node": "broadcast-queue",          "label": "Firestore"        },        {          "node": "send-broadcast-bulk",          "label": "sendBroadcastBulk"        },        {          "node": "postmark",          "label": "Postmark"        }      ],      "messages": [        {          "id": "enqueue",          "from": "queue-route",          "to": "broadcast-queue",          "label": "enqueue broadcast job",          "kind": "async",          "delta": "modified",          "animated": true,          "files": []        },        {          "id": "trigger",          "from": "broadcast-queue",          "to": "send-broadcast-bulk",          "label": "onWrite trigger",          "kind": "async",          "delta": "added",          "animated": true,          "files": []        },        {          "id": "suppressions-request",          "from": "send-broadcast-bulk",          "to": "postmark",          "label": "GET suppression dump",          "kind": "sync",          "delta": "added",          "animated": true,          "files": []        },        {          "id": "suppressions-response",          "from": "postmark",          "to": "send-broadcast-bulk",          "label": "suppressed addresses",          "kind": "return",          "delta": "added",          "animated": true,          "note": "Fetched once per broadcast, not once per recipient.",          "files": []        },        {          "id": "batch-post",          "from": "send-broadcast-bulk",          "to": "postmark",          "label": "POST /email/batch · 500 msgs",          "kind": "sync",          "delta": "added",          "animated": true,          "repeat": 4,          "note": "One request per 500 recipients; four for this 2,000-recipient broadcast.",          "files": []        },        {          "id": "batch-results",          "from": "postmark",          "to": "send-broadcast-bulk",          "label": "per-message results",          "kind": "return",          "delta": "added",          "animated": true,          "files": []        },        {          "id": "write-results",          "from": "send-broadcast-bulk",          "to": "broadcast-queue",          "label": "write results",          "kind": "async",          "delta": "added",          "animated": true,          "files": []        }      ]    }  ],  "stats": {    "filesChanged": 14,    "additions": 486,    "deletions": 212,    "chips": [      {        "label": "Postmark calls",        "value": "500× fewer",        "tone": "hero"      },      {        "label": "New",        "value": "4 units",        "tone": "added"      },      {        "label": "Retired",        "value": "2 units",        "tone": "removed"      }    ]  },  "views": [    {      "id": "overview",      "title": "Architecture — blast radius",      "lens": "architecture",      "summary": "Everything this change touches, across all three lanes.",      "scope": {        "kind": "all"      },      "defaultOpen": true,      "children": [        {          "id": "new-batch-path",          "title": "The new batch path",          "lens": "architecture",          "summary": "What replaced the per-recipient loop.",          "scope": {            "kind": "selection",            "lanes": [],            "nodes": [              "send-broadcast-bulk",              "build-bulk-payload",              "get-suppressed-emails",              "broadcast-lib",              "postmark"            ],            "edges": [              "bulk-to-payload",              "bulk-to-suppressions",              "bulk-to-lib",              "suppressions-to-postmark",              "bulk-to-postmark",              "bulk-to-firestore"            ],            "flows": []          },          "defaultOpen": false,          "children": []        },        {          "id": "retired-path",          "title": "What was retired",          "lens": "architecture",          "summary": "The single-send path, kept visible so a reviewer can confirm nothing else called it.",          "scope": {            "kind": "selection",            "lanes": [],            "nodes": [              "process-broadcast",              "send-single-email"            ],            "edges": [              "firestore-to-process",              "process-to-single",              "single-to-postmark"            ],            "flows": []          },          "defaultOpen": false,          "children": []        }      ]    },    {      "id": "send-pipeline-view",      "title": "Data flow — sending a broadcast",      "lens": "data-flow",      "scope": {        "kind": "selection",        "lanes": [],        "nodes": [],        "edges": [],        "flows": [          "send-pipeline"        ]      },      "defaultOpen": false,      "children": []    }  ],  "walkthrough": {    "steps": [      {        "id": "batches-of-500",        "heading": "sendBroadcastBulk and buildBulkPayload added",        "body": "Nothing loops over recipients any more. The sender works on a whole batch at a time.",        "stage": {          "kind": "view",          "view": "overview"        },        "focus": {          "kind": "selection",          "lanes": [],          "nodes": [            "send-broadcast-bulk",            "build-bulk-payload",            "postmark"          ],          "edges": [],          "messages": []        }      },      {        "id": "suppression-first",        "heading": "getSuppressedEmails added before the send",        "body": "It pulls the blocked addresses once, before any batch is built.",        "stage": {          "kind": "view",          "view": "new-batch-path"        },        "focus": {          "kind": "selection",          "lanes": [],          "nodes": [            "get-suppressed-emails",            "postmark"          ],          "edges": [],          "messages": []        }      },      {        "id": "old-path-goes-dark",        "heading": "processBroadcast and sendSingleEmail removed",        "body": "sendBroadcastBulk does their job for whole batches.",        "stage": {          "kind": "view",          "view": "overview"        },        "focus": {          "kind": "selection",          "lanes": [],          "nodes": [            "process-broadcast",            "send-single-email"          ],          "edges": [],          "messages": []        }      },      {        "id": "sequence-start-to-finish",        "heading": "The send sequence gained 6 new steps",        "body": "The queue write is the only step that was there before, and it now stamps the batch size.",        "stage": {          "kind": "flow",          "flow": "send-pipeline"        },        "focus": {          "kind": "all"        }      },      {        "id": "four-batch-calls",        "heading": "Postmark now gets 500 emails per call",        "body": "One call per batch, and Postmark answers with a result for each message.",        "stage": {          "kind": "flow",          "flow": "send-pipeline"        },        "focus": {          "kind": "selection",          "lanes": [],          "nodes": [],          "edges": [],          "messages": [            "batch-post",            "batch-results"          ]        }      },      {        "id": "blast-radius",        "heading": "4 parts added, 2 removed, across 3 lanes",        "body": "A 2,000-person broadcast used to make 2,000 calls to Postmark. It now makes 4.",        "stage": {          "kind": "view",          "view": "overview"        },        "focus": {          "kind": "all"        }      }    ]  },  "layout": {    "direction": "right",    "laneOrder": [      "web",      "functions",      "external"    ],    "rank": {      "queue-route": 0,      "send-broadcast-bulk": 1,      "postmark": 2    }  }} 
Referenced from SKILL.md