Glow Agent
Take a selfie, see YouCam's AI map of your skin, try makeup shades on your own photo, and check out a routine built for your skin with PayPal.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗تحائف · Send cakes, flowers, perfumes and more to your loved ones anywhere in Pakistan.
Tahaif is a Pakistan-first gift delivery e-commerce platform. Customers browse a catalog of cakes, flowers, perfumes and gift hampers, choose a recipient and delivery date, and pay via Cash on Delivery or Bank Transfer.
Brand color: #16a34a Emerald Green
Domain: tahaif.pk
Full documentation: docs/production-roadmap.md
| Layer | Technology |
|---|---|
| API | FastAPI 0.110+, Python 3.12 |
| ORM / DB | SQLAlchemy 2 async + Alembic + PostgreSQL 16 |
| Cache | Redis 7 |
| Search | Meilisearch |
| Object Storage | MinIO (local) / S3 (production) |
| Frontend | Next.js 15, React 19, TypeScript strict |
| Styling | TailwindCSS + shadcn/ui |
| State | Zustand + TanStack Query |
| Forms | react-hook-form + Zod |
| Resend (MailHog locally) | |
| Payments | COD + Bank Transfer (Stripe/JazzCash via config) |
| CI | GitHub Actions |
| Deploy | Vercel (frontend) + Fly.io (API) |
Install these once on your machine before anything else.
| Tool | Version | Install |
|---|---|---|
| Docker Desktop | Latest | docker.com/get-started |
| Node.js | 22+ | nodejs.org |
| pnpm | 8+ | npm install -g pnpm |
| Python | 3.12+ | python.org |
| uv | Latest | pip install uv or curl -LsSf https://astral.sh/uv/install.sh | sh |
docker --version # Docker version 24+
node --version # v22+
pnpm --version # 8+
python3 --version # Python 3.12+
uv --version # uv 0.4+
Fastest path — runs everything: Docker services, DB migrations, seed data, API, and web app.
cd gift-delivery
./start.sh
That's it. Once complete:
| What | URL |
|---|---|
| 🌐 Web app | http://localhost:3000 |
| 📖 API docs | http://localhost:8000/api/v1/docs |
| 💚 API health | http://localhost:8000/api/v1/healthz |
| 📧 Test emails | http://localhost:8025 |
| 🪣 File storage | http://localhost:9001 |
Stopping: Press
Ctrl+Cin the terminal wherestart.shis running.
To stop Docker services:docker compose -f infra/docker-compose.yml down
If you prefer to understand and control each step, follow this guide.
git clone <repo-url>
cd gift-delivery
cp .env.example .env
Then open .env and set the one required value:
# Generate a secure secret key
python3 -c "import secrets; print(secrets.token_hex(32))"
# Copy the output and set it as SECRET_KEY in .env
All other values in .env have working defaults for local development. You only need to change them when integrating external services (Stripe, Twilio, etc.).
docker compose -f infra/docker-compose.yml up -d
Wait for all services to be healthy (usually ~20 seconds):
docker compose -f infra/docker-compose.yml ps
# All services should show "healthy"
Services started:
localhost:5433localhost:6380localhost:7700localhost:9000 (console: localhost:9001)localhost:8025cd apps/api
# Install Python dependencies
uv sync
# Apply database migrations (creates all tables)
uv run alembic upgrade head
# Seed the database with cities, vendors, and products
uv run python scripts/seed.py
# Make yourself the first super admin (then add admins and staff from Back office → Team)
uv run python scripts/create_admin.py [email protected]
Expected seed output:
Seeding cities... 9 cities
Seeding occasions...
Seeding categories... 13 categories
Seeding vendors... 10 vendors
Seeding products... 12 products seeded
✓ Seed complete
# Still inside apps/api/
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
Verify: open http://localhost:8000/api/v1/healthz — should return {"status":"ok"}.
Open a new terminal:
cd apps/web
# Install Node dependencies
pnpm install
# Start the dev server
pnpm dev
Verify: open http://localhost:3000 — the Tahaif home page should load.
The .env file at the repo root is read by both the API and the web app.
DATABASE_URL=postgresql+asyncpg://tahaif_user:tahaif_dev_password@localhost:5433/tahaif
REDIS_URL=redis://localhost:6380/0
SECRET_KEY=<generate with: python3 -c "import secrets; print(secrets.token_hex(32))">
| Variable | Default | Required | Description |
|---|---|---|---|
DATABASE_URL | (see .env.example) | ✅ | PostgreSQL async connection string |
REDIS_URL | redis://localhost:6380/0 | ✅ | Redis connection string |
SECRET_KEY | — | ✅ | JWT signing secret (32+ random bytes) |
ACCESS_TOKEN_EXPIRE_MINUTES | 15 | No | JWT access token lifetime |
REFRESH_TOKEN_EXPIRE_DAYS | 7 | No | Refresh token lifetime |
MEILISEARCH_URL | http://localhost:7700 | No | Meilisearch base URL |
MEILISEARCH_MASTER_KEY | dev_master_key | No | Meilisearch API key |
S3_ENDPOINT_URL | http://localhost:9000 | No | MinIO/S3 endpoint |
S3_ACCESS_KEY_ID | minioadmin | No | MinIO access key |
S3_SECRET_ACCESS_KEY | minioadmin | No | MinIO secret key |
S3_BUCKET_NAME | tahaif-media | No | S3 bucket for uploads |
RESEND_API_KEY | — | No | Resend email API key (dev uses MailHog) |
EMAIL_FROM | [email protected] | No | Sender email address |
GOOGLE_CLIENT_ID | — | No | Google OAuth client ID |
GOOGLE_CLIENT_SECRET | — | No | Google OAuth client secret |
STRIPE_SECRET_KEY | — | No | Stripe secret key (not needed for COD/bank transfer) |
Never commit
.env— it is in.gitignore. Only commit.env.examplewith safe placeholder values.
| Service | URL | Credentials |
|---|---|---|
| 🌐 Web app | http://localhost:3000 | — |
| 📖 API Swagger docs | http://localhost:8000/api/v1/docs | — |
| 🔄 API ReDoc | http://localhost:8000/api/v1/redoc | — |
| 💚 API healthcheck | http://localhost:8000/api/v1/healthz | — |
| 📧 MailHog (test email) | http://localhost:8025 | — |
| 🔍 Meilisearch | http://localhost:7700 | Master key: dev_master_key |
| 🪣 MinIO console | http://localhost:9001 | minioadmin / minioadmin |
| 🐘 PostgreSQL | localhost:5433 | tahaif_user / tahaif_dev_password |
| 🔴 Redis | localhost:6380 | — |
# 1. Start Docker services (if not running)
docker compose -f infra/docker-compose.yml up -d
# 2. Start API (terminal 1)
cd apps/api
uv run uvicorn app.main:app --reload --port 8000
# 3. Start web (terminal 2)
cd apps/web
pnpm dev
Or just run ./start.sh to do all of the above automatically.
# Stop API and web: Ctrl+C in each terminal
# Stop Docker services
docker compose -f infra/docker-compose.yml down
# Stop Docker AND delete all data (full reset)
docker compose -f infra/docker-compose.yml down -v
All database commands run from apps/api/.
uv run alembic upgrade head
uv run alembic downgrade -1
uv run alembic revision --autogenerate -m "add_column_to_table"
# Always review the generated file in alembic/versions/ before applying
uv run alembic current
uv run alembic history --verbose
# Drop and recreate (development only)
uv run alembic downgrade base
uv run alembic upgrade head
uv run python scripts/seed.py
docker exec -it $(docker compose -f infra/docker-compose.yml ps -q postgres) \
psql -U tahaif_user -d tahaif
cd apps/api
# Run all tests
uv run pytest
# Run with coverage report
uv run pytest --cov=app --cov-report=term-missing
# Run a specific test file
uv run pytest tests/test_auth.py -v
# Run a specific test
uv run pytest tests/test_auth.py::test_register_happy_path -v
Note: Tests use a separate in-memory test database. Docker services must be running for integration tests.
cd apps/web
# Run unit tests (Vitest)
pnpm test
# Run tests in watch mode
pnpm test:watch
# Type-check only
pnpm typecheck
# Lint only
pnpm lint
# Backend
cd apps/api
uv run ruff check .
uv run mypy .
uv run pytest
# Frontend
cd apps/web
pnpm lint
pnpm typecheck
pnpm test
pnpm build
gift-delivery/
│
├── apps/
│ ├── api/ # FastAPI backend
│ │ ├── app/
│ │ │ ├── api/v1/endpoints/ # Route handlers
│ │ │ ├── core/ # Config, security, DB, rate limiting
│ │ │ ├── integrations/ # Stripe, Resend, Meilisearch, OAuth
│ │ │ ├── models/ # SQLAlchemy ORM models
│ │ │ ├── repositories/ # Database access layer
│ │ │ ├── schemas/ # Pydantic request/response schemas
│ │ │ ├── services/ # Business logic
│ │ │ ├── workers/ # Background tasks (Arq)
│ │ │ └── main.py # App factory
│ │ ├── alembic/versions/ # Database migrations (0001–0005)
│ │ ├── scripts/
│ │ │ └── seed.py # Seed cities, vendors, products
│ │ ├── tests/ # Pytest test suite
│ │ └── pyproject.toml
│ │
│ └── web/ # Next.js 15 frontend
│ ├── app/ # App Router pages
│ │ ├── (auth)/ # Login, register, forgot/reset password
│ │ ├── p/[slug]/ # Product detail
│ │ ├── c/[...slug]/ # Category pages
│ │ ├── vendor/[slug]/ # Vendor pages
│ │ ├── cart/ # Shopping cart
│ │ ├── checkout/ # Checkout flow
│ │ ├── account/ # User dashboard
│ │ └── track/[token]/ # Order tracking (public)
│ ├── components/
│ │ ├── auth/ # Login, register, forgot/reset forms
│ │ ├── layout/ # Header, Footer, ThemeToggle
│ │ └── ui/ # shadcn/ui base components
│ ├── hooks/ # useAuth, etc.
│ ├── lib/ # api.ts, utils.ts
│ ├── stores/ # Zustand stores (auth, cart)
│ ├── styles/globals.css
│ └── middleware.ts # Route guards
│
├── packages/
│ └── api-client/ # Generated OpenAPI TypeScript client
│
├── infra/
│ ├── docker-compose.yml # All local dev services
│ ├── Dockerfile.api # Production API image
│ └── Dockerfile.web # Production web image
│
├── docs/
│ ├── production-roadmap.md # Master plan with all milestones
│ ├── project-spec.md # Full product specification
│ ├── questions.md # All product decisions (resolved)
│ ├── state.md # Current resume point
│ └── decisions/0001-stack.md # Architecture Decision Record
│
├── .env.example # Environment variable template
├── .editorconfig
├── .pre-commit-config.yaml
├── pnpm-workspace.yaml
├── start.sh # ← One-command startup script
└── README.md # ← This file
| Migration | Tables created |
|---|---|
0001_auth_users | users, refresh_tokens, oauth_accounts, password_reset_tokens, addresses |
0002_catalog | cities, vendors, categories, products, product_images, product_cities |
0003_catalog_extensions | product_variants, occasions, product_occasions, product_categories, customization_fields, fx_rates |
0004_cart_orders | carts, cart_items, orders, order_items, fulfillments, payments |
0005_notifications_loyalty_reviews | notifications_outbox, loyalty_wallets, loyalty_ledger, reviews, coupons, banners, testimonials, audit_logs |
| Group | Prefix | Description |
|---|---|---|
| Health | /api/v1/healthz /api/v1/readyz | Liveness and readiness |
| Auth | /api/v1/auth/* | Register, login, refresh, logout, OAuth, password reset |
| Me | /api/v1/me | Profile + address CRUD |
| Catalog | /api/v1/cities /api/v1/vendors /api/v1/categories /api/v1/products | Public catalog |
| Search | /api/v1/search | Meilisearch passthrough |
Full interactive docs: http://localhost:8000/api/v1/docs
# Check what's using the ports
lsof -i :5433 # Postgres
lsof -i :6380 # Redis
lsof -i :7700 # Meilisearch
lsof -i :9000 # MinIO
# If ports are in use, either stop the conflicting process or change ports in
# infra/docker-compose.yml and update .env accordingly
cd apps/api
uv sync # reinstall dependencies
# Check Docker is running and postgres is healthy
docker compose -f infra/docker-compose.yml ps
# Restart just postgres
docker compose -f infra/docker-compose.yml restart postgres
# Check logs
docker compose -f infra/docker-compose.yml logs postgres
# Check current state
cd apps/api
uv run alembic current
# If the DB is corrupted or in a bad state (dev only — destroys data)
docker compose -f infra/docker-compose.yml down -v
docker compose -f infra/docker-compose.yml up -d
uv run alembic upgrade head
uv run python scripts/seed.py
cd apps/web
rm -rf node_modules .next
pnpm install
pnpm dev
All emails in development go to MailHog. Open http://localhost:8025 — they should be there. If MailHog isn't running:
docker compose -f infra/docker-compose.yml up -d mailhog
# Create the bucket manually
docker exec -it $(docker compose -f infra/docker-compose.yml ps -q minio) \
mc alias set local http://localhost:9000 minioadmin minioadmin
docker exec -it $(docker compose -f infra/docker-compose.yml ps -q minio) \
mc mb local/tahaif-media --ignore-existing
docker compose -f infra/docker-compose.yml down -v --remove-orphans
docker compose -f infra/docker-compose.yml up -d
cd apps/api
uv run alembic upgrade head
uv run python scripts/seed.py
docs/production-roadmap.md — understand what's built and what's nextdocs/project-spec.md — understand the product requirements./start.sh and verify everything worksBuilt with ❤️ for Pakistan.
SENTRY_DSN| — |
| No |
| Sentry error tracking DSN |
NEXT_PUBLIC_API_URL | http://localhost:8000/api/v1 | No | API base URL for browser |