ENGINEERING CASE STUDY · DWG FG-001 · 2026 / ONGOING
Building eleven11 Finder
Full-Stack Product Engineering · Cloud Architecture · Quality Strategy
From product concept to a production serverless platform: how monorepo boundaries, single-table DynamoDB design, and automated AST/infra guardrails work together at scale.
| Project | eleven11 Finder | Doc ID | FG-001 |
|---|---|---|---|
| Role | Founder & Software Architect (Finder Group) | ||
| Scope | 4 Apps · 12 Packages · 14 Terraform Roots | Sheet | 2 / 5 |
| Verified | API 89% · Web 88% · Mobile 88% · 14 AST Guards · 52+ ADRs | ||
| Links | |||
01 / The Challenge & System Scope Problem statement
Everyday retail prices for groceries, fuel, and pet supplies vary significantly across neighborhoods and chains, while data arrives from heterogeneous sources: community reports, optical receipt and flyer extraction, WhatsApp messages, and official government feeds (such as ANP in Brazil).
The architectural challenge is to normalize, verify, and serve location-aware price comparisons across multiple countries (Brazil, Spain, and the Netherlands) and five languages (pt-BR, en, es, nl, ca) while keeping cloud operating costs predictable and solo/small-team engineering velocity high.
Production Footprint
- Consumer Web (
apps/web): React, Vite, TanStack Router, MapLibre GL, live ateleven11finder.com. - Mobile App (
apps/mobile): Expo / React Native with custom flat Material 3 primitives on iOS TestFlight and Android internal testing. - Staff Admin (
apps/admin): Dedicated operations console for catalog curation, flyer imports, moderation, and partner claims. - Serverless API (
apps/api): Per-handler Node.js 24 AWS Lambda functions behind API Gateway, backed by DynamoDB and Cognito.
02 / System Architecture Schematic view
Platform-specific code stays strictly inside apps/*. Domain contracts, business logic, API clients, design tokens, and E2E fixtures live in packages/*. Infrastructure is provisioned exclusively through Terraform, split into a base stack plus domain-scoped roots.
03 / Key Architectural Decisions Selected from 52+ ADRs
Every non-trivial architectural trade-off in eleven11 is recorded as a numbered ADR in docs/decisions/. Below are five representative decisions currently running in production.
| ADR | Context & Problem | Decision | Trade-offs & Outcome |
|---|---|---|---|
| ADR-001 ADR-036 |
Full-text accent-insensitive product search across multiple languages needed sub-100ms latency without a high fixed monthly bill. | Use DynamoDB single-table storage paired with an in-memory catalog index built from a versioned snapshot and patched via declared bumps, deferring OpenSearch/Typesense. | Requires memory_size >= 1024 on handlers that hydrate the catalog index, enforced by a static call-graph guard. Saves ~$50 to $150/month in idle search cluster costs. |
| ADR-038 | As API endpoints grew, consolidating handlers into monolithic per-domain Lambda routers was evaluated to reduce Terraform resource count. | Keep per-handler AWS Lambdas deployed across domain-split Terraform roots, with shared dependencies packaged in a verified Lambda layer. | Slightly larger Terraform state, but preserves least-privilege IAM per endpoint, isolated blast radius, accurate per-route metrics, and fast cold starts. |
| ADR-016 | Stale retail prices erode user trust, and bundling seed catalogs into production responses blurred the line between real and reference data. | Enforce a strict 31-day price freshness window across every surface and retire the bundled seed catalog from production responses. | Smaller cities show fewer items until community or flyer ingestion populates them, but every displayed price is guaranteed fresh and traceable. |
| ADR-047 | On-demand DynamoDB read units in the shared dev account spiked due to full-suite Playwright E2E runs triggered on every pull request. |
Cut CI E2E volume first by selecting only impacted specs via e2e-impact-map.mjs and balancing shards by measured duration weights. |
PRs only execute affected suites (plus nightly full runs on e2e-real-aws.yml), slashing DynamoDB read consumption and CI wall-clock time while keeping per-run capacity telemetry. |
| ADR-048 | Users wanted a conversational way to ask for product prices and store comparisons inside the app without maintaining a separate AI backend. | Build the in-app assistant on Amazon Bedrock tool-use orchestration directly over existing domain services. | Zero duplicate query logic; the model invokes deterministic domain tools. E2E tests intercept /assistant/** routes to test UI resilience without incurring Bedrock costs in CI. |
04 / Quality Engineering Strategy Verification architecture
1. Unified Quality Orchestrator (pnpm qa)
A single custom runner (packages/testing-tools/qa.mjs) orchestrates lint, format, types, unit, scripts, seed, workflows, and e2e. Every run logs timing to .qa-history/runs.jsonl so slowdowns and repeat offenders are surfaced via pnpm qa report.
2. 14 Static Code-to-Terraform AST Guards
Fourteen custom static analyzers (pnpm --filter @eleven11/api verify:terraform) walk the TypeScript call graph and compare it against HCL declarations across 14 Terraform roots before push and in CI:
verify:dynamodb-write-iam: proves all 68 handlers markeddynamodb_read_only = truecannot reach a DynamoDB write command.verify:catalog-hydration-memory: proves all 31 handlers reachinggetCatalogIndices()provision at least 1024 MB RAM across 210 deployed Lambdas.verify:local-server-routes&verify:config-name-parity: verify 238 routes, 54 GSI references, and 65 env vars match between code and Terraform.
3. Eliminating 850s of CI Setup Overhead
Building the 71 MB manual seed catalog took ~5s per test file on CI runners, burning ~850s of setup per shard against 80s of actual tests. Moving catalog construction into vitest.global-setup.ts to write a single temp JSON snapshot primed by worker forks reduced per-file setup to milliseconds and fails loudly if the snapshot path is missing.
4. Real-AWS E2E Hygiene & Intercepts
For repository-layer verification where module mocks hide key-shape bugs, *.integration.test.ts suites use dynamodb-intercept.ts at the AWS SDK client boundary. For full E2E against shared dev Cognito and DynamoDB, post-deploy cleanup sweeps apply a 2-hour age guard and preserve fixed worker accounts so concurrent PR shards never collide.
What I Deliberately Chose Not to Automate in PR CI (and Why)
- Per-PR Android Emulator (Maestro) E2E: Mobile UI flows exist in
apps/mobile/e2e/, but booting Android emulators on every PR adds high latency and runner flake. Instead, shared business logic and hooks are unit-tested at 88% coverage in Jest, mobile-web viewports run in Playwright, and Maestro runs on-demand before mobile releases. - Live LLM / Bedrock Calls in Automated UI Suites: Asserting on non-deterministic generative outputs in CI wastes budget and creates flaky gates. Playwright intercepts
/assistant/**to verify UI state transitions, rate-limit (429) recovery, and retry behavior deterministically. - Repeating Functional E2E Across Every Viewport: Running 230+ functional specs across 5 device viewports would multiply CI cost 5x without catching new logic defects. Device projects (
desktop-macbook-16,tablet-ipad-13,phone-iphone-15) are scoped strictly to layout/responsive specs while business journeys run once on the default project.
05 / Engineering Leadership & AI-Assisted Workflows Ways of working
Building a multi-surface platform as an independent architect requires treating AI agents and coding assistants as junior-to-mid contributors operating inside strict guardrails. The repository maintains dedicated onboarding paths, architectural invariants, and automated checks (such as setup-console-error-guard.ts failing tests on any unexpected React console.error, and external-test-inputs.test.mjs ensuring CI path filters never miss cross-workspace test dependencies).
Every bug fix ships with a regression test, seed assertions test invariants rather than brittle item counts, and time-sensitive freshness logic runs against pinned fake timers.
Summary of Verified Metrics
- Unit Test Coverage: 89% API · 88% Web · 88% Mobile (CI-enforced via
coverage:badges:check) - Architecture Decisions: 52+ numbered ADRs + 16 foundational records
- Infrastructure Guards: 14 non-vacuous static AST/Terraform checks across 210 Lambdas and 238 routes
- Localization & Markets: 3 countries (BR, ES, NL) · 5 locales
Next Sheet Navigation
Continue to the 420finder multi-tenant architecture case study or return to the executive overview.