Skip to content

feat(core): implement ADR-010 reporting as an admin operation#628

Merged
d-klotz merged 4 commits into
nextfrom
claude/reporting-operations-plan-5b607f
Jul 17, 2026
Merged

feat(core): implement ADR-010 reporting as an admin operation#628
d-klotz merged 4 commits into
nextfrom
claude/reporting-operations-plan-5b607f

Conversation

@d-klotz

@d-klotz d-klotz commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Treat reporting as a sibling of the Admin Script Runner (ADR-005) on shared primitives, replacing PR #607's standalone reporting silo. Reports register via reports: [] in the app definition (plus admin.includeBuiltinReports for core built-ins), extend ReportBase, and run through the same runner, admin API key, async/SQS execution, and EventBridge scheduling as admin scripts.

Run modes: live (compute inline, persist nothing), recorded (persist an execution record), snapshot (recorded run tagged into a named series). All three use the isolated AdminScriptExecution store (type: 'REPORT', no user/ integration FK), so a user-scoped query can never return a report record.

Highlights:

  • ReportBase + built-in integrations report (PR feat(reporting): read-only integrations reporting API in core #607 aggregation preserved, schemaVersion 1) reading via the admin command bundle, not a repository.
  • Fold the retired reporting repository triad into the canonical integration / integration-mapping repositories (findAllForReport, countByIntegrationIds); hoist the DocumentDB cursor-drain into documentdb-utils (findManyDrained / aggregateDrained) so deployment-wide scans never truncate at the first batch.
  • report-commands (type:'REPORT', guarded findExecutionById, findSnapshotSeries), report-runner, report-router (live + async + snapshots + executions + schedule), report-executor-handler, bootstrap wiring with a script/report name-collision guard.
  • devtools AdminScriptBuilder: dedicated ReportQueue + report executor Lambda, report router, artifact bucket + scheduler resources gated on reports; remove the always-on standalone reporting function.
  • Artifact storage (S3 + signed URL, private + SSE) for non-JSON report output.
  • Credential-refresh generic (countActiveByType) reading only a non-secret projection — never decrypts credential secrets.

Retire the silo: delete reporting-router, reporting/repositories/*, use-cases/list-integrations-report, handlers/routers/reporting; collapse the dedicated reporting API key into the admin API key.

Reviewed across three adversarial passes; confirmed findings fixed (artifact dev-stage selection, DocumentDB truncation, execution-record compensation on enqueue/requeue failure).

NOTE: adds @aws-sdk/client-s3 and @aws-sdk/s3-request-presigner to packages/core/package.json — package-lock.json must be regenerated with the repo's canonical npm 10 before merge (do not commit an npm 11 lockfile).

Treat reporting as a sibling of the Admin Script Runner (ADR-005) on shared
primitives, replacing PR #607's standalone reporting silo. Reports register via
`reports: []` in the app definition (plus `admin.includeBuiltinReports` for
core built-ins), extend `ReportBase`, and run through the same runner, admin API
key, async/SQS execution, and EventBridge scheduling as admin scripts.

Run modes: live (compute inline, persist nothing), recorded (persist an
execution record), snapshot (recorded run tagged into a named series). All three
use the isolated `AdminScriptExecution` store (type: 'REPORT', no user/
integration FK), so a user-scoped query can never return a report record.

Highlights:
- ReportBase + built-in `integrations` report (PR #607 aggregation preserved,
  schemaVersion 1) reading via the admin command bundle, not a repository.
- Fold the retired reporting repository triad into the canonical integration /
  integration-mapping repositories (findAllForReport, countByIntegrationIds);
  hoist the DocumentDB cursor-drain into documentdb-utils (findManyDrained /
  aggregateDrained) so deployment-wide scans never truncate at the first batch.
- report-commands (type:'REPORT', guarded findExecutionById, findSnapshotSeries),
  report-runner, report-router (live + async + snapshots + executions + schedule),
  report-executor-handler, bootstrap wiring with a script/report name-collision
  guard.
- devtools AdminScriptBuilder: dedicated ReportQueue + report executor Lambda,
  report router, artifact bucket + scheduler resources gated on reports; remove
  the always-on standalone reporting function.
- Artifact storage (S3 + signed URL, private + SSE) for non-JSON report output.
- Credential-refresh generic (countActiveByType) reading only a non-secret
  projection — never decrypts credential secrets.

Retire the silo: delete reporting-router, reporting/repositories/*,
use-cases/list-integrations-report, handlers/routers/reporting; collapse the
dedicated reporting API key into the admin API key.

Reviewed across three adversarial passes; confirmed findings fixed (artifact
dev-stage selection, DocumentDB truncation, execution-record compensation on
enqueue/requeue failure).

NOTE: adds @aws-sdk/client-s3 and @aws-sdk/s3-request-presigner to
packages/core/package.json — package-lock.json must be regenerated with the
repo's canonical npm 10 before merge (do not commit an npm 11 lockfile).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

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

Claude Code Review

Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.

Tip: disable this comment in your organization's Code Review settings.

@d-klotz d-klotz added the release Create a release when this pr is merged label Jul 15, 2026
Add a Reports (ADR-010) section to the frigg skill covering the reports registry,
ReportBase, run modes (live/recorded/snapshot), endpoints, artifact output, and
scheduling, with two examples: a snapshot+scheduled JSON report reading via the
frigg command bundle, and a recorded CSV report writing to artifact storage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@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: 5477c3a6aa

ℹ️ 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".

router.post('/:name/run', async (req, res) => {
try {
const { name } = req.params;
const { mode = 'live', params = {} } = req.body || {};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor report-defined default modes

When callers omit mode, this forces every report through live instead of using the report's declared default (Definition.runModes[0], which ReportRunner already implements). For reports that default to snapshot/recorded or do not support live, POST /api/v2/reports/:name/run without a mode now either fails with INVALID_MODE or runs inline when the report author intended an async recorded run.

Useful? React with 👍 / 👎.

Comment on lines +393 to +394
mode,
input: params,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Validate async runs before enqueueing

For recorded/snapshot requests this path creates a persisted execution and sends an SQS message without first checking that the requested mode and params satisfy the report definition. A request such as mode: "recorded" with invalid input, or mode: "bogus", receives 202 QUEUED and only later becomes a failed execution, unlike live runs and admin scripts which fail fast with 400; validate against the report definition before createExecution.

Useful? React with 👍 / 👎.

@d-klotz

d-klotz commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

🤖 Generated with Claude Code

…isolation)

Follow-up to ADR-010 reporting, resolving verified code-review findings:

- Artifact retrieval: report execution + snapshot reads now mint a signed
  download URL (report-commands) so stored non-JSON artifacts are reachable
  via the API; snapshot artifactUrl is a real URL, not the raw storage ref.
- Async run validation: recorded/snapshot runs validate mode + inputSchema
  before persisting/enqueueing, returning 400 up front instead of a 202 that
  fails later in the worker.
- Isolation: admin-script findExecutionById now rejects REPORT rows,
  symmetric with report findExecutionById rejecting non-REPORT rows.
- Report stays protocol-agnostic: integrations-report throws a coded
  INVALID_INPUT error instead of Boom (no HTTP in the application layer).
- Add zip artifact content type; remove orphan findMany import; correct the
  local artifact adapter comment.
- Docs: clarify that a Definition-declared schedule only supplies the default
  mode; the recurring trigger is activated via PUT /:name/schedule.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

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

Claude Code Review

Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.

Tip: disable this comment in your organization's Code Review settings.

…unwrap helper

Reduce PR-added code comments across the reporting stack so the code speaks
for itself (~700 -> ~290 comment lines), keeping only non-obvious "why":
invariants, ordering/consistency reasons, and gotchas. Removed route-path
JSDoc banners, architecture-tag headers, and param/flow restatements.
Comment-only changes; no runtime behavior altered.

Also drop the unwrap() helper in integrations-report: read commands directly
so the report body reads plainly. A failed read still fails the report (the
runner records FAILED), just without unwrap's synthesized message.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

💡 Need a hand with PR review? Try Gitar by Sonar!

@d-klotz
d-klotz merged commit 9652cae into next Jul 17, 2026
5 of 8 checks passed
@d-klotz
d-klotz deleted the claude/reporting-operations-plan-5b607f branch July 17, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release Create a release when this pr is merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant