feat(events): expose personal RSVP (myRsvp) in events list; fix isHost - #58
Conversation
`events list` dropped the per-event `guest` object returned by the Partiful home-page endpoints, so a caller could not see their own RSVP. It also computed `isHost` from `config.userId`, which is undefined in most auth.json files, making `isHost` always false. Both stem from not resolving "who am I". Fix: - auth.js: add decodeJwtPayload() + getUserIdFromToken() to read the user id from the Firebase token (user_id, falling back to sub). Backfill config.userId on token refresh so it self-heals for older auth.json files. - events.js (lib): extract a pure, unit-testable mapEventSummary(e, me) that adds `myRsvp` (e.guest.status: GOING|MAYBE|DECLINED|SENT, null when hosting) and fixes `isHost` to check ownerIds against the resolved id. - events.js (command): resolve `me` from config.userId, falling back to decoding the token (covers the PARTIFUL_TOKEN env path), then map via the helper. Additive and backward-compatible: existing fields keep their names, order, and defaults. Verified against a live account (myRsvp populated across GOING/MAYBE/DECLINED/SENT; isHost true only for owned events). Docs: README JSON output example, partiful-events skill, AGENTS.md. Tests: 21 new unit tests (jwt-identity, map-event-summary); suite 106 -> 127. Closes #56
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 52 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds JWT payload decoding and user id extraction to auth.js, backfilling config.userId during token refresh. Introduces a pure mapEventSummary helper exposing myRsvp and fixing isHost, wires it into the events list command, adds corresponding tests, and updates documentation and version. ChangesmyRsvp and isHost fix via JWT identity
Estimated code review effort: 2 (Simple) | ~15 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant EventsCommand
participant getUserIdFromToken
participant mapEventSummary
User->>EventsCommand: partiful events list
EventsCommand->>EventsCommand: check config.userId
alt userId missing
EventsCommand->>getUserIdFromToken: decode token
getUserIdFromToken-->>EventsCommand: me
end
loop each event
EventsCommand->>mapEventSummary: map(event, me)
mapEventSummary-->>EventsCommand: summary with myRsvp, isHost
end
EventsCommand-->>User: event summaries JSON
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/events.js (1)
207-207: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMinor duplication: event URL template repeated across files.
The
https://partiful.com/e/${e.id}construction here duplicates the identical pattern in thegetcommand handler (src/commands/events.js,url: \https://partiful.com/e/${eventId}\`` per the provided graph context). Consider extracting a smallbuildEventUrl(id)helper insrc/lib/events.jsto keep the URL format in one place.🤖 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 `@src/lib/events.js` at line 207, The event URL template is duplicated in the event helpers and the get command handler, so centralize it in src/lib/events.js. Add a small buildEventUrl(id) helper there and update the existing url assignment in the events logic and the get command path to call that helper instead of inlining https://partiful.com/e/${...}. Use the existing events-related symbols like the URL field in the event object and the get command’s eventId usage to locate the repeated construction.
🤖 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 `@src/lib/events.js`:
- Line 207: The event URL template is duplicated in the event helpers and the
get command handler, so centralize it in src/lib/events.js. Add a small
buildEventUrl(id) helper there and update the existing url assignment in the
events logic and the get command path to call that helper instead of inlining
https://partiful.com/e/${...}. Use the existing events-related symbols like the
URL field in the event object and the get command’s eventId usage to locate the
repeated construction.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 39537cc4-116d-431a-8749-560e00015f57
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (9)
AGENTS.mdREADME.mdpackage.jsonskills/partiful-events/SKILL.mdsrc/commands/events.jssrc/lib/auth.jssrc/lib/events.jstests/jwt-identity.test.jstests/map-event-summary.test.js
CodeRabbit flagged the duplicated `https://partiful.com/e/${id}` template. Add a canonical buildEventUrl(id) in src/lib/events.js and use it in mapEventSummary; add unit tests. Pre-existing duplicate call sites in other commands are left for a dedicated cleanup to keep this PR scoped.
|
@coderabbitai review |
✅ Action performedReview finished.
|
The version was hardcoded as '2.0.0' in src/cli.js, separate from package.json. The 2.1.0 bump in #58 updated package.json but not this string, so `partiful --version` misreported 2.0.0 while the package was 2.1.0. Read the version from package.json via createRequire so the two can never drift again.
Summary
Closes #56.
partiful events listdropped each event's personalguestobject, so callers couldn't see their own RSVP. It also computedisHostfromconfig.userId, which isundefinedin mostauth.jsonfiles — makingisHostalwaysfalse.Both stem from not resolving "who am I". This PR resolves the authenticated user's ID by decoding the Firebase token and uses it for both.
Changes
src/lib/auth.js— adddecodeJwtPayload()+getUserIdFromToken()(readsuser_id, falls back tosub; null-safe, never throws). Backfillconfig.userIdon the token-refresh path so older credential files self-heal.src/lib/events.js— extract a pure, unit-testablemapEventSummary(e, me)that adds:myRsvp— your own RSVP:GOING/MAYBE/DECLINED/SENT, ornullon events you host (e.guest?.status ?? null).isHost— checksownerIdsagainst the resolved id, guarded so a null id can never match.src/commands/events.js— resolveme = config.userId || getUserIdFromToken(token)(the fallback covers thePARTIFUL_TOKENenv path) and map via the helper.partiful-eventsskill, AGENTS.md.Compatibility
Purely additive. Every pre-existing field keeps its name, order, and defaults — asserted with an exact-shape
toEqualtest. Version2.0.0 → 2.1.0(minor).Testing
tests/jwt-identity.test.js,tests/map-event-summary.test.js(base64url edge cases, non-object payloads, all four RSVP statuses, hosted/guest/missing-status/missing-ownerIds, null & undefined identity, full backward-compat shape). Suite 106 → 129, all green.myRsvppopulated correctly across GOING/MAYBE/DECLINED/SENT andnullon hosted events;isHosttrue only for the 3 events I actually host (was always false before).Unblocks selective Partiful → Google Calendar sync (sync only
myRsvp == "GOING").Summary by CodeRabbit
New Features
events listnow shows more accurate per-event details, including whether you’re the host and your RSVP status.Bug Fixes
Documentation
Tests