Remove repeated Plant, Financial and Workforce shortcut cards. Add site-scoped Plant and Financial sidebar attention status with automatic refresh. Include accumulated delivery processing, purchase order recovery, supplier reconciliation, plant data and user management changes and audit records.
38 lines
3.8 KiB
JavaScript
38 lines
3.8 KiB
JavaScript
/** Additive allocation storage. Dry-run by default; --apply backs up and verifies. */
|
|
import PocketBase from 'pocketbase';
|
|
import {mkdtemp,writeFile} from 'node:fs/promises';
|
|
import {tmpdir} from 'node:os';
|
|
import {join,resolve} from 'node:path';
|
|
import {fileURLToPath} from 'node:url';
|
|
import {equalJson} from './2026-09-30-add-supplier-reconciliation-rules.mjs';
|
|
const additions={
|
|
delivery_notes:[{name:'receiving_identity_key',type:'text',required:false,max:100}],
|
|
dn_batch_notes:[{name:'line_posting',type:'json',required:false,maxSize:2000000}],
|
|
delivery_note_items:[{name:'allocation_key',type:'text',required:false,max:100},{name:'source_line_keys',type:'json',required:false,maxSize:10000},{name:'booking',type:'json',required:false,maxSize:100000}],
|
|
dn_pipeline_locks:[{name:'scope_key',type:'text',required:false,max:100}],
|
|
};
|
|
export const normalizeIndex=sql=>sql.replace(/`/g,'').replace(/\s+/g,'').toLowerCase();
|
|
const indexes={delivery_notes:"CREATE UNIQUE INDEX idx_dn_receiving_identity ON delivery_notes (receiving_identity_key) WHERE receiving_identity_key != ''",delivery_note_items:'CREATE UNIQUE INDEX idx_dn_allocation_key ON delivery_note_items (allocation_key) WHERE allocation_key != \'\'',dn_pipeline_locks:'CREATE UNIQUE INDEX idx_dn_posting_scope ON dn_pipeline_locks (scope_key) WHERE scope_key != \'\''};
|
|
const pb=new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL||process.env.PB_URL);
|
|
async function main(){
|
|
if(process.argv.slice(2).some(a=>a!=='--apply'))throw Error('Only --apply supported');
|
|
if(process.env.POCKETBASE_ADMIN_TOKEN)pb.authStore.save(process.env.POCKETBASE_ADMIN_TOKEN);else await pb.collection('_superusers').authWithPassword(process.env.POCKETBASE_ADMIN_EMAIL,process.env.POCKETBASE_ADMIN_PASSWORD);
|
|
const schemas=await Promise.all(Object.keys(additions).map(n=>pb.collections.getOne(n)));
|
|
const dir=process.argv.includes('--apply')?await mkdtemp(join(tmpdir(),'mega-line-posting-schema-')):null;
|
|
for(const schema of schemas){
|
|
const key=schema.name.toLowerCase();const fields=additions[key];for(const f of fields){const e=schema.fields.find(v=>v.name===f.name);if(e&&(e.type!==f.type||e.required||(f.maxSize&&e.maxSize<f.maxSize)))throw Error(`Incompatible ${schema.name}.${f.name}`);}
|
|
const extra=fields.filter(f=>!schema.fields.some(v=>v.name===f.name));const index=indexes[key];
|
|
const updatedIndexes=index&&!schema.indexes.some(i=>normalizeIndex(i)===normalizeIndex(index))?[...schema.indexes,index]:schema.indexes;
|
|
console.log(JSON.stringify({collection:schema.name,addFields:extra.map(f=>f.name),addIndex:updatedIndexes.length>schema.indexes.length}));
|
|
if(!dir)continue;await writeFile(join(dir,schema.name+'.json'),JSON.stringify(schema,null,2),{mode:0o600});
|
|
if(!equalJson(schema,await pb.collections.getOne(schema.id)))throw Error('Schema changed');
|
|
await pb.collections.update(schema.id,{fields:[...schema.fields,...extra],indexes:updatedIndexes});
|
|
const after=await pb.collections.getOne(schema.id);
|
|
if(!equalJson(schema.fields,after.fields.filter(f=>!extra.some(e=>e.name===f.name))))throw Error('Existing fields changed');
|
|
for(const k of ['listRule','viewRule','createRule','updateRule','deleteRule'])if(!equalJson(schema[k],after[k]))throw Error('Access rules changed');
|
|
if(!equalJson(after.indexes.map(normalizeIndex),updatedIndexes.map(normalizeIndex)))throw Error('Index verification failed');
|
|
for(const field of fields){const verified=after.fields.find(f=>f.name===field.name);if(!verified||verified.type!==field.type||verified.required||field.maxSize&&verified.maxSize<field.maxSize||field.max&&verified.max<field.max)throw Error('Added field verification failed: '+field.name);}
|
|
}
|
|
if(dir)console.log('Schema backups: '+dir);
|
|
}
|
|
if(process.argv[1]&&resolve(process.argv[1])===fileURLToPath(import.meta.url))main().catch(e=>{console.error(e.status?`PocketBase HTTP ${e.status}`:e.message);process.exitCode=1;});
|