Personal product · After hours
Bede.app
Prepare event invitations, preview the guest experience, and collect household RSVPs without guest accounts.
- Wyzwanie
- I wanted better invitation design and a clearer response flow than I found in existing RSVP tools. Hosts need to prepare the page guests receive and collect individual answers from people sharing one household invitation.
- Podejście
- I built the entire app myself, working intermittently after hours. Composer reuses the guest page, keeps unfinished edits in a recoverable local draft, and saves related changes in one transaction.
- Rezultat
- An unlaunched product with an organizer dashboard, household invitations, account-free RSVP, Composer, sharing tools, email integration, and event-specific checkout. Real-event usage and measured outcomes remain [NEEDS CONTEXT].
Najważniejsze elementy
- • Solo creator and full-stack developer
- • One household link with individual guest and group answers
- • Shared guest rendering in the invitation editor
- • Local draft recovery and one atomic save
- • Separate draft creation, publishing capacity, and event upgrades
TypeScript · Next.js · NestJS · PostgreSQL · Drizzle ORM · Zod · Stripe · AWS S3 / SES / SQS
Overview
Bede.app is an event invitation and RSVP product, with weddings as its primary use case. Organizers prepare an invitation and manage attendance; guests open a secret link and respond without creating an account.
One invitation can represent a household. Each person has their own attendance status and answers, while some questions apply to the group. Guests can return through the same link to revise a response.
I created and built the entire app myself, working intermittently after hours. The idea came from my assessment of existing RSVP tools: I wanted better invitation design and a clearer response flow. Bede.app has not launched yet.
The problem
Preparing an invitation and collecting attendance are connected tasks. An organizer needs to see the page guests will receive, decide what information appears, and understand who has responded. A shared household link must still preserve individual answers.
The editor introduces another constraint: changing a preview must not update the guest page on every keystroke. Fictional preview people must also stay out of guest counts and delivery lists.
The approach
I separated organizer identity, invitation access, and the person making a response. An invitation secret grants access to a group; selecting a name records who is acting within it.
I placed Composer outside the dashboard shell and reused the actual guest rendering at natural scale. Supported edits form one recoverable local draft and one explicit save command. Configured sections show real content or a truthful placeholder; RSVP remains fixed.
Key decisions
Use invitation access for household responses
Context: A wedding invitation can include several people, each with a different attendance status or answer.
Decision: I used one secret link per invitation group and stored individual guest responses separately from group answers.
Why: Guests can respond for their household without registering, while the organizer retains per-person attendance information.
Trade-off: The link acts as the credential. Name selection identifies the acting person within the group but does not independently verify their identity; anyone holding the link can act for that household.
Reuse the guest page in Composer
Context: A separate mock preview can drift from the invitation guests actually receive.
Decision: I reused the guest component with a dedicated preview invitation and separate edit and walkthrough modes.
Why: The organizer can inspect the actual reading flow, including the envelope and guest selection, without first creating a real guest invitation.
Trade-off: Preview records need a distinct purpose and explicit exclusions from delivery, quotas, and statistics. Preview mode also needs guards that suppress RSVP and engagement writes.
Keep edits local until one explicit save
Context: Composer changes several related records. Saving each control separately could expose an incomplete combination of content and section settings.
Decision: I kept unfinished edits in an event-scoped browser draft and persisted the complete supported change set in one database transaction.
Why: Reloading can restore the draft, and a failed child write rolls back the save. Late query results update untouched draft chunks without replacing fields the organizer has already edited.
Trade-off: Drafts stay in that browser and disappear if its storage is cleared. Composer assumes one active organizer and does not resolve edits from another tab or device.
Separate preparation, publishing, and payment
Context: Creating a draft, occupying a published-event slot, and buying features for one event have different consequences.
Decision: I made event creation produce a draft, checked publishing capacity separately, and scoped Event Premium to one event.
Why: Preparation does not consume publishing capacity, and an event upgrade does not imply an account subscription or extra published-event slots.
Trade-off: These boundaries need distinct UI explanations. Publishing governs saved Composer section configuration; it does not make all draft event data inaccessible to someone with a valid invitation link.
How it works
- The organizer signs in with Google and creates a draft with event details, locations, RSVP questions, and invitation groups.
- In Materials, the organizer opens Composer, reviews the guest page, and stages supported edits. Reloading restores the local draft in the same browser.
- Saving commits the change set. For a published event, guests receive the updated configuration; for a draft, saved section configuration takes effect after publishing.
- The organizer shares group links or QR codes. Email sending uses a separate delivery workflow.
- A guest opens the invitation, selects the acting person, submits attendance and answers, and can later revise them. The organizer sees the resulting statuses and responses.
Outcome
I built the organizer dashboard, group invitations, account-free RSVP, Composer, sharing tools, email integration, and event-specific checkout. The concrete access requirement is zero guest accounts; this is a product scope signal, not an adoption metric.
Unit tests cover draft recovery, preview provisioning, ownership, and Composer rollback behavior. Browser scenarios cover Composer saving through to a fresh guest view and a guest response reaching the owner dashboard. These are repository test scenarios, not evidence of real-event usage.
Bede.app is an unlaunched product under development. The production workflow documents an unprovisioned production stack, and SMS remains a stub. Real-event usage and measured outcomes: [NEEDS CONTEXT].
What I'd improve today
- Close the free-event email gap: the MVP promises a small included allowance, but the shared default still sets it to zero. Verify the full free journey before calling it ready.
- Make draft visibility explicit. Either gate all guest access until publishing or clearly explain what a valid draft invitation link already exposes.
- Protect restored drafts against stale server data. Add a version check before saving if editing across tabs or devices becomes a real usage pattern.
- Run a small real-event pilot and measure guest completion without help, organizer corrections, and delivery failures before expanding the invitation catalog.