case-studies · 24 Oct 2026

Max Bid: preserving one business contract across two implementations

How a Rails reference application and a TypeScript static site preserve the same calculation contract across browsers and releases.

Max Bid is a public resale-margin calculator built around one decision: what is the highest price someone can pay for an item and still reach a target profit after the sale?

The engineering challenge was not the size of the form. It was keeping one business contract understandable and consistent across a Rails reference application, a TypeScript browser implementation and a GitHub Pages release. This case study documents those decisions without claiming users, revenue, client outcomes or production scale. The evidence comes from the public calculator, published Mirtilo IO technical notes and the documented release record. The implementation repositories are private; this page does not imply public source-code inspection.

The working method behind this evidence is described in AI-assisted engineering: evidence over output.

Business rule

The calculator works backward from the expected sale price:

maximum bid =
  selling price
  − auction commission
  − platform fee
  − shipping
  − packaging
  − target profit

The seven inputs are expected selling price, purchase cost, shipping cost, packaging cost, auction commission, platform fee and target profit. Monetary values use integer euro cents and consistent half-up rounding at the defined calculation boundaries.

The observable decisions are explicit: a purchase cost equal to the maximum bid is Buy it.; a higher purchase cost is Don’t buy.; invalid input cannot leave an old recommendation on screen; and changing currency changes the unit and formatting but never applies an exchange rate.

Max Bid is a planning aid, not financial, tax, legal or marketplace-policy advice. Taxes, returns, discounts and marketplace rules can change the real result.

Rails reference implementation

The Rails 8.1 application is the reference implementation for the formulas, copy, accessibility, security and tests. It provides a complete environment for exercising the calculator behaviour and for making the contract visible in a server-rendered application.

The reference implementation is not treated as an informal prototype. The repository records the business rules, edge cases, content contract, UI behaviour, security expectations and test strategy. That gives the second implementation something more precise to match than a screenshot.

TypeScript parity implementation

The public implementation is a static TypeScript application built with Vite. It runs the calculation in the browser and publishes the generated assets on GitHub Pages. There is no long-running application server or database for the public calculator.

The TypeScript project has a typed boundary between domain rules, locale handling and the DOM UI. A canonical content contract owns the user-visible field identifiers, labels, descriptions, validation messages and localized SEO content. The static implementation preserves the Rails behaviour that a person can observe while fitting a different hosting model.

Keeping the public version static reduces the number of runtime components, but it does not remove release responsibility. The artifact still needs to be inspected, the browser behaviour needs to be tested and the deployment needs to publish the exact commit that passed CI.

Localization

Max Bid is available in English and Brazilian Portuguese. English supports EUR and US Dollar choices. Portuguese supports EUR and Brazilian Real. Currency selection changes the unit and formatting; it does not perform currency conversion, so every value in one calculation must use the same currency.

The parser and presentation rules are localized together. Portuguese users can enter values such as 1.200,50, while the English interface displays 1,200.50. The examples, input masks, validation messages and result breakdown follow the same locale instead of translating labels while leaving the calculation experience inconsistent.

Localization therefore belongs to the contract. It is part of parity, not a final layer of copy editing.

Accessibility

The Rails reference and the TypeScript implementation treat accessibility as observable behaviour. Inputs, units, controls, validation messages and the result region have accessible names and relationships. Result updates are announced, focus remains usable and the interface supports keyboard interaction and responsive layouts.

The TypeScript project includes DOM, end-to-end and accessibility checks. The documented browser baseline includes desktop and mobile scenarios, theme changes, direct navigation and the public static artifact. The goal is that the same business decision remains understandable regardless of device or assistive technology.

Security and privacy

The public calculator keeps calculation values in browser memory. The TypeScript boundary validates input, allowlists supported languages and currencies, renders user-controlled values as text and excludes calculator data from analytics, URLs and external APIs. The production artifact does not include source maps, and an artifact check scans generated output for secrets and unsafe content.

The Rails reference adds CSRF protection, a Content Security Policy, HTTPS enforcement, strong parameters and parameter filtering. Brakeman, dependency auditing and the release checklist cover risks that browser tests cannot cover alone.

This is a deliberately narrow privacy boundary: no account, calculation history, upload, payment flow or stored resale data in the public calculator.

CI/CD and GitHub Pages delivery

When a change affects typescript/, GitHub Actions installs the locked Node.js 22 dependencies with npm ci and runs type checking, linting, unit and DOM tests, end-to-end tests, accessibility tests, the production build, artifact inspection, the security scan and the high-severity dependency audit. CI uses read-only repository permissions, cancels obsolete runs and pins third-party actions to commit SHAs.

The Pages workflow waits for a successful CI run from a push to main. It checks out the exact commit evaluated by CI, installs the locked dependencies again, rebuilds and inspects typescript/dist, configures GitHub Pages and deploys the artifact. Only the deployment job receives Pages write and OIDC token permissions.

The public static calculator is configured for maxbid.mirtilo.io. The release path is therefore part of the case: Rails behaviour is the reference, TypeScript is the public parity implementation and GitHub Pages is the hosting boundary.

Release evidence

The repository maintains a release-evidence record instead of treating a successful build as the whole release decision. It records the gate names, commands, thresholds, browser baseline and rollback expectations.

At the recorded checkpoint, local automated gates were marked as passed. The same record explicitly marked the native browser matrix, manual keyboard and screen-reader verification, the first production deployment, production rollback smoke and rollback timing as pending. This case study keeps those states visible; it does not convert pending checks into claims of completed production operations.

Product limits and next decisions

Max Bid has no accounts, payment flow, exports, uploads, marketplace comparison, affiliate links or calculation-value telemetry. It is a small planning tool, not a marketplace integration or a financial advice product.

There is no evidence here for adoption, paid users, revenue, client impact, high-scale incident management, advanced observability or a completed production rollback exercise. Those claims require separate records.

The next decisions should preserve the contract first: any future feature must keep the calculation explainable, preserve parity between implementations and justify its effect on privacy, accessibility, testing and release complexity.

Sources