尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗A small digital version of a landlord's rent book: record a rent payment,
send the tenant a link over WhatsApp/SMS, they draw a signature and verify an
SMS OTP, and a signed PDF receipt is generated for both sides. Payments and
corrections are append-only - see supabase/migrations/0001_init.sql for the
ledger design.
Stack: Next.js (App Router) on Vercel, Postgres/Auth/Storage on Supabase, Twilio for SMS OTP + WhatsApp/SMS delivery.
supabase db push with the Supabase CLI, or Project →
SQL Editor → paste and run each file in supabase/migrations/ in
order (0001 … 0007): 0003 single owner (app_owner), 0004
transactional ledger functions and rate limiting, 0005 the private
rent-register storage bucket, 0006 the site → tower → house master
data and dated tenancies, 0007 draft tenants. The design and its reasons are in
docs/database-design.md.
0006 refuses to run if properties or tenants already exist. On a
project with only test data, first run
supabase/scripts/reset_owner_data.sql (it deletes every property,
tenant and payment).supabase/seed/arnapal_master_data.sql, and run it in the SQL Editor. It
registers you as the one owner (app_owner) and creates the 2 sites, 7
towers and 40 houses from the paper register. Then run
supabase/seed/arnapal_tenants.sql (local only - it holds real occupant
names, so it's gitignored and not in the repo), which adds the register's
26 occupants as draft tenants on their houses. Open each one in the app
and use Edit to add the phone, combined monthly rent and lease start; that
makes it active and starts billing. Both seeds are safe to re-run.
Until an owner is registered the database shows nobody anything; to hand
the rent book to another account later, update the app_owner row by
hand.0005_storage.sql creates the bucket
(private, PNG/PDF only, 2 MB per file). The app only reads/writes it with
the server-side secret key and mints short-lived signed URLs.NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEYSUPABASE_SECRET_KEY (never expose
this to the browser)http://localhost:3000 for local dev) to the redirect
allow-list, since the login flow redirects to /auth/callback.The owner never needs Twilio to sign in. Without it the app still works: payments count, receipts download, and the "send to tenant" step shows as "not delivered". Add it whenever you're ready; no code change is needed.
TWILIO_ACCOUNT_SID
/ TWILIO_AUTH_TOKEN.TWILIO_VERIFY_SERVICE_SID.TWILIO_SMS_FROM (E.164 format, e.g. +14155551234).whatsapp:+14155238886 by default) as
TWILIO_WHATSAPP_FROM - each tenant needs to send the sandbox join code
once. For production, apply for a WhatsApp Business Platform sender
through Twilio (takes Meta approval) and use that number instead.cp .env.local.example .env.local
# fill in the values from steps 1-2, plus:
# NEXT_PUBLIC_APP_URL - http://localhost:3000 for now
# OWNER_EMAILS - your email, so you can create your owner account
# ALLOW_DEV_LOGIN=1 - optional: show the sign-in link on screen instead of emailing it
npm install
npm run dev
Open http://localhost:3000, sign in with the Email link tab, then go
to Profile → Password and set a password - from then on the Password tab
signs you in without email. Then add a property, a tenant, and record a
payment.
Every variable is validated when the server starts (src/server/env.ts).
Twilio may be left empty anywhere (messages then show as "not delivered";
a production server logs a warning). CRON_SECRET may be empty in
development - the cron endpoint then stays locked - but is required in
production.
Who can sign in: with OWNER_EMAILS set, only those emails (and they may
create their account on first sign-in). Without it, only accounts that
already exist in Supabase Auth can sign in; nobody can sign up by typing an
email.
npm run lint
npm run typecheck
npm test # unit + service tests, and every migration run against an in-process Postgres
npm run build
CI (.github/workflows/ci.yml) runs the same on every push and pull request.
app_owner. Under Authentication → URL Configuration set the Site URL to
the production URL and add https://<your-app>.vercel.app/auth/callback
to the redirect allow-list.NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY,
SUPABASE_SECRET_KEY, NEXT_PUBLIC_APP_URL (the production URL),
OWNER_EMAILS and a CRON_SECRET of 16+ random characters (the server
refuses to start without it). Twilio may stay unset for now. Don't set
ALLOW_DEV_LOGIN - it is ignored in production anyway.vercel.json runs the functions in Mumbai (bom1), next to the
Supabase project (ap-south-1) - every page makes several database round
trips, so keep the two in the same region if either moves. It also
schedules /api/cron/ensure-periods to run daily - Vercel automatically sends Authorization: Bearer $CRON_SECRET
for cron invocations, so no extra setup is needed.TWILIO_* variables and redeploy.Houses and tenants: a tenant is onboarded onto one or more vacant houses (across towers if needed) with one combined monthly rent, billed per tenant. Editing a tenant can swap houses from a date or change the rent from a month; earlier months keep the old rent. "Move out" ends their houses, which can be re-let from the next day; their dues stay on their ledger. Each house keeps its full occupancy history.
Currency: edit CURRENCY_SYMBOL in src/lib/money.ts.
Time zone: "today" and month boundaries follow APP_TIME_ZONE
(Asia/Kolkata) in src/lib/dates.ts.
Owner name on receipts: taken from the owner's Supabase Auth profile
(full_name in user metadata - set it under Authentication → Users), else
their email.
Rate limits: OTP sends (5/hour per record, 20/hour per IP), confirm
attempts and sign-in emails are capped in Postgres (rate_limits, pruned by
the daily cron).
Link lifetime: confirmation links expire after 14 days
(CONFIRM_LINK_TTL_DAYS in src/server/token.ts); the owner can resend a
fresh link from the tenant's page.
Corrections: a confirmed payment is never edited - use "Adjust" on the tenant's page to record a correction, which goes through the same signature + OTP flow with the tenant before it changes anything.
Cost at this scale should be close to Supabase's and Vercel's free tiers, plus a few dollars a month in Twilio per-message charges.