尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證PawPoints marketing site — landing page, privacy, terms
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗The marketing site, sign-up flows, merchant portal and founder admin tools for PawPoints — the NZ dog-walking rewards app. The mobile app itself lives in a separate repository; both share one Supabase project (database, auth, storage).
Last reviewed: 30 Sep 2026.
main; every merge to main deploys www.pawpoints.co.nz)send-store-code edge function (Resend)| Route | What it is |
|---|---|
/ | Homepage: hero, how-it-works, Fair-Paw goals, business pitch, mascot gallery, Play Store links. Nav: "Log in" + "Join for free" |
/how-points-work | Points-earning explainer |
/why-it-matters | Mission page |
/gallery | Featured mascot photo gallery (public bucket) |
/join-walker | Walker sign-up: account + first dog metadata (server trigger builds profile/dog), email-link verification |
/join-merchant | Merchant application: creates the account, files a merchant_applications row, requires viewing + agreeing to Merchant Terms (v1.1 recorded), email-link verification, triggers the founder alert |
/email-confirmed | Landing page for the confirmation link: congratulations + Play Store QR + "iOS coming soon", celebration overlay |
/login, /forgot-password, /reset-password | Auth pages |
/terms, /privacy, /merchant-terms, /delete-account | Legal + account deletion |
Site-wide: SiteCelebration mounts an ambient celebration (confetti,
fireworks, Hugo running slow laps — 45 s/lap) on marketing pages only;
excluded on portal/admin/legal pages; honours prefers-reduced-motion.
/account (+ /account/rewards, /account/friends, /account/photos):
walker's web account — points history, friends, photos./merchant: merchant portal — owner views their business and proposes/edits
rewards through owner-gated SECURITY DEFINER RPCs (get_my_merchant,
merchant_list_rewards, merchant_upsert_reward,
merchant_set_reward_active, reward message thread RPCs). Proposals land
approval='pending'./admin/rewards: founder-only review queue (gated by app_admins /
is_app_admin), calls admin_review_reward(p_id, p_verdict, p_message)
with verdicts approve / changes / reject.Merchant application → live merchant
/join-merchant signs the account up (link verification via
/auth/callback?next=/email-confirmed), inserts the application with a
client-generated id (RLS allows anon insert but not select), then POSTs
/api/applications/notify.notify (service role) re-reads the row, emails the founder every field
plus an HMAC-signed Approve link, stamps notified_at (idempotent)./api/applications/approve verifies the HMAC and calls the
admin_approve_application(app_id uuid) → jsonb DB function
(supabase/admin_approve_application.sql): merchants row (unique slug,
5-digit store code), owner link in merchant_operators, trial
merchant_subscriptions row, application marked approved, best-effort
store-code email via the send-store-code edge function. Idempotent on
re-click. PIN and address/lat/lng stay manual on purpose.Reward proposal → live reward
reward_review_alert → public.notify_reward_review,
pg_net) POSTs to /api/rewards/notify with an x-webhook-secret header.notify emails the founder the full offer (photo, description, terms,
validity, 1,000-point wallet-cap warning) with signed Approve/Reject
links; review_notified_at makes it idempotent./api/rewards/review: Approve is one click → live immediately; Reject
shows a form demanding a reason, which is saved to the reward's message
thread. The merchant's verdict email is sent by the
pp_notify_reward_verdict DB trigger, so it fires identically from the
email links, /admin/rewards, or the app.Both flows detect already-registered emails on sign-up (Supabase's
anti-enumeration fake success: empty identities) and show a
"this email already has an account" message instead of waiting for an email
that will never come.
| Var | Purpose |
|---|---|
NEXT_PUBLIC_SUPABASE_URL / NEXT_PUBLIC_SUPABASE_ANON_KEY | optional overrides; public defaults are in lib/supabase/config.ts |
SUPABASE_SERVICE_ROLE_KEY | server routes (bypasses RLS) — secret |
SMTP_USER, SMTP_PASS, SMTP_FROM, (SMTP_HOST, SMTP_PORT) | founder alert emails (Gmail app password) |
APPROVAL_SECRET | HMAC key for approve/reject links |
REWARDS_WEBHOOK_SECRET | shared secret the reward DB trigger sends in x-webhook-secret |
{{ .ConfirmationURL }} (link flow)https://www.pawpoints.co.nz/auth/callback (+ non-www)pg_net extension + reward_review_alert trigger on merchant_rewardssupabase/admin_approve_application.sql appliedmerchant_applications.status/approved_at/notified_at,
merchant_rewards.review_notified_atnpm install
npm run dev # http://localhost:3000
npx tsc --noEmit && npx eslint app lib && npm run build # pre-push checks
See AGENTS.md for contributor/agent conventions (including: this Next.js
version has breaking changes — read node_modules/next/dist/docs/ first).