From 96285737f53da8cfdeeebd3288ff51107bddae3c Mon Sep 17 00:00:00 2001 From: Danila Khodjaef Date: Tue, 7 Jul 2026 12:37:21 +0300 Subject: [PATCH] Rename npm scripts to environment-prefixed names (dev:/prod:/devtoprod:/prodto:dev:/infra:). Align package.json scripts and their references across scripts/, infra/, and db/ SQL with the dev-first workflow naming scheme. Co-authored-by: Cursor --- db/schema.sql | 2 +- db/split-dev-prod-pgadmin.sql | 2 +- infra/docker/DEPLOY-truenas.md | 12 ++-- infra/docker/compose.truenas.yaml | 4 +- infra/scripts/sync-images-from-prod.ps1 | 2 +- infra/scripts/sync-images-to-prod.ps1 | 2 +- package.json | 80 ++++++++++++------------- scripts/backup-db-data.js | 2 +- scripts/fetch-artist-images.js | 2 +- scripts/import-painter-palette.js | 12 ++-- scripts/restore-db-data.js | 4 +- scripts/seed-catalog-data.js | 2 +- scripts/seed-wikipedia.js | 10 ++-- scripts/split-dev-prod-databases.js | 8 +-- scripts/sync-image-paths.js | 2 +- scripts/update-influences.js | 2 +- 16 files changed, 73 insertions(+), 75 deletions(-) diff --git a/db/schema.sql b/db/schema.sql index 691d782..5e7b938 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -1,5 +1,5 @@ -- Virtual Art Gallery — canonical PostgreSQL schema --- Applied by: npm run migrate (server/migrate.js) +-- Applied by: npm run dev:migrate (server/migrate.js) -- Incremental ALTER migrations in db/migrate-*.sql run after this on existing databases. CREATE TABLE IF NOT EXISTS historical_eras ( diff --git a/db/split-dev-prod-pgadmin.sql b/db/split-dev-prod-pgadmin.sql index d7bf0f6..3a2cae6 100644 --- a/db/split-dev-prod-pgadmin.sql +++ b/db/split-dev-prod-pgadmin.sql @@ -27,7 +27,7 @@ -- -- AFTER SUCCESS: -- On dev PC (normal PowerShell, repo root): --- npm run migrate +-- npm run dev:migrate -- npm run dev:web -- Open http://devgallery.mysuperlab.netcraze.pro -- diff --git a/infra/docker/DEPLOY-truenas.md b/infra/docker/DEPLOY-truenas.md index 40bb97e..9de149d 100644 --- a/infra/docker/DEPLOY-truenas.md +++ b/infra/docker/DEPLOY-truenas.md @@ -36,10 +36,10 @@ If deploy fails with **`manifest unknown`**, the image is not in Gitea yet — c ```powershell cd C:\Users\SNAP\Nextcloud\Personal\Repo\Gallery docker login gitea.mysuperlab.netcraze.pro -npm run docker:publish +npm run prod:docker:publish ``` -Push only (already built): `npm run docker:publish:push-only` +Push only (already built): `npm run prod:docker:push-only` Image: `gitea.mysuperlab.netcraze.pro/danilka/gallery-web:latest` @@ -84,7 +84,7 @@ Enable SMB share **`Gallery`** → `/mnt/BasePool/Applications/Gallery` (for ima ```powershell net use \\192.168.10.122\Gallery /user:YOUR_TRUENAS_USER cd C:\Users\SNAP\Nextcloud\Personal\Repo\Gallery -npm run images:sync-to-prod +npm run devtoprod:images ``` UNC destination: `\\192.168.10.122\Gallery\data\images` @@ -132,7 +132,7 @@ On TrueNAS shell: `bash infra/docker/truenas-verify.sh` After code changes on dev PC: ```powershell -npm run docker:publish +npm run prod:docker:publish ``` Restart **gallery-web** on TrueNAS (or rely on `pull_policy: always`). @@ -141,11 +141,11 @@ Restart **gallery-web** on TrueNAS (or rely on `pull_policy: always`). | Issue | Fix | |-------|-----| -| **`manifest unknown`** | Run `npm run docker:publish` first; or offline `truenas-load-image.sh` | +| **`manifest unknown`** | Run `npm run prod:docker:publish` first; or offline `truenas-load-image.sh` | | **502 / 504 public URL** | Keenetic → `192.168.10.122:5173`, protocol **`http`**; verify LAN curl above | | Container cannot reach Postgres | `DB_HOST=192.168.10.122`; `extra_hosts` in compose | | Empty timeline | `DB_NAME=gallery_prod`; run pgAdmin split if still on legacy `Gallery` | -| Missing images | `npm run images:sync-to-prod`; check volume mount and `chown 1001:1001` | +| Missing images | `npm run devtoprod:images`; check volume mount and `chown 1001:1001` | | Pull 401 | Gitea registry credentials on TrueNAS; `read:package` token | | Push fails on dev PC | Gitea `ROOT_URL` HTTPS fix; use Admin PowerShell for LAN push | \ No newline at end of file diff --git a/infra/docker/compose.truenas.yaml b/infra/docker/compose.truenas.yaml index ebb2f95..d7e49c4 100644 --- a/infra/docker/compose.truenas.yaml +++ b/infra/docker/compose.truenas.yaml @@ -1,10 +1,10 @@ # Paste into TrueNAS: Apps → Custom App → Install via Docker Compose # # BEFORE deploy: -# 1. npm run docker:publish on dev PC (image must exist in Gitea) +# 1. npm run prod:docker:publish on dev PC (image must exist in Gitea) # 2. Replace YOUR_POSTGRES_PASSWORD below # 3. Gitea pull credentials on TrueNAS (read:package token) -# 4. mkdir + chown image dir; npm run images:sync-to-prod +# 4. mkdir + chown image dir; npm run devtoprod:images # 5. Keenetic: gallery.mysuperlab.netcraze.pro → 192.168.10.122:5173, protocol http # # See infra/docker/DEPLOY-truenas.md and Documentation/environments.md diff --git a/infra/scripts/sync-images-from-prod.ps1 b/infra/scripts/sync-images-from-prod.ps1 index 3a2deea..fa208ce 100644 --- a/infra/scripts/sync-images-from-prod.ps1 +++ b/infra/scripts/sync-images-from-prod.ps1 @@ -1,7 +1,7 @@ # Sync production image files from TrueNAS to dev repo. # # Usage: -# npm run images:sync-from-prod +# npm run prodto:dev:images # .\infra\scripts\sync-images-from-prod.ps1 param( diff --git a/infra/scripts/sync-images-to-prod.ps1 b/infra/scripts/sync-images-to-prod.ps1 index a1fd36c..10e51f2 100644 --- a/infra/scripts/sync-images-to-prod.ps1 +++ b/infra/scripts/sync-images-to-prod.ps1 @@ -1,7 +1,7 @@ # Sync dev image files to TrueNAS production volume. # # Usage (from repo root): -# npm run images:sync-to-prod +# npm run devtoprod:images # Copies data/images/ → \\192.168.10.122\Gallery\data\images # Map the share first if needed: net use \\192.168.10.122\Gallery /user:YOUR_TRUENAS_USER diff --git a/package.json b/package.json index de9940a..1d4c61a 100644 --- a/package.json +++ b/package.json @@ -4,50 +4,48 @@ "description": "", "main": "index.js", "scripts": { - "migrate": "node server/migrate.js", - "migrate:thumbnails": "node -e \"require('./server/db').query(require('fs').readFileSync('./db/migrate-thumbnails.sql','utf8')).then(()=>{console.log('OK');process.exit(0);}).catch(e=>{console.error(e);process.exit(1);})\"", - "seed": "node scripts/seed-wikipedia.js", - "fetch-images": "node scripts/fetch-missing-images.js", - "search-missing-paintings": "node scripts/fetch-missing-images.js", - "fetch-artist-images": "node scripts/fetch-artist-images.js", - "fetch-artist-bios": "node scripts/fetch-artist-bios.js", - "sync-image-paths": "node scripts/sync-image-paths.js", - "regenerate-thumbnails": "node scripts/regenerate-thumbnails.js", - "regenerate-portrait-thumbs": "node scripts/regenerate-portrait-thumbs.js", - "audit-painting-images": "node scripts/audit-painting-images.js", - "expand-catalog": "node scripts/expand-paintings.js", - "update-influences": "node scripts/update-influences.js", - "migrate:influence-sources": "node scripts/migrate-influence-sources.js", - "migrate:checkup-flags": "node scripts/migrate-checkup-flags.js", - "migrate:artist-checkup-flags": "node scripts/migrate-artist-checkup-flags.js", - "migrate:painting-annotations": "node scripts/migrate-painting-annotations.js", - "migrate:artist-palette": "node scripts/migrate-artist-palette.js", - "import-painter-palette": "node scripts/import-painter-palette.js", - "analyze-painter-palette": "node scripts/analyze-painter-palette.js", - "export-paintings": "node scripts/export-paintings-csv.js", - "update-painting-annotations": "node scripts/update-painting-annotations.js", - "find-duplicates": "node scripts/find-duplicate-paintings.js", - "audit-influence-duplicates": "node scripts/audit-influence-duplicates.js", - "discover-influences": "node scripts/update-influences.js --discover-only", - "build": "npm run build --prefix client", - "start": "node server/index.js", - "start:prod": "npm run build && node server/index.js", - "server": "node server/index.js", "dev:web": "node scripts/dev-web.js", "dev:server": "nodemon server/index.js", "dev:client": "npm run dev --prefix client", - "docker:publish": "powershell -NoProfile -ExecutionPolicy Bypass -File infra/docker/build-push-lan.ps1", - "docker:publish:push-only": "powershell -NoProfile -ExecutionPolicy Bypass -File infra/docker/build-push-lan.ps1 -SkipBuild", - "db:split-databases": "node scripts/split-dev-prod-databases.js", - "db:sync-from-prod": "node scripts/sync-prod-to-dev.js", - "db:backup": "node scripts/backup-db-data.js", - "db:backup:prod": "node scripts/backup-db-data.js --prod", - "db:restore": "node scripts/restore-db-data.js", - "db:restore:prod": "node scripts/restore-db-data.js --prod", - "images:sync-to-prod": "powershell -NoProfile -ExecutionPolicy Bypass -File infra/scripts/sync-images-to-prod.ps1", - "images:sync-from-prod": "powershell -NoProfile -ExecutionPolicy Bypass -File infra/scripts/sync-images-from-prod.ps1", - "dev": "node server/index.js", - "setup": "node server/migrate.js && node scripts/seed-wikipedia.js" + "dev:start": "node server/index.js", + "dev:migrate": "node server/migrate.js", + "dev:setup": "node server/migrate.js && node scripts/seed-wikipedia.js", + "dev:seed": "node scripts/seed-wikipedia.js", + "dev:fetch-images": "node scripts/fetch-missing-images.js", + "dev:search-missing-paintings": "node scripts/fetch-missing-images.js", + "dev:fetch-artist-images": "node scripts/fetch-artist-images.js", + "dev:fetch-artist-bios": "node scripts/fetch-artist-bios.js", + "dev:sync-image-paths": "node scripts/sync-image-paths.js", + "dev:regenerate-thumbnails": "node scripts/regenerate-thumbnails.js", + "dev:regenerate-portrait-thumbs": "node scripts/regenerate-portrait-thumbs.js", + "dev:audit-painting-images": "node scripts/audit-painting-images.js", + "dev:expand-catalog": "node scripts/expand-paintings.js", + "dev:update-influences": "node scripts/update-influences.js", + "dev:discover-influences": "node scripts/update-influences.js --discover-only", + "dev:migrate:thumbnails": "node -e \"require('./server/db').query(require('fs').readFileSync('./db/migrate-thumbnails.sql','utf8')).then(()=>{console.log('OK');process.exit(0);}).catch(e=>{console.error(e);process.exit(1);})\"", + "dev:migrate:influence-sources": "node scripts/migrate-influence-sources.js", + "dev:migrate:checkup-flags": "node scripts/migrate-checkup-flags.js", + "dev:migrate:artist-checkup-flags": "node scripts/migrate-artist-checkup-flags.js", + "dev:migrate:painting-annotations": "node scripts/migrate-painting-annotations.js", + "dev:migrate:artist-palette": "node scripts/migrate-artist-palette.js", + "dev:import-painter-palette": "node scripts/import-painter-palette.js", + "dev:analyze-painter-palette": "node scripts/analyze-painter-palette.js", + "dev:export-paintings": "node scripts/export-paintings-csv.js", + "dev:update-painting-annotations": "node scripts/update-painting-annotations.js", + "dev:find-duplicates": "node scripts/find-duplicate-paintings.js", + "dev:audit-influence-duplicates": "node scripts/audit-influence-duplicates.js", + "dev:db:backup": "node scripts/backup-db-data.js", + "dev:db:restore": "node scripts/restore-db-data.js", + "prod:build": "npm run build --prefix client", + "prod:start": "npm run prod:build && node server/index.js", + "prod:docker:publish": "powershell -NoProfile -ExecutionPolicy Bypass -File infra/docker/build-push-lan.ps1", + "prod:docker:push-only": "powershell -NoProfile -ExecutionPolicy Bypass -File infra/docker/build-push-lan.ps1 -SkipBuild", + "prod:db:backup": "node scripts/backup-db-data.js --prod", + "devtoprod:db:restore": "node scripts/restore-db-data.js --prod", + "devtoprod:images": "powershell -NoProfile -ExecutionPolicy Bypass -File infra/scripts/sync-images-to-prod.ps1", + "prodto:dev:db": "node scripts/sync-prod-to-dev.js", + "prodto:dev:images": "powershell -NoProfile -ExecutionPolicy Bypass -File infra/scripts/sync-images-from-prod.ps1", + "infra:db:split-dev-prod": "node scripts/split-dev-prod-databases.js" }, "keywords": [], "author": "", diff --git a/scripts/backup-db-data.js b/scripts/backup-db-data.js index 05cbea3..1d286c9 100644 --- a/scripts/backup-db-data.js +++ b/scripts/backup-db-data.js @@ -21,7 +21,7 @@ if (fromProd) { } else { assertDevDatabase(config.database); if (config.database.endsWith('_prod')) { - console.error('Refusing backup of production database without --prod. Use: npm run db:backup:prod'); + console.error('Refusing backup of production database without --prod. Use: npm run prod:db:backup'); process.exit(1); } } diff --git a/scripts/fetch-artist-images.js b/scripts/fetch-artist-images.js index 3d2976d..aaa60e4 100644 --- a/scripts/fetch-artist-images.js +++ b/scripts/fetch-artist-images.js @@ -1,6 +1,6 @@ /** * Download artist portrait images from Wikipedia (and fallbacks) into data/images/portraits/. - * Run: npm run fetch-artist-images + * Run: npm run dev:fetch-artist-images * Flags: --force (re-fetch even when portrait_path is set), --limit=N */ require('dotenv').config(); diff --git a/scripts/import-painter-palette.js b/scripts/import-painter-palette.js index f497677..ff7eecb 100644 --- a/scripts/import-painter-palette.js +++ b/scripts/import-painter-palette.js @@ -4,11 +4,11 @@ * - Insert artist/movement influence sources from Influencedby, Teachers, Influencedon, Pupils * * Usage: - * npm run migrate:artist-palette - * npm run import-painter-palette # metadata + influences - * npm run import-painter-palette -- --dry-run - * npm run import-painter-palette -- --metadata-only - * npm run import-painter-palette -- --influences-only + * npm run dev:migrate:artist-palette + * npm run dev:import-painter-palette # metadata + influences + * npm run dev:import-painter-palette -- --dry-run + * npm run dev:import-painter-palette -- --metadata-only + * npm run dev:import-painter-palette -- --influences-only */ require('dotenv').config(); const pool = require('../server/db'); @@ -47,7 +47,7 @@ async function main() { ) AS ok `); if (!tableCheck.rows[0]?.ok) { - console.error('Run npm run migrate:artist-palette first.'); + console.error('Run npm run dev:migrate:artist-palette first.'); process.exit(1); } diff --git a/scripts/restore-db-data.js b/scripts/restore-db-data.js index e7a23af..8ddbc43 100644 --- a/scripts/restore-db-data.js +++ b/scripts/restore-db-data.js @@ -1,8 +1,8 @@ /** - * Restore a data-only backup (INSERT dumps from npm run db:backup) into a database. + * Restore a data-only backup (INSERT dumps from npm run dev:db:backup) into a database. * * Dev: node scripts/restore-db-data.js --file db/DataBackup/gallery_dev_data_....txt - * Prod: npm run db:restore:prod -- --file db/DataBackup/gallery_dev_data_....txt + * Prod: npm run devtoprod:db:restore -- --file db/DataBackup/gallery_dev_data_....txt */ const fs = require('fs'); const path = require('path'); diff --git a/scripts/seed-catalog-data.js b/scripts/seed-catalog-data.js index 08f2330..4c4e389 100644 --- a/scripts/seed-catalog-data.js +++ b/scripts/seed-catalog-data.js @@ -1,5 +1,5 @@ /** - * Curated eras, movements, and artist metadata for npm run seed. + * Curated eras, movements, and artist metadata for npm run dev:seed. * Flagship paintings are resolved from art-influences-data.js and famous-paintings-data.js. */ const FAMOUS = require('./famous-paintings-data'); diff --git a/scripts/seed-wikipedia.js b/scripts/seed-wikipedia.js index ed0a8f0..3288474 100644 --- a/scripts/seed-wikipedia.js +++ b/scripts/seed-wikipedia.js @@ -1,6 +1,6 @@ /** * Seed historical eras, art movements, artists, periods, and flagship paintings. - * Run: npm run seed + * Run: npm run dev:seed * Flags: --force (re-seed), --fetch-images (download portraits and paintings from Wikipedia) */ require('dotenv').config(); @@ -180,12 +180,12 @@ async function main() { console.log(` Portraits downloaded: ${stats.portraitsFetched}`); console.log(` Painting images: ${stats.imagesFetched}`); } else { - console.log(' Run with --fetch-images to download artwork files, or npm run fetch-images later.'); + console.log(' Run with --fetch-images to download artwork files, or npm run dev:fetch-images later.'); } console.log('\nNext steps:'); - console.log(' npm run fetch-artist-bios'); - console.log(' npm run expand-catalog'); - console.log(' npm run update-influences'); + console.log(' npm run dev:fetch-artist-bios'); + console.log(' npm run dev:expand-catalog'); + console.log(' npm run dev:update-influences'); } main() diff --git a/scripts/split-dev-prod-databases.js b/scripts/split-dev-prod-databases.js index 23f9554..6896765 100644 --- a/scripts/split-dev-prod-databases.js +++ b/scripts/split-dev-prod-databases.js @@ -2,7 +2,7 @@ * One-time split of legacy Gallery → gallery_prod + gallery_dev on TrueNAS PostgreSQL. * * Usage: - * PGPASSWORD=... PGHOST=192.168.10.122 PGUSER=postgres npm run db:split-databases + * PGPASSWORD=... PGHOST=192.168.10.122 PGUSER=postgres npm run infra:db:split-dev-prod * * Options: * --copy pg_dump legacy → gallery_prod instead of rename @@ -116,12 +116,12 @@ async function main() { } else { console.warn(`No legacy database (${LEGACY_DB_NAMES.join(' / ')}) or "${PROD_DB_NAME}" found`); await createDatabaseIfMissing(admin, PROD_DB_NAME); - console.log('Run npm run migrate against gallery_prod to apply schema'); + console.log('Run npm run dev:migrate against gallery_prod to apply schema'); } if (!skipDev) { await cloneDevFromProd(admin); - console.log(`Next on dev PC: set .env DB_NAME=${DEV_DB_NAME}, then npm run migrate`); + console.log(`Next on dev PC: set .env DB_NAME=${DEV_DB_NAME}, then npm run dev:migrate`); } await admin.end(); @@ -134,7 +134,7 @@ main().catch((error) => { 'Permission denied — the gallery user cannot rename databases.\n' + 'Use pgAdmin on the dev PC (recommended):\n' + ' Open db/split-dev-prod-pgadmin.sql → connect as postgres → run each STEP (F5)\n' - + 'Or: PGUSER=postgres PGPASSWORD=... npm run db:split-databases\n' + + 'Or: PGUSER=postgres PGPASSWORD=... npm run infra:db:split-dev-prod\n' + 'Or: psql -h 192.168.10.122 -U postgres -d postgres -f db/split-dev-prod.sql', ); } diff --git a/scripts/sync-image-paths.js b/scripts/sync-image-paths.js index 8deb437..54e6854 100644 --- a/scripts/sync-image-paths.js +++ b/scripts/sync-image-paths.js @@ -1,6 +1,6 @@ /** * Align painting image_path / thumbnail_path with files on disk and import missing rows. - * Run: npm run sync-image-paths + * Run: npm run dev:sync-image-paths * Flags: --dry-run (report only, no DB writes) */ require('dotenv').config(); diff --git a/scripts/update-influences.js b/scripts/update-influences.js index a241c01..7129e47 100644 --- a/scripts/update-influences.js +++ b/scripts/update-influences.js @@ -135,7 +135,7 @@ async function main() { ) AS ok `); if (!tableCheck.rows[0]?.ok) { - console.error('Run npm run migrate:influence-sources before update-influences.'); + console.error('Run npm run dev:migrate:influence-sources before update-influences.'); process.exit(1); }