Files
Art-gallery/Documentation/FAC.md
T
Danila KhodjaefandCursor a2263ca186 Document gallery loading markers, WebGL recovery, and movement filtering.
Update basics.md for the new loading indicators, 3D WebGL context-loss recovery, and the corrected movement-visibility rule (span overlap plus any catalogued artist). Refresh remaining docs and config for the current dev-first workflow and npm script names.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 12:36:34 +03:00

339 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gallery — command reference (FAC)
Quick cheat sheet for daily operations. All `npm` commands run from the **repository root** unless noted.
**Default target: dev.** Day-to-day commands use `gallery_dev`, repo `data/images/`, and https://devgallery.mysuperlab.netcraze.pro. Prod (`gallery_prod`, Docker, `prod:docker:publish`) is for **scheduled releases** (~weekly) — see [Promote dev → prod](#promote-dev--prod-scheduled-release) below.
**Script prefixes:** `dev:``gallery_dev` / dev PC · `prod:` → production / TrueNAS · `devtoprod:` → promote dev → prod · `prodto:dev:` → refresh dev from prod · `infra:` → one-time setup
**Environments:**
| | Dev | Prod |
|---|-----|------|
| URL | https://devgallery.mysuperlab.netcraze.pro | https://gallery.mysuperlab.netcraze.pro |
| Host | Dev PC `192.168.10.70:5173` | TrueNAS `192.168.10.122:5173` |
| Database | `gallery_dev` | `gallery_prod` |
Details: [environments.md](environments.md) · Deploy: [../infra/docker/DEPLOY-truenas.md](../infra/docker/DEPLOY-truenas.md)
---
## Start and stop servers
### Start — public dev (Keenetic URL)
```powershell
cd C:\Users\SNAP\Nextcloud\Personal\Repo\Gallery
npm run dev:web
```
Vite on **:5173**, API on **:3451**. Open https://devgallery.mysuperlab.netcraze.pro or http://localhost:5173.
### Start — local HMR (no Keenetic)
Two terminals:
```powershell
npm run dev:server # API — PORT from .env (default 3451)
npm run dev:client # Vite on :5173
```
### Start — production-style (single Node process, built SPA)
```powershell
npm run prod:start # build client + serve on PORT from .env
# or:
npm run prod:build
npm run dev:start
```
### Stop dev servers
| Method | When |
|--------|------|
| **Ctrl+C** in the terminal running `dev:web` / `dev:server` / `dev:client` | Normal stop |
| Close the terminal tab | Same effect |
Free ports **5173**, **3451**, **3520** before DB maintenance or if “port in use” errors appear.
**Find what holds a port (PowerShell):**
```powershell
netstat -ano | findstr ":5173 :3451"
# Stop by PID:
Stop-Process -Id <PID> -Force
```
### Stop / restart production (TrueNAS)
| Action | Where |
|--------|-------|
| **Stop** | TrueNAS Web UI → Apps → **gallery-web** → Stop |
| **Restart** | Same → Restart (after `docker:publish` or config change) |
| **Update image** | Dev PC: `npm run prod:docker:publish` → restart app on TrueNAS |
---
## First-time install
```powershell
cd C:\Users\SNAP\Nextcloud\Personal\Repo\Gallery
copy .env.example .env # edit DB credentials, PUBLIC_URL
npm install
cd client; npm install; cd ..
npm run dev:migrate # schema + incremental SQL (+ auth tables, bootstrap curator)
npm run dev:setup # migrate + seed (fresh empty DB only)
```
**Curator auth (after migrate):** set in `.env` before first `npm run dev:migrate` if the DB has no curator yet:
```env
SESSION_SECRET=your-long-random-secret
CURATOR_USERNAME=curator
CURATOR_PASSWORD=your-secure-password
```
Then open the gallery → **Curator login** (top-right) → use debug mode / Checkup. Mutations are logged in `curator_audit_log` (view in pgAdmin).
**Roles:**
| Role | Access |
|------|--------|
| Guest (`user`) | Timeline, movement flow, 3D halls, painting detail, bios |
| Curator | Above + debug mode, Checkup, image fix/upload/delete APIs |
**Audit log (pgAdmin on `gallery_dev` or `gallery_prod`):**
```sql
SELECT l.created_at, u.username, l.action, l.resource_type, l.resource_id
FROM curator_audit_log l
JOIN users u ON u.id = l.user_id
ORDER BY l.created_at DESC
LIMIT 30;
```
**Prod auth env** (TrueNAS app or `infra/docker/.env.prod`):
```env
SESSION_SECRET=long-random-secret
SESSION_COOKIE_SECURE=true
CURATOR_USERNAME=curator
CURATOR_PASSWORD=your-secure-password
```
Run `npm run dev:migrate` against prod DB after first deploy with auth vars set (creates tables + bootstrap curator if `users` is empty).
---
## Database
| Command | Description |
|---------|-------------|
| `npm run dev:migrate` | Apply `db/schema.sql` + incremental migrations (safe to re-run) |
| `npm run dev:setup` | `migrate` + `seed` — fresh catalog from Wikipedia data |
| `npm run infra:db:split-dev-prod` | One-time: legacy `Gallery``gallery_prod` + `gallery_dev` (needs `PGUSER=postgres`) |
| `npm run prodto:dev:db` | Clone `gallery_prod``gallery_dev` (TEMPLATE); also runs image sync from prod |
| `npm run dev:db:backup` | Dev data-only backup → `db/DataBackup/*.txt` + `.zip` |
| `npm run prod:db:backup` | Prod backup (reads `infra/docker/.env.prod`) |
| `npm run dev:db:restore -- --file <path>` | Restore backup into **dev** (truncates tables first; prompts `yes`) |
| `npm run devtoprod:db:restore -- --file <path>` | Restore into **prod** (requires confirmation) |
**One-time split (recommended):** pgAdmin on dev PC → open [`db/split-dev-prod-pgadmin.sql`](../db/split-dev-prod-pgadmin.sql) → run each STEP on database `postgres`, then verify on `gallery_dev`.
**Dev `.env` essentials:**
```env
DB_NAME=gallery_dev
PORT=3451
PUBLIC_URL=https://devgallery.mysuperlab.netcraze.pro
SESSION_SECRET=your-long-random-secret
SESSION_COOKIE_SECURE=false
CURATOR_USERNAME=curator
CURATOR_PASSWORD=your-secure-password
```
---
## Import and enrich catalog data
Run in this order on a **new** or **re-seeded** database:
| # | Command | What it does |
|---|---------|----------------|
| 1 | `npm run dev:seed` | Eras, movements, artists, one flagship painting per artist |
| 2 | `npm run dev:sync-image-paths` | Import paintings from `data/images/paintings/`; link paths in DB |
| 3 | `npm run dev:fetch-artist-images` | Portraits → `data/images/portraits/`, set `portrait_path` |
| 4 | `npm run dev:fetch-artist-bios` | Wikipedia bios → `bio_short` / `bio_full` |
| 5 | `npm run dev:expand-catalog` | Add famous works per artist (below `MIN_PAINTINGS`) |
| 6 | `npm run dev:update-influences` | Influence graph (detail panels, 3D hall lamps) |
| 7 | `npm run dev:fetch-images -- --limit=50` | Download missing painting files (batch) |
**One-shot bootstrap:** `npm run dev:setup` = steps 1 + migrate only; still run 27 for a full catalog.
### Useful flags
```powershell
npm run dev:sync-image-paths -- --dry-run
npm run dev:fetch-artist-images -- --force
npm run dev:fetch-artist-bios -- --force
npm run dev:expand-catalog -- --fetch-images
npm run dev:fetch-images -- --artist="Claude Monet"
npm run dev:fetch-images -- --limit=50 --max-wait=120
npm run dev:update-influences -- --discover
npm run dev:discover-influences # discovery only, no curated insert
```
### Optional migrations / imports
| Command | Description |
|---------|-------------|
| `npm run dev:migrate:thumbnails` | Add thumbnail columns |
| `npm run dev:migrate:influence-sources` | `painting_influence_sources` table + backfill |
| `npm run dev:migrate:checkup-flags` | Review flags on `paintings` |
| `npm run dev:migrate:artist-checkup-flags` | Review flags on `artists` |
| `npm run dev:migrate:painting-annotations` | Art-history notes table |
| `npm run dev:migrate:artist-palette` | `palette_metadata` JSONB on artists |
| `npm run dev:import-painter-palette` | Enrich from `Inputs/PainterPalette.csv` |
| `npm run dev:update-painting-annotations` | Load curated notes |
| `npm run dev:update-painting-annotations -- --wikipedia` | Add Wikipedia intro sentences |
### Audit / export
| Command | Description |
|---------|-------------|
| `npm run dev:audit-painting-images` | Thumb vs full aspect-ratio mismatches |
| `npm run dev:find-duplicates` | Duplicate / near-duplicate painting rows |
| `npm run dev:audit-influence-duplicates` | Duplicate influence edges |
| `npm run dev:analyze-painter-palette` | CSV ↔ artist name match report |
| `npm run dev:export-paintings` | Write `Output/paintings.csv` |
---
## Images (local files)
| Command | Description |
|---------|-------------|
| `npm run dev:fetch-images` | Search/download missing painting files (alias: `search-missing-paintings`) |
| `npm run dev:fetch-artist-images` | Download or link artist portraits |
| `npm run dev:sync-image-paths` | Align DB paths with files on disk; import new rows |
| `npm run dev:regenerate-thumbnails` | Rebuild all thumbs from full images |
**Local paths:** `data/images/portraits/`, `data/images/paintings/`, `data/images/paintings/thumbs/`
---
## Dev ↔ prod image sync (SMB)
SMB share **`Gallery`** → `/mnt/BasePool/Applications/Gallery` on TrueNAS.
```powershell
net use \\192.168.10.122\Gallery /user:YOUR_TRUENAS_USER
npm run devtoprod:images # dev repo → TrueNAS (promote / first deploy)
npm run prodto:dev:images # TrueNAS → dev repo
```
Type `yes` when prompted. Robocopy exit codes **07** = success.
---
## Docker and production deploy
| Command | Where | Description |
|---------|-------|-------------|
| `npm run prod:docker:publish` | Dev PC, **Admin** PowerShell, Docker Desktop running | Build + push `gallery-web:latest` to Gitea |
| `npm run prod:docker:push-only` | Same | Push only (skip rebuild) |
| `.\infra\docker\save-for-truenas.ps1` | Dev PC | Save image to `gallery-web.tar` (offline deploy) |
**Before first deploy:** `npm run prod:docker:publish` → TrueNAS Custom App from `infra/docker/compose.truenas.yaml`.
**After code changes:** `npm run prod:docker:publish` → restart **gallery-web** on TrueNAS.
```powershell
docker login gitea.mysuperlab.netcraze.pro
```
---
## Build frontend
```powershell
npm run prod:build # client → client/dist/
cd client && npm run build && cd ..
```
Prod container serves `client/dist/` from the Docker image (rebuild image after UI changes).
---
## Verify (health checks)
```powershell
# Dev (servers running)
curl.exe -sk https://devgallery.mysuperlab.netcraze.pro/api/bounds
curl.exe -s http://192.168.10.70:5173/api/bounds
# Prod (bypass Keenetic)
curl.exe -s http://192.168.10.122:5173/api/bounds
# Prod (public)
curl.exe -sk https://gallery.mysuperlab.netcraze.pro/api/bounds
```
Expect JSON with `min_year` / `max_year`. HTML shell only from `curl` on `/` is normal (Vite dev).
**PowerShell note:** use `curl.exe`, not `curl` — PowerShell aliases `curl` to `Invoke-WebRequest` (no `-k` flag).
---
## Promote dev → prod (scheduled release)
~Weekly (or when explicitly releasing to prod). Not part of daily dev.
1. Test on https://devgallery.mysuperlab.netcraze.pro
2. `npm run dev:db:backup`
3. `npm run devtoprod:db:restore -- --file db/DataBackup/gallery_dev_data_....txt` (if DB/catalog changed)
4. `npm run devtoprod:images` (if images changed)
5. `npm run prod:docker:publish` (if code changed)
6. Restart **gallery-web** on TrueNAS
7. Verify https://gallery.mysuperlab.netcraze.pro
---
## Keenetic (router)
Both rules: **protocol to device = `http`**, **Preserve Host = ON**.
| Domain | Upstream |
|--------|----------|
| `devgallery.mysuperlab.netcraze.pro` | `192.168.10.70:5173` |
| `gallery.mysuperlab.netcraze.pro` | `192.168.10.122:5173` |
Wrong IP or `https` to device → **502 / 504** (`Server: Web server`).
---
## Git (Gitea)
```powershell
git status
git add .
git commit -m "Your message"
git push origin main
```
Remote: https://gitea.mysuperlab.netcraze.pro/Danilka/Art-gallery
---
## Related docs
| Document | Contents |
|----------|----------|
| [environments.md](environments.md) | Full dev/prod walkthrough |
| [setup.md](setup.md) | Install, env vars, troubleshooting |
| [data-and-images.md](data-and-images.md) | Catalog and image pipeline |
| [API.md](API.md) | REST endpoints |
| [DB_structure.md](DB_structure.md) | PostgreSQL schema |