Inspiration

At every hackathon, the fastest fix for a stuck team is usually the team at the next table. Someone walks over, spots the missing driver or the CORS header, and leaves. That help is what makes events like Hack the Hill work, but it leaves no trace: the helpers get nothing for it, and organizers can't see who's actually making the event better.

We wanted to reward helping other teams. But any points system gets gamed, so we made one rule from the start: every point needs evidence.

What it does

Lifts turns "can someone help us?" into a tracked, confirmed contribution.

  1. Join your team with an invite code from the organizers.
  2. Post a blocker: what's broken, tags, and what you already tried.
  3. Another team clicks "Help with this" and gets a private help thread to chat, share code, or meet at your table.
  4. The helpers submit the outcome with evidence: a link, a code diff, or a written explanation.
  5. The team that asked confirms it's fixed, and the helpers get points and a line on their contribution receipt.

Scoring rewards reaching more teams, not trading fixes with friends. Points are counted per pair of teams, in either direction:

Confirmed fixes between the same two teams Points to the helper
1st 20
2nd 5
3rd and later 0 (still listed on the receipt)

So if A helps B, B, C, then B, A earns \(20 + 5 + 20 + 0 = 45\) points.

To keep points honest:

  • Teams join with organizer-issued invite codes. Each person is on one team, locked once they join.
  • Only the team that asked can confirm, so helpers can't award themselves.
  • One award per blocker. Confirming twice or reopening never pays again.
  • Every points change goes into an append-only ledger, and a verification script checks the totals.
  • Organizers can reverse an award, but only with a recorded reason.

How we built it

  • Next.js 16 and TypeScript for the app and its 20 API routes, with Tailwind CSS in a mobile-first Hack the Hill III theme.
  • Auth0 for sign-in. The organizer role comes from Auth0 RBAC, added to the ID token by a post-login Action. Every page and API route that needs a sign-in, a team, or the organizer role checks it on the server.
  • Tiger Data (Tiger Cloud): Postgres 18 with TimescaleDB.
    • Every state change is written to an activity hypertable in the same transaction, with continuous aggregates for activity, repeat pairs, and wait and solve times.
    • Points come only from an awards table and the ledger, never from the aggregates.
  • Render hosts the app, runs database migrations on every build, and redeploys on every push to main.
  • Vitest and GitHub Actions, with integration tests against a real TimescaleDB container in CI.

We split the plan into build steps (setup, foundation, accounts and teams, help workflow, scoring, presentation, deployment), and each of us ran our steps in order.

Challenges we ran into

  • Getting scoring right under pressure.
    • The same two teams share one allowance in both directions, and reversing an award has to re-score everything after it.
    • Two confirmations at the same moment could double-count, so each pair is re-scored under a database lock, and every change is written to an append-only ledger.
  • Production-only bugs.
    • Render gave us a different URL than we expected, so Auth0 rejected our login callback until we fixed the allowed URLs and APP_BASE_URL.
    • A one-letter typo in a time zone setting crashed the help thread page, but only in production.
  • Scope. We planned Gemini-powered review and Vultr hosting, and cut both to ship a working core flow.

Accomplishments that we're proud of

  • The full loop works live: post, accept, chat, submit evidence, confirm, points, receipt. We tested it across two laptops with separate teams.
  • Anti-farming is built into the core, not bolted on: invite codes, confirmation by the team that asked, one award per blocker, diminishing points per pair, and an auditable ledger.
  • A clean, mobile-first interface themed for Hack the Hill III, with contrast checked on every color pair.

What we learned

  • Incentives shape behavior: paying per message or per minute rewards noise, so we only pay for confirmed fixes, with less for repeat pairs.
  • Never trust the browser. Team IDs, roles, and points all come from the server.
  • TimescaleDB is great for analytics, but the authoritative score should live in its own table with an audit trail.
  • Deployment details like exact URLs, secrets, and even time zone names matter as much as the code, so test in production mode early.

What's next for Lifts

  • Gemini review: summaries for receipt lines, plus evidence-backed flags for suspicious patterns like bursts, cycles, and near-duplicate blockers, in an organizer review queue.
  • Activity charts from the continuous aggregates we already record: wait times, solve times, and repeat pairs.
  • Organizer tools in the UI for reversing and restoring awards.
  • A full pilot with every team at the next Hack the Hill, with invite codes handed out at check-in.

Built With

Share this project:

Updates

Submission history