# ALZAR FZE Website — Self-Hosting Deployment Guide

This package is a standalone full-stack app (React front end + Express/tRPC back end)
that runs on **any Linux host** with **Node.js 20+** and **PostgreSQL 14+**. It has been
converted from MySQL to PostgreSQL and de-coupled from Manus (self-hosted email+password
admin login). The production build is verified passing and the SQL schema is validated
against the real PostgreSQL parser.

You deploy this yourself. Two supported paths below — pick one.

---

## What's in the box
- Full website source (client + server), all images self-hosted in `client/public/images/`.
- `database/schema.sql` — the complete PostgreSQL schema (run once).
- `scripts/create-admin.ts` — seeds your admin login.
- `.env.example` — copy to `.env` and fill in.
- Product pages SEO-optimized for GCC search terms (see `SEO_STRATEGY_GCC.md`).

## Requirements
- Node.js 20+ and pnpm 10+ (`npm install -g pnpm`)
- PostgreSQL 14+ reachable from the app
- A domain (alzarfze.com / .org) pointing at the host

---

## Path A — Docker (recommended for self-hosting; app + Postgres together)

A `docker-compose.yml` and `Dockerfile` are included. This runs the app and a Postgres
database side by side, with a persistent volume for the data.

```bash
cp .env.example .env
# edit .env: set a strong JWT_SECRET (openssl rand -hex 32).
# For docker-compose, DATABASE_URL is already wired to the db service.

docker compose up -d --build          # build + start app and postgres
docker compose exec app sh -c \
  'psql "$DATABASE_URL" -f database/schema.sql'      # create tables (once)
docker compose exec app sh -c \
  'pnpm tsx scripts/create-admin.ts you@alzarfze.com "STRONG_PASSWORD" "Your Name"'
```

App is now on `http://SERVER_IP:3000`. Put a reverse proxy (Nginx/Caddy) in front for
HTTPS + the domain (sample Nginx block at the bottom).

---

## Path B — Manual (app on the host, Postgres wherever you like)

```bash
# 1. Install deps and build
pnpm install
pnpm build

# 2. Create the database and schema
createdb alzar_website          # or use your managed Postgres console
psql "postgresql://USER:PASS@HOST:5432/alzar_website" -f database/schema.sql

# 3. Configure environment
cp .env.example .env
#   - DATABASE_URL -> your Postgres connection string
#   - JWT_SECRET   -> openssl rand -hex 32
#   - DATABASE_SSL=false only if local Postgres without TLS

# 4. Seed your admin login
pnpm tsx scripts/create-admin.ts you@alzarfze.com "STRONG_PASSWORD" "Your Name"

# 5. Run it (production)
pnpm start                      # serves on $PORT (default 3000)
```

For a long-running service, use a process manager (systemd, pm2) so it restarts on
reboot/crash. Sample systemd unit at the bottom.

---

## Admin login
- The public website needs no login.
- The admin dashboard (contact submissions) logs in at `/api/auth/login` via the app's
  admin UI, using the email + password you seeded. Passwords are argon2-hashed; only the
  hash is stored. Add more admins by running `create-admin.ts` again with a new email.

## DNS cutover (do last, zero downtime)
1. Keep Manus serving `.com`/`.org` until this app is verified good on the host.
2. Point both domains at your host (A record → server IP, via your DNS provider).
3. Issue TLS (Let's Encrypt via Caddy/Certbot). Verify both domains + the contact form.
4. Decommission Manus.

---

## Still to wire before/after launch (see HANDOFF_TO_CLAUDE_CODE.md)
- **Email notifications**: fill SMTP_* in `.env` to get emailed on new submissions.
  Optional — submissions are always saved to the DB regardless.
- **SPA SEO rendering**: the highest-value SEO improvement (pre-render per-page meta).
  Explained in SEO_STRATEGY_GCC.md → Technical SEO.
- **Google Analytics / Search Console**: verification tag already present; confirm
  ownership and submit the sitemap.

---

## Sample Nginx reverse proxy (HTTPS via Certbot)
```nginx
server {
  server_name alzarfze.com www.alzarfze.com alzarfze.org www.alzarfze.org;
  location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }
  listen 80;
}
# Then: certbot --nginx -d alzarfze.com -d www.alzarfze.com -d alzarfze.org -d www.alzarfze.org
```

## Sample systemd unit (Path B)
```ini
[Unit]
Description=ALZAR FZE Website
After=network.target postgresql.service

[Service]
WorkingDirectory=/opt/alzar-website
EnvironmentFile=/opt/alzar-website/.env
ExecStart=/usr/bin/pnpm start
Restart=on-failure
User=www-data

[Install]
WantedBy=multi-user.target
```

## Backups (self-hosting responsibility)
```bash
# Nightly dump (cron): keeps your content + submissions safe
pg_dump "$DATABASE_URL" | gzip > /backups/alzar_$(date +\%F).sql.gz
```
Verified in prep: `pnpm build` passes, `tsc --noEmit` clean, `database/schema.sql`
validated by libpg_query (the real Postgres parser).
