docs: document setup and deployment
This commit is contained in:
212
README.md
212
README.md
@@ -1,35 +1,217 @@
|
||||
# ZarinPal Merchant Analytics — Frontend
|
||||
|
||||
Persian RTL merchant analytics panel built with SvelteKit 2, Svelte 5, strict TypeScript, and Tailwind CSS v4.
|
||||
Persian-first, RTL merchant analytics dashboard built with SvelteKit 2, Svelte 5, strict TypeScript, Tailwind CSS v4, and a generated OpenAPI client contract.
|
||||
|
||||
Current state: design, specifications, implementation plan, and task list are approved. Phase 4 frontend implementation is authorized.
|
||||
The application is a client-rendered static SPA. In development, Vite serves it and proxies same-origin `/api` requests to the Go backend. In production, it is built into static files and served by the deployment repository's unprivileged Nginx container. Authentication remains backend-owned through an HttpOnly cookie; credentials and tokens are never stored in browser storage.
|
||||
|
||||
## Local development
|
||||
## Local setup
|
||||
|
||||
The dashboard is a client-rendered static SvelteKit application. During development, Vite serves it at `http://127.0.0.1:5173` and proxies same-origin `/api` requests to the Go backend at `http://127.0.0.1:8080`. This preserves the backend-owned secure session model without storing credentials in browser storage.
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 20.19+ or 22.12+
|
||||
- npm
|
||||
- The backend API running at `http://127.0.0.1:8080`
|
||||
- PostgreSQL and Redis running for the backend
|
||||
|
||||
The frontend does not connect directly to PostgreSQL or Redis. Those external services are required by the backend: PostgreSQL stores application/analytics data, while Redis coordinates and caches background work. Follow the backend README to start them, apply migrations, import the dataset, create the demo account, and run both `cmd/api` and `cmd/worker`.
|
||||
|
||||
### 1. Configure and install
|
||||
|
||||
From the frontend repository root:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
npm ci
|
||||
```
|
||||
|
||||
PowerShell equivalent:
|
||||
|
||||
```powershell
|
||||
Copy-Item .env.example .env
|
||||
npm ci
|
||||
npm run dev -- --host 127.0.0.1
|
||||
```
|
||||
|
||||
Open `http://127.0.0.1:5173`. The demo merchant credentials are created by the backend importer/bootstrap process; they are intentionally not stored in this repository.
|
||||
The normal local configuration is:
|
||||
|
||||
Quality commands:
|
||||
```dotenv
|
||||
PUBLIC_API_BASE_URL=/api/v1
|
||||
PUBLIC_AI_GROWTH_ENABLED=false
|
||||
PUBLIC_AI_COACH_ENABLED=false
|
||||
```
|
||||
|
||||
```powershell
|
||||
`PUBLIC_API_BASE_URL` is browser-visible routing configuration, not a secret. Keep `/api/v1` for the same-origin Vite proxy. To use a backend at another local address, add `LOCAL_API_ORIGIN=http://127.0.0.1:8080`; this variable configures Vite only.
|
||||
|
||||
Do not put database URLs, Redis passwords, session secrets, AI provider keys, or any other credential in a frontend environment variable. Every `PUBLIC_*` value is included in the browser build.
|
||||
|
||||
### 2. Start the application
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Open `http://127.0.0.1:5173`. The Vite server proxies `/api/*` to `http://127.0.0.1:8080` by default.
|
||||
|
||||
### 3. Sign in with the local demo user
|
||||
|
||||
The backend creates/resets this account when its `go run ./cmd/admin` command runs with the documented values:
|
||||
|
||||
```text
|
||||
Username: merchant-0001
|
||||
Password: merchant-demo-2026
|
||||
```
|
||||
|
||||
If login fails, confirm the backend `.env` contains those exact `DEMO_USERNAME` and `DEMO_PASSWORD` values and rerun `go run ./cmd/admin` from the backend repository. These are public development credentials; use a different password on every internet-accessible deployment.
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Purpose |
|
||||
| ---------------------- | --------------------------------------------------------------------- |
|
||||
| `npm run dev` | Start the Vite development server on `127.0.0.1:5173` |
|
||||
| `npm run generate:api` | Regenerate TypeScript API types from the sibling backend OpenAPI file |
|
||||
| `npm run check` | Run Svelte and TypeScript checks |
|
||||
| `npm test` | Run the Vitest suite once |
|
||||
| `npm run test:watch` | Run Vitest in watch mode |
|
||||
| `npm run format:check` | Check formatting without changing files |
|
||||
| `npm run format` | Format the repository |
|
||||
| `npm run build` | Create the production static build in `build/` |
|
||||
| `npm run preview` | Preview the production build locally |
|
||||
|
||||
`npm run generate:api` expects the backend repository at `../zarinpal-analytics-backend`. If your checkout uses another layout, update the input path in `package.json` or copy the OpenAPI contract into the expected sibling location before running it.
|
||||
|
||||
Before submitting a change, run:
|
||||
|
||||
```bash
|
||||
npm run generate:api
|
||||
npm run format:check
|
||||
npm run check
|
||||
npm test
|
||||
npm run build
|
||||
```
|
||||
|
||||
`PUBLIC_API_BASE_URL` is public routing configuration, not a secret. Keep its default `/api/v1` for the local Vite proxy and the production same-origin Nginx proxy.
|
||||
## Production deployment on a remote server
|
||||
|
||||
- [`DESIGN.md`](DESIGN.md): visual language, interaction rules, responsive behavior, and current design-system state.
|
||||
- [`docs/DASHBOARD-SPEC.md`](docs/DASHBOARD-SPEC.md): approved product requirements and acceptance criteria for implementation planning.
|
||||
- [`docs/DASHBOARD-UX-SPEC.md`](docs/DASHBOARD-UX-SPEC.md): detailed screen map, RTL layouts, async states, data presentation, accessibility, and authorized export workflows.
|
||||
- [`tasks/plan.md`](tasks/plan.md): approved SDD Phase 2 dependency order, risk spikes, vertical slices, and approval gates.
|
||||
- [`tasks/todo.md`](tasks/todo.md): approved SDD Phase 3 task list and dependency order for authorized Phase 4 implementation.
|
||||
- [`AGENTS.md`](AGENTS.md): durable rules for future coding agents and contributors.
|
||||
Deploy the frontend and backend together through the `zarinpal-analytics-deployment` repository. Its Compose stack builds this static SPA, serves it through Nginx, runs the Go API and worker, and keeps PostgreSQL/Redis private. A separate shared Caddy deployment owns the public domain and HTTPS.
|
||||
|
||||
The examples use `analytics.example.com`; replace it with your own domain and replace repository URL placeholders with your template/fork URLs.
|
||||
|
||||
### 1. Prepare the server
|
||||
|
||||
1. Provision an Ubuntu server with a public IP.
|
||||
2. Install Git, Docker Engine, and the Docker Compose plugin.
|
||||
3. Permit inbound TCP 80/443 and restrict SSH to trusted addresses.
|
||||
4. Never expose PostgreSQL 5432 or Redis 6379 publicly.
|
||||
|
||||
### 2. Install the main Caddy router
|
||||
|
||||
Clone and follow the [Caddy deployment repository](https://git.amiirkhl.ir/Interanet/caddy-deployment.git):
|
||||
|
||||
```bash
|
||||
git clone https://git.amiirkhl.ir/Interanet/caddy-deployment.git ~/caddy-deployment
|
||||
cd ~/caddy-deployment
|
||||
```
|
||||
|
||||
Start Caddy according to that repository's README. Its container must join an external Docker network named `caddy_proxy`. If the repository does not create it, run `docker network create caddy_proxy` once before starting Caddy.
|
||||
|
||||
### 3. Clone the application repositories
|
||||
|
||||
```bash
|
||||
git clone <deployment-repository-url> ~/zarinpal-analytics-deployment
|
||||
cd ~/zarinpal-analytics-deployment
|
||||
git clone <backend-repository-url> backend
|
||||
git clone <frontend-repository-url> frontend
|
||||
```
|
||||
|
||||
Keep all three repositories on clean `main` branches matching `origin/main`; the guarded deployment script checks this layout.
|
||||
|
||||
### 4. Configure production
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
cp backend/.env.production.example backend/.env
|
||||
cp frontend/.env.production.example frontend/.env
|
||||
chmod 600 .env backend/.env frontend/.env
|
||||
```
|
||||
|
||||
Replace every placeholder. In particular:
|
||||
|
||||
- Set `FRONTEND_ORIGIN=https://analytics.example.com` and `COOKIE_SECURE=true` in `backend/.env`.
|
||||
- Generate distinct PostgreSQL, Redis, session, and cursor secrets with `openssl rand -hex 32`.
|
||||
- Replace the public local demo password before exposing the site.
|
||||
- Keep `PUBLIC_API_BASE_URL=/api/v1` in `frontend/.env` for same-origin routing.
|
||||
- Enable frontend AI switches only when the matching backend capability, provider key, and budgets are configured.
|
||||
- Never place a private value in `frontend/.env`.
|
||||
|
||||
Place the dataset at the private absolute path configured by `IMPORT_FILE`, for example `/srv/zarinpal-data/challenge_data.csv.gz`.
|
||||
|
||||
### 5. Run the first deployment
|
||||
|
||||
From `~/zarinpal-analytics-deployment`, run in order:
|
||||
|
||||
```bash
|
||||
docker compose config --quiet
|
||||
docker compose build backend frontend
|
||||
docker compose up -d postgres redis
|
||||
docker compose --profile tools run --rm migrate
|
||||
docker compose --profile import run --rm importer
|
||||
docker compose --profile tools run --rm admin
|
||||
docker compose up -d backend worker frontend
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
The migration, importer, and admin containers are intentional one-off tools. The API, worker, and frontend are long-running. Wait for every service to become healthy and inspect problems with:
|
||||
|
||||
```bash
|
||||
docker compose logs --tail=200 postgres redis backend worker frontend
|
||||
```
|
||||
|
||||
### 6. Point the domain to the application
|
||||
|
||||
Create an `A` record for `analytics.example.com` pointing to the server's public IPv4 address. Add `AAAA` only when IPv6 is actually configured.
|
||||
|
||||
In the Caddy deployment, add this site to the `Caddyfile` or equivalent template:
|
||||
|
||||
```caddyfile
|
||||
analytics.example.com {
|
||||
@backend path /api/* /healthz
|
||||
|
||||
handle @backend {
|
||||
reverse_proxy zarinpal-backend:8080 {
|
||||
flush_interval -1
|
||||
}
|
||||
}
|
||||
|
||||
handle {
|
||||
reverse_proxy zarinpal-frontend:8080
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Validate and reload Caddy with the commands documented in its repository. Once DNS resolves and ports 80/443 reach the server, Caddy obtains and renews the HTTPS certificate automatically.
|
||||
|
||||
Verify the public site and API routing:
|
||||
|
||||
```bash
|
||||
curl -I https://analytics.example.com/
|
||||
curl https://analytics.example.com/healthz
|
||||
```
|
||||
|
||||
Open the site, sign in with the production demo credentials configured in `backend/.env`, and confirm that dashboard data loads without browser console errors.
|
||||
|
||||
### 7. Deploy later updates
|
||||
|
||||
```bash
|
||||
cd ~/zarinpal-analytics-deployment
|
||||
git pull --ff-only origin main
|
||||
git -C backend pull --ff-only origin main
|
||||
git -C frontend pull --ff-only origin main
|
||||
bash scripts/deploy.sh
|
||||
```
|
||||
|
||||
Later deployments rebuild both images and apply migrations. They do not rerun the one-time importer or reset the demo account. Never run `docker compose down -v` in production because it deletes persistent volumes.
|
||||
|
||||
## Project documentation
|
||||
|
||||
- [`DESIGN.md`](DESIGN.md) defines the visual language, accessibility, RTL, responsive, and interaction rules.
|
||||
- [`docs/DASHBOARD-SPEC.md`](docs/DASHBOARD-SPEC.md) defines dashboard product behavior.
|
||||
- [`docs/DASHBOARD-UX-SPEC.md`](docs/DASHBOARD-UX-SPEC.md) defines screen flows and async/data states.
|
||||
- [`AGENTS.md`](AGENTS.md) defines durable contributor and automation rules.
|
||||
|
||||
Reference in New Issue
Block a user