12 KiB
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 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 · Deploy: ../infra/docker/DEPLOY-truenas.md
Start and stop servers
Start — public dev (Keenetic URL)
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:
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)
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):
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
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:
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):
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):
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 → run each STEP on database postgres, then verify on gallery_dev.
Dev .env essentials:
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 2–7 for a full catalog.
Useful flags
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.
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 0–7 = 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.
docker login gitea.mysuperlab.netcraze.pro
Build frontend
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)
# 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. Full runbook with per-change decision matrix and rollback: deploy-dev-to-prod.md.
- Test on https://devgallery.mysuperlab.netcraze.pro
npm run dev:db:backupnpm run devtoprod:db:restore -- --file db/DataBackup/gallery_dev_data_....txt(if DB/catalog changed)npm run devtoprod:images(if images changed)npm run prod:docker:publish(if code changed)- Restart gallery-web on TrueNAS
- 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)
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 |
|---|---|
| deploy-dev-to-prod.md | Step-by-step release runbook (code, DB, data, images) |
| environments.md | Full dev/prod walkthrough |
| setup.md | Install, env vars, troubleshooting |
| data-and-images.md | Catalog and image pipeline |
| API.md | REST endpoints |
| DB_structure.md | PostgreSQL schema |