Skip to content

Give the Slack agent a Postgres analytics warehouse and finish its Sentry lab - #11

Merged
sergical merged 3 commits into
mainfrom
slack-agent-analytics-warehouse
Oct 2, 2026
Merged

sergical merged 3 commits into
mainfrom
slack-agent-analytics-warehouse

Conversation

@sergical

@sergical sergical commented Oct 2, 2026

Copy link
Copy Markdown
Member

Lab 4 now runs on a plain Node Slack bot with a seeded Postgres analytics warehouse. Each warehouse query is one analytics.scan span tagged with the metric, the range length, and the row count. Prompts and replies are recorded in channels only, never in a direct message. The eve framework and tsx are removed. The lab doc, runsheet, prompt sheet, and solution patch match the new code.

Checks: npm run typecheck and npm test (14 tests) in apps/slack-agent pass.

Created with Claude Code

sergical and others added 3 commits September 24, 2026 14:47
instrument.ts turns gen AI inputs and outputs off for the whole app.
agent.ts sets telemetry.recordInputs and recordOutputs per call, and
app.ts passes true for a channel mention and false for a DM. The root
span carries slack.channel_type so the trace shows why content is
missing. In Sentry 11.0.0 a per-call boolean beats the dataCollection
default, so the DM path never records the conversation.

Co-authored-by: Claude <[email protected]>
…ntry lab

The bot now answers metric questions from a seeded Postgres table through
one analytics.scan span per warehouse query, tagged with the metric, the
range length, and the row count. The eve framework and tsx are gone; the
process starts with node --import ./src/instrument.ts. Lab 4, the runsheet,
the prompt sheet, and the solution patch follow the new shape.

Co-authored-by: Claude <[email protected]>
@sergical
sergical merged commit 591687d into main Oct 2, 2026
9 of 10 checks passed
@sergical
sergical deleted the slack-agent-analytics-warehouse branch October 2, 2026 19:31

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 5 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3b6dd15. Configure here.

// Prompts and replies are off by default for this app; src/agent.ts turns
// them on per call when the message is in a channel.
dataCollection: { genAI: { inputs: false, outputs: 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.

Lab solutions already in starting apps

High Severity

Lab 2 and Lab 4 still ask students to add Sentry to apps that have none, and ./scripts/solution.sh applies a patch on that basis, but this change already lands the full instrumentation in apps/slack-agent and apps/storefront. The instrument-by-prompt step is a no-op, and git apply --check on the solution patches fails.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3b6dd15. Configure here.

openrouter: { cacheControl: { type: "ephemeral" } },
};

const TODAY = new Date().toISOString().slice(0, 10);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Prompt date disagrees with validation

Medium Severity

SYSTEM_PROMPT sets today's date from toISOString() (UTC), while validateQuery and db:seed use the host's local calendar day. After UTC midnight, the model treats tomorrow as today and warehouse queries that end on that date are rejected as after today.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3b6dd15. Configure here.

throw new AnalyticsQueryError(
`The range ${from} to ${to} is ${rangeDays} days, outside the 90-day retention window.`,
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Old lookback ranges are not rejected

Medium Severity

validateQuery only rejects a span longer than 90 days. A range that starts before the warehouse (for example the previous 90 days when comparing a full window) still succeeds and returns empty rows, so the assistant reports zeros instead of the lookback error the system prompt describes.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3b6dd15. Configure here.

const previousPoints = previousDates.map((date, i) => ({
date,
value: output.series.previous[i] ?? 0,
}));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Comparison charts shift values by index

Medium Severity

compare_periods returns only value arrays from dates that have rows, and comparePeriodsBlocks then pairs those values with every calendar day in the range by index. A missing day at the start of the window slides later values onto the wrong dates and pads the end with zeros.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3b6dd15. Configure here.

rowCount: rows.length,
total: total(rows, unit),
rows: rows.slice(0, 200),
groupTotals: groupBy ? groupTotalsOf(rows, groupBy, unit) : undefined,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Grouped charts use truncated rows

Medium Severity

query_metric keeps full groupTotals but returns only the first 200 rows. Grouped charts in queryMetricBlocks series from that truncated rows list, so a 90-day breakdown by plan, platform, country, or path plots only the earliest days while the card title still names the full range.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3b6dd15. Configure here.

@linear-code

linear-code Bot commented Oct 5, 2026

Copy link
Copy Markdown

MAR-1676

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.

1 participant