Node.js + Express + SQLite backend for the house plan catalog frontend.
cd backend
npm install
cp .env.example .env # then edit ADMIN_KEY to your own secret
npm run seed # creates blueline.sqlite and loads the 12 starter designs
npm start # runs on http://localhost:4000Use npm run dev instead of npm start during development (auto-restarts on file changes).
The database is a single file, db/blueline.sqlite, created automatically. Delete it and re-run npm run seed to reset.
There are no user accounts yet — write operations (create/update/delete a house, list or update plan requests) are protected by a single shared secret. Send it as a header:
x-admin-key: <value from .env>
Anyone submitting a plan request from the public site does not need this header.
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/houses |
— | List houses. Query params: type, minBeds, maxBeds, search |
| GET | /api/houses/types |
— | Distinct list of house types currently in the DB |
| GET | /api/houses/:id |
— | Single house with full spec sheet |
| POST | /api/houses |
admin | Create a house |
| PUT | /api/houses/:id |
admin | Update a house (partial updates allowed) |
| DELETE | /api/houses/:id |
admin | Delete a house |
House JSON shape (matches the frontend's existing mock data fields):
{
"id": 1,
"type": "Villa",
"variant": "villa",
"name": "Lakeview Villa",
"area": "4,200",
"plot": "60x80",
"beds": 5,
"floors": 2,
"desc": "A five-bedroom villa with a rear-facing living room...",
"features": ["Floor-to-ceiling rear glazing", "Home office wing"]
}type must be one of: Bungalow, Duplex, Villa, Cottage, Apartment, Farmhouse.
variant should match one of the SVG keys already in the frontend (bungalow, duplex, villa, cottage, apartment, farmhouse) so the right line-art elevation renders.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/requests |
— | Submit a plan request (the "Request this plan" / "Request a custom plan" forms) |
| GET | /api/requests |
admin | List requests, optional ?status=new|contacted|closed |
| PATCH | /api/requests/:id |
admin | Update a request's status |
POST body:
{
"houseId": 5,
"name": "Asha Rao",
"email": "asha@example.com",
"phone": "9876543210",
"plotDims": "40x60, east-facing",
"message": "Need this adapted for a sloped plot."
}houseId is optional — omit it for the general "custom plan" request at the bottom of the site.
The frontend currently uses a hardcoded houses array in its <script> tag. To connect it to this API:
- Replace the hardcoded array with a fetch call:
const res = await fetch('http://localhost:4000/api/houses'); const houses = await res.json();
- Update the filter bar to call
GET /api/houses/typesinstead of a hardcoded list, if you want it to stay in sync automatically as you add new house types. - Point the "Request this plan" and "Request a custom plan" buttons at
POST /api/requestsinstead of themailto:links.
CORS is open (*) by default for local development — set CORS_ORIGIN in .env to your real frontend URL before deploying.
backend/
├── db/
│ ├── db.js # connection + schema
│ └── seed.js # starter data (run with npm run seed)
├── middleware/
│ └── auth.js # x-admin-key check
├── routes/
│ ├── houses.js
│ └── requests.js
├── server.js
├── package.json
└── .env.example