Files
Art-gallery/Documentation/FAC.md
T
Danila KhodjaefandCursor 21e3e41e48 Add one-command dev-to-prod release with clear SUCCESS/FAILED banners.
Introduce devtoprod:release orchestrator, config file, CLI result footers on deploy scripts, auto-thumb regeneration on curator fixes, and updated deploy documentation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 14:54:56 +03:00

13 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, 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 Gallerygallery_prod + gallery_dev (needs PGUSER=postgres)
npm run prodto:dev:db Clone gallery_prodgallery_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 27 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 painting thumbs from full images
npm run dev:regenerate-portrait-thumbs Rebuild timeline portrait thumbs (~256px)
npm run devtoprod:thumbnails Both of the above — run on dev before promote backup/sync
npm run devtoprod:release Config-driven full promote (see deploy-dev-to-prod.md)

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:release        # full promote from infra/deploy/devtoprod.config.json
npm run devtoprod:thumbnails   # rebuild thumb files + DB paths on dev (before backup)
npm run devtoprod:images      # dev repo → TrueNAS (promote / first deploy)
npm run prodto:dev:images    # TrueNAS → dev repo

Type yes when prompted (or set autoConfirm: true in release config). Robocopy exit codes 07 = success. Deploy scripts print a final ===== SUCCESS ===== or ===== FAILED ===== banner.


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.

One command (recommended): copy infra/deploy/devtoprod.config.example.jsoninfra/deploy/devtoprod.config.json, edit SMB/git settings, then:

npm run devtoprod:release
# or: deploy-dev-to-prod.cmd

Dry-run: npm run devtoprod:release -- -DryRun. The script pauses for a manual gallery-web restart on TrueNAS before verify.

Manual steps (partial releases):

  1. Test on https://devgallery.mysuperlab.netcraze.pro
  2. npm run devtoprod:thumbnails (if paintings/portraits changed — rebuild thumb files + DB paths on dev)
  3. npm run dev:db:backup
  4. npm run devtoprod:db:restore -- --file db/DataBackup/gallery_dev_data_....txt (if DB/catalog changed)
  5. npm run devtoprod:images (if images changed)
  6. npm run prod:docker:publish (if code changed)
  7. Restart gallery-web on TrueNAS
  8. 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
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