尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Scan. Pay. Done. — pay your electricity bill by scanning the QR code on your meter.
VoltPay V2 is a secure, installable web app (PWA) built with Next.js. The full plan, including the V1 audit and the delivery phases, is in docs/PLAN_V2.md.
Prototype: billing data is simulated and payments run in Razorpay test mode. No real money moves.
Next.js 16 (App Router, React 19) · TypeScript · Tailwind CSS 4 + shadcn/ui-style components · PostgreSQL · Drizzle ORM · Better Auth · Zod · Vitest · GitHub Actions. Runtime: Node.js 24 LTS.檢視完整 README ↗Scan. Pay. Done. — pay your electricity bill by scanning the QR code on your meter.
VoltPay V2 is a secure, installable web app (PWA) built with Next.js. The full plan, including the V1 audit and the delivery phases, is in docs/PLAN_V2.md.
Prototype: billing data is simulated and payments run in Razorpay test mode. No real money moves.
| Phase | Scope | Status |
|---|---|---|
| 0 | Housekeeping: V1 removed from the tree (kept in git tag v1.0) | ✅ Done |
| 1 | Foundation: Next.js 16, Postgres + Drizzle, Better Auth, roles, CI | ✅ Done |
| 2 | Core flow: meters, signed QR, scanner, bills, Razorpay, receipts | ✅ Done |
| 3 | Customer features: link meters, bills, usage chart, complaints | ✅ Done |
| 4 | Admin console: meters, billing cycle, tariffs, complaints, audit | ✅ Done |
| 5 | PWA (installable, offline page), reminder emails, contact inbox | ✅ Done |
| 6 | Hardening & launch: CSP, rate limits, E2E + a11y tests, deploy docs | ✅ Done |
Next.js 16 (App Router, React 19) · TypeScript · Tailwind CSS 4 + shadcn/ui-style components · PostgreSQL · Drizzle ORM · Better Auth · Zod · Vitest · GitHub Actions. Runtime: Node.js 24 LTS.
Prerequisites: Node.js 24+ and a free Neon Postgres database (create a project, then copy its connection string).
# 1. Install dependencies
npm install
# 2. Configure environment
cp .env.example .env.local
# then set DATABASE_URL (Neon), BETTER_AUTH_SECRET and QR_SIGNING_SECRET
# (generate each with: openssl rand -base64 32)
# and, when you have them, RAZORPAY_KEY_ID / RAZORPAY_KEY_SECRET (test mode)
# 3. Create tables, demo accounts and demo meters/bills
npm run db:migrate
npm run db:seed
# 4. Run the app
npm run dev # http://localhost:3000
No Docker needed. A local Postgres via
docker compose up -dalso works if you prefer (use theDATABASE_URLfromdocker-compose.yml).
localhost; on a laptop you can also use the consumer-number box on /scan, e.g. VP-2024-000101)..env.local, a simulated checkout is used (development only; it is disabled in production). With real test keys, the Razorpay checkout opens (use Razorpay's test cards / UPI).npm run db:seed -- --fresh to reset the demo data, or sign in as admin and use Billing → Run billing cycle to create the next bills.| Role | Password | |
|---|---|---|
| Admin | [email protected] | Admin@12345 |
| Customer | [email protected] | Customer@12345 |
In production, set SEED_* variables instead; the seed script refuses default passwords there.
npm run build && npm start, then open the site on your phone/Chrome and choose Install app (button in the footer) or Add to Home Screen. Offline, the app shows the last bill you viewed on that device (amount, due date, meter number only; cleared on sign-out)./api/cron/daily, protected by CRON_SECRET) marks past-due bills overdue and emails customers 3 days before the due date and once when overdue (each at most once; customers can turn them off on their profile). Without RESEND_API_KEY, emails are printed to the server console in development. Admins can run the job from Admin → Billing → Run daily job now./contact page (rate-limited, honeypot) → Admin → Inbox.| Command | What it does |
|---|---|
npm run dev | Dev server with hot reload |
npm run build / npm start | Production build / serve |
npm run lint · npm run typecheck · npm test | Quality checks (also run in CI) |
npm run e2e | Browser tests (Playwright) incl. accessibility |
npm run format | Format with Prettier |
npm run db:generate | Create a migration after editing src/db/schema/* |
npm run db:migrate | Apply migrations |
npm run db:seed | Create demo accounts |
npm run db:studio | Browse the database in Drizzle Studio |
src/
app/ routes: /, /login, /signup, /dashboard, /meters/*, /payments, /complaints, /profile, /scan, /m/[code], /receipts/[id], /admin/* (meters, billing, bills, payments, tariffs, complaints, audit, qr), /api/auth/*, /api/webhooks/razorpay
components/ UI (components/ui = shadcn-style primitives)
db/ Drizzle schema, migrations, connection
lib/ auth (server + client), env validation, utils
server/ server-only logic: authorization helpers, services
proxy.ts optimistic auth redirect for protected routes
tests/unit/ Vitest unit tests
docs/ V2 plan, original plan PDF, legal notes
npm test runs the unit tests. npm run e2e runs the browser tests against a dev server and re-seeds the database first, so point DATABASE_URL at a throw-away database, not data you care about. First time only: npx playwright install chromium. The suite covers the guest scan→pay→receipt flow, the customer area, the admin console, security headers, and WCAG A/AA accessibility checks on every main page.
See docs/DEPLOY.md (Vercel + Neon + Razorpay + Resend, backups) and docs/DEMO.md (the demo script).
requireUser() / requireAdmin() from src/server/authz.ts. proxy.ts is only a fast redirect, not the security boundary.src/proxy.ts) blocks injected scripts; Razorpay's checkout is explicitly allowed.src/lib/env.ts..env.local or any *.db file. The V1 database contained real contact details and is deliberately git-ignored.components.json is configured for shadcn/ui, so you can run npx shadcn@latest add dialog (for example) to add more components.