Kiến trúc
Tổng quan kiến trúc hệ thống Steadii
Sơ đồ tổng quan
┌────────────────────────────────────────────┐
│ Cloudflare Pages (CDN) │
│ steadii.dahodo.com / dudeu.dahodo.com │
└──────────────────┬─────────────────────────┘
│ Static SPA
┌──────────────────▼─────────────────────────┐
│ Frontend (React + Vite) │
│ TypeScript, TailwindCSS v4, Zustand │
│ PWA: vite-plugin-pwa + Workbox │
└──────────────────┬─────────────────────────┘
│ HTTPS REST API
┌──────────────────▼─────────────────────────┐
│ Backend (Express.js) │
│ api.dahodo.com/steadii/* │
│ Auth: Google OAuth 2.0 → JWT │
│ Payments: LemonSqueezy REST API │
└──────────────────┬─────────────────────────┘
│ pg (node-postgres)
┌──────────────────▼─────────────────────────┐
│ PostgreSQL 16 │
│ 4 tables: users, user_data, │
│ push_subscriptions, subscriptions │
└────────────────────────────────────────────┘Tech Stack
| Layer | Technology | Vai trò |
|---|---|---|
| Frontend | React 18 + TypeScript | UI components |
| Build | Vite 6 | Bundler + dev server |
| Styling | TailwindCSS 4 | CSS utility classes |
| State | Zustand 5 | Global state (persisted localStorage) |
| Routing | React Router 6 | Client-side routing |
| Icons | Material Symbols Outlined | Variable icon font |
| PWA | vite-plugin-pwa + Workbox | Service worker, offline, install |
| Backend | Express.js 5 | REST API server |
| Database | PostgreSQL 16 | Persistent data storage |
| Auth | Google OAuth 2.0 + JWT RS256 | User authentication |
| Payments | LemonSqueezy REST API | Subscription billing |
| CDN | Cloudflare Pages | Frontend hosting |
| VPS | Docker Compose + Nginx | Backend hosting |
Cấu trúc thư mục
steadii/
├── frontend/src/
│ ├── pages/ # 8 trang
│ ├── components/ # 14 components
│ ├── hooks/ # useAuth, useSubscription
│ ├── store/ # Zustand store
│ ├── utils/ # API, sync, audio, helpers
│ ├── i18n/ # Translations (en.ts, vi.ts)
│ └── types/ # TypeScript interfaces
├── backend/src/
│ ├── index.js # Express routes
│ ├── db.js # PostgreSQL queries
│ ├── auth.js # Google OAuth verification
│ └── stripe.js # LemonSqueezy integration
└── steadii-docs/ # Fumadocs (this site)