尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Multi-currency personal finance dashboard — accounts, transactions, net worth, cash-flow forecasting, savings objectives, and loans.
Built with Next.js 16 (App Router), Postgres on Neon, and Tailwind + shadcn/ui.
Requires Node 20+ and a Postgres database.
npm install
Create .env.local:
DATABASE_URL=postgres://... # Neon pooled connection string
SESSION_SECRET=... # openssl rand -base64 32
If the project is linked to Vercel, DATABASE_URL is already set there and can
be pulled with vercel env pull. Generate SESSION_SECRET yourself — rotating
it invalidates every existing session.
Apply the schema, then start the dev server:
npm run db:migrate
npm run dev
Sign up at /login to create the first account.
Database. Plain Postgres, accessed with the Neon serverless driver through
tagged-template queries in src/lib/queries.ts (reads) and the per-route
actions.ts files (writes). Values interpolated into sql`...` are sent as
bound parameters, not concatenated.
Auth. Email + password, hashed with scrypt (src/lib/password.ts). Sessions
are stateless JWTs signed with SESSION_SECRET and stored in an httpOnly cookie
(src/lib/session.ts).
Authorization. This is the part worth understanding. There is no Row Level
Security — that was a Supabase feature built on auth.uid(), and it does not
exist here. Every query that touches user data must filter on user_id
explicitly, and the id must come from requireUserId() in src/lib/dal.ts,
never from a form field or a client argument.
src/proxy.ts also redirects signed-out visitors, but that check is optimistic
only — it reads the cookie and never queries the database. It is not the
security boundary; the user_id filter is.
SQL files in migrations/, applied in filename order by npm run db:migrate.
Each runs in a transaction and is written to be idempotent, so re-running is
safe. Add new files as 0002_*.sql, 0003_*.sql, and so on.