Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,26 @@ partiful events cancel <id>
### `events rsvp` / `events interested` — RSVP to events

```bash
partiful events rsvp <id> # RSVP going (default)
partiful events rsvp <id> --status maybe # going | maybe | declined
partiful events rsvp <id> --plus-one Maddie --plus-one Justin # bring guests
partiful events rsvp <id> --name "Kaleb Cole" --message "Stoked!"
partiful events rsvp get <id> # Read your RSVP and questionnaire answers
partiful events rsvp set <id> # RSVP going (default)
partiful events rsvp set <id> --status maybe # going | maybe | declined
partiful events rsvp set <id> --plus-one Maddie --plus-one Justin # bring guests
partiful events rsvp set <id> --name "Kaleb Cole" --message "Stoked!"
partiful events rsvp set <id> --answer "<question-id-or-text>=<value>" # repeat per host question
partiful events interested <id> # mark interest
partiful events interested <id> --remove # remove interest
```

RSVP does a read-before-write: it updates your existing guest record if you
already RSVP'd, otherwise creates one. Ticketed and questionnaire-gated events
are refused with a clear error (use the app for those). The same verbs are
available under `explore` (`partiful explore rsvp <id>`) for the discovery flow.
`events rsvp get` reads your saved status, guest details, and questionnaire
answers without changing the RSVP. RSVP writes do a read-before-write: they update your existing guest record if you
already RSVP'd, otherwise create one. Ticketed events are refused with a clear
error (use the app to purchase a ticket). For host-questionnaire events, pass one
repeatable `--answer "<question-id-or-exact-text>=<value>"` per answer; required
answers are validated before submission. Plain `--dry-run` stays offline, while
`--answer ... --dry-run` performs read-only guest/event lookups so the preview can
validate and preserve live questionnaire state, then read the Firestore guest record
back to verify the saved status and answers. The same verbs are available under
`explore` (`partiful explore rsvp get <id>`) for the discovery flow.

### `guests` — Manage event guests

Expand Down
47 changes: 27 additions & 20 deletions docs/explore-command-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Wire callables are hidden — the CLI never says `addGuest`.
| User verb | Hidden callable |
|---|---|
| `explore list` / `explore trending` / `explore regions` | `getDiscoverFeed`, `getDiscoverSections` |
| `explore rsvp` | `addGuest` |
| `explore rsvp set` | `addGuest` |
| `explore interested` | `markEventInterest` |

---
Expand All @@ -27,7 +27,8 @@ Subcommands:
list Browse the discovery feed (default region: nyc)
trending Trending carousels grouped by region
regions List available regions + their tags
rsvp <eventId> RSVP yourself to a public event (going/maybe/declined)
rsvp get <eventId> Read your current RSVP and questionnaire answers
rsvp set <eventId> RSVP yourself to a public event (going/maybe/declined)
interested <eventId> Mark yourself interested (softer than RSVP)
```

Expand Down Expand Up @@ -56,19 +57,24 @@ partiful explore regions [--format json|table]
Lists region slugs + the tag list (id + friendly name) for --tag filtering.
```

### `explore rsvp <eventId>`
```
partiful explore rsvp <eventId> [options]
### `explore rsvp set <eventId>`
```text
partiful explore rsvp set <eventId> [options]
Comment thread
coderabbitai[bot] marked this conversation as resolved.

--status <s> going | maybe | declined (default: going)
--status <s> going | maybe | declined (preserves current status;
defaults to going for a new RSVP)
--plus-one <name> Add a named plus-one (repeatable)
--count <n> Total headcount incl. yourself + plus-ones (default: 1)
--count <n> Total headcount incl. yourself + plus-ones
--message <msg> Public comment posted on the event page
--answer <key=value>
Host-questionnaire answer by question ID or exact text
(repeatable)
-y, --yes Skip the confirmation prompt (agent flows)
--dry-run Print the payload, don't write
--dry-run Print the payload, don't write. Plain previews stay offline;
previews with --answer read current guest and event state.

Refuses (exit 4, type unsupported_event) on ticketed / password-gated /
questionnaire events — use the Partiful app for those.
Refuses unsupported ticketed events. Supported host-questionnaire events
require complete valid answers and preserve omitted saved answers.
```

### `explore interested <eventId>`
Expand Down Expand Up @@ -124,7 +130,7 @@ partiful explore interested <eventId> [options]
}
```

### `explore rsvp` (success)
### `explore rsvp set` (success)
```json
{
"eventId": "JKQD5kibarjDeBw4LN6W",
Expand All @@ -136,7 +142,7 @@ partiful explore interested <eventId> [options]
}
```

### `explore rsvp` (refused — ticketed)
### `explore rsvp set` (refused — ticketed)
```json
{
"status": "error",
Expand All @@ -152,21 +158,22 @@ partiful explore interested <eventId> [options]

## Behavior notes for IMPLEMENT

1. **Statelessness → read-before-write.** CLI won't have a `guestId` on a repeat
run. `explore rsvp` should call `getCurrentGuest {eventId}` first: if a record
exists, pass its `guestId` back to `addGuest` (update); else send
`guestId:null` (create). Same for `--status declined` (revert path).
1. **Statelessness → read-before-write.** Live `explore rsvp set` calls
`getCurrentGuest {eventId}` first: if a record exists, it preserves omitted RSVP
fields and passes its `guestId` back to `addGuest` (update); otherwise it sends
`guestId:null` (create). Answer-aware dry-runs perform the same reads so they can
validate and merge questionnaire answers; plain dry-runs remain offline.
2. **`addGuest` payload** (built by `wrapPayload`, hidden from user):
`{eventId, rsvp:{name, count, plusOnes[], message, emailInvitationId:null,
status, guestId, timezone, password:null}}`. `name` = `config.displayName`;
`timezone` = config tz (default America/Los_Angeles).
3. **Status mapping:** CLI `going|maybe|declined` → wire `GOING|MAYBE|DECLINED`.
4. **Confirmation gate** (AGENTS.md destructive policy): `rsvp` + `interested`
4. **Confirmation gate** (AGENTS.md destructive policy): `rsvp set` + `interested`
write to a real host's guest list → prompt unless `-y`. `--dry-run` prints
payload + target endpoint, no write.
5. **Ticketed/password/questionnaire guard:** detect via `getEventInfo` /
`getEventRestrictions` before writing; refuse rather than create a broken
record. (These branches are UNTESTED against `addGuest` — see ticket 02/07.)
5. **Unsupported-event guard:** detect ticketed events via `getEventInfo` before
writing and refuse rather than create a broken record. Supported host
questionnaires are validated and submitted with the RSVP.
6. **File layout:** new `src/commands/explore.js`, `registerExploreCommands`,
one command group, structured `{status, error:{code,type,message}}` errors,
`jsonOutput`/`jsonError` like the rest.
Expand Down
22 changes: 15 additions & 7 deletions skills/partiful/references/rsvps-and-interest.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
# RSVPs and Interest

```bash
partiful events rsvp <event-id> --dry-run
partiful events rsvp <event-id> --status going
partiful events rsvp <event-id> --status going --plus-one "Alex Smith"
partiful events rsvp <event-id> --status maybe --message "I may be late"
partiful events rsvp <event-id> --status declined
partiful events rsvp get <event-id>
partiful events rsvp set <event-id> --dry-run
partiful events rsvp set <event-id> --status going
partiful events rsvp set <event-id> --status going --plus-one "Alex Smith"
partiful events rsvp set <event-id> --status maybe --message "I may be late"
partiful events rsvp set <event-id> --status declined
partiful events interested <event-id>
partiful events interested <event-id> --remove
```

`explore rsvp` and `explore interested` are equivalent aliases.
`events rsvp get` reads your saved status and questionnaire answers without changing the RSVP. `explore rsvp get`, `explore rsvp set`, and `explore interested` are equivalent aliases under the discovery command group.

The current CLI cannot complete ticket purchases or host questionnaires. Questionnaire response fields are known internally, but `events rsvp` exposes no answer option and deliberately rejects questionnaire-gated events. Use Partiful directly for either flow.
For questionnaire events, pass one repeatable answer per question. Keys may be the question ID or its exact text:

```bash
partiful events rsvp set <event-id> --answer "<question-id>=<value>"
partiful events rsvp set <event-id> --answer "Dietary restrictions?=None" --answer "Song request?=Anything"
```

Required answers are validated before submission. Successful writes read the Firestore guest document back to verify the saved status and questionnaire answers. Plain `--dry-run` remains offline; combining `--answer` with `--dry-run` performs read-only guest and event lookups to validate the live questionnaire preview. Ticketed or paid events remain unsupported because the CLI cannot purchase tickets.
Loading