---
title: "GenAI-Logic vs. Traditional Stack: A Worked Example"
subtitle: "Customs Surtax System — Spring Boot Equivalent Estimate"
prepared_by: Claude Code
methodology: Estimate generated by Claude Code from stated per-unit formulas applied against the public schema in database/models.py. All formulas reproducible — see Part 1.
version: 1.0
date: 2026-06-13
status: Directional estimate for technical review. All formulas stated explicitly — reproducible against the public repo.
---

# GenAI-Logic vs. Traditional Stack: A Worked Example

*Customs Surtax System — Spring Boot Equivalent Estimate*

---

## TL;DR

A complete, governed customs duty calculation system — schema, rules, REST API, admin UI, security — built with GenAI-Logic requires **93 lines of non-boilerplate code**.

The Spring Boot equivalent of the same system: **approximately 2,000 lines** for the backend alone, **2,550 lines** including the admin UI.

That's a **21x difference** on the backend. **27x** full stack.

The 93 lines aren't a subset of the system. They are the entire human-authored, project-specific work — rules, calculations, constraints. Everything else is generated by the platform and requires no maintenance.

---

## Executive Summary

This document provides a worked, reproducible estimate of what it would take to build the GenAI-Logic `demo_customs_surtax` system using a conventional Spring Boot stack. The purpose is to give technical reviewers a concrete basis for evaluating the productivity and maintainability claims in *Enterprise AI: The Missing Piece*.

**The system in question** implements the Canadian CBSA Steel Derivative Goods Surtax Order (PC 2025-0917) — a real customs regulation cited directly as written. It covers:

- 5 domain tables (CustomsEntry, SurtaxLineItem, HsCodeRate, Province, CountryOrigin)
- 18 declarative rules (copy, formula, sum, constraint)
- Live cross-table calculations with automatic dependency ordering
- Full REST API with filtering, sorting, pagination, and relationship navigation
- Generated admin application

**The GenAI-Logic baseline:** 93 lines. No hand-written scaffold. The system is open-source and installable — the rules are there to count.

**The Spring Boot equivalent:** ~2,000 lines backend, ~2,550 lines full stack. All formulas stated below — challenge them.

---

## What the Numbers Mean

Before reading the detail, one framing note.

The 93 lines are not the total size of the running system. The running system includes generated scaffold — entities, repositories, DTOs, mappers, controllers, admin screens — that the platform produces automatically in seconds. That code exists, but it is uniform, platform-owned, and requires no maintenance from your team.

The 93 lines are what your team writes, owns, reviews, and changes. The rules. The business logic. The actual decisions.

The Spring Boot comparison counts everything — because in a Spring Boot project, your team owns everything.

**Primary comparison (most defensible):** 93 lines vs. ~2,000 lines backend. 21x.

**Full-stack comparison:** 93 lines vs. ~2,550 lines including admin UI. 27x. (Note: if your team would use an existing admin tool rather than React-Admin, use the backend number as the primary claim.)

---

## Schema Profile

*Source of truth: `database/models.py` in the public repo.*

| Table | Non-meta columns | Relationships |
|---|---|---|
| CountryOrigin | 5 | 1 |
| HsCodeRate | 5 | 1 |
| Province | 4 | 1 |
| SysConfig | 11 | 1 |
| CustomsEntry | 20 | 4 |
| SurtaxLineItem | 11 | 2 |
| **Total** | **56** | **10** |

---

## Part 1 — Scaffold Layer

This is the Spring Boot equivalent of what GenAI-Logic generates automatically: JPA entities, repositories, DTOs, mappers, service layer, REST controllers with JSON:API-compliant filtering, sorting, pagination, and relationship navigation.

### Per-table formulas

All formulas stated explicitly so this estimate can be reproduced or challenged.

| Layer | Formula | Rationale |
|---|---|---|
| JPA `@Entity` | `10 + 1×cols + 2×rels` | Lombok-annotated class, `@Column`/`@ManyToOne`/`@OneToMany` |
| `Repository` | `8 + 2×rels` | `JpaRepository<T,Long>` + navigation finder methods |
| DTOs (request + response) | `10 + 2×cols` | Java records for create/update + response shape |
| Mapper (MapStruct) | `6 + 1×cols` | Entity↔DTO field mapping |
| Service | `25 + 5×rels` | `@Service` CRUD + cascade handling |
| `@RestController` | `40 + 12×rels + 0.5×cols` | CRUD endpoints + pagination/sort + relationship endpoints |

### Per-table totals

| Table | Entity | Repo | DTOs | Mapper | Service | Controller | **Total** |
|---|---|---|---|---|---|---|---|
| CountryOrigin | 17 | 10 | 20 | 11 | 30 | 55 | **143** |
| HsCodeRate | 17 | 10 | 20 | 11 | 30 | 55 | **143** |
| Province | 16 | 10 | 18 | 10 | 30 | 54 | **138** |
| SysConfig | 23 | 10 | 32 | 17 | 30 | 58 | **170** |
| CustomsEntry | 38 | 16 | 50 | 26 | 45 | 98 | **273** |
| SurtaxLineItem | 25 | 12 | 32 | 17 | 35 | 70 | **191** |
| **Subtotal** | 136 | 68 | 172 | 92 | 200 | 390 | **1,058** |

### Cross-cutting infrastructure

| Item | LOC | Rationale |
|---|---|---|
| Filter/`Specification` builder | 150 | Parse query params → JPA `Specification` predicates |
| Pagination/sort envelope + relationship resolution | 200 | Custom response wrapper to match JSON:API document shape |
| `@ControllerAdvice` exception handling | 75 | 404/400/409 mapping, validation error shape |
| OpenAPI/Swagger + CORS/security config | 65 | `springdoc-openapi` config, `WebMvcConfigurer` |
| App bootstrap | 40 | `application.yml` equivalents requiring Java config |
| **Subtotal** | **530** | |

**Scaffold total: ~1,600 LOC**

---

## Part 2 — Business Logic Layer

The 18 declarative rules, implemented as imperative Java.

| # | Rule | Spring Boot equivalent | LOC |
|---|---|---|---|
| 1–3 | Copy effective_date, program_code, pc_number from SysConfig | Fetch SysConfig singleton in create(), assign fields | 28 |
| 4 | Copy country_surtax_rate from CountryOrigin | Fetch by FK, assign | 11 |
| 5 | Copy province_tax_rate from Province | Fetch by FK, assign | 11 |
| 6–7 | Copy base_duty_rate, is_steel_derivative from HsCodeRate | Fetch by FK in line-item create | 20 |
| | **Copy subtotal (7 rules)** | | **70** |
| 8 | surtax_applicable = ship_date ≥ effective_date && country_surtax_rate > 0 | Boolean expression, recompute on save | 10 |
| 9 | duty_paid_value = total_customs_value + total_duty_amount + total_surtax_amount | BigDecimal chain + explicit re-trigger after sum updates | 18 |
| 10 | sales_tax_amount = duty_paid_value × province_tax_rate | BigDecimal.multiply() + scale/rounding | 16 |
| 11 | total_tax_due = total_duty_amount + total_surtax_amount + sales_tax_amount | BigDecimal chain + re-trigger | 18 |
| 12 | SurtaxLineItem.surtax_applicable = entry.surtax_applicable && is_steel_derivative *(live cross-table)* | Re-fetch parent CustomsEntry, re-evaluate; must re-run when parent ship_date/country_origin_id changes | 16 |
| 13 | base_duty_amount = customs_value × base_duty_rate | BigDecimal.multiply() | 14 |
| 14 | surtax_amount = customs_value × entry.country_surtax_rate if surtax_applicable *(live cross-table)* | Conditional multiply + live parent-rate read + re-trigger on parent change | 18 |
| | **Formula subtotal (7 rules)** | | **110** |
| 15–17 | SUM(customs_value), SUM(base_duty_amount), SUM(surtax_amount) → CustomsEntry | Custom @Query aggregation + recalc-on-child-change wiring | 60 |
| 18 | customs_value > 0 | @DecimalMin annotation + custom validator | 10 |
| — | Cascade orchestration — wire above into 5 write paths | ~30 LOC × 5 write-path handlers | 150 |
| | **Logic layer total** | | **~400** |

### A note on correctness

Rules 12 and 14 are live cross-table references — `SurtaxLineItem` reads live values from its parent `CustomsEntry` and must re-evaluate whenever the parent changes. In GenAI-Logic, the dependency engine handles this automatically. In a hand-built implementation, the natural shortcut is to snapshot these values at insert time. That shortcut reproduces the same stale-value bug class documented in the published A/B benchmark — except here the consequence is a customs/regulatory miscalculation, not a stale balance. This is not a theoretical risk: it is the most common error pattern in hand-written multi-table logic.

---

## Part 3 — Admin UI (Optional)

The GenAI-Logic platform generates a React-Admin application automatically. The Spring Boot equivalent:

| Item | LOC |
|---|---|
| Data provider (JSON:API-compatible) | 120 |
| Per-resource List/Edit/Create/Show (×6 tables) | 356 |
| App shell / routing / auth | 80 |
| **Admin UI total** | **~556** |

*Note: if your team would use an existing admin tool rather than building React-Admin, omit this from the comparison and use the backend-only figures.*

---

## Summary

| Scope | LOC | Ratio vs. 93 lines |
|---|---|---|
| **GenAI-Logic** (entire non-boilerplate codebase) | **93** | 1x |
| Spring Boot — scaffold only | ~1,600 | 17x |
| Spring Boot — business logic only | ~400 | 4x |
| **Spring Boot — backend total** | **~2,000** | **21x** |
| Spring Boot — full stack (incl. admin UI) | ~2,550 | 27x |

Of the ~2,000 Spring Boot backend lines, approximately 80% is scaffold — code that exists in every Spring Boot project, differs slightly in every shop, and must be understood and maintained by every developer who joins the team.

The 93 GenAI-Logic lines are the entire human-authored, project-specific work. The scaffold is generated once and never touched.

---

## Verification

This is a directional estimate. All per-unit formulas are stated explicitly in Part 1 so they can be re-derived, challenged, or adjusted against the actual schema.

The GenAI-Logic baseline (93 lines) is verified against the project governance report and can be confirmed by anyone who installs the open-source sample:

```
genai-logic create --project_name=demo_customs_surtax \
  --using=samples/prompts/customs_cbsa.prompt
```

The rules are in `logic/logic_discovery/cbsa_steel_surtax.py`. Count them yourself.

---

*This estimate was generated by Claude Code, applying stated per-unit formulas to the public schema in `database/models.py`. All formulas are in Part 1 — reproduce or challenge them against the actual repo. This is a directional estimate for evaluation purposes, not a software estimation deliverable.*
