Ctrl K
ComunidadGuías…

scripts/sie-import/acceptance-manual-review.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { readFileSync, writeFileSync, existsSync } from 'node:fs'
import assert from 'node:assert/strict'
import { randomUUID } from 'node:crypto'
import dotenv from 'dotenv'
import { createClient } from '@supabase/supabase-js'

// Uses only the existing synthetic browser company on designated staging.
// Leaves the renewed review visible for browser verification.
async function main() {
Object.assign(process.env, dotenv.parse(readFileSync('.env.sie-runtime.local')), { SIE_IMPORT_JOBS: 'true' })
assert.equal(process.env.NEXT_PUBLIC_SUPABASE_URL, 'https://metjnjrhvujscngnpzdv.supabase.co')
const fixture = JSON.parse(readFileSync('.env.sie-ui.json', 'utf8'))
const client = createClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.SUPABASE_SERVICE_ROLE_KEY!, {
  auth: { persistSession: false, autoRefreshToken: false },
  global: { fetch: (input, init) => fetch(input, { ...init, signal: AbortSignal.timeout(10000) }) },
})
const company = await client.from('companies').select('name').eq('id', fixture.company).single()
assert.ok(company.data?.name.startsWith('SIE acceptance'))
assert.ok(fixture.email.endsWith('@test.invalid'))
const { createJournalEntry } = await import('../../src/lib/bookkeeping/engine')
const { submitSIEJob, requestSIEJobAction } = await import('../../src/lib/import/sie-jobs')
const { runSIEWorker } = await import('../../src/lib/import/sie-job-worker')
const reportPath = '.env.sie-manual-review.json'
let report: { sourcePeriod:string; nextPeriod:string; openingEntry:string; job?:string; staleMs?:number }
if (existsSync(reportPath)) report = JSON.parse(readFileSync(reportPath, 'utf8'))
else {
  const sourcePeriod=randomUUID(), nextPeriod=randomUUID()
  for (const [id,year] of [[sourcePeriod,2030],[nextPeriod,2031]] as const) {
    const period=await client.from('fiscal_periods').insert({id,company_id:fixture.company,user_id:fixture.user,
      name:String(year),period_start:`${year}-01-01`,period_end:`${year}-12-31`})
    if(period.error) throw period.error
  }
  const opening=await createJournalEntry(client,fixture.company,fixture.user,{
    fiscal_period_id:nextPeriod,entry_date:'2031-01-01',description:'Synthetic retained opening balance',
    source_type:'opening_balance',voucher_series:'IB',
    lines:[{account_number:'1930',debit_amount:100,credit_amount:0},{account_number:'2091',debit_amount:0,credit_amount:100}],
  })
  const linked=await client.from('fiscal_periods').update({opening_balance_entry_id:opening.id,opening_balances_set:true}).eq('company_id',fixture.company).eq('id',nextPeriod)
  if(linked.error) throw linked.error
  report={sourcePeriod,nextPeriod,openingEntry:opening.id}
  writeFileSync(reportPath,JSON.stringify(report,null,2))
}
async function rows() {
  const header=await client.from('journal_entries').select('*').eq('company_id',fixture.company).eq('id',report.openingEntry).single()
  const lines=await client.from('journal_entry_lines').select('*').eq('journal_entry_id',report.openingEntry).order('id')
  if(header.error || lines.error) throw header.error || lines.error
  return {header:header.data,lines:lines.data}
}
const before=await rows()
let supersedesImportId:string|undefined
if(report.job) {
  const prior=await client.from('sie_imports').select('job_state').eq('id',report.job).single()
  const target=await client.from('fiscal_periods').select('opening_balance_review_token').eq('id',report.nextPeriod).single()
  if(prior.data?.job_state==='undone' && !target.data?.opening_balance_review_token) {
    supersedesImportId=report.job
    report.job=undefined
  }
}
if(!report.job) {
  const content='#FLAGGA 0\n#PROGRAM "Manual review acceptance" 1\n#SIETYP 4\n#FNAMN "Synthetic AB"\n#RAR 0 20300101 20301231\n#KONTO 1930 "Bank"\n#KONTO 3001 "Sales"\n#VER A 1 20300201 "Test"\n{\n#TRANS 1930 {} 100\n#TRANS 3001 {} -100\n}'
  const mappings=['1930','3001'].map(number=>({sourceAccount:number,targetAccount:number,sourceName:number,
    targetName:number,confidence:1,matchType:'exact' as const,isOverride:false}))
  const job=await submitSIEJob(client,fixture.company,fixture.user,content,mappings,{
    filename:'manual-review.se',createFiscalPeriod:false,importTransactions:true,importOpeningBalances:false,updateAccountNames:false,
    ...(supersedesImportId ? {supersedesImportId,onExistingPeriod:'replace' as const} : {}),
  })
  report.job=job.id
  writeFileSync(reportPath,JSON.stringify(report,null,2))
}
await runSIEWorker({supabase:client,importId:report.job,budgetMs:60000})
let job=(await client.from('sie_imports').select('*').eq('id',report.job).single()).data!
if(job.job_state==='completed') {
  const review=job.job_result.nextPeriodOpeningBalanceReview
  assert.equal(review.nextPeriodId,report.nextPeriod)
  assert.equal(review.openingBalanceEntryId,report.openingEntry)
  const args={p_company_id:fixture.company,p_period_id:report.nextPeriod,p_actor:fixture.user,
    p_review_token:review.reviewToken,p_expected_entry_id:report.openingEntry}
  const acknowledged=await client.rpc('acknowledge_sie_opening_balance_review',args)
  if(acknowledged.error) throw acknowledged.error
  const started=performance.now()
  const stale=await client.rpc('acknowledge_sie_opening_balance_review',args)
  report.staleMs=performance.now()-started
  assert.equal(stale.error?.code,'55000')
  assert.ok(report.staleMs<5000,'Stale response must return promptly')
  await requestSIEJobAction(client,fixture.company,fixture.user,report.job!,'undo')
  await runSIEWorker({supabase:client,importId:report.job,budgetMs:60000})
}
job=(await client.from('sie_imports').select('*').eq('id',report.job).single()).data!
assert.equal(job.job_state,'undone')
const next=(await client.from('fiscal_periods').select('*').eq('id',report.nextPeriod).single()).data!
assert.equal(next.opening_balance_review_reason,'undo')
assert.ok(next.opening_balance_review_token)
assert.equal(next.opening_balance_entry_id,report.openingEntry)
assert.deepEqual(await rows(),before)
writeFileSync(reportPath,JSON.stringify(report,null,2))
console.log(JSON.stringify({checks:'HTTP completion, acknowledgment, stale rejection, undo review renewal, unchanged next-year voucher',staleResponseMs:report.staleMs}))
}
void main().catch(error => { console.error(error); process.exitCode=1 })