Architecture Overview
Executive Summary
BookWish is an indie-first book wishlist and commerce platform connecting readers with independent bookstores. This document defines the complete system architecture respecting the 4-layer dependency model.
App Identity & Store Listings
| Platform | Identifier |
|---|---|
| App Name | BookWish |
| Version | 3.1.0 (Flutter rewrite) |
| iOS Bundle ID | Willow-Tree-Creative.bw-app |
| App Store SKU | Willow-Tree-Creative.bw-app |
| Apple ID | 6748889200 |
| Android App ID | com.willowtreecreative.bookwish |
| Company | Willow Tree Creative LLC |
Note: Version 3.x represents the complete Flutter rewrite of the original BookWish app.
System Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ CLIENT LAYER │
│ │
│ Flutter App (Single Codebase) │
│ iOS / Android / Web (Vercel) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ API LAYER │
│ Node.js/TypeScript Backend │
│ (REST API + WebSocket for real-time) │
└─────────────────────────────────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌─────────────────┐ ┌─────────────────────┐
│ PostgreSQL │ │ Redis Cache │ │ Object Storage │
│ (Supabase) │ │ (Railway) │ │ (Images/Covers) │
└───────────────┘ └───────────── ────┘ └─────────────────────┘
│
┌─────────────────────────────────────────────────────────────────┐
│ EXTERNAL INTEGRATIONS │
├──────────┬──────────┬──────────┬──────────┬──────────┬─────────┤
│ Stripe │ RevenueCat│ Square │ Ingram │ EasyPost │BooksRun │
│(Payments)│ (Subscr.) │ (POS) │ (Supply) │(Shipping)│ (Used) │
└──────────┴──────────┴──────────┴──────────┴──────────┴─────────┘
Key Design Decisions
Fan-Out-On-Read Feed Architecture
The Share tab feed uses fan-out-on-read with caching for optimal performance:
- No pre-computed timelines (simpler, fine for under 1M users)
- Query composition at read time with filters
- Cache recent feed pages in Redis (5-min TTL)
- Seed feeds with:
- BookWish official content
- Popular lines about user's wishlisted books
- Home store posts
Guest Session Management
Strategy: Device-based guest sessions
// Guest creation
POST /auth/guest
Body: { device_id: "uuid" }
Response: { guest_token: "jwt", user_id: "uuid" }
// Migration on signup
POST /auth/migrate-guest
Body: {
guest_token: "jwt",
email: "...",
password: "...",
display_name: "..."
}
// Server merges: wishlists, notes, cart → new user
Data to migrate:
- Wishlists + items
- Private notes
- Cart contents
- Device push token
BookWish Direct + Indie Alignment
The Indie Pool Model:
┌─────────────────────────────────────────┐
│ BookWish Direct Sale │
│ $20 book │
├─────────────────────────────────────────┤
│ 7% user discount → -$1.40 │
│ Ingram cost → -$12.00 │
│ BookWish margin → $5.00 │
│ ↓ │
│ Indie Pool (20%) → $1.00 │
└─────────────────────────────────────────┘
Indie Pool Distribution:
- 50% by referral (if user came via store link)
- 30% by geography (stores in user's region)
- 20% evenly among all partner stores
UX messaging:
- "Your Home Store doesn't have this one. We'll get it for you—and part of the sale supports indie bookstores."
Inventory Sync (Square)
One-way sync: Square → BookWish
┌──────────┐ webhook ┌──────────────┐
│ Square │ ───────────────► │ BookWish │
│ POS │ │ Inventory │
└──────────┘ └──────────────┘
│ │
│ hourly poll (backup) │
└──────────────────────────────┘
- Webhooks for real-time updates
- Hourly full sync as backup
- ISBN matching via catalog lookup
- Stock reservation: 15-min hold during checkout
Feature Gating
| Feature | Guest | Free | Premium | Bookstore |
|---|---|---|---|---|
| Browse/search |