Plain SQL as output
ETL processes generated automatically from metadata. The generated code is the contract - versioned, diffable, with no extra abstraction layer.
A project of my own, self-built from spec through UX to production deploy. This page shows not only what DI² is - but also how it is built.
Vision, output format, method lineage and data quality philosophy - compressed into four paragraphs.
DI² generates maintainable, readable and auditable ETL processes from the metadata of your source system - automatically, in plain SQL. The output currently runs on PostgreSQL and SQL Server.
The starting point is tables, columns, types and relationships - they become the model, enriched with domain knowledge such as allowed values, business keys and historization rules. From this model, extraction and SCD2 historization are generated automatically; the transformation into DWH or OLTP deliberately remains handcraft - DI² delivers the scaffolding, you write the business logic.
Data quality is the product, not a feature. Business rules as WHERE clauses in the metadata; faulty records land in an error table instead of silently in the DWH. Three logging levels - process, step, stack trace - queryable with a SELECT.
Not a reinvention: The method has existed since 2015 in constant iteration - initially as a VBA/Excel-based code generator, today as a PostgreSQL-native engine with a Next.js web layer. DI² is the re-implementation of an approach proven over more than 10 years, on a modern stack.
Every tool makes assumptions about what matters. These are ours - explicit, so they stay open to debate.
ETL processes generated automatically from metadata. The generated code is the contract - versioned, diffable, with no extra abstraction layer.
The process is derived directly from tables, columns, types, relationships - data-model-driven instead of click-driven.
Versioned SQL runs on PostgreSQL and SQL Server today. Porting to other dialects (Snowflake, BigQuery, Oracle, DuckDB) is manageable because the output stays plain SQL.
Every code change visible as a Git diff. Plain SQL without a DSL - engineers and analysts understand it without ramp-up.
Three logging levels - process, step, stack trace - all queryable with a SELECT. Not felt, but measured.
Allowed values, value ranges, business and alternate keys, historization rules live in the model - not as comments in the code.
Extraction and SCD2 historization are generated automatically; the DWH/OLTP transformation remains handcraft - deliberately.
Business rules as WHERE clauses. Faulty records land in an error table - not silently in the DWH.
Self-hosted on Hetzner (EU data center, Germany) - no Vercel, no Supabase, no US managed service for sensitive layers. Data, auth and mail stack entirely within the EU, GDPR-compliant. Docker Compose with a multi-app layout, Nginx as reverse proxy, Let's Encrypt for SSL.
AI-driven development does not mean "Claude writes code on its own". It means: specialized skills per workflow step, clear checkpoints, and at every phase the system waits for a decision.
Feature spec with user stories, acceptance criteria, edge cases - and a mark on what can only be checked by clicking.
Technical architecture, PM-friendly, without code.
UX critique + mockups (HTML / React + shadcn) as the template - plus the click test cases, before anything is built.
API routes, DB schema, stored procedures, RLS policies.
UI with shadcn/ui - against real APIs, no mocks.
Runs the declared test cases and logs the run. Acceptance + edge cases + feature-scoped security checks.
Diff against spec & conventions; approve / request changes.
GitHub Actions: dev → int → test → prod, every stage gated - red tests mean: no deploy.
Mandatory gate before prod: OWASP, auth, headers, dependencies.
/bug - docs/bugs/bug-NNNN-<slug>.md
Can be triggered at any time - documentation, targeted fix, QA re-test, close. Bugs are never reopened; a regression gets a new ID.
/check-updates · npm · Docker · Actions · VPS
Periodic maintenance: dev dependencies and VPS components - read-only findings, no auto-apply.
AI-driven development is suspected of dropping tests first. This section states what is checked, how it is checked, and when the expectation is fixed.
Vitest · unit and component tests
Branching logic, validation, sorting, wording per language. The tests sit right next to the code they check and move with it on every refactoring.
docs/test-cases · click test cases
Only what cannot be computed: the interplay of several views, the moment a result becomes visible, messages, sign-in and sign-out.
Red means: no deployEvery push runs lint, convention checks, tests and build. Before every deploy the tests run a second time - if they fail, or if a test file is missing from the run, the deploy does not start.
The catalog holds 158 active test cases in 22 suites. Each one is written so that someone who has never seen the code can work through it.
In the classic setup, separating tester and developer prevents a test from being written along the finished implementation. AI-driven development has no such separation. It is therefore established in time instead of in people.
The expected result is written down as an acceptance criterion in the spec - before a single line of code exists.
The test case takes over that expectation word for word and adds the click steps from the mockups. Only then does the build start.
After the build the case is run and logged. If the result differs, that is a finding - the expectation is not adjusted.
Two writing rules hold the separation in place: the expected result contains no term that does not appear on screen. And every test case contains at least one statement about what must not happen.
This section was built the same way: its test cases were in the catalog before it existed.