caterium-app/ops/pdf/audit-curated.mjs

57 lines
4.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import fs from 'node:fs/promises';
import path from 'node:path';
import {chromium} from '@playwright/test';
import {boxes} from '../demo/trial-demo-data.mjs';
// Fictional fixtures, isolated browser, blocked external requests. No customer writes.
const phase=process.argv[2]||'final';
const root=path.resolve('..','caterium-six-proposals-20260918');
const out=path.join(root,phase==='final'?'output/pdf':'tmp/pdfs/'+phase);
const assets=path.join(root,'tmp','pdfs',phase);
await fs.mkdir(out,{recursive:true});
await fs.mkdir(assets,{recursive:true});
const browser=await chromium.launch();
const page=await browser.newPage();
await page.route('https://**',r=>r.abort());
await page.goto('http://127.0.0.1:4182/index.html',{waitUntil:'domcontentloaded'});
await page.waitForFunction(()=>Boolean(window.sunClientOfferDebugPdfPages));
const image=async file=>'data:image/'+({'.png':'png','.webp':'webp'}[path.extname(file)]||'jpeg')+';base64,'+(await fs.readFile(path.resolve('public',file))).toString('base64');
const items=await Promise.all(boxes.slice(0,8).map(async(b,i)=>({...b,categoryId:0,categoryName:'Фуршетные боксы',qty:i===0?2:1,unitPrice:b.price,sum:b.price*(i===0?2:1),photoData:await image(b.photo)})));
const base=items.reduce((n,i)=>n+i.sum,0);
const logo=await page.evaluate(async()=>{
await CateriumProposalPDF.ready();
const c=document.createElement('canvas');c.width=1400;c.height=500;const x=c.getContext('2d');
x.fillStyle='#234734';x.font='500 150px "Caterium Playfair"';x.fillText('ЛИСТ',250,270);
x.font='600 38px "Caterium Manrope"';x.fillText('К Е Й Т Е Р И Н Г',260,340);
return c.toDataURL('image/png');
});
const snapshot={brandName:'Лист · кейтеринг',brandCity:'Санкт-Петербург',brandContacts:'Пример оформления · Данные вымышлены',logo,client:'Анна и Михаил',event:'Вечер в кругу друзей',date:'2026-10-24',time:'18:00',guests:20,items,pricing:{base,manual:1500,promo:0,discount:1500,itemsTotal:base-1500,delivery:1500,total:base},foodGrams:9200,foodPieces:156,controlLines:['Согласуем время и адрес доставки','Подготовим заказ к началу вашего события'],extraServices:['Сервировка стола — по согласованию','Обслуживание — по отдельному расчёту'],finalGallery:[await image('offer-gallery/001.jpg'),await image('offer-gallery/002.jpg')],pdfSettings:{texts:{heroNote:'Сезонные вкусы, любимые сочетания и красивые детали вашего вечера.'}}};
await page.evaluate(s=>window.__pdfFixture=s,snapshot);
let choices=await page.evaluate(()=>CateriumProposalPDF.templates);
if(phase==='first-four')choices=choices.slice(0,4);
const report=[];
for(const [index,{id,name}] of choices.entries()){
const result=await page.evaluate(async id=>{
const s={...window.__pdfFixture,offerTemplateId:id};
const pages=await sunClientOfferDebugPdfPages(s);
const jpg=pages.map(c=>({width:c.width,height:c.height,bytes:Uint8Array.from(atob(c.toDataURL('image/jpeg',.94).split(',')[1]),c=>c.charCodeAt(0))}));
const blob=SunPdfEngine.fromJpegs(jpg);
const pdf=await new Promise(resolve=>{const r=new FileReader();r.onload=()=>resolve(r.result.split(',')[1]);r.readAsDataURL(blob)});
const thumb=document.createElement('canvas');thumb.width=420;thumb.height=594;thumb.getContext('2d').drawImage(pages[0],0,0,420,594);
const thumbnail=thumb.toDataURL('image/jpeg',.9).split(',')[1];
const info={id,pages:pages.length,width:pages[0].width,layout:pages.map(p=>p.__proposalLayout),images:pages.map(p=>p.__proposalImages||[])};
pages.forEach(c=>{c.width=0;c.height=0});return {pdf,info,thumbnail};
},id);
const filename=`${String(index+1).padStart(2,'0')}-${id}.pdf`;
await fs.writeFile(path.join(out,filename),Buffer.from(result.pdf,'base64'));
await fs.writeFile(path.join(assets,id+'-cover.jpg'),Buffer.from(result.thumbnail,'base64'));
if(phase==='final'){
// Thumbnails in the app are brand-neutral; actual PDFs use the customer's PNG.
const thumb=await page.evaluate(async id=>{const pages=await CateriumProposalPDF.renderPages({...window.__pdfFixture,offerTemplateId:id,brandName:'Ваша компания',brandCity:'',brandContacts:'',logo:''});const c=document.createElement('canvas');c.width=420;c.height=594;c.getContext('2d').drawImage(pages[0],0,0,420,594);const data=c.toDataURL('image/jpeg',.9).split(',')[1];pages.forEach(p=>{p.width=0;p.height=0});return data},id);
await fs.writeFile(path.resolve('public','offer-templates','quality-'+id+'.jpg'),Buffer.from(thumb,'base64'));
}
report.push({...result.info,name,filename});console.log(name,result.info.pages,'pages');
}
await fs.writeFile(path.join(assets,'report.json'),JSON.stringify(report,null,2));
await browser.close();