itmo-wad / itmo-wad/projects-2026

TravelTote

Open
#8 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

# Travel & Tote — Peer-to-Peer Global Delivery Marketplace

## Summary

**Travel & Tote** turns every traveler into a delivery agent. Anyone going from
City A to City B — by walking, car, train, metro, bus, ferry, ship, or plane — can
carry a package for a sender along the same route, get paid through Stripe escrow,
and build a reputation through reviews. We also support a **Shop & Bring** mode:
a buyer pays into escrow for a product available only in another country, and a
traveler in that country buys the item and hand-delivers it at a pre-agreed meeting
point.

---

## The Problem

International courier services are slow, expensive, and rigid:

- **Cost** — DHL/UPS/FedEx for a 1.5 kg parcel between continents often costs
**$80–$200**, plus customs handling fees.
- **Speed** — air freight is fast but expensive; standard sea/road shipping
takes 1–4 weeks.
- **Geographic gaps** — many regions (rural areas, smaller cities, sanctioned
countries) have no reliable last-mile delivery at all.
- **Product availability** — many items (region-locked electronics, regional
cosmetics, niche groceries, limited-edition releases) are simply unavailable
to buy from another country, regardless of how much you'd pay for shipping.
- **Trust** — informal "ask a friend" arrangements break down when no one you
know is going where you need.

Meanwhile, **billions of people travel every day** with unused luggage capacity:
the empty 5 kg of allowance on a flight, the empty trunk of a road trip, the
empty backpack space of a daily commuter.

## The Solution

A two-sided marketplace that connects:

1. **Travelers** with unused capacity → who post their route, mode, dates, and
per-kg fee.
2. **Senders** who need something delivered → who post a request with route,
weight, deadline, item description, and offered fee.
3. **Buyers** who want a product from another country → who post a product link,
target price, destination meeting point, and delivery fee.

The platform handles **smart matching** (city/date/mode/capacity compatibility),
**escrowed payment** (Stripe holds funds until delivery is confirmed),
**identity verification** (Stripe Identity), **proof-of-handover and
proof-of-delivery** photos with geolocation, and **post-delivery reviews**.

---

## How It Works (User Flows)

### Flow 1 — Standard Delivery (Sender ↔ Traveler)

1. **Traveler posts a trip:** "NYC → Boston, train, Friday, 5 kg available, $10/kg."
2. **Sender posts a request:** "Hardcover textbook, 1.5 kg, NYC → Boston by Sunday,
$50 declared value, train/bus OK."
3. **Match proposed:** sender (or our smart matcher) sees the trip, clicks
"Propose match" with an agreed fee (e.g. $15).
4. **Traveler accepts.**
5. **Sender funds escrow:** $15 charged via Stripe to the platform account.
6. **Realtime chat** opens between the two parties to coordinate handover.
7. **Traveler uploads handover photo** at pickup (geolocation stamped).
8. **Traveler uploads delivery photo** at drop-off.
9. **Sender confirms receipt:** Stripe Transfer to traveler's connected account
(minus our 5% platform fee).
10. **Both parties leave star + text reviews.**

### Flow 2 — Shop & Bring (Buyer ↔ Shopper-Traveler)

1. **Buyer posts a shop request:** product URL, name, source country (e.g.
"Japan"), destination meeting point ("Brooklyn, NY — Starbucks at 86th &
Broadway, July 15"), max price ($120 item + $30 delivery fee).
2. **A traveler in Japan** browsing the Shop tab sees the request, clicks
"I'll buy this for you."
3. **Buyer accepts** the shopper.
4. **Buyer funds escrow:** $150 charged (item + delivery fee + platform fee).
5. **Shopper buys the item locally**, uploads receipt as proof.
6. **Shopper carries the item** on their next trip.
7. **Shopper delivers** at the agreed meeting point, uploads delivery photo.
8. **Buyer confirms receipt** → escrow releases the full amount to the shopper
(covering item reimbursement + delivery fee).
9. **Reviews submitted by both parties.**

---

## Tech Stack

| Layer | Choice | Why |
|---|---|---|
| Frontend | Next.js 16 (App Router, TypeScript, Tailwind v4) | Server components, edge rendering, file-based routing |
| UI library | shadcn/ui + Radix primitives | Accessible primitives, full source ownership |
| Database | Supabase Postgres (eu-central-2) | Postgres + RLS + generated types |
| Auth | Supabase Auth (Email magic link + Google OAuth) | Built-in OTP + provider support |
| Realtime | Supabase Realtime (postgres_changes) | Live chat without dedicated WS infra |
| Storage | Supabase Storage (RLS-gated buckets) | Photo proofs gated to match parties only |
| Payments | Stripe Connect Express + Stripe Identity | Regulated payouts + KYC, day one |
| Maps & Geocoding | Yandex Maps JS API 2.1 + Yandex Geocoder HTTP API | Global coverage, generous free tier |
| Hosting | Vercel | First-class Next.js deploys |
| Email | Resend (planned) | Branded transactional + magic-link templates |

### Architectural decisions

- **Stripe escrow uses "separate charges and transfers"**, not destination charges.
Senders pay the platform; on delivery confirmation we create a Transfer to the
traveler's connected account. This keeps refund logic simple and gives us full
control of fund flow.
- **Row-Level Security on every table.** Match parties can only read their own
matches, messages, escrows, proofs. A `is_match_party()` SQL helper centralizes
the check.
- **Stripe webhook idempotency** via a dedicated `stripe_events` table — first
insert wins, duplicates rejected by the unique PK.
- **Photo proofs upload directly client → Storage**, not streaming through Next.js,
to keep the API path stateless.
- **Smart matching** is a pure function over haversine endpoint distance, mode
compatibility, capacity, item flags, and deadline — no ML, no opaque ranking.

---

## APIs We're Working With

### Internal (our own routes)

- `POST /api/stripe/connect/onboard` — start traveler payouts onboarding
- `POST /api/stripe/identity/start` — start KYC verification session
- `POST /api/stripe/escrow/create` — fund escrow on a match
- `POST /api/stripe/escrow/release` — release escrow → Transfer to traveler
- `POST /api/stripe/escrow/refund` — refund escrow → return to sender
- `POST /api/stripe/webhook` — Stripe events (idempotent)
- `GET /api/geocode?q=…` — server-proxied Yandex Geocoder (keeps key off client)

### External

| API | Purpose | Limits / Notes |
|---|---|---|
| Stripe Connect Express API | Onboarding, payouts | Test mode initially; real platform onboarding handled in parallel |
| Stripe Identity API | KYC + verified badge | Per-verification fee in production |
| Stripe Payment Intents API | Sender escrow funding | Standard Stripe pricing |
| Stripe Transfers API | Pay traveler on completion | Free for Connect Express |
| Stripe Webhooks | Async event delivery | Signed; handled idempotently |
| Yandex Maps JS API 2.1 | Map rendering, route preview | 25 000 map loads/day free |
| Yandex Geocoder HTTP API | City autocomplete | 25 000 requests/day free |
| Supabase Auth | Magic link + Google OAuth | Free tier: 50 000 MAU |
| Supabase Realtime | Live chat | Free tier: 200 concurrent connections |
| Supabase Storage | Photo proofs | Free tier: 1 GB, 2 GB transfer/mo |
| Resend (planned) | Branded transactional email | Free tier: 3 000 emails/mo |

---

## Current Limitations (MVP scope)

- **No 2FA** — magic link + Google OAuth only.
- **No insurance** on delivered items beyond declared value (Stripe Connect risk
isn't enforced at item level).
- **No dispute resolution UI yet** — `disputed` status exists in the schema, but
there's no human-in-the-loop mediation flow built.
- **No prohibited-item AI screening** — we rely on user-declared item flags
(fragile, liquid, batteries, etc.) to filter mode compatibility (no liquids
>100 ml on flights, etc.).
- **No customs handling** — declared value goes on the photo proof; we don't yet
generate customs forms or handle import duties.
- **Mapbox-style street routing not yet implemented** — we draw a geodesic
(great-circle) line for any transport mode. Road/walking turn-by-turn would
need Yandex Routing API integration.
- **No native mobile app** — responsive web only for v1.
- **No multi-language** — English copy only.
- **No PWA install polish** — installable but not optimized.
- **No referral/credits program.**
- **No recurring trips** — each trip is a single-shot post.
- **No QR-code handover** — handover currently relies on the photo proof alone.

These are explicitly **deferred**, not abandoned — most are 2–4 day add-ons
once we have signal from real users.

---

## Open Questions

- [ ] **Liability model:** if an item is lost/damaged in transit, who eats the
cost — the platform (insurance), the traveler (deposit), or the sender
(declared-value cap)?
- [ ] **KYC threshold:** require Stripe Identity for every traveler, or only
above a per-month earnings limit?
- [ ] **Customs:** do we generate CN22/CN23 forms for international parcels, or
shift that responsibility to senders?
- [ ] **Cross-currency settlement:** how do we handle a USD escrow paying out
to an EUR-denominated connected account? (Stripe handles FX, but the user
experience needs explicit copy.)
- [ ] **Pricing experiments:** is 5% the right platform fee, or should we A/B
test 3% / 5% / 7% by route?

---

## Roadmap

**Phase 1 — Live MVP (current state):**
schema applied, 23 routes shipping, Yandex maps wired, Supabase project
provisioned (`icvfblvhcsvdvhcmbdkg`).

**Phase 2 — Trust & polish:**
branded email templates (Resend), Shop & Bring feature, reputation badges,
in-app push for new matches.

**Phase 3 — Scale:**
multi-currency, customs forms, dispute mediation UI, AI item screening, native
mobile apps (Expo).

**Phase 4 — Network effects:**
referral credits, route-subscription alerts, recurring trips for commuters,
business accounts for SMB shippers.

Contributor guide

No contributing guide indexed for this repository

Research direction

Begin by reviewing the listed internal API routes, architectural decisions, and current MVP scope. The issue describes a broad marketplace and roadmap rather than a specific change, file, or test, so a concrete definition of done is not provided.

Written by the indexing model from the issue text.

Assessment

Tech stack
nextjs, postgresql, supabase, tailwindcss, typescript
Domain
api, authentication, backend, cloud, database, frontend, full-stack, payments
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
15/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.