🌍 Language: 🇩🇪 German →
GSF stands for Go Small Frameworks — minimalist tools for robust applications.
This project is developed and maintained on Codeberg.
Canonical repository:
GitHub is an automated mirror of the Codeberg repository:
GitHub mirror:
GSF-NexFact is a modular system designed for flexible generating, analyzing, and validating ZUGFeRD and Factur-X e-invoices from JSON data.
It transforms inputs into XML, standard PDFs, or hybrid ZUGFeRD invoices (including attachments) using a file-based architecture with clear conventions (Convention over Configuration).
The entire system relies on a strictly file-based data exchange using a defined directory
structure (NEXFACT-env). The Go Orchestrator manages state transitions,
while specialized workers (running natively or within isolated containers)
monitor and process the directories. A standardized RenderJob file acts as
the bridge between Go, the LibreOffice Basic macro, and the Mustang engine (Java).
+-----------------------+
| nexfact-orchestrator |
+-----------+-----------+
| (Handles orchestration, transforms
| input-json into internal MasterZugFerd-Struct)
v
+-----------------------+
| nexfact-env | <--- Common state (Directories)
+-----------+-----------+
|
+----------------+-------------+
v v
+------------------------+ +-----------------------+
| PDF via LibreOffice | | ZUGFeRD via Mustang |
| native or container | | native or container | (Workers)
+------------------------+ +-----------------------+
This repository is organized as a multi-module repository:
api: Core interfaces, types, structs, centralized error handling (e.g.,RenderJob,Error,Writer)engines: Processing engines (writer), synchronization & worker controlorchestrator: Control unit, entry point for the Goexamples: Ready-to-run code examplesenv: Directory structure & configurationsdeployments: Container repos for Docker/Podman (PDF/Mustang)
Detailed Module Documentation: Each core package (
api,engines,orchestrator,env,deployments) contains its own dedicatedREADME.mdwith in-depth technical documentation, architectural details, and specific usage examples.
A simple main.go snippet serving as an entry point. This setup utilizes default values:
- The
envstructure is located right next to themain.goin the current working directory. - The
defaultseller profile is used (found inenv/sellers/default). - The provider type is set to
native(configured inenv/system/systm.yamlviazugferd_provider=nativeandpdf_provider=native).
You can find the documented, working example at examples.
You can find the containerized counterpart to this main.go at deployments.
You can find a detailed and complex template in the orchestrator.
package main
import (
"os"
"codeberg.org/tiny-frameworks/nexfact/orchestrator"
nexerrors "codeberg.org/tiny-frameworks/nexutils/errors"
"codeberg.org/tiny-frameworks/nexutils/logger"
)
func main() {
// Required for the local monorepo example:
os.Setenv(orchestrator.EnvRootKey, "../env")
orch, err := orchestrator.NewDefault()
if err != nil {
nexerrors.LogError(logger.Logger, err)
os.Exit(nexerrors.GetExitCode(err))
}
// Execute job (expects JSON payload for the toolchain)
jsonPayload := jsonJob()
result, err := orch.RunJsonJob(jsonPayload)
if err != nil {
nexerrors.LogError(logger.Logger, err)
os.Exit(nexerrors.GetExitCode(err))
}
logger.Logger.Info("Job succeeded", "JobID", result.JobID, "OutputPath", result.OutputPath)
if err := openPDF(result.OutputPath); err != nil {
nexerrors.LogError(logger.Logger, err)
os.Exit(nexerrors.GetExitCode(err))
}
os.Exit(0)
}
func openPDF(filePath string) error {
// Go code to open the generated PDF file
// See: examples/main.go
return nil
}
func jsonJob() []byte {
// Byte stream for a minimal sample ZUGFeRD invoice
// See: examples/main.go
return []byte{}
}nexfact relies on reference environments, XML schemas, and test fixtures
provided by the shared nexfact-assets repository.
To run tests locally, ensure nexfact-assets is cloned alongside nexfact. During test
execution, setup.SetupTestEnv automatically copies the required test fixtures into
an isolated, temporary directory (t.TempDir()) to guarantee side-effect-free test runs:
import "codeberg.org/tiny-frameworks/nexfact-assets/setup"
func TestInvoiceGeneration(t *testing.T) {
// Copies fixtures into t.TempDir()
envRoot := setup.SetupTestEnv(t, setup.NATIVE)
// ... execute test logic
}Please consult the readme orchestrator.
nexfact provides two test execution modes:
orchestrator/orchestrator_suite_test.go: Full Integration Suite with Docker/Podman container isolation (Podman preferred).orchestrator/orchestrator_suite_native_test.go: Direct test execution without containers or network (LibreOffice and Java/Mustang must be installed on the host).
- Copyright: © 2026 Georg Hagn.
- Repository:
codeberg.org/tiny-frameworks/nexfact - License: Apache License, Version 2.0.
GSF-NexFact is an independent open-source project and is not affiliated with any corporation of a similar name.
For inquiries, architectural discussions, or security issues, please contact:
📧 georghagn [at] tiny-frameworks.io
