WallpaperMachine
The wallpapers you love. A new home on your Mac.
Know what you have, what's about to expire, and what to cook.
LifestyleJavaScript · TypeScriptGitHub @mcab4196-gitOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗Personal kitchen inventory, expiry tracking, and AI meal planning. Mobile-first PWA.
Stack: Next.js 15 (App Router) · React 19 · TypeScript · Tailwind · PostgreSQL (Supabase) · Prisma · Supabase Auth + Storage · Vercel.
What works after setup:
/login.Inventory entry, receipt scanning, recipes, etc. arrive in later milestones.
psql on your PATH (ships with the Postgres client tools) for applying RLS.npm install
From your Supabase dashboard:
Project URL and the anon public key.6543) and direct (Session, port 5432) URIs.cp .env.example .env
Fill in .env. The two Postgres URLs matter:
DATABASE_URL → pooled connection, port 6543, must end with ?pgbouncer=true. Used at runtime.DIRECT_URL → direct connection, port 5432. Used for migrations, RLS, and seeding.npm run db:generate # generate the Prisma client
npm run db:migrate # create tables (uses DIRECT_URL)
npm run db:rls # runs prisma/rls.sql against DIRECT_URL via psql
Alternatively, paste
prisma/rls.sqlinto the Supabase SQL editor and run it.
npm run db:seed
Expected output ends with something like:
Seed complete: { categories: 12, ingredients: 23, aliases: ~70, shelfLifeRules: 22, units: 14 }
npm run dev
Open http://localhost:3000 → you'll be redirected to /login.
/auth/callback). For local dev you can disable "Confirm email" in Supabase → Authentication → Providers → Email./dashboard, greeted by time of day, with three zero-valued stat cards and an empty-state prompt. This confirms auth + Prisma + user-scoped queries all work end-to-end.profiles, confirm a row was auto-created for your user (the trigger). A user_preferences row is created on first dashboard load./login and the guard blocks /dashboard until you sign back in.profiles/inventory_items rows via the Supabase client.Runtime data access goes through Prisma, which connects with a privileged role and therefore bypasses RLS. Primary authorization is enforced in the service/query layer: every query is scoped to the authenticated user.id (see the dashboard queries for the pattern). RLS is defense-in-depth — it governs the anon/authenticated roles used by the browser Supabase client and Storage, so a leaked anon key can never read another user's rows. Keep both layers; don't rely on either alone.
prisma/
schema.prisma # full data model
rls.sql # signup trigger + RLS policies
seed.ts # reference data
src/
app/
(auth)/login/ # login page + auth server actions
(app)/ # authenticated shell (dashboard + tab stubs)
auth/callback/ # email-confirm / OAuth callback
components/ # bottom nav, UI primitives
lib/
supabase/ # browser / server / middleware clients
env.ts # validated env
server/db.ts # Prisma singleton
middleware.ts # session refresh + route guard
Environment variable not found: DATABASE_URL — you haven't created .env, or you're running a DB command that needs DIRECT_URL.prepared statement errors — your DATABASE_URL is missing ?pgbouncer=true./login in a loop — the anon key or Supabase URL is wrong, so getUser() never resolves a session.db:migrate at the pooled URL; migrations must use the direct (5432) connection.Manual add/edit/delete inventory, search/filter/sort, the expiry engine with status badges, and the cook/deduction flow. The schema and seed data here already support all of it.