A Sinhala novel reading platform built for a single author. Users authenticate via phone OTP, browse/purchase books, and read offline via PWA.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Database | Supabase (PostgreSQL) |
| Auth | Custom phone OTP via TextIt.lk + Supabase Auth |
| Styling | Tailwind CSS 4 + feature CSS files |
| Offline | IndexedDB + Service Worker |
- users - User profiles with reader preferences (theme, font size, line spacing)
- books - Book metadata (bilingual titles, price, chapter count)
- chapters - Chapter content with word count and reading time
- purchases - Payment tracking with proof upload and admin approval
- reading_progress - Scroll position and chapter progress per user/book
- otp_codes - Phone verification codes with expiry
- Anyone can view published books and all chapter metadata
- Only authenticated users can create purchases
- Only purchasers/free book readers can access chapter content in reader
- Admins have full access to all tables
src/app/
├── (public)/ # No auth required
│ ├── books/ # Catalog and book details
│ ├── auth/ # Phone + OTP login
│ └── read/ # Reader (checks access server-side)
├── (authenticated)/ # Auth required (middleware redirects)
│ ├── library/ # User's purchased books
│ ├── purchase/ # Bank transfer flow
│ ├── settings/ # User preferences
│ └── welcome/ # First login onboarding
├── (admin)/ # Admin role required
│ └── admin/ # Dashboard, books, users, purchases
└── api/ # API routes
├── auth/ # OTP send/verify, session, logout
├── admin/ # Book/chapter CRUD
├── purchases/ # Purchase submission
└── progress/ # Reading progress sync
- User enters phone number → API sends OTP via TextIt.lk
- User enters OTP → API verifies and creates Supabase auth user
- Session stored in HTTP-only cookie
- Middleware checks session for protected routes
- User clicks "Purchase" → Redirected to login if not authenticated
- Shows bank transfer details (account number, amount)
- User makes transfer and uploads proof screenshot
- Admin reviews in dashboard and approves/rejects
- On approval, book appears in user's library
- Service Worker - Caches static assets and API responses
- IndexedDB - Stores downloaded book content for offline reading
- Sync Manager - Queues reading progress updates, syncs when online
CSS is split by feature in src/styles/:
globals.css- Tailwind imports, CSS variables, base stylesauth.css- Login/OTP formsbooks.css- Catalog, book cards, chapter listreader.css- Reader themes (light/dark/sepia)pages.css- Purchase, settings pagesadmin.css- Admin panelnav.css- Navigation headerpwa.css- Install prompts, offline indicators
| Decision | Choice | Rationale |
|---|---|---|
| Auth | Phone OTP | Common in Sri Lanka, no email needed |
| Payments | Bank transfer + manual approval | Simple for small scale, no payment gateway fees |
| Styling | CSS variables + feature files | Easy theming, smaller bundles than CSS-in-JS |
| Offline | IndexedDB | Large storage capacity for book content |
| i18n | Server dictionaries | SEO benefit, no client bundle bloat |