This project is a demo laundry app adapted to use a local PostgreSQL database via Prisma (no Firebase).
Key points:
- Database: PostgreSQL on localhost port
55432(you can change the URL viaDATABASE_URL). - ORM: Prisma. Schema is in
prisma/schema.prisma. - API: Next.js Route Handlers under
app/api/*using the Prisma client inlib/prisma.ts. - Frontend: Client component mount at
app/components/AppClient.tsxandapp/page.tsxloads it.
Getting started (local development):
- Start a Postgres instance listening on port 55432. Example (Docker):
docker run --name laundry-postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_USER=postgres -e POSTGRES_DB=laundrydb -p 55432:5432 -d postgres:15- Set
DATABASE_URLin your environment (PowerShell example):
$env:DATABASE_URL = "postgresql://postgres:postgres@localhost:55432/laundrydb"- Install dependencies:
# from project root
npm install- Generate Prisma client and run migrations:
npx prisma generate
npx prisma migrate dev --name init
# optionally open Studio
npx prisma studio- Run the app:
npm run devNotes and next steps:
- The frontend uses a lightweight local identity (stored in
localStorage) for demo purposes. - The API endpoints are under
/api/shopsand/api/orders. - For production you should add proper auth, validation, and tests.
This is a Next.js project bootstrapped with
create-next-app.
First, run the development server:
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun devOpen http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.
This repository includes a middleware.ts that protects routes under /api/* so that requests are allowed only when one of the following is true:
- The request
OriginorRefererheader matches the app origin (value set inNEXT_PUBLIC_APP_URL), or - The request contains the internal header
x-internal-secretwith a value equal toNEXT_INTERNAL_API_SECRET(server-to-server calls).
This approach lets your Next.js frontend (browser) call APIs normally when served from the same origin, and also lets server-side code (server components / API routes) call the API by attaching a secret header that is never exposed to the browser.
Environment variables to configure:
NEXT_PUBLIC_APP_URL— the public URL of your app (example:https://example.comorhttp://localhost:3000for dev). This is used to allow browser-originated requests.NEXT_INTERNAL_API_SECRET— a server-only secret used by server-side fetches to identify internal requests. DO NOT prefix this withNEXT_PUBLIC_and DO NOT commit it.
Server-side fetch example (use only from server code; e.g., in an API route or server component):
# PowerShell example, environment variable is available on the server
$env:NEXT_INTERNAL_API_SECRET = "your-secret-here"
# Node / server-side fetch example (inside a server component or API route)
await fetch(`${process.env.NEXT_PUBLIC_APP_URL}/api/orders`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-internal-secret': process.env.NEXT_INTERNAL_API_SECRET,
},
body: JSON.stringify({ /* payload */ }),
})Notes and caveats:
- This middleware is a defense-in-depth mechanism. Determined attackers can spoof headers; for strong security you should still require proper authentication (sessions, JWTs) and server-side authorization checks inside your API handlers.
- The
NEXT_INTERNAL_API_SECRETmechanism is intended for server-to-server calls originating from your Next.js server (server components or API routes). Never expose that secret in client-side code.