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 <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
a2263ca186
commit
96285737f5
+1
-1
@@ -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 (
|
||||
|
||||
@@ -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
|
||||
--
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+39
-41
@@ -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": "",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user