# B2B Workflow Automation Quote Estimator & Lead Capture

An embeddable, zero-runtime-dependency TypeScript + Tailwind CSS Custom Element (`<quote-calculator>`) built as a client-facing portfolio case demo for B2B workflow automation services.

---

## What This Demonstrates

In custom B2B workflow automation and integration consulting, scoping conversations frequently stall before they begin: prospective clients don't know if their budget aligns with the technical complexity, and agencies spend valuable engineering hours on exploratory discovery calls before basic financial qualification occurs.

This component solves that bottleneck with **self-serve budget clarity**:
1. **Interactive Estimation**: Clients configure automation scope tier, delivery urgency, and monthly workflow count to see an instant, transparent price range and delivery timeline.
2. **Qualified Lead Intake**: When prospects are ready, they submit their contact information and project requirements through an integrated lead capture form that validates parameters in-browser and prepares a structured handoff payload.
3. **Encapsulated & Portable Architecture**: Packaged as a standalone native Custom Element with open Shadow DOM styling, preventing stylesheet collisions with host landing pages.
4. **Production API Compatibility**: Dispatches an observable, composed custom event with a stable SHA-256 idempotency key designed to interface with the AgencyAutomation intake worker (`POST /api/leads`).

---

## Demonstration Pages

- **Main Portfolio Case (`index.html`)**: The primary client-facing portfolio demo. Features a clear visitor value proposition, grounded business context, an interactive simulation badge, a single visible calculator instance, and collapsed developer technical notes.
- **Multi-Instance Verification Fixture (`verification.html`)**: A dedicated testing fixture hosting multiple concurrent calculator instances (`#calc-primary` and `#calc-secondary`) with independent scope parameters, isolated internal states, and a live document-level event logger.

---

## Quick Embed Guide

### 1. Include the Distributable Script
Include the compiled script in your HTML `<head>` or before `</body>`:

```html
<script src="dist/quote-calculator.js"></script>
```

### 2. Add the Custom Element
Insert `<quote-calculator>` wherever you want the widget to appear:

```html
<quote-calculator
  id="automation-quote-calculator"
  data-service-title="Workflow Automation & Integration Pricing"
  data-default-scope="2"
  data-default-urgency="2"
  data-default-volume="20"
></quote-calculator>
```

### Supported Attributes

| Attribute | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `data-service-title` | `string` | `"Workflow Automation & Integration Estimator"` | Heading displayed in the component header. |
| `data-default-scope` | `1 \| 2 \| 3 \| 4` | `2` | Initial scope tier (1: Essential, 2: Standard, 3: Advanced, 4: Enterprise). |
| `data-default-urgency`| `1 \| 2 \| 3 \| 4` | `2` | Initial delivery urgency (1: Flexible, 2: Standard, 3: Expedited, 4: Critical). |
| `data-default-volume` | `number (1-100)` | `15` | Initial unit/module/endpoint count. |

---

## Composed Custom Event Contract

When a user submits the quote form, the component dispatches an observable, composed custom event named `quote-submit`. Because `composed: true` is enabled, the event traverses outside the Shadow DOM and can be captured at `document` or `window` level:

```javascript
document.addEventListener('quote-submit', (event) => {
  const { payload, idempotencyKey, estimate, mock, timestamp } = event.detail;

  console.log('Submission received:', {
    idempotencyKey,
    estimateRange: estimate.formattedRange,
    timeline: estimate.timeline,
  });

  // AgencyAutomation API Payload Contract:
  // {
  //   name: string,
  //   phone: string, // Validated international phone number
  //   email: string, // RFC-compliant work email
  //   jobDetails: string, // Project requirements & notes
  //   reviewConsent: false // Default off
  // }
});
```

---

## Production Proxy Notes & Security Architecture

In production, client-side browser JavaScript **must never directly invoke the backend leads API with tenant credentials**.

### Security & Compliance Architecture

```
[ Browser / Web Component ]
          │
          │ (1) User Submits Quote Request
          ▼
[ Server-Side Proxy / Form Action ] (e.g. Cloudflare Pages Function, Next.js Route, or Express)
          │
          ├─► (2) Enforce Rate Limiting (e.g., 5 requests / IP / min)
          ├─► (3) Validate Anti-Bot Challenge (Cloudflare Turnstile token)
          ├─► (4) Attach Secure Tenant Bearer Token from Server Environment
          ├─► (5) Retain Stable Idempotency-Key
          ▼
[ AgencyAutomation Intake API: POST /api/leads ]
          │
          ├─► Durable D1 Persistence & Deduplication
          ├─► Immediate Owner SMS Notification (Twilio)
          └─► Customer Confirmation Email (Resend)
```

### Why a Server Proxy is Mandatory

1. **Credential Protection**: The AgencyAutomation endpoint requires `Authorization: Bearer <tenant-scoped-token>`. Embedding intake tokens in client JavaScript allows malicious actors to spam or spoof submissions.
2. **Anti-Bot Defense**: Public forms must be shielded by an anti-bot check (such as Cloudflare Turnstile). The server-side proxy validates the Turnstile response before forwarding the payload to the worker.
3. **Strict Deduplication & Idempotency**: The proxy forwards the stable `Idempotency-Key` (8–128 characters) generated for the payload. The intake API deduplicates retried requests and rejects conflicting payloads reusing the same key with HTTP `409 Conflict`.
4. **No Public CORS**: The AgencyAutomation worker does not enable wildcard public CORS; requests originate from the trusted proxy.
5. **PII Handling & Consent**: Phone numbers are validated for international calling. In compliance with the intake contract, `reviewConsent` defaults to `false`. Consent to receive post-job review SMS requests must not be set to `true` without affirmative, explicit customer opt-in.

---

## Local Development & Build Verification

### Scripts
```bash
# Install development dependencies (Tailwind CLI, esbuild, TypeScript)
npm install

# Build compiled Tailwind CSS, bundle component into dist/, and emit types
npm run build

# Run Playwright Edge smoke suite (verifies sliders, invalid/valid inputs, multi-instance, and 0 console warnings)
npm run test:smoke
```

### Output Artifacts
- `dist/quote-calculator.js`: IIFE standalone bundle with embedded CSS (for `<script src="...">`).
- `dist/quote-calculator.esm.js`: ESM bundle for module environments.
- `dist/styles.css`: Compiled, minified Tailwind CSS.
- `dist/types/`: Emitted TypeScript declarations (`.d.ts`).
- `screenshots/`: Viewport verification renders (`desktop.png`, `mobile.png`, `mobile-small.png`).
- `smoke_evidence.json`: Initial widget Playwright assertion/console results from before the portfolio redesign. Final redesign regression execution remains deferred until the owner testing phase; current screenshots are render-only evidence.
