# Registration Flow Overhaul Implementation Plan

> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

**Goal:** Improve onboarding usability for non-technical dealers by reordering steps, adding subdomain examples, and enabling Empowerkit migration.

**Architecture:** Modify the existing 3-step accordion form to collect business profile first (enabling migration lookup), then domain selection with visual examples. Add feature-flagged migration check via modal flow after step 1.

**Tech Stack:** React 19, Next.js 16, Radix UI Accordion, TypeScript, Jest

---

## Task 1: Add `includeSubdomains` Parameter to Migration Lookup

**Files:**

- Modify: `lib/migration-dealer-lookup.ts:145-220`
- Test: `lib/__tests__/migration-dealer-lookup.test.ts`

**Step 1: Write the failing tests**

Add to `lib/__tests__/migration-dealer-lookup.test.ts` after line 500 (inside the `findPotentialMigrationDealerMatches` describe block):

```typescript
describe('includeSubdomains parameter', () => {
  it('filters out AMSOIL subdomains by default (includeSubdomains=false)', async () => {
    mockQueryRaw.mockResolvedValueOnce([
      {
        dealerNumber: '123456',
        contactEmail: 'test@example.com',
        customDomain: 'dealer.myamsoil.com',
      },
    ]);

    const result = await findPotentialMigrationDealerMatches('123456', 'test@example.com');

    expect(result).toEqual([]);
  });

  it('includes AMSOIL subdomains when includeSubdomains=true', async () => {
    mockQueryRaw.mockResolvedValueOnce([
      {
        dealerNumber: '123456',
        contactEmail: 'test@example.com',
        customDomain: 'dealer.myamsoil.com',
      },
    ]);

    const result = await findPotentialMigrationDealerMatches('123456', 'test@example.com', true);

    expect(result).toHaveLength(1);
    expect(result[0].customDomain).toBe('dealer.myamsoil.com');
    expect(result[0].matchedOn).toBe('both');
  });

  it('includes results with null customDomain when includeSubdomains=true', async () => {
    mockQueryRaw.mockResolvedValueOnce([
      { dealerNumber: '123456', contactEmail: 'test@example.com', customDomain: null },
    ]);

    const result = await findPotentialMigrationDealerMatches('123456', 'test@example.com', true);

    expect(result).toHaveLength(1);
    expect(result[0].customDomain).toBeNull();
  });

  it('includes both custom domains and AMSOIL subdomains when includeSubdomains=true', async () => {
    mockQueryRaw.mockResolvedValueOnce([
      { dealerNumber: '123456', contactEmail: 'test@example.com', customDomain: 'custom.com' },
      {
        dealerNumber: '123456',
        contactEmail: 'other@example.com',
        customDomain: 'dealer.myamsoil.com',
      },
    ]);

    const result = await findPotentialMigrationDealerMatches('123456', 'test@example.com', true);

    expect(result).toHaveLength(2);
  });
});
```

**Step 2: Run tests to verify they fail**

Run: `npm test -- lib/__tests__/migration-dealer-lookup.test.ts --testNamePattern="includeSubdomains"`

Expected: FAIL - function signature doesn't accept third parameter

**Step 3: Update function signature and implementation**

In `lib/migration-dealer-lookup.ts`, update the function (around line 145):

```typescript
/**
 * Find potential MigrationDealer matches using OR logic.
 *
 * This function queries the legacy MigrationDealer table to find records
 * where EITHER the dealerNumber OR contactEmail matches. Used by admin
 * panel to show potential migration matches for dealers who may qualify
 * for grandfathered custom domain access.
 *
 * @param dealerNumber - Dealer's AMSOIL dealer/ZO number
 * @param contactEmail - Dealer's contact email address
 * @param includeSubdomains - When true, include standard AMSOIL subdomains in results (default: false)
 * @returns Array of potential matches with match type info
 */
export async function findPotentialMigrationDealerMatches(
  dealerNumber: string | null | undefined,
  contactEmail: string | null | undefined,
  includeSubdomains: boolean = false
): Promise<PotentialMigrationMatch[]> {
```

Then update the filtering logic (around line 190-196). Replace:

```typescript
// Filter to only include results with actual custom domains
// (exclude standard AMSOIL subdomains like dealer.myamsoil.com)
const customDomainResults = results.filter((result) => isCustomDomain(result.customDomain));

if (customDomainResults.length === 0) {
  return [];
}
```

With:

```typescript
// Filter results based on includeSubdomains parameter
// When false (default): only include actual custom domains
// When true: include all results (custom domains + AMSOIL subdomains + null)
const filteredResults = includeSubdomains
  ? results
  : results.filter((result) => isCustomDomain(result.customDomain));

if (filteredResults.length === 0) {
  return [];
}
```

And update the return statement to use `filteredResults` instead of `customDomainResults`:

```typescript
    // Determine what matched for each result
    return filteredResults.map((result) => {
```

**Step 4: Run tests to verify they pass**

Run: `npm test -- lib/__tests__/migration-dealer-lookup.test.ts`

Expected: All tests PASS

**Step 5: Commit**

```bash
git add lib/migration-dealer-lookup.ts lib/__tests__/migration-dealer-lookup.test.ts
git commit -m "feat: add includeSubdomains parameter to findPotentialMigrationDealerMatches

Allows callers to include standard AMSOIL subdomains in results,
needed for Empowerkit migration flow during onboarding (#482)"
```

---

## Task 2: Remove margin-bottom from Accordion Inputs

**Files:**

- Modify: `app/registration/onboarding/accordion-styles.css:214-227`

**Step 1: Update the CSS rule**

In `app/registration/onboarding/accordion-styles.css`, find the input selector (lines 214-227) and remove `margin-bottom: 16px;`:

Before:

```css
/* Form Elements in Accordion Content */
.accordion-content input[type='text'],
.accordion-content input[type='email'],
.accordion-content input[type='tel'] {
  background: #ffffff;
  border: 1px solid #008bff;
  border-radius: 5px;
  padding: 12px;
  font-family: Inter, sans-serif;
  font-weight: 700;
  font-size: 16px;
  line-height: 1.3;
  color: rgba(2, 6, 24, 0.64);
  margin-bottom: 16px;
}
```

After:

```css
/* Form Elements in Accordion Content */
.accordion-content input[type='text'],
.accordion-content input[type='email'],
.accordion-content input[type='tel'] {
  background: #ffffff;
  border: 1px solid #008bff;
  border-radius: 5px;
  padding: 12px;
  font-family: Inter, sans-serif;
  font-weight: 700;
  font-size: 16px;
  line-height: 1.3;
  color: rgba(2, 6, 24, 0.64);
}
```

**Step 2: Commit**

```bash
git add app/registration/onboarding/accordion-styles.css
git commit -m "style: remove margin-bottom from accordion inputs

Brings helper text closer to its associated field (#482)"
```

---

## Task 3: Reorder Accordion Steps (Profile First, Domain Second)

**Files:**

- Modify: `app/registration/onboarding/OnboardingForm.tsx`

**Step 1: Update initial state**

Change line 42 from:

```typescript
const [currentStep, setCurrentStep] = useState<Step>(hasSubdomain ? 'profile' : 'subdomain');
```

To:

```typescript
const [currentStep, setCurrentStep] = useState<Step>(hasSubdomain ? 'subdomain' : 'profile');
```

**Step 2: Swap the Accordion.Item blocks**

Move the entire "Step 2: Business Profile" block (lines 352-548) to come BEFORE "Step 1: Subdomain Selection" block (lines 190-350).

After moving, update the step numbers and labels:

For the Business Profile section (now first):

- Line with `<div className="number-badge...">2.</div>` → change to `1.`
- Line with "Step 2 of 3:" → change to "Step 1 of 3:"

For the Subdomain Selection section (now second):

- Line with `<div className="number-badge...">1.</div>` → change to `2.`
- Line with "Step 1 of 3:" → change to "Step 2 of 3:"

**Step 3: Update navigation buttons**

In the Business Profile section (now Step 1), remove the Back button. Change lines 529-546 from:

```tsx
{
  /* Navigation Buttons */
}
<div className="flex justify-between pt-4 onboarding-nav-buttons">
  <button onClick={() => setCurrentStep('subdomain')} className="btn-secondary">
    Back
  </button>
  <button
    onClick={handleSaveProfile}
    disabled={
      !formData.phone || !formData.address || !formData.city || !formData.state || !formData.zip
    }
    className="btn-primary onboarding-continue-button"
  >
    Continue to Review
  </button>
</div>;
```

To:

```tsx
{
  /* Navigation Buttons */
}
<div className="flex justify-end pt-4 onboarding-nav-buttons">
  <button
    onClick={() => setCurrentStep('subdomain')}
    disabled={
      !formData.phone || !formData.address || !formData.city || !formData.state || !formData.zip
    }
    className="btn-primary onboarding-continue-button"
  >
    Continue to Domain
  </button>
</div>;
```

In the Subdomain Selection section (now Step 2), update the continue button. Change lines 335-348:

```tsx
<div className="flex justify-end pt-4 onboarding-button-wrapper">
  <button
    onClick={() => {
      setFormData({ ...formData, subdomain, customDomain });
      setCurrentStep('profile');
    }}
    disabled={!subdomain || subdomainStatus.available !== true || subdomainStatus.checking}
    className="btn-primary onboarding-continue-button"
  >
    Continue to Profile
  </button>
</div>
```

To:

```tsx
<div className="flex justify-between pt-4 onboarding-button-wrapper">
  <button onClick={() => setCurrentStep('profile')} className="btn-secondary">
    Back
  </button>
  <button
    onClick={() => {
      setFormData({ ...formData, subdomain, customDomain });
      setCurrentStep('review');
    }}
    disabled={!subdomain || subdomainStatus.available !== true || subdomainStatus.checking}
    className="btn-primary onboarding-continue-button"
  >
    Continue to Review
  </button>
</div>
```

In the Review section (Step 3), update the Back button target. Change:

```tsx
<button onClick={() => setCurrentStep('profile')} className="btn-secondary" disabled={publishing}>
  Back to Edit
</button>
```

To:

```tsx
<button onClick={() => setCurrentStep('subdomain')} className="btn-secondary" disabled={publishing}>
  Back to Edit
</button>
```

**Step 4: Verify manually**

Run: `npm run dev`

Navigate to the onboarding page and verify:

1. Business Profile is Step 1
2. Choose Your Domain is Step 2
3. Navigation flows correctly between steps

**Step 5: Commit**

```bash
git add app/registration/onboarding/OnboardingForm.tsx
git commit -m "refactor: reorder onboarding steps - profile first, domain second

Collecting dealer info first enables migration check before
subdomain selection (#482)"
```

---

## Task 4: Add Subdomain Example with Visual Styling

**Files:**

- Modify: `app/registration/onboarding/OnboardingForm.tsx`

**Step 1: Add the example element**

In the Subdomain Selection section, after the closing `</div>` of the input group (after line 256 in original, now in Step 2), add:

```tsx
{
  /* Subdomain Example */
}
<p className="mt-2 text-sm text-white/70">
  Example:{' '}
  <span
    style={{
      color: '#38bdf8',
      textDecoration: 'underline',
      textDecorationColor: '#38bdf8',
    }}
  >
    jsmith
  </span>
  {' → '}
  <span
    style={{
      color: '#38bdf8',
      textDecoration: 'underline',
      textDecorationColor: '#38bdf8',
    }}
  >
    jsmith
  </span>
  <span className="text-white/70">.{fullBaseDomain}</span>
</p>;
```

This should appear between the input group and the subdomain status section.

**Step 2: Verify manually**

Run: `npm run dev`

Navigate to onboarding Step 2 (Choose Your Domain) and verify the example appears with underlined sky-blue styling on "jsmith".

**Step 3: Commit**

```bash
git add app/registration/onboarding/OnboardingForm.tsx
git commit -m "feat: add subdomain example with visual styling

Shows 'jsmith -> jsmith.shopamsoil.com' with the editable portion
underlined in accent color (#482)"
```

---

## Task 5: Fix Subdomain Input Alignment

**Files:**

- Modify: `app/registration/onboarding/OnboardingForm.tsx`

**Step 1: Change flex alignment to items-end**

Find the subdomain input group div (line 219 in original):

```tsx
<div className="flex items-center onboarding-subdomain-input-group">
```

Change to:

```tsx
<div className="flex items-end onboarding-subdomain-input-group">
```

**Step 2: Remove marginBottom from domainPrefix select**

Find the select element for domainPrefix (around line 238-255 in original) and remove `marginBottom: '15px'` from the style prop:

Before:

```tsx
<select
  id="domainPrefix"
  value={domainPrefix}
  onChange={(e) => setDomainPrefix(e.target.value)}
  className="onboarding-domain-suffix"
  style={{
    fontSize: '16px',
    padding: '12px',
    borderRadius: '5px',
    backgroundColor: 'white',
    color: 'black',
    border: '1px solid #d1d5db',
    marginBottom: '15px',
  }}
>
```

After:

```tsx
<select
  id="domainPrefix"
  value={domainPrefix}
  onChange={(e) => setDomainPrefix(e.target.value)}
  className="onboarding-domain-suffix"
  style={{
    fontSize: '16px',
    padding: '12px',
    borderRadius: '5px',
    backgroundColor: 'white',
    color: 'black',
    border: '1px solid #d1d5db',
  }}
>
```

**Step 3: Commit**

```bash
git add app/registration/onboarding/OnboardingForm.tsx
git commit -m "style: fix subdomain input alignment

Change to flex-end alignment and remove margin-bottom from
domain suffix select (#482)"
```

---

## Task 6: Update Info Text Class

**Files:**

- Modify: `app/registration/onboarding/OnboardingForm.tsx`

**Step 1: Change text-xs to text-sm**

Find the helper text div in the subdomain section (around line 287 in original):

```tsx
<div className="mt-3 text-xs text-white/70 space-y-2">
```

Change to:

```tsx
<div className="mt-3 text-sm text-white/70 space-y-2">
```

**Step 2: Commit**

```bash
git add app/registration/onboarding/OnboardingForm.tsx
git commit -m "style: increase subdomain helper text size

Change from text-xs (0.75rem) to text-sm (0.875rem) for
better readability (#482)"
```

---

## Task 7: Add Environment Variable

**Files:**

- Modify: `.env.example`

**Step 1: Add the feature flag**

Add after line 156 (after the `PRODUCTION_MODE` section):

```bash
# Migration Check Feature Flag
# When enabled, checks MigrationDealer table during onboarding to offer
# data migration for dealers coming from Empowerkit
# Set to "true" to enable, leave empty or "false" to disable
ENABLE_MIGRATION_CHECK=""
```

**Step 2: Commit**

```bash
git add .env.example
git commit -m "docs: add ENABLE_MIGRATION_CHECK to .env.example

Feature flag for Empowerkit migration check during onboarding (#482)"
```

---

## Task 8: Create Migration Check Modal Component

**Files:**

- Create: `app/registration/onboarding/MigrationCheckModal.tsx`

**Step 1: Create the modal component**

```tsx
'use client';

import { useState } from 'react';
import type { PotentialMigrationMatch } from '@/lib/migration-dealer-lookup';
import { isCustomDomain } from '@/lib/migration-dealer-lookup';

interface MigrationCheckModalProps {
  match: PotentialMigrationMatch;
  onConfirm: (data: {
    subdomain: string;
    customDomain: string;
    dealerNumber: string;
    email: string;
  }) => void;
  onSkip: () => void;
  domainExtension: string;
}

type ModalStep = 'ask' | 'confirm';

/**
 * Extract subdomain from an AMSOIL domain string.
 * e.g., "jsmith.myamsoil.com" -> "jsmith"
 */
function extractSubdomain(domain: string): string {
  const match = domain.match(/^([^.]+)\.(my|shop)amsoil\.(com|ca)$/i);
  return match ? match[1] : '';
}

export default function MigrationCheckModal({
  match,
  onConfirm,
  onSkip,
  domainExtension,
}: MigrationCheckModalProps) {
  const [step, setStep] = useState<ModalStep>('ask');

  // Determine if the domain is custom or AMSOIL subdomain
  const hasCustomDomain = isCustomDomain(match.customDomain);
  const extractedSubdomain =
    match.customDomain && !hasCustomDomain ? extractSubdomain(match.customDomain) : '';

  // Editable form state
  const [formData, setFormData] = useState({
    email: match.contactEmail || '',
    dealerNumber: match.dealerNumber || '',
    subdomain: extractedSubdomain,
    customDomain: hasCustomDomain ? match.customDomain || '' : '',
  });

  const handleConfirm = () => {
    onConfirm(formData);
  };

  // Modal 1: Ask if coming from Empowerkit
  if (step === 'ask') {
    return (
      <div className="fixed inset-0 bg-black/70 flex items-center justify-center z-50 p-4">
        <div className="bg-slate-800 rounded-lg max-w-md w-full p-6 border border-slate-600">
          <h2 className="text-xl font-bold text-white mb-4">Coming from Empowerkit?</h2>
          <p className="text-white/80 mb-6">
            If you previously had a site with Empowerkit, we may be able to migrate your basic
            information and domain information automatically.
          </p>
          <div className="flex gap-3 justify-end">
            <button
              onClick={onSkip}
              className="px-4 py-2 rounded-md bg-slate-600 text-white hover:bg-slate-500 transition-colors"
            >
              No, start fresh
            </button>
            <button
              onClick={() => setStep('confirm')}
              className="px-4 py-2 rounded-md bg-sky-500 text-slate-900 font-semibold hover:bg-sky-400 transition-colors"
            >
              Yes, migrate my info
            </button>
          </div>
        </div>
      </div>
    );
  }

  // Modal 2: Confirm/edit migration data
  return (
    <div className="fixed inset-0 bg-black/70 flex items-center justify-center z-50 p-4">
      <div className="bg-slate-800 rounded-lg max-w-lg w-full p-6 border border-slate-600">
        <h2 className="text-xl font-bold text-white mb-4">Does this information look correct?</h2>
        <p className="text-white/70 text-sm mb-4">
          You can edit any fields below before continuing.
        </p>

        <div className="space-y-4">
          {/* Contact Email */}
          <div>
            <label className="block text-sm font-medium text-white mb-1">Contact Email</label>
            <input
              type="email"
              value={formData.email}
              onChange={(e) => setFormData({ ...formData, email: e.target.value })}
              className="w-full px-3 py-2 rounded-md bg-white text-slate-900 border border-slate-300"
            />
          </div>

          {/* Dealer Number */}
          <div>
            <label className="block text-sm font-medium text-white mb-1">ZO Account Number</label>
            <input
              type="text"
              value={formData.dealerNumber}
              onChange={(e) => setFormData({ ...formData, dealerNumber: e.target.value })}
              className="w-full px-3 py-2 rounded-md bg-white text-slate-900 border border-slate-300"
            />
          </div>

          {/* Domain - show what we found */}
          <div>
            <label className="block text-sm font-medium text-white mb-1">
              {hasCustomDomain ? 'Custom Domain' : 'Subdomain'}
            </label>
            {hasCustomDomain ? (
              <input
                type="text"
                value={formData.customDomain}
                onChange={(e) => setFormData({ ...formData, customDomain: e.target.value })}
                placeholder="yourdomain.com"
                className="w-full px-3 py-2 rounded-md bg-white text-slate-900 border border-slate-300"
              />
            ) : (
              <div className="flex items-center gap-2">
                <input
                  type="text"
                  value={formData.subdomain}
                  onChange={(e) =>
                    setFormData({ ...formData, subdomain: e.target.value.toLowerCase() })
                  }
                  placeholder="yourname"
                  className="flex-1 px-3 py-2 rounded-md bg-white text-slate-900 border border-slate-300"
                />
                <span className="text-white/70">.myamsoil{domainExtension}</span>
              </div>
            )}
            {match.customDomain && (
              <p className="mt-1 text-xs text-white/50">Found: {match.customDomain}</p>
            )}
          </div>
        </div>

        <div className="flex gap-3 justify-end mt-6">
          <button
            onClick={() => setStep('ask')}
            className="px-4 py-2 rounded-md bg-slate-600 text-white hover:bg-slate-500 transition-colors"
          >
            Back
          </button>
          <button
            onClick={handleConfirm}
            className="px-4 py-2 rounded-md bg-sky-500 text-slate-900 font-semibold hover:bg-sky-400 transition-colors"
          >
            Confirm & Continue
          </button>
        </div>
      </div>
    </div>
  );
}
```

**Step 2: Commit**

```bash
git add app/registration/onboarding/MigrationCheckModal.tsx
git commit -m "feat: add MigrationCheckModal component

Two-step modal for Empowerkit migration:
1. Ask if coming from Empowerkit
2. Confirm/edit migration data (#482)"
```

---

## Task 9: Integrate Migration Check into Onboarding Flow

**Files:**

- Modify: `app/registration/onboarding/OnboardingForm.tsx`

**Step 1: Add imports**

At the top of the file, add:

```tsx
import MigrationCheckModal from './MigrationCheckModal';
import type { PotentialMigrationMatch } from '@/lib/migration-dealer-lookup';
```

**Step 2: Add state for migration check**

After line 67 (after the `error` state), add:

```tsx
// Migration check state
const [migrationMatch, setMigrationMatch] = useState<PotentialMigrationMatch | null>(null);
const [showMigrationModal, setShowMigrationModal] = useState(false);
const [checkingMigration, setCheckingMigration] = useState(false);
```

**Step 3: Add migration check handler**

After the `handleSaveProfile` function, add:

```tsx
const handleContinueToSubdomain = async () => {
  setError('');

  // Validate required fields first
  if (!formData.phone || !formData.address || !formData.city || !formData.state || !formData.zip) {
    setError('Please fill in all required fields');
    return;
  }

  // Check for migration if feature is enabled
  if (process.env.NEXT_PUBLIC_ENABLE_MIGRATION_CHECK === 'true') {
    setCheckingMigration(true);
    try {
      const response = await fetch('/api/registration/check-migration', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          email: formData.email,
          dealerNumber: formData.dealerNumber,
        }),
      });

      if (response.ok) {
        const data = await response.json();
        if (data.match) {
          setMigrationMatch(data.match);
          setShowMigrationModal(true);
          setCheckingMigration(false);
          return;
        }
      }
    } catch (err) {
      // Silently continue if migration check fails
      console.error('Migration check failed:', err);
    }
    setCheckingMigration(false);
  }

  // No migration match or feature disabled - proceed to subdomain step
  setCurrentStep('subdomain');
};

const handleMigrationConfirm = (data: {
  subdomain: string;
  customDomain: string;
  dealerNumber: string;
  email: string;
}) => {
  // Update form data with migration data
  setFormData({
    ...formData,
    dealerNumber: data.dealerNumber,
  });
  setSubdomain(data.subdomain);
  setCustomDomain(data.customDomain);

  // Close modal and proceed to subdomain step
  setShowMigrationModal(false);
  setMigrationMatch(null);
  setCurrentStep('subdomain');
};

const handleMigrationSkip = () => {
  setShowMigrationModal(false);
  setMigrationMatch(null);
  setCurrentStep('subdomain');
};
```

**Step 4: Update the Business Profile continue button**

Change the button's onClick handler from `() => setCurrentStep('subdomain')` to `handleContinueToSubdomain`:

```tsx
<button
  onClick={handleContinueToSubdomain}
  disabled={
    checkingMigration ||
    !formData.phone ||
    !formData.address ||
    !formData.city ||
    !formData.state ||
    !formData.zip
  }
  className="btn-primary onboarding-continue-button"
>
  {checkingMigration ? 'Checking...' : 'Continue to Domain'}
</button>
```

**Step 5: Add modal render**

Before the closing `</div>` of the component (before the final `);`), add:

```tsx
{
  /* Migration Check Modal */
}
{
  showMigrationModal && migrationMatch && (
    <MigrationCheckModal
      match={migrationMatch}
      onConfirm={handleMigrationConfirm}
      onSkip={handleMigrationSkip}
      domainExtension={domainExtension}
    />
  );
}
```

**Step 6: Commit**

```bash
git add app/registration/onboarding/OnboardingForm.tsx
git commit -m "feat: integrate migration check into onboarding flow

After Business Profile step, check MigrationDealer table for
Empowerkit data and show modal if match found (#482)"
```

---

## Task 10: Create Migration Check API Endpoint

**Files:**

- Create: `app/api/registration/check-migration/route.ts`

**Step 1: Create the API route**

```typescript
import { NextRequest, NextResponse } from 'next/server';
import { findPotentialMigrationDealerMatches } from '@/lib/migration-dealer-lookup';
import { logger } from '@/lib/logger';

export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const { email, dealerNumber } = body;

    if (!email && !dealerNumber) {
      return NextResponse.json({ error: 'Email or dealer number required' }, { status: 400 });
    }

    // Check for migration matches (include subdomains for onboarding flow)
    const matches = await findPotentialMigrationDealerMatches(
      dealerNumber,
      email,
      true // includeSubdomains
    );

    if (matches.length === 0) {
      return NextResponse.json({ match: null });
    }

    // Return the first/best match (prioritize 'both' matches)
    const bestMatch = matches.find((m) => m.matchedOn === 'both') || matches[0];

    logger.info(
      { email, dealerNumber, matchedOn: bestMatch.matchedOn },
      'Migration match found during onboarding'
    );

    return NextResponse.json({ match: bestMatch });
  } catch (error) {
    logger.error({ err: error }, 'Error checking migration data');
    return NextResponse.json({ error: 'Failed to check migration data' }, { status: 500 });
  }
}
```

**Step 2: Commit**

```bash
git add app/api/registration/check-migration/route.ts
git commit -m "feat: add migration check API endpoint

POST /api/registration/check-migration queries MigrationDealer
table for Empowerkit data during onboarding (#482)"
```

---

## Task 11: Add NEXT_PUBLIC Environment Variable

**Files:**

- Modify: `.env.example`

**Step 1: Update the environment variable name**

The migration check feature flag needs to be accessible on the client side, so it must be prefixed with `NEXT_PUBLIC_`. Update the entry added in Task 7:

```bash
# Migration Check Feature Flag
# When enabled, checks MigrationDealer table during onboarding to offer
# data migration for dealers coming from Empowerkit
# Set to "true" to enable, leave empty or "false" to disable
NEXT_PUBLIC_ENABLE_MIGRATION_CHECK=""
```

**Step 2: Commit**

```bash
git add .env.example
git commit -m "fix: use NEXT_PUBLIC prefix for migration check flag

Client-side code needs access to the feature flag (#482)"
```

---

## Task 12: Manual Testing Checklist

**Verify the complete flow:**

1. Start dev server: `npm run dev`
2. Navigate to onboarding page
3. Verify step order: Business Profile (1) → Choose Domain (2) → Review (3)
4. Fill out Business Profile, click Continue
5. Verify subdomain example appears with underline styling
6. Verify input alignment (flex-end)
7. Verify helper text size is readable (text-sm)
8. Complete flow through Review step

**Test migration check (requires `NEXT_PUBLIC_ENABLE_MIGRATION_CHECK=true` and MigrationDealer data):**

1. Enter dealer info that matches MigrationDealer record
2. Verify modal appears asking "Coming from Empowerkit?"
3. Click "Yes, migrate my info"
4. Verify data is shown and editable
5. Click "Confirm & Continue"
6. Verify subdomain/custom domain is pre-filled

---

## Summary

| Task | Description                       | Files                                   |
| ---- | --------------------------------- | --------------------------------------- |
| 1    | Add `includeSubdomains` parameter | `lib/migration-dealer-lookup.ts`, tests |
| 2    | Remove margin-bottom from inputs  | `accordion-styles.css`                  |
| 3    | Reorder accordion steps           | `OnboardingForm.tsx`                    |
| 4    | Add subdomain example             | `OnboardingForm.tsx`                    |
| 5    | Fix input alignment               | `OnboardingForm.tsx`                    |
| 6    | Update info text class            | `OnboardingForm.tsx`                    |
| 7    | Add env variable                  | `.env.example`                          |
| 8    | Create migration modal            | `MigrationCheckModal.tsx`               |
| 9    | Integrate migration check         | `OnboardingForm.tsx`                    |
| 10   | Create API endpoint               | `route.ts`                              |
| 11   | Fix env var prefix                | `.env.example`                          |
| 12   | Manual testing                    | N/A                                     |
