Skip to content

feat(posthog): add relayfile adapter - #255

Merged
khaliqgant merged 7 commits into
mainfrom
agent/posthog-adapter
Jul 26, 2026
Merged

feat(posthog): add relayfile adapter#255
khaliqgant merged 7 commits into
mainfrom
agent/posthog-adapter

Conversation

@kjgbot

@kjgbot kjgbot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

What changed

  • add a new @relayfile/adapter-posthog package
  • implement PostHog layout prompt, resource definitions, path mapping, auxiliary file emission, digest handling, webhook normalization, and sync bucketing
  • add PostHog webhook trigger metadata and regenerate the trigger catalog

Why

Cloud needs a real adapter package to materialize PostHog sync and webhook records into Relayfile. The trigger catalog updates are also required for webhook autocomplete and deploy-time lint coverage.

Validation

  • npm run build --workspace=packages/posthog
  • npm run build
  • node packages/core/dist/src/cli.js triggers generate --repo-root .
  • node packages/core/dist/src/cli.js triggers check --repo-root .

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kjgbot, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 45 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a0c4dbbe-cec1-429b-b2f6-44a02c6d514a

📥 Commits

Reviewing files that changed from the base of the PR and between e2eb72d and 04468ae.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • CHANGELOG.md
  • packages/posthog/package.json
  • packages/posthog/src/digest.test.ts
  • packages/posthog/src/emit-auxiliary-files.test.ts
  • packages/posthog/src/path-mapper.test.ts
  • packages/posthog/src/webhook-normalizer.test.ts
  • turbo.json
📝 Walkthrough

Walkthrough

Adds a new ECMAScript-module PostHog adapter with canonical paths, resource discovery, webhook normalization, digest classification, auxiliary index/alias emission, package exports, and build integration.

Changes

PostHog adapter contracts and package setup

Layer / File(s) Summary
Package, route, and public contracts
packages/posthog/package.json, packages/posthog/posthog.mapping.yaml, packages/posthog/src/types.ts, packages/posthog/src/index.ts, packages/posthog/tsconfig.json, turbo.json
Defines the adapter package, webhook routes, supported path types, public exports, compiler settings, generated resource-path validation, and build dependency wiring.

Path discovery and sync surfaces

Layer / File(s) Summary
Canonical paths and model bucketing
packages/posthog/src/path-mapper.ts, packages/posthog/src/sync-bucketing.ts, packages/posthog/src/path-mapper.test.ts
Maps PostHog objects to encoded entity, index, and alias paths and normalizes model names for sync buckets.
Resource discovery and layout
packages/posthog/src/read-only-resources.ts, packages/posthog/src/resources.ts, packages/posthog/src/layout-prompt.ts, packages/posthog/src/*test.ts
Defines resource path patterns, discovery metadata, path lookup, and the mounted PostHog layout prompt.

Webhook and digest processing

Layer / File(s) Summary
Webhook normalization
packages/posthog/src/webhook-normalizer.ts, packages/posthog/src/webhook-normalizer.test.ts
Extracts identifiers, state, timestamps, and canonical records from alert payloads and derives file events.
Digest identification and classification
packages/posthog/src/digest.ts
Creates PostHog digest entries with category-specific titles and terminal-state verbs.

Auxiliary file emission

Layer / File(s) Summary
Indexes, aliases, and deletion handling
packages/posthog/src/emit-auxiliary-files.ts, packages/posthog/src/emit-auxiliary-files.test.ts
Emits project and project-scoped indexes and aliases, handles deletions and alternate aliases, sorts index rows, bounds concurrent reads, and aggregates file-operation errors.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PostHogWebhook
  participant normalizePostHogWebhook
  participant computePostHogPath
  participant emitPostHogAuxiliaryFiles
  participant AuxiliaryEmitterClient
  PostHogWebhook->>normalizePostHogWebhook: alert payload
  normalizePostHogWebhook->>computePostHogPath: object type, object ID, project ID
  computePostHogPath-->>normalizePostHogWebhook: canonical JSON path
  normalizePostHogWebhook->>emitPostHogAuxiliaryFiles: normalized record and file event
  emitPostHogAuxiliaryFiles->>AuxiliaryEmitterClient: write indexes and aliases
Loading

Suggested labels: size:XL

Poem

I’m a rabbit with routes in a PostHog maze,
Indexes bloom in orderly arrays.
Webhooks hop, digest verbs ring,
Aliases hide where records sing.
With every build path neatly set,
My adapter is ready—no carrots unmet!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: adding a new PostHog Relayfile adapter package.
Description check ✅ Passed The description accurately describes the new PostHog adapter, trigger metadata updates, and validation steps.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/posthog-adapter

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@khaliqgant
khaliqgant marked this pull request as ready for review July 26, 2026 06:26

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 76b1d3c395

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/posthog/src/resources.ts Outdated
Comment on lines +11 to +14
export const resources = [
{
name: "projects",
path: "/posthog/projects/{projectId}.json",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not catalog unsupported PostHog writeback routes

These entries cause the generators to publish PostHog in WRITEBACK_PATH_CATALOG and expose posthogClient, but a repo-wide search finds no PostHog writeback resolver, no discovery/posthog/.adapter.md, and none of the referenced schemas or create examples. Consequently consumers are told these paths support mutations even though writes cannot be validated or translated into PostHog API calls; either implement the complete writeback contract or leave resources empty so the adapter is cataloged as read-only.

AGENTS.md reference: AGENTS.md:L210-L218

Useful? React with 👍 / 👎.

Comment on lines +24 to +25
const projectId = readString(payload.project_id) ?? readString(payload.projectId);
const objectId = readString(payload.id) ?? readString(payload.alert_id);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Accept numeric PostHog identifiers

PostHog project and resource IDs are commonly JSON numbers, but readString rejects them, so a normal alert payload with numeric project_id returns null here instead of producing an event. The auxiliary emitter has the same string-only assumption in readProjectId/readObjectId, causing numeric projects, dashboards, insights, flags, and similar records to be silently skipped during sync; normalize finite string/number IDs to strings before path construction.

AGENTS.md reference: AGENTS.md:L108-L108

Useful? React with 👍 / 👎.

Comment on lines +26 to +30
const eventType =
readString(payload.event_type) ??
readString(payload.eventType) ??
readString(payload.type) ??
"posthog.alert.triggered";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Derive the fallback event type from the alert state

When an accepted payload supplies state: "resolved" or status: "resolved" but omits an explicit event-type field, this fallback still emits posthog.alert.triggered; the later state normalization only changes fileEventType. Workflows subscribed to the declared resolved trigger therefore miss the resolution while triggered workflows run incorrectly, so select posthog.alert.resolved after normalizing the lifecycle state.

AGENTS.md reference: AGENTS.md:L21-L24

Useful? React with 👍 / 👎.

Comment thread packages/posthog/src/path-mapper.ts Outdated
Comment on lines +155 to +157
return `${POSTHOG_PATH_ROOT}/projects/${projectId}/${posthogAggregateCollection(
objectType,
)}/${id}.json`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Emit flat records with canonical slug-and-ID names

All project-scoped entities are emitted as bare <id>.json files even though these flat records have human-readable names or titles and no child artifacts. That conflicts with the workspace path contract requiring <slug>__<id>.json, leaving PostHog paths inconsistent with cross-adapter consumers; the mapper, templates, layout documentation, indexes, and aliases should use the canonical slug-and-ID filename together.

AGENTS.md reference: AGENTS.md:L94-L99

Useful? React with 👍 / 👎.

Comment thread packages/posthog/package.json Outdated
],
"scripts": {
"build": "tsc",
"test": "node --import tsx --test 'src/**/*.test.ts'",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the required PostHog contract tests

This test command currently discovers zero files because the new package contains no tests, so none of the path helpers have compose/parse round-trip coverage, none of the alias trees have collision coverage, and the LAYOUT.md emitter has no length or content assertions. The package test therefore passes while the adapter's required filesystem contracts remain entirely unverified.

AGENTS.md reference: AGENTS.md:L127-L132

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
packages/posthog/src/emit-auxiliary-files.ts (3)

354-379: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

groupByProject hardcodes "insight" regardless of the actual resource type.

groupByProject is used for every project-scoped resource (dashboards, feature flags, annotations, experiments, surveys, alert events) but always calls readProjectId(record, "insight") (Line 359). It's harmless today only because readProjectId's non-"project" branch is type-agnostic — but the hardcoded literal is misleading and becomes a silent bug the moment readProjectId gains per-type branching for a non-project type.

♻️ Thread the actual objectType through
-function groupByProject(
-  records: readonly PostHogRecord[],
-): Map<string, PostHogRecord[]> {
+function groupByProject(
+  records: readonly PostHogRecord[],
+  objectType: ProjectScopedObjectType,
+): Map<string, PostHogRecord[]> {
   const grouped = new Map<string, PostHogRecord[]>();
   for (const record of records) {
-    const projectId = readProjectId(record, "insight");
+    const projectId = readProjectId(record, objectType);
-  const grouped = groupByProject(records);
+  const grouped = groupByProject(records, objectType);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/posthog/src/emit-auxiliary-files.ts` around lines 354 - 379, Update
groupByProject to accept the actual PostHogPathObjectType and pass that
objectType to readProjectId instead of hardcoding "insight". Update every
groupByProject call site to provide its resource type, preserving the existing
grouping behavior for each project-scoped resource.

112-194: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy lift

Fully sequential per-record I/O in both emit loops.

emitProjects and emitProjectScopedCollection await a read + up to several writes/deletes for every record, one at a time, inside for...of loops. For larger PostHog workspaces (many insights/dashboards/feature flags) this serializes all network round-trips and will materially slow down each sync.

Since the Map mutations (rows.set/delete) are synchronous and independent per record, the inner loops are good candidates for controlled concurrency:

⚡ Example: bounded concurrency for the per-record loop
-    for (const record of projectRecords) {
-      const objectId = readObjectId(record, objectType);
-      ...
-    }
+    await runWithConcurrencyLimit(projectRecords, CONCURRENCY, async (record) => {
+      const objectId = readObjectId(record, objectType);
+      ...
+    });
Use a small limiter (e.g. `p-limit`) rather than unbounded `Promise.all` to avoid overwhelming the underlying client.

Also applies to: 196-352

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/posthog/src/emit-auxiliary-files.ts` around lines 112 - 194, Update
emitProjects and emitProjectScopedCollection to process records with bounded
concurrency using the repository’s limiter pattern (such as p-limit), rather
than awaiting each record sequentially in for...of loops. Keep each record’s
read, Map mutation, and related writes/deletes within one limited task, then
await completion of all tasks before writing the sorted index; preserve existing
per-record behavior and avoid unbounded Promise.all.

450-464: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

readUpdated falls back to the current timestamp when no date field exists.

For records lacking every known timestamp field, updated becomes new Date().toISOString() (Line 462), which skews the sort order in writeSortedIndex (records with no real timestamp always sort as "most recently updated") and changes every sync run even if nothing changed. Falling back to the previously stored row's updated value (from the existing index) instead of "now" would be more stable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/posthog/src/emit-auxiliary-files.ts` around lines 450 - 464, The
readUpdated fallback should not use the current timestamp for records without
date fields. Update readUpdated and its callers, including writeSortedIndex, to
reuse the record’s previously stored updated value from the existing index when
available, preserving stable sorting and sync output; only use a non-time
fallback when no prior value exists.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/posthog/posthog.mapping.yaml`:
- Around line 1-5: Add a scopeKeys declaration to the posthog mapping, setting
it to project_id to advertise and validate the supported project-level
connection scope for personas.

In `@packages/posthog/src/emit-auxiliary-files.ts`:
- Around line 120-121: Update the merge flow around readIndex and
writeSortedIndex so a missing or unavailable prior index cannot be treated as an
empty Map and overwrite existing rows; distinguish an absent prior state from a
genuinely empty index, then guard or fail the incremental write unless the
emitter is explicitly operating on a complete dataset.

In `@packages/posthog/src/path-mapper.ts`:
- Around line 46-104: Extend the path-mapper helpers beyond
posthogProjectByNameAliasPath to provide deterministic by-name paths for
dashboards, experiments, and surveys using their project-scoped collection,
slugifyAlias, aliasCollisionSuffix, and encoded name/suffix/project-ID format.
Update the alias emission and documentation for these resources so the new
by-name aliases are generated and described, while preserving existing ID-based
aliases and excluding resources without a natural human-readable key.

In `@packages/posthog/src/resources.ts`:
- Around line 11-84: Update the mapping configuration to define the canonical
PostHog mount templates under the appropriate resources or writebacks block,
then change the resources export to derive each { name, path } entry from those
mapping templates instead of hardcoding them. Preserve the existing resource
names and downstream metadata such as patterns and schema paths, while ensuring
routing uses the mapping-derived paths.

In `@packages/posthog/src/webhook-normalizer.ts`:
- Around line 48-59: Update the record construction in the webhook normalizer so
the raw payload is spread before the normalized fields. Ensure normalized id,
project_id, source, kind, title, occurred_at, event_type, state, and severity
values remain authoritative and cannot be overwritten by payload properties.

---

Nitpick comments:
In `@packages/posthog/src/emit-auxiliary-files.ts`:
- Around line 354-379: Update groupByProject to accept the actual
PostHogPathObjectType and pass that objectType to readProjectId instead of
hardcoding "insight". Update every groupByProject call site to provide its
resource type, preserving the existing grouping behavior for each project-scoped
resource.
- Around line 112-194: Update emitProjects and emitProjectScopedCollection to
process records with bounded concurrency using the repository’s limiter pattern
(such as p-limit), rather than awaiting each record sequentially in for...of
loops. Keep each record’s read, Map mutation, and related writes/deletes within
one limited task, then await completion of all tasks before writing the sorted
index; preserve existing per-record behavior and avoid unbounded Promise.all.
- Around line 450-464: The readUpdated fallback should not use the current
timestamp for records without date fields. Update readUpdated and its callers,
including writeSortedIndex, to reuse the record’s previously stored updated
value from the existing index when available, preserving stable sorting and sync
output; only use a non-time fallback when no prior value exists.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c1e6b9b7-87f8-40a9-85fa-bee760a855f1

📥 Commits

Reviewing files that changed from the base of the PR and between d5dcad5 and 76b1d3c.

⛔ Files ignored due to path filters (8)
  • package-lock.json is excluded by !**/package-lock.json
  • packages/core/src/scope-keys/adapters-without-known-scope-keys.generated.json is excluded by !**/*.generated.*
  • packages/core/src/scope-keys/catalog.generated.ts is excluded by !**/*.generated.*
  • packages/core/src/triggers/catalog.generated.json is excluded by !**/*.generated.*
  • packages/core/src/triggers/catalog.generated.ts is excluded by !**/*.generated.*
  • packages/core/src/writeback-paths/catalog.generated.json is excluded by !**/*.generated.*
  • packages/core/src/writeback-paths/catalog.generated.ts is excluded by !**/*.generated.*
  • packages/relay-helpers/src/generated/clients.ts is excluded by !**/generated/**
📒 Files selected for processing (13)
  • packages/posthog/package.json
  • packages/posthog/posthog.mapping.yaml
  • packages/posthog/src/digest.ts
  • packages/posthog/src/emit-auxiliary-files.ts
  • packages/posthog/src/index.ts
  • packages/posthog/src/layout-prompt.ts
  • packages/posthog/src/path-mapper.ts
  • packages/posthog/src/resources.ts
  • packages/posthog/src/sync-bucketing.ts
  • packages/posthog/src/types.ts
  • packages/posthog/src/webhook-normalizer.ts
  • packages/posthog/tsconfig.json
  • turbo.json

Comment thread packages/posthog/posthog.mapping.yaml
Comment thread packages/posthog/src/emit-auxiliary-files.ts Outdated
Comment thread packages/posthog/src/path-mapper.ts
Comment thread packages/posthog/src/resources.ts Outdated
Comment thread packages/posthog/src/webhook-normalizer.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/posthog/src/emit-auxiliary-files.test.ts`:
- Around line 65-72: Update the rows[0] expected object in the
emitProjectScopedCollection test to include both state and status properties
with undefined values, matching the keys emitted on project-local rows while
preserving the existing assertions.

In `@packages/posthog/src/path-mapper.test.ts`:
- Around line 61-79: Extend the “named aliases use deterministic collision
suffixes” test to cover the by-id, by-short-id, and by-key alias helpers,
asserting repeated inputs remain stable and distinct inputs produce distinct
paths with the expected collision suffix. If any subtree cannot collide by
design, document that provider-uniqueness exception instead of adding a test.

In `@packages/posthog/src/webhook-normalizer.test.ts`:
- Around line 19-20: Update the webhook normalization logic exercised by
normalized.eventType and normalized.fileEventType so posthog.alert.resolved maps
to the repository’s supported terminal lifecycle action and its corresponding
digest classification, not file.updated. Adjust the test assertions to verify
the terminal action and classification while preserving ordinary update behavior
for non-terminal events.
- Around line 44-50: Update the test case “explicit upstream event type remains
authoritative” to use a status that derives a conflicting event type, such as
“resolved,” while keeping the explicit event_type unchanged. Add assertions for
the expected resolved state and file semantics so the test verifies both
event-type precedence and the resulting normalized output.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: aa0deb2e-fba8-4bdb-991c-d9f025ad3c9c

📥 Commits

Reviewing files that changed from the base of the PR and between 76b1d3c and e2eb72d.

⛔ Files ignored due to path filters (6)
  • package-lock.json is excluded by !**/package-lock.json
  • packages/core/src/scope-keys/catalog.generated.json is excluded by !**/*.generated.*
  • packages/core/src/scope-keys/catalog.generated.ts is excluded by !**/*.generated.*
  • packages/core/src/writeback-paths/adapters-without-writeback-paths.generated.json is excluded by !**/*.generated.*
  • packages/core/src/writeback-paths/catalog.generated.ts is excluded by !**/*.generated.*
  • packages/posthog/src/resource-paths.generated.ts is excluded by !**/*.generated.*
📒 Files selected for processing (15)
  • CHANGELOG.md
  • packages/posthog/package.json
  • packages/posthog/posthog.mapping.yaml
  • packages/posthog/scripts/generate-resource-paths.mjs
  • packages/posthog/src/emit-auxiliary-files.test.ts
  • packages/posthog/src/emit-auxiliary-files.ts
  • packages/posthog/src/layout-prompt.test.ts
  • packages/posthog/src/layout-prompt.ts
  • packages/posthog/src/path-mapper.test.ts
  • packages/posthog/src/path-mapper.ts
  • packages/posthog/src/read-only-resources.ts
  • packages/posthog/src/resources.test.ts
  • packages/posthog/src/resources.ts
  • packages/posthog/src/webhook-normalizer.test.ts
  • packages/posthog/src/webhook-normalizer.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/posthog/posthog.mapping.yaml
  • packages/posthog/package.json
  • packages/posthog/src/webhook-normalizer.ts

Comment on lines +65 to +72
assert.deepEqual(rows[0], {
id: "73",
title: "Checkout funnel",
updated: "2026-07-25T08:10:00.000Z",
canonicalPath:
"/posthog/projects/17/dashboards/checkout-funnel__73.json",
archived: false,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
node -e "
const assert = require('node:assert/strict');
try {
  assert.deepEqual({ id: '73', archived: false }, { id: '73', state: undefined, archived: false });
  console.log('PASSED (objects considered equal)');
} catch (e) {
  console.log('FAILED:', e.message);
}
"

Repository: AgentWorkforce/relayfile-adapters

Length of output: 308


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file and relevant symbols =="
fd -a 'emit-auxiliary-files.*' . | sed 's#^\./##'
echo

echo "== test snippet =="
sed -n '45,80p' packages/posthog/src/emit-auxiliary-files.test.ts || true

echo
echo "== main emitter references =="
rg -n "emitProjectScopedCollection|rows\\[0\\]|state:\\s*readString|status:\\s*readString" packages/posthog/src -S

echo
echo "== implementation snippet around collection emitters =="
sed -n '320,365p' packages/posthog/src/emit-auxiliary-files.ts || true

Repository: AgentWorkforce/relayfile-adapters

Length of output: 7468


Include state/status in the project-local row assertion.

emitProjectScopedCollection writes state and status onto project rows, so rows[0] has those own keys with undefined values. assert.deepEqual compares object key sets, so the expected literal must include them.

🔧 Proposed fix
   assert.deepEqual(rows[0], {
     id: "73",
     title: "Checkout funnel",
     updated: "2026-07-25T08:10:00.000Z",
     canonicalPath:
       "/posthog/projects/17/dashboards/checkout-funnel__73.json",
+    state: undefined,
+    status: undefined,
     archived: false,
   });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
assert.deepEqual(rows[0], {
id: "73",
title: "Checkout funnel",
updated: "2026-07-25T08:10:00.000Z",
canonicalPath:
"/posthog/projects/17/dashboards/checkout-funnel__73.json",
archived: false,
});
assert.deepEqual(rows[0], {
id: "73",
title: "Checkout funnel",
updated: "2026-07-25T08:10:00.000Z",
canonicalPath:
"/posthog/projects/17/dashboards/checkout-funnel__73.json",
state: undefined,
status: undefined,
archived: false,
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/posthog/src/emit-auxiliary-files.test.ts` around lines 65 - 72,
Update the rows[0] expected object in the emitProjectScopedCollection test to
include both state and status properties with undefined values, matching the
keys emitted on project-local rows while preserving the existing assertions.

Comment thread packages/posthog/src/path-mapper.test.ts
Comment on lines +19 to +20
assert.equal(normalized.eventType, "posthog.alert.resolved");
assert.equal(normalized.fileEventType, "file.updated");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Do not encode resolved as file.updated.

This assertion locks in generic update semantics for a terminal PostHog state. Normalize resolved webhooks to the repository’s supported terminal lifecycle action and update the corresponding digest classification, rather than treating them as ordinary edits.

As per coding guidelines, terminal states such as resolved must not fall through to a generic updated line unless the provider has no terminal concept.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/posthog/src/webhook-normalizer.test.ts` around lines 19 - 20, Update
the webhook normalization logic exercised by normalized.eventType and
normalized.fileEventType so posthog.alert.resolved maps to the repository’s
supported terminal lifecycle action and its corresponding digest classification,
not file.updated. Adjust the test assertions to verify the terminal action and
classification while preserving ordinary update behavior for non-terminal
events.

Source: Coding guidelines

Comment thread packages/posthog/src/webhook-normalizer.test.ts
@khaliqgant
khaliqgant merged commit d87b2cc into main Jul 26, 2026
3 checks passed
@khaliqgant
khaliqgant deleted the agent/posthog-adapter branch July 26, 2026 10:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants