# jtlsrv Built on **libuv** (event loop), **OpenSSL** (TLS), **llhttp** (HTTP parsing), **unixODBC** + [**ODBC Driver 18 for SQL Server**](https://learn.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server) (database), and **libvips** (image thumbnails). Blocking work (ODBC queries, image processing) runs on libuv worker threads. ## Requirements | Dependency | Purpose | |---|---| | C++17 compiler | gcc or clang | | GNU Make | Build | | pkg-config | Dependency flags | | libuv | Async I/O and thread pool | | OpenSSL | TLS | | libvips | Product/category image resizing | | unixODBC + dev headers | ODBC runtime | | [ODBC Driver 18 for SQL Server](https://learn.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server) | Connect to JTL-Wawi (MSSQL) | Vendored in `vendor/`: **llhttp**, **nlohmann/json** (no install needed). ### Install on Ubuntu / Debian ```bash sudo apt install \ build-essential make pkg-config \ libuv1-dev libssl-dev libvips-dev unixodbc-dev ``` Install [Microsoft's ODBC driver](https://learn.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server) (required for MSSQL): ```bash curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | \ sudo gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-prod.gpg] \ https://packages.microsoft.com/ubuntu/$(lsb_release -rs)/prod $(lsb_release -cs) main" | \ sudo tee /etc/apt/sources.list.d/mssql-release.list sudo apt update sudo ACCEPT_EULA=Y apt install msodbcsql18 ``` ## Build ```bash make ``` The binary is written to `./jtlsrv`. After code changes always run `make` before starting the server. Debug build: ```bash make debug ``` ## Configuration Copy the example env file from the repo root and edit as needed: ```bash cp ../.env.example .env ``` Key settings: | Variable | Default | Description | |---|---|---| | `PORT` | `4443` | HTTPS listen port | | `PAIRING_CODE` | `307018` | Code shown to the POS during pairing | | `AUTH_TOKEN` | (built-in default) | Device auth token after pairing | | `MSSQL_*` | — | JTL-Wawi database connection | | `MANDANT_*` | — | Mandant metadata returned to the client | | `ROOT_CATEGORY_ID` | `1` | Root category for sync | | `TAX_ZONE_NAME` | `Zone-EU` | Tax zone for product prices | | `LOG_FILE` | `logs/requests.log` | Request log path | | `ORDER_LOG_FILE` | `logs/orders.log` | Order log path | The server starts without MSSQL if `MSSQL_USER` is unset or the connection fails — pairing and handshake still work, but catalog sync from the database is unavailable. ## TLS certificates Place a certificate and key at `certs/cert.pem` and `certs/key.pem` (relative to the working directory when you run the binary). ```bash mkdir -p certs openssl req -x509 -newkey rsa:2048 -nodes \ -keyout certs/key.pem -out certs/cert.pem -days 3650 \ -subj '/CN=localhost/O=JTL POS Sync/C=DE' \ -addext 'subjectAltName=DNS:localhost,IP:127.0.0.1,IP:0.0.0.0' ``` On startup the server prints the pairing code and whether MSSQL connected. ## API endpoints | Method | Path | Description | |---|---|---| | GET | `/v1/client` | Client discovery / pairing | | GET | `/v1/init` | Init handshake | | GET | `/v1/category` | Category sync | | GET | `/v1/product` | Product sync | | GET | `/v1/productcomposite` | Composite product sync | | GET | `/v1/deletedentity` | Deleted entity sync | | GET | `/v1/customergroup` | Customer group sync | | POST | `/v1/order` | Submit orders | | GET | `/v1/pimage` | Product image (resized) | | GET | `/v1/cimage` | Category image (resized) | ## Project layout ``` Makefile src/ main.cpp Entry point, route registration, startup config.hpp .env loader tls_server.{hpp,cpp} HTTPS over libuv + OpenSSL http.{hpp,cpp} llhttp request/response handling router.{hpp,cpp} Route dispatch pairing.{hpp,cpp} In-memory pairing store endpoints/ HTTP handlers queries/ SQL query builders (header-only) db/pool.{hpp,cpp} ODBC connection pool vendor/ llhttp, nlohmann/json ```