TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Next.js (App Router) + TypeScript + Tailwind CSS + Supabase. See CLAUDE.md for the plan.
Open http://localhost:3000.檢視完整 README ↗Next.js (App Router) + TypeScript + Tailwind CSS + Supabase. See CLAUDE.md for the plan.
npm install
cp .env.example .env.local # then fill in the Supabase values
npm run dev
Open http://localhost:3000.
| Variable | Exposure | Purpose |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | public | Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | public | anon key |
SUPABASE_SERVICE_ROLE_KEY | server-only secret | admin client (lib/supabase-admin.ts); bypasses RLS |
NEXT_PUBLIC_SITE_URL | public | base URL for auth redirect links (magic link, OAuth, email confirm) |
ANTHROPIC_API_KEY | server-only secret | Claude vision extraction |
EXTRACTION_WEBHOOK_SECRET | server-only secret | shared secret for /api/extraction; must match the Supabase Vault secret extraction_webhook_secret |
INTERNAL_TOOLS_EMAILS | server-only | optional CSV allow-list for /internal/* pages |
RESEND_API_KEY | server-only secret | Resend key for reminder email; unset = reminders are logged as skipped, not sent |
REMINDERS_FROM_EMAIL | server-only | From: address for reminder email, on a domain verified in Resend |
CRON_SECRET | server-only secret | bearer token for /api/cron/reminders and /api/cron/school-calendars; Vercel sends it automatically once set |
STRIPE_SECRET_KEY | server-only secret | Stripe key; unset = billing off, every household keeps the paid entitlements |
STRIPE_WEBHOOK_SECRET | server-only secret | signing secret for /api/stripe/webhook; unset = the webhook no-ops |
STRIPE_PRICE_GBP_MONTHLY | server-only | price ID offered to UK households, £7.99/mo |
STRIPE_PRICE_GBP_YEARLY | server-only | price ID offered to UK households, £69/yr |
STRIPE_PRICE_USD_MONTHLY | server-only | price ID offered to US households, $6.99/mo |
STRIPE_PRICE_USD_YEARLY | server-only | price ID offered to US households, $59/yr |
GOOGLE_CLIENT_ID | server-only | OAuth client ID for Gmail read-only import (separate from Supabase sign-in Google) |
GOOGLE_CLIENT_SECRET | server-only secret | OAuth client secret for Gmail import |
Set the secrets in the Vercel project settings (Production + Preview).
NEXT_PUBLIC_SITE_URL must match the deployment origin (https://homeapp-mu.vercel.app).
Migrations live in supabase/migrations/ and are already applied
to the linked project. Tables: households, household_members, properties,
household_invites, documents, document_chunks, reminder_rules, reminders,
reminder_events, subscriptions, renewal_items, household_calendar_feeds; plus a
private documents Storage bucket. Every table has row-level security scoped to household
membership. The subscriptions, renewal_items and household_calendar_feeds
migrations are written but not yet applied.
Read-only Gmail import lets a household scan the last 12 months of inbox PDFs, review candidates, and confirm what to file — nothing is stored until import.
Google Cloud setup (Ross):
https://homeapp-mu.vercel.app/api/gmail/callback (production)http://localhost:3000/api/gmail/callback (local)GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in .env.local and Vercel.20260914130000_gmail_import.sql if not already applied.The OAuth scope is gmail.readonly only. Tokens are stored server-side; members
disconnect from the Add document sheet.
A new documents row (extraction_status = 'pending') fires a Supabase database
webhook → POST /api/extraction → Claude (claude-sonnet-4-6) vision extraction →
fields + confidence written back, full text chunked into document_chunks. Review and
confirm extracted fields on /documents. /internal/extraction-test is a benchmark
harness (not linked from any nav).
Document email reminders — every extracted or confirmed document with a future
renewal (or, failing that, end) date gets a reminders row, written server-side by
syncRemindersForDocument() in lib/reminders.ts whenever
extraction finishes or a review is confirmed. How far ahead to nudge comes from
reminder_rules, keyed on the category from lib/home-overview.ts and the household's
locale — 60/30/7/0 days by default.
Tracked renewals (phase 9) — passports, MOT, insurance and the like live in
renewal_items, managed on /family and surfaced in Coming up inside each item's
remind window. They do not send email yet; the cron only covers document reminders.
GET /api/cron/reminders runs daily at 08:00 UTC (see vercel.json),
emails every household member whose reminder falls due that day via Resend, and logs
each send in reminder_events — the unique (reminder_id, offset_days) there is what
stops a nudge going out twice. The day-of send closes the reminder off as sent.
GET /api/cron/school-calendars runs daily at 06:15 UTC on the same CRON_SECRET,
re-reading every school's linked ICS feed through syncSchoolCalendar() so term dates
on the dashboard stay fresh. It takes at most 50 schools a run, stalest first, and one
unreadable feed is recorded against that school rather than failing the run.
Free households keep unlimited documents but get three live reminders, no export and (later) no AI answers. Paying lifts all of that: £7.99/mo or £69/yr in the UK, $6.99/mo or $59/yr in the US, cancelled in one click from Stripe's billing portal.
Billing is off until STRIPE_SECRET_KEY is set, and off means inert —
lib/billing.ts hands back the paid entitlements, so the gates
change nothing for anyone until the keys are in place. With the key set, plans come
off the subscriptions table: POST /api/stripe/checkout starts a Checkout Session
(household id in the metadata), POST /api/stripe/portal opens the portal, and
POST /api/stripe/webhook verifies Stripe's signature against the raw body and
writes the row on the service role. /settings shows the plan and the buttons.
The subscriptions migration is written but not yet applied to the project.
Invite a partner or another adult from Family or Settings → People. The app
creates a single-use link (expires in 7 days) you share yourself — no email is sent.
The invitee opens /join/<token>, signs in or creates an account, and joins as a
member with full household access. Legacy email invites on /invite still work when
sent to the matching address.
Apply migration 20260926140000_household_invite_links.sql before link invites work
in production.
Kid view — from Family → People, edit a child and create a kid view link. Anyone
with the URL sees a read-only schedule for that child only (today + six days, Europe/London):
school timetable (including kit/ingredients reminders), key dates linked to them, their
school's cached term dates, who's-where status, and a birthday countdown within two weeks.
No documents, renewals, routines, meals, other household members, or notes. The link has
no expiry; regenerate or turn off revokes the old URL. Apply
20260926160000_person_kid_links.sql before it works in production.
For local UI screenshots only (not committed):
/dev-sharing-preview?view=invite|join|join-signedout|kid|kidlink.
${NEXT_PUBLIC_SITE_URL}/auth/callback (and
${NEXT_PUBLIC_SITE_URL}/auth/callback** or per-path entries if your project needs
them for ?next= on OAuth/magic links), plus
${NEXT_PUBLIC_SITE_URL}/auth/native-bridge (local and prod) to the redirect
allow-list; set the Site URL to the prod origin. The native-bridge URL is used by
the Capacitor iOS shell for Google OAuth (in-app browser → deep link back).${SUPABASE_URL}/auth/v1/callback as an authorized redirect URI in Google Cloud.
Until then the "Continue with Google" button returns an error; email + magic link work.extraction_webhook_url and extraction_webhook_secret are set on
the project (URL → https://homeapp-mu.vercel.app/api/extraction). The secret must
match Vercel's EXTRACTION_WEBHOOK_SECRET.App Store requirement (5.1.1(v)): users can delete their account from Settings →
Account. The flow is implemented in lib/account-deletion.ts
(deleteAccountForUser) and called from app/actions/account.ts.
Before deleting, users can Download my data (same zip as /api/export). Deletion
cancels Stripe subscriptions on sole-member households when billing is configured;
aborts if a live subscription row exists but Stripe is not set up. Gmail tokens are
revoked best-effort. Storage under sole-member <household_id>/ prefixes is removed
before the auth user is deleted (failure aborts). Shared households keep their data;
if the leaving member was owner, migration
20260926170000_household_owner_transfer.sql promotes the longest-standing remaining
member.
Public pages: /account-deletion (instructions),
/account-deleted (confirmation after delete).
End-to-end harness (not committed): npx tsx .agent-logs/account-deletion-e2e.mts —
run after applying the owner-transfer migration.
Vercel builds from main.