Files
Art-gallery/Documentation/FAC.md
T
Danila Khodjaef bdddadc4d6 Document development-first workflow with weekly prod releases.
Default all day-to-day work to gallery_dev and devgallery; add Cursor rule and update docs, env examples, and deploy guide for scheduled prod promotion.
2026-07-06 09:58:01 +03:00

11 KiB
Raw Blame History

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, docker:publish) is for scheduled releases (~weekly) — see Promote dev → prod below.

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 start:prod   # build client + serve on PORT from .env
# or:
npm run build
npm run 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 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 migrate                 # schema + incremental SQL (+ auth tables, bootstrap curator)
npm run setup                   # migrate + seed (fresh empty DB only)

Curator auth (after migrate): set in .env before first npm run 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 migrate against prod DB after first deploy with auth vars set (creates tables + bootstrap curator if users is empty).


Database

Command Description
npm run migrate Apply db/schema.sql + incremental migrations (safe to re-run)
npm run setup migrate + seed — fresh catalog from Wikipedia data
npm run db:split-databases One-time: legacy Gallerygallery_prod + gallery_dev (needs PGUSER=postgres)
npm run db:sync-from-prod Clone gallery_prodgallery_dev (TEMPLATE); also runs image sync from prod
npm run db:backup Dev data-only backup → db/DataBackup/*.txt + .zip
npm run db:backup:prod Prod backup (reads infra/docker/.env.prod)
npm run db:restore -- --file <path> Restore backup into dev (truncates tables first; prompts yes)
npm run db:restore:prod -- --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 seed Eras, movements, artists, one flagship painting per artist
2 npm run sync-image-paths Import paintings from data/images/paintings/; link paths in DB
3 npm run fetch-artist-images Portraits → data/images/portraits/, set portrait_path
4 npm run fetch-artist-bios Wikipedia bios → bio_short / bio_full
5 npm run expand-catalog Add famous works per artist (below MIN_PAINTINGS)
6 npm run update-influences Influence graph (detail panels, 3D hall lamps)
7 npm run fetch-images -- --limit=50 Download missing painting files (batch)

One-shot bootstrap: npm run setup = steps 1 + migrate only; still run 27 for a full catalog.

Useful flags

npm run sync-image-paths -- --dry-run
npm run fetch-artist-images -- --force
npm run fetch-artist-bios -- --force
npm run expand-catalog -- --fetch-images
npm run fetch-images -- --artist="Claude Monet"
npm run fetch-images -- --limit=50 --max-wait=120
npm run update-influences -- --discover
npm run discover-influences          # discovery only, no curated insert

Optional migrations / imports

Command Description
npm run migrate:thumbnails Add thumbnail columns
npm run migrate:influence-sources painting_influence_sources table + backfill
npm run migrate:checkup-flags Review flags on paintings
npm run migrate:artist-checkup-flags Review flags on artists
npm run migrate:painting-annotations Art-history notes table
npm run migrate:artist-palette palette_metadata JSONB on artists
npm run import-painter-palette Enrich from Inputs/PainterPalette.csv
npm run update-painting-annotations Load curated notes
npm run update-painting-annotations -- --wikipedia Add Wikipedia intro sentences

Audit / export

Command Description
npm run audit-painting-images Thumb vs full aspect-ratio mismatches
npm run find-duplicates Duplicate / near-duplicate painting rows
npm run audit-influence-duplicates Duplicate influence edges
npm run analyze-painter-palette CSV ↔ artist name match report
npm run export-paintings Write Output/paintings.csv

Images (local files)

Command Description
npm run fetch-images Search/download missing painting files (alias: search-missing-paintings)
npm run fetch-artist-images Download or link artist portraits
npm run sync-image-paths Align DB paths with files on disk; import new rows
npm run 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 images:sync-to-prod      # dev repo → TrueNAS (promote / first deploy)
npm run images:sync-from-prod    # TrueNAS → dev repo

Type yes when prompted. Robocopy exit codes 07 = success.


Docker and production deploy

Command Where Description
npm run docker:publish Dev PC, Admin PowerShell, Docker Desktop running Build + push gallery-web:latest to Gitea
npm run docker:publish: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 docker:publish → TrueNAS Custom App from infra/docker/compose.truenas.yaml.

After code changes: npm run docker:publish → restart gallery-web on TrueNAS.

docker login gitea.mysuperlab.netcraze.pro

Build frontend

npm run 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.

  1. Test on https://devgallery.mysuperlab.netcraze.pro
  2. npm run db:backup
  3. npm run db:restore:prod -- --file db/DataBackup/gallery_dev_data_....txt (if DB/catalog changed)
  4. npm run images:sync-to-prod (if images changed)
  5. npm run 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)

git status
git add .
git commit -m "Your message"
git push origin main

Remote: https://gitea.mysuperlab.netcraze.pro/Danilka/Art-gallery


Document Contents
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