221 lines
7.2 KiB
Markdown
221 lines
7.2 KiB
Markdown
# Debbie Windler Seamstress Website
|
|
|
|
Self-hosted website and owner administration system for `debbiewindlerseamstress.com`.
|
|
|
|
This project is intentionally a small, understandable Node.js application with Express, SQLite, session login, local image storage, Docker support, backups, and a nontechnical owner backend. It does not include checkout, customer accounts, public comments, customer uploads, payments, or scheduling.
|
|
|
|
## What Was Built
|
|
|
|
- Four public pages: Home, Items, Services, About and Contact.
|
|
- Full-screen editable hero with replaceable background image, overlay, position, text, and buttons.
|
|
- Editable featured/new/sale item showcase.
|
|
- Alphabetical item browsing with search and filters.
|
|
- Editable services page.
|
|
- Editable about text and equipment list.
|
|
- Website contact form that stores messages in SQLite even when email notification is not configured or fails.
|
|
- Secure first-owner setup flow at `/admin/setup`.
|
|
- Owner login at `/admin`.
|
|
- Admin dashboard, page editor, item manager, service manager, about/equipment manager, messages inbox, media library, appearance settings, navigation settings, business settings, search/sharing settings, security settings, backups, and maintenance mode.
|
|
- Local image upload validation and WebP optimization through Sharp.
|
|
- Manual downloadable backup archives for the database and uploaded images.
|
|
- Docker and Docker Compose support.
|
|
- Sample content and one sample sewing-themed hero image that should be replaced with Debbie's real artwork/photos.
|
|
|
|
## Project Location
|
|
|
|
`C:\Users\Owner\Documents\UO private Server\DebbieWindlerSeamstress`
|
|
|
|
## Local Development
|
|
|
|
Install Node.js 24 or newer, then from this folder:
|
|
|
|
```powershell
|
|
pnpm install
|
|
pnpm run init-db
|
|
pnpm run dev
|
|
```
|
|
|
|
Open:
|
|
|
|
```text
|
|
http://localhost:3000
|
|
```
|
|
|
|
If `pnpm` is not installed globally, `npm install` and `npm run dev` also work.
|
|
|
|
## First Owner Setup
|
|
|
|
1. Start the site.
|
|
2. Set a private `SETUP_TOKEN` in `.env`.
|
|
3. Open `http://localhost:3000/admin/setup?token=YOUR_SETUP_TOKEN`.
|
|
4. Enter owner name, email, and a password with at least 10 characters.
|
|
5. After setup, future visits to `/admin` use the owner login screen.
|
|
|
|
No administrator password is hardcoded or stored as plain text.
|
|
|
|
## Common Owner Tasks
|
|
|
|
Edit the home page:
|
|
|
|
1. Log in at `/admin`.
|
|
2. Choose `Home Page`.
|
|
3. Change hero text, background URL, overlay, buttons, and showcase text.
|
|
4. Use `Preview Home Page`.
|
|
|
|
Add an item:
|
|
|
|
1. Choose `Items`.
|
|
2. Choose `Add Item`.
|
|
3. Fill in name, descriptions, category, price notes, availability, badges, and publish setting.
|
|
4. Upload one or more item images.
|
|
5. Save.
|
|
|
|
Read a customer message:
|
|
|
|
1. Choose `Messages`.
|
|
2. Open a message.
|
|
3. Use `Reply by Email` to open the computer's normal email program.
|
|
4. Mark unread, archive, or delete as needed.
|
|
|
|
Create a backup:
|
|
|
|
1. Choose `Backups`.
|
|
2. Choose `Create Manual Backup`.
|
|
3. Download the created ZIP file.
|
|
|
|
## Environment Setup
|
|
|
|
Copy `.env.example` to `.env` for local or production configuration.
|
|
|
|
Important values:
|
|
|
|
- `PORT`: app port, default `3000`.
|
|
- `APP_BASE_URL`: final public URL, for example `https://debbiewindlerseamstress.com`.
|
|
- `SESSION_SECRET`: long random secret for sessions.
|
|
- `SETUP_TOKEN`: private one-time setup token required before the first owner account can be created.
|
|
- `TRUST_PROXY`: use `loopback` for a local reverse proxy; avoid broad proxy trust unless the proxy is configured to strip client-supplied forwarding headers.
|
|
- `DATABASE_PATH`: SQLite file path.
|
|
- `UPLOAD_DIR`: uploaded image folder.
|
|
- `BACKUP_DIR`: backup output folder.
|
|
- `OWNER_EMAIL`: where contact form notifications go.
|
|
- `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASS`, `SMTP_FROM`: email notification settings.
|
|
|
|
Messages are always stored in the database even when SMTP is empty or fails.
|
|
|
|
## Docker
|
|
|
|
Create `.env`, then run:
|
|
|
|
```powershell
|
|
docker compose up -d --build
|
|
```
|
|
|
|
The app stores persistent files in:
|
|
|
|
- `./storage`
|
|
- `./public/uploads`
|
|
|
|
Do not include `.env` in downloadable backups or source control.
|
|
|
|
## Production Hosting Notes
|
|
|
|
Recommended production shape:
|
|
|
|
1. Run the app with Docker Compose on Perry's server.
|
|
2. Put a reverse proxy such as Caddy, Nginx, or IIS ARR in front of it.
|
|
3. Configure TLS for `debbiewindlerseamstress.com`.
|
|
4. Later, redirect `debbiewindler.com` to `debbiewindlerseamstress.com`.
|
|
5. Set `NODE_ENV=production`, `APP_BASE_URL`, `SESSION_SECRET`, `SETUP_TOKEN`, `TRUST_PROXY`, SMTP values, and owner email in `.env`.
|
|
6. Create the first owner account using `/admin/setup?token=YOUR_SETUP_TOKEN`.
|
|
|
|
This project does not make DNS, router, firewall, reverse proxy, or live production changes.
|
|
|
|
## Backup and Restore
|
|
|
|
Manual backups are created from `/admin/backups`.
|
|
|
|
Backups include:
|
|
|
|
- SQLite database.
|
|
- Uploaded images.
|
|
|
|
Backups exclude:
|
|
|
|
- `.env`.
|
|
- passwords and SMTP secrets outside the database.
|
|
|
|
Restore process:
|
|
|
|
1. Stop the app.
|
|
2. Make a copy of the current `storage` and `public/uploads` folders.
|
|
3. Extract the backup ZIP.
|
|
4. Replace `storage/site.sqlite` and restore the `uploads` folder.
|
|
5. Start the app and check `/healthz`.
|
|
|
|
Use strong confirmation before replacing production files.
|
|
|
|
## Testing
|
|
|
|
Run:
|
|
|
|
```powershell
|
|
pnpm test
|
|
```
|
|
|
|
Current smoke tests verify:
|
|
|
|
- Public pages load.
|
|
- Admin redirects to setup/login.
|
|
- Contact form validation and CSRF session behavior.
|
|
|
|
Manual checklist before going live:
|
|
|
|
- Create owner account.
|
|
- Log in and log out.
|
|
- Edit the home hero and preview.
|
|
- Upload an image and confirm it appears in the media library.
|
|
- Add an item and confirm `/items` stays alphabetical.
|
|
- Add a service and reorder it.
|
|
- Edit About and Equipment entries.
|
|
- Submit a contact form message.
|
|
- Confirm the message appears in the admin inbox.
|
|
- Configure SMTP and confirm email notifications.
|
|
- Confirm messages are still stored if SMTP is disabled.
|
|
- Create and download a backup.
|
|
- Enable maintenance mode and confirm admins can still log in.
|
|
- Check phone, tablet, and desktop widths.
|
|
|
|
## Security Checklist
|
|
|
|
- Set a long `SESSION_SECRET`.
|
|
- Set a private `SETUP_TOKEN` before first boot in production.
|
|
- Use HTTPS in production.
|
|
- Keep `.env` private.
|
|
- Use a strong owner password.
|
|
- Keep Docker base images and npm packages updated.
|
|
- Back up before updates.
|
|
- Do not expose `public/uploads` as executable content.
|
|
- Do not add customer file uploads without a separate security review.
|
|
- Keep private home address hidden unless Debbie deliberately chooses to publish it.
|
|
|
|
## Still Needed From Owner
|
|
|
|
- Final Debbie business wording.
|
|
- Final email address and phone number.
|
|
- Facebook page link, if desired.
|
|
- Service area and business hours.
|
|
- Final photos, artwork, logo, favicon, and business card artwork.
|
|
- Real service descriptions and pricing notes.
|
|
- Real item listings and item photos.
|
|
- SMTP provider settings.
|
|
- Decision on whether `debbiewindler.com` should redirect at the reverse proxy or DNS/hosting layer later.
|
|
|
|
## Notes About Initial Version
|
|
|
|
This is a complete working first version, but a few advanced features are intentionally conservative:
|
|
|
|
- CAPTCHA is wired as a future setting but not enabled by default.
|
|
- Revision history is stored for important edits; a polished one-click restore screen can be expanded later.
|
|
- The page editor uses controlled section layouts instead of arbitrary code or drag-and-drop.
|
|
- The owner reply flow uses `mailto:` instead of a built-in outgoing email client.
|