Files
dwroller/scripts/prune-bestiary.js
Alex caf8a03553 feat: Add scripts for upserting and validating bestiary data
- Implemented `upsert-allewis-from-5001.js` to fetch and update Allewis data from API.
- Created `upsert-missing-movement-from-5001.js` to fill missing movement and wounds data from API.
- Developed `upsert-missing-movement-from-pdfs.js` to extract movement and wounds from PDF text.
- Added `upsert-missing-profiles-from-pdfs.js` to fill missing profiles from PDF data.
- Introduced `upsert-missing-wounds-from-pdfs.js` to update wounds data from PDF sources.
- Created `validate-bestiary.js` to validate the structure of the bestiary JSON.
- Updated `BestiaryTab.jsx` component to display bestiary data with improved structure and search functionality.
- Added tests for `BestiaryTab` to ensure proper rendering and functionality.
2025-08-17 16:21:00 +02:00

77 lines
2.2 KiB
JavaScript

const fs = require('fs')
const path = require('path')
const DB_PATH = path.join(__dirname, '..', 'database', 'deathwatch-bestiary-extracted.json')
const BACKUP_DIR = path.join(__dirname, '..', 'database', 'backups')
function loadDb() {
return JSON.parse(fs.readFileSync(DB_PATH, 'utf8'))
}
function writeBackup(db) {
if (!fs.existsSync(BACKUP_DIR)) fs.mkdirSync(BACKUP_DIR, { recursive: true })
const ts = Date.now()
const backupPath = path.join(BACKUP_DIR, `deathwatch-bestiary-extracted.json.backup.${ts}.json`)
fs.writeFileSync(backupPath, JSON.stringify(db, null, 2), 'utf8')
return backupPath
}
function saveDb(db) {
db.generatedAt = new Date().toISOString()
db.count = db.results.length
fs.writeFileSync(DB_PATH, JSON.stringify(db, null, 2), 'utf8')
}
function hasCompleteProfile(entry) {
if (!entry || !entry.stats) return false
const p = entry.stats.profile
if (!p || typeof p !== 'object') return false
const required = ['ws','bs','s','t','ag','int','per','wp','fel']
for (const k of required) {
if (p[k] === undefined || p[k] === null) return false
}
return true
}
function main() {
const db = loadDb()
if (!Array.isArray(db.results)) {
console.error('DB format unexpected: results is not an array')
process.exit(2)
}
const originalCount = db.results.length
const toKeep = []
const removed = []
for (const entry of db.results) {
if (hasCompleteProfile(entry)) {
toKeep.push(entry)
} else {
removed.push({ name: entry.bestiaryName || '<unknown>', pdf: entry.pdf || '', page: entry.page || '' })
}
}
if (removed.length === 0) {
console.log(`No entries removed. DB count remains ${originalCount}`)
process.exit(0)
}
const backupPath = writeBackup(db)
console.log(`Backed up DB to ${backupPath}`)
db.results = toKeep
db.count = toKeep.length
db.generatedAt = new Date().toISOString()
fs.writeFileSync(DB_PATH, JSON.stringify(db, null, 2), 'utf8')
console.log(`Pruned bestiary: removed ${removed.length} entries (from ${originalCount} -> ${db.count})`)
console.log('Removed entries:')
for (const r of removed) console.log(` - ${r.name} (pdf=${r.pdf} page=${r.page})`)
process.exit(0)
}
if (require.main === module) main()