FAQ
Short answers to the questions that come up first.
What is a spooled file, and why not read the database instead?
A spooled file is what a program on the IBM i prints: pages of text in *SCS format on an output queue, waiting for a printer. Most ERP output (invoices, pick lists, reports) exists only that way, laid out by programs nobody wants to change. Spooldoc reads what the program already prints, so nothing on the IBM i changes.
Why turn the pages into JSON first, instead of rendering straight from the spooled file?
Because reading a page and laying out a document are different jobs, and keeping them apart makes both easier:
- The template never sees lines and columns. The definition knows that
the invoice number follows
Invoice no.......:and that the lines start under a header at column 7. The template only knows{d.pg.invoiceNo}and{d.pg.lines[i].item}. It is HTML, a Word document or an Excel workbook with Carbone tags for named values, not column arithmetic. - Each side changes on its own. A new look needs a new template, not a new definition. A program change that moves a column needs one fix in the definition, and every template still works.
- Values are typed once. Numbers and dates are converted in the definition, so templates format them with formatters and can sum them, and a value that does not convert is reported where it was read.
- You can check the reading before the rendering. The workbench shows the JSON next to the page with every hit highlighted, and the extraction report lists found, missing and empty fields. The agent works from that report too.
- One spooled file, many documents. Six invoices printed back to back are six page groups, split on the invoice number: six JSON objects and six documents.
- Same JSON for every template. An HTML, Word or Excel template reads the same page groups and makes PDF, HTML, DOCX or XLSX files.
See Definitions for the YAML that does the reading and Templates for the templates that do the layout.
Does Spooldoc install anything on the IBM i?
No. It signs on with a user profile, lists and reads spooled files through SQL services and jt400, and holds, moves or deletes them as the job says. Real-time watching creates a data queue and attaches it to the output queue, only when you ask. See Security.
Which spooled files can it read?
Plain *SCS text, which is what most operational reports and program-described printer files produce, in any EBCDIC code page the file declares. XML printed into a spooled file works too. AFPDS and *USERASCII are not supported.
Do I need a model?
No. The agent writes the first definition and template and fixes missing fields, which saves most of the work, but a definition is plain YAML you can write by hand with the page view beside you, and the starter template renders every field. See Definitions.
What does the model see?
The page text of one preview spooled file, with the values as printed, or masked when you turn masking on so digits and letters are replaced while the layout stays, plus the definition and template, and the documents it renders from a Word template. Never credentials, never other spooled files. See agent.
The page shows [ and \ where Ä and Ö should be
The spooled file carries bytes in one code page and declares another, or
declares none. Spooldoc decodes with the file's own CHRID; when the file
has none and the job CCSID is 65535, set SPOOLDOC_DEFAULT_CCSID to the
code page the programs actually print in, such as 273 or 37. See
Configuration.
Why is a run skipped?
The spooled file does not pass the definition's match rules (splf,
queue, userData, page1). A job on a mixed queue takes only its own
files; loosen the rules or add a job for the other files.
Why was a file not picked up by the watcher?
The watcher takes ready files, and held files only when the trigger says so. A file that was on the queue before watching started is left for Run now unless Backlog is on. Each file runs once, even after its run was deleted by retention. See Watching a queue.
The connection dropped after I changed networks
Spooldoc throws a dropped connection away and opens a new one on the next try, so pages and the watcher recover by themselves once the IBM i can be reached again; no restart is needed. Until then the server shows "Cannot reach" with the reason. Press Reconnect on the Servers page to try at once. See Connection status.
Can I run the same file again?
Yes: Retry in the job log runs it again with the active version.
Why port 3000?
Because it is what Next.js and most web apps use. From source, pnpm dev
takes the next free port when 3000 is busy; in the container, PORT
changes it. See Deployment.
Where is the data?
All of it is in Postgres: servers, jobs, versions, captured spooled files,
runs and their files. One pg_dump is the whole backup. See
Deployment.
Can I use it without Docker?
Yes: Node 22, a JDK 17 for the jt400 bridge, Postgres, and a Carbone server to render documents. See Contributing.
What is coming?
Plans are in the README and the issues.
Where do I ask a question?
In Discussions Q&A. Bugs and feature requests go to the issues, and security problems to a private report (see SECURITY.md). Replace real customer, host, library and user names before you paste a spooled file or a log.