Inspiration

Each student club has one person who pays first and gets paid back last. They put $300 of boba supplies on their own card the night before an event, post a spreadsheet, and spend the next two weeks sending reminders, as prices change between the group chat and checkout, receipts do not match what was agreed, and someone always ends up short.

We wanted the money settled before anyone spends it, and checked after they do.

What it does

  • One shared room. The organizer makes a room and sends an invite link. Members join from their phones and set the most they can pay, and each change shows up live for all.
  • Real prices. Our Apify Actor collects product, pack size, price and stock from two real boba suppliers, Bossen and Lollicup, and the organizer picks the options that are fine for each item while members can rule out any option they will not pay for.
  • The cheapest basket that fits. A solver inside the database tries each combo, even a mix of pack sizes (3 kg + 1 kg beats 2 × 3 kg). It adds shipping and tax for each merchant and checks the budget and each member's cap, and if nothing fits, it says why and shows the dollar shortfall.
  • A fair split that all approve. Costs are split evenly up to each member's cap, and all members must approve the same version before the organizer can export the purchase plan, so a change to the basket or to a share needs a new approval.
  • AI that does real work, with a person in charge. Claude suggests items from an event description, matches catalog products to each item with a reason and units per pack, and reads receipts you upload, but each idea stays a draft until a person says yes.
  • After checkout, the books. Each receipt and bank charge is checked against the approved plan, and any gap of $1 or more is flagged, such as price changes, swaps, short shipments, double charges and receipts that do not add up. The organizer who is repaid cannot approve their own overage, and a member whose share rose must agree to the new amount. Close-out writes a balanced double-entry journal, and members pay their share through the Capital One Nessie sandbox.

How we built it

  • SpacetimeDB 2.13 is the whole backend, a TypeScript module on Maincloud. It holds the tables and the transactional reducers, plus per-user views that keep each room private, procedures for outbound HTTP calls, and an HTTP route for the Apify webhook. The solver runs inside a reducer, so a basket is never built from stale inputs.
  • React 18 + Vite on Vercel, subscribed to the database for live updates.
  • Apify runs our own Crawlee Actor, with schema.org JSON-LD and Shopify adapters. It checks each offer, and a webhook imports each run that works, but an import is held for review if it would drop a merchant in use or lose over half the catalog.
  • Claude Sonnet 5.5 runs through the Messages API, with JSON-schema output at low effort. The server checks each answer against the catalog before it shows it.
  • Capital One Nessie handles the simulated transfers from members to the organizer.
  • Mana was linked to the repo. It wrote the README as a pull request and tested the live app in four sessions (a bug hunt, a second test drive, and two re-tests of our fixes), and it filed 31 issues that we fixed and it re-tested.

Challenges we ran into

  • Two merchants blocked scrapers or hid their prices, so we dropped them rather than get around the blocks, and moved to suppliers whose shops allow it.
  • Getting "stale edit" protection right took three rounds, as at first it checked too late, and then it fired on changes that did not matter, like someone's cap.
  • Money edge cases were hard too, such as extra cents, shares that rise after checkout, and organizers who approve their own payback.

Accomplishments that we're proud of

  • A planted-error answer key: we caught 11 of 11 seeded errors with 0 false positives (npm run eval:reconcile).
  • The full loop, from event idea to repaid organizer, runs live on the deployed site.

What we learned

Group money is a trust problem more than a math problem, and the hard parts were consent, meaning who agreed to what amount, and separation of duties, meaning who may approve what.

What's next for ClubCart

Next we want real checkout links for each merchant, bank-feed import in place of simulated charges, more suppliers, and private caps that only the organizer can see.

Links

Built With

Share this project:

Updates

Submission history