Projects IdeaWood P.03

IS WoodSoft

A system for timber trading that we designed as a team and I built: warehouse, delivery notes, invoicing, maps and EUDR reporting for companies that buy and sell timber.

Role
Design, development, operations
Period
2026 → present
Scope
Backend (REST API, admin), web app
Status
In production

Product site at ideawood.cz ↗

Dashboard: invoices, timber stock, active deals and EUDR status on one screen, so the trader does not have to open each module. Sample data, no real customer.
Fig. 1 · Dashboard: invoices, timber stock, active deals and EUDR status on one screen, so the trader does not have to open each module. Sample data, no real customer.

The brief

The brief was to build one system for timber trading that holds the warehouse, delivery notes, invoicing, maps and the mandatory reporting under the EUDR regulation. The application serves several companies at once, and each of them sees only its own data.

I built all of it, from the REST API and admin to the web app, and I also run it. The product is described on ideawood.cz ↗ as well.

What is worth mentioning

01

EUDR reporting straight into the EU TRACES system

A due diligence statement is submitted to an EU authority and includes plot polygons. From the plots and the risk assessment the system builds the XML statement, signs the SOAP request with a WS-Security header, sends it to EU TRACES, and then reads the statement status and reference numbers back from TRACES. The EU test server is not always available, so next to the real client there is a fake one that simulates a wrong key, an outage or a withdrawn statement. The customer's key is stored encrypted with libsodium. Old evidence attached to statements is removed by a separate command.

02

Importing supplier documents: parsers, and AI that never saves anything on its own

Suppliers send price lists, contracts and receipts in various formats, and the system should read them without anyone retyping. The import has two paths. CSV, XML and PDF in a known template are read by deterministic parsers that fail on a mismatch instead of guessing. A document that no parser recognises goes through AI import with Mistral OCR and a language model, and every price it returns is checked against the quoted line of the document. Both paths end in a preview that a person confirms, and only then is anything saved.

03

Reading forest management plans onto the map

A forest management plan (LHP) is uploaded as an archive and processed in the background by a separate parsing service, so uploading does not slow down the web app. On a network or server error the processing is retried, and on an error in the plan itself the plan is marked as failed. The resulting stands are saved in batches of up to 500 features as map features, and stands with prescribed felling have their own layer. The map runs on Leaflet and shows the cadastre and orthophoto next to the plans.

What it looks like

EUDR reporting: a list of due diligence statements with the status Submitted to TRACES or Draft, showing which statement has already been sent and which is still in progress
Fig. 2 · EUDR reporting: a list of due diligence statements with the status Submitted to TRACES or Draft, showing which statement has already been sent and which is still in progress
Delivery notes: a list of delivery notes with the Import receipt button, which brings receipts from the sawmill into the system
Fig. 3 · Delivery notes: a list of delivery notes with the Import receipt button, which brings receipts from the sawmill into the system
Map: orthophoto with the cadastre and forest management plan layers, the Upload LHP button is in the layers panel
Fig. 4 · Map: orthophoto with the cadastre and forest management plan layers, the Upload LHP button is in the layers panel

More about WoodSoft at ideawood.cz ↗

What it runs on

  • PHP
  • Nette
  • Doctrine
  • PostgreSQL
  • Redis
  • Symfony Messenger
  • React
  • TypeScript
  • Vite
  • Mistral OCR

Supplier documents are read by deterministic parsers (CSV, XML and recognised PDF templates), and unknown scans go through AI import with Mistral OCR. Either way the result is a preview that a person confirms before anything is saved.

WoodSoft architecture The web app calls the REST API. The API writes to PostgreSQL with row-level security, sends jobs to a queue, creates PDFs and reports EUDR to EU TRACES. Supplier documents enter the queue through two paths: deterministic parsers and AI import with Mistral OCR. The queue worker stores the result in the database as a draft for approval. WEB APP (REACT) API (NETTE) PDF (GOTENBERG) EU TRACES QUEUE WORKER POSTGRESQL + RLS DOCUMENT PARSERS MISTRAL OCR

I describe how I build systems like this on the How I work page.

Want to build something similar?

Get in touch →