Repository navigation
Add admin-only community activity visibility - #794
Conversation
📝 WalkthroughWalkthroughAdds role-gated admin activity listings for public community forks and ratings, metadata-only subscription events, durable queue processing with retry handling, and production Cloudflare queue provisioning. Documentation defines the privacy boundary, event payload, storage rules, and operational configuration. ChangesCommunity activity projection
Admin capability and privacy boundary
Activity events and subscription dispatch
Queue infrastructure
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
…munity-activity-9b86 # Conflicts: # packages/worker/worker-configuration.d.ts
|
🔎 Preview deployed: https://kody-pr-794.kody-a99.workers.dev Worker: Mocks:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
packages/worker/src/community/activity-subscription-event.ts (1)
64-68: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueImprove runtime error message formatting for object types.
When handling an unexpected
activitykind at runtime,String(exhaustive)will output[object Object], making debugging difficult. Consider usingJSON.stringifyto capture the actual object contents.♻️ Proposed refactor
default: { const exhaustive: never = input.activity - throw new Error(`Unsupported community activity: ${String(exhaustive)}`) + throw new Error(`Unsupported community activity: ${JSON.stringify(exhaustive)}`) }🤖 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/worker/src/community/activity-subscription-event.ts` around lines 64 - 68, Update the default branch of the activity handling switch to serialize unexpected object-valued activities with JSON.stringify instead of String(exhaustive), preserving the existing “Unsupported community activity” context and exhaustive type check.packages/worker/src/community/service.ts (1)
111-125: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAdd correlation context to the swallowed enqueue failure.
console.error('community-activity-dispatch-enqueue-failed', error)doesn't includekind/activityId, so a failed dispatch can't be traced back to which fork/rating never got a queued admin notification.♻️ Proposed fix
} catch (error) { - console.error('community-activity-dispatch-enqueue-failed', error) + console.error('community-activity-dispatch-enqueue-failed', { + kind: input.kind, + activityId: input.activityId, + error, + }) }🤖 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/worker/src/community/service.ts` around lines 111 - 125, Update enqueueRecordedCommunityActivity so its failure log includes the relevant correlation context, specifically input.kind and input.activityId, alongside the existing error while preserving the current swallowed-error behavior.packages/worker/src/mcp/capabilities/admin-community-activity.node.test.ts (1)
39-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winExclusion assertions don't actually exercise the privacy filter.
The mocked service result never includes
note/user_id/package_sourceto begin with, andformatCommunityActivityonly ever whitelists specific fields (no spread), soresult.activity[0]).not.toHaveProperty(...)at Lines 93-95 will pass regardless of whether the filtering logic is correct. To make this a meaningful regression guard, include those sensitive-looking fields in the mocked record and assert they're stripped from the formatted output. Also consider adding akind: 'fork'case, since only theratingbranch is currently exercised.♻️ Suggested strengthening of the mock/assertions
mocks.listCommunityActivityForAdmin.mockResolvedValue({ total: 3, page: 2, pageSize: 2, items: [ { id: 'rating-1', kind: 'rating', listingId: 'listing-1', listingName: '`@owner/package`', listingKodyId: 'package', actingUsername: 'rater', occurredAt: '2026-07-20T01:00:00.000Z', stars: 5, adaptationEffort: 2, + note: 'private rating note', + userId: 'rater-user-id', + packageSource: 'private source blob', }, ], })Also applies to: 93-95
🤖 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/worker/src/mcp/capabilities/admin-community-activity.node.test.ts` around lines 39 - 56, Strengthen the tests around formatCommunityActivity by adding note, user_id, and package_source to the mocked activity record, then assert those fields are absent from result.activity[0] after formatting. Add a separate kind: 'fork' fixture or case so the fork-specific formatting branch is exercised, while preserving the existing rating assertions.
🤖 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/worker/src/community/repo.ts`:
- Around line 181-211: Update communityActivityUnion’s fork activity query to
preserve fork events after their listing is deleted: replace the
community_listings INNER JOIN with a LEFT JOIN and provide appropriate
placeholders for missing listing fields, or ensure deleteCommunityListing
removes associated community_forks rows if fork history should not survive.
---
Nitpick comments:
In `@packages/worker/src/community/activity-subscription-event.ts`:
- Around line 64-68: Update the default branch of the activity handling switch
to serialize unexpected object-valued activities with JSON.stringify instead of
String(exhaustive), preserving the existing “Unsupported community activity”
context and exhaustive type check.
In `@packages/worker/src/community/service.ts`:
- Around line 111-125: Update enqueueRecordedCommunityActivity so its failure
log includes the relevant correlation context, specifically input.kind and
input.activityId, alongside the existing error while preserving the current
swallowed-error behavior.
In `@packages/worker/src/mcp/capabilities/admin-community-activity.node.test.ts`:
- Around line 39-56: Strengthen the tests around formatCommunityActivity by
adding note, user_id, and package_source to the mocked activity record, then
assert those fields are absent from result.activity[0] after formatting. Add a
separate kind: 'fork' fixture or case so the fork-specific formatting branch is
exercised, while preserving the existing rating assertions.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f5df1425-85ff-4f44-913d-2a49249604bb
📒 Files selected for processing (37)
docs/contributing/adding-capabilities.mddocs/contributing/architecture/authorization.mddocs/contributing/architecture/data-storage.mddocs/contributing/architecture/primitives.yamldocs/contributing/community-packages.mddocs/contributing/packages-and-manifests.mddocs/contributing/project-intent.mddocs/contributing/setup-manifest.mddocs/guides/package-subscriptions.mddocs/use/privacy.mdpackages/worker/client/routes/privacy.tsxpackages/worker/src/community/activity-dispatch-queue-names.tspackages/worker/src/community/activity-dispatch-queue-producer.tspackages/worker/src/community/activity-dispatch-queue.node.test.tspackages/worker/src/community/activity-dispatch-queue.tspackages/worker/src/community/activity-package-subscriptions.node.test.tspackages/worker/src/community/activity-package-subscriptions.tspackages/worker/src/community/activity-subscription-event.tspackages/worker/src/community/community-activity-service.node.test.tspackages/worker/src/community/community-flow-test-schema.tspackages/worker/src/community/community-flow.workers.test.tspackages/worker/src/community/community-service.node.test.tspackages/worker/src/community/errors.tspackages/worker/src/community/repo.tspackages/worker/src/community/service.tspackages/worker/src/community/types.tspackages/worker/src/mcp/capabilities/admin-community-activity.node.test.tspackages/worker/src/mcp/capabilities/admin/admin-community-activity-list.tspackages/worker/src/mcp/capabilities/admin/domain.tspackages/worker/src/mcp/capabilities/packages/list-package-subscriptions.tspackages/worker/src/queue-handler.node.test.tspackages/worker/src/queue-handler.tspackages/worker/worker-configuration.d.tspackages/worker/wrangler.jsonctools/ci/production-queue-resources.node.test.tstools/ci/production-queue-resources.tstools/ci/production-resources.ts
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 82f80b1. Configure here.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/worker/migrations/0068-community-fork-listing-snapshots.sql (1)
4-15: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winPrefer
UPDATE ... FROMhere. SQLite/D1 supports join-updates, so this can replace the two correlated subqueries and avoid per-row repetition.🤖 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/worker/migrations/0068-community-fork-listing-snapshots.sql` around lines 4 - 15, Rewrite the community_forks update using SQLite/D1’s UPDATE ... FROM join syntax, joining community_listings to community_forks via listing_id. Set both listing_name and listing_kody_id from the joined community_listings row, and remove the two correlated subqueries.
🤖 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.
Nitpick comments:
In `@packages/worker/migrations/0068-community-fork-listing-snapshots.sql`:
- Around line 4-15: Rewrite the community_forks update using SQLite/D1’s UPDATE
... FROM join syntax, joining community_listings to community_forks via
listing_id. Set both listing_name and listing_kody_id from the joined
community_listings row, and remove the two correlated subqueries.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 260411e5-1650-4452-89f1-ea82676c39d8
📒 Files selected for processing (14)
docs/contributing/architecture/authorization.mddocs/contributing/architecture/data-storage.mddocs/contributing/architecture/primitives.yamldocs/contributing/community-packages.mddocs/contributing/setup-manifest.mdpackages/worker/migrations/0068-community-fork-listing-snapshots.sqlpackages/worker/src/community/community-activity-service.node.test.tspackages/worker/src/community/community-flow-test-schema.tspackages/worker/src/community/community-service.node.test.tspackages/worker/src/community/repo.tspackages/worker/src/community/service.tspackages/worker/src/community/types.tspackages/worker/worker-configuration.d.tspackages/worker/wrangler.jsonc
🚧 Files skipped from review as they are similar to previous changes (11)
- docs/contributing/architecture/primitives.yaml
- packages/worker/worker-configuration.d.ts
- packages/worker/wrangler.jsonc
- docs/contributing/setup-manifest.md
- docs/contributing/architecture/data-storage.md
- packages/worker/src/community/types.ts
- docs/contributing/architecture/authorization.md
- packages/worker/src/community/community-service.node.test.ts
- docs/contributing/community-packages.md
- packages/worker/src/community/service.ts
- packages/worker/src/community/repo.ts
…munity-activity-9b86 # Conflicts: # docs/contributing/community-packages.md # docs/use/privacy.md # packages/worker/src/community/community-flow.workers.test.ts

Summary
admin_community_activity_list, a paginated admin-role-gated feed for fork and rating metadatacommunity.activity.recordedevents only to admin-owned package subscriptionsAuthorization boundary
This is a narrow, documented exception to per-user isolation: admins receive activity metadata only—public listing id/name/kody id, acting username, timestamp, and rating scores. The capability and event omit package source, forked package/source ids, target ids, rating notes, email, stable user ids, secrets, private profiles, and unrelated account content. Execute-time capability access requires the
adminrole, and subscription fan-out reloads admin ownership for every Queue attempt.The existing schema does not distinguish one-click installs from ordinary forks; both persist a
community_forksrow and are reported asfork. The exception is linked to the documented boundaries in project intent, authorization, and data storage.Migration decisions
0070-community-fork-listing-snapshots.sqlrebuildscommunity_forks, backfills listing name/kody id, and works whether preview state already has the snapshot columns or production starts from the original schema.Fork-count verification
The aggregate SQL already counts
community_forkscorrectly for every listing materialized by detail/search/browse loaders. The production mismatch is consistent with a snapshot/cache artifact, so this PR does not change aggregate logic; it adds real-SQL and Worker-flow regression assertions.Verification
✅ Validatepassed🔎 Deploy Preview Resourcespassednpm run primitives:classifyandnpm run primitives:checkpassedSystem recap — adds a new primitive (high risk)
Mode: recap · Base:
main@a270fcc· Head:b648fa6Classification: adds — introduces a dedicated durable community-activity dispatch Queue; extends community listing persistence/metadata reads and the role-gated admin capability contract.
Primitives touched
community-activity-dispatch-queuecommunity-listingsd1-app-dbrbaccapability-registryadmin_community_activity_listsaved-packagesapp-uiplatform-feedback-dispatch-queueSystem map
Fork and rating writes persist in D1, enqueue opaque activity identifiers, and fan out a metadata-only event to freshly authorized admin package owners.
Legend: green = composes (wiring only) · amber = extended by this PR · red = new primitive · gray = context (unchanged, included only when an edge crosses it).
Before / after
community.activity.recordeddeliveryfork; no invented install classificationInvariants
Summary by CodeRabbit