BlockRun

BlockRun lib Architecture Refactor Plan

For Claude: REQUIRED SUB-SKILL: Use superpowers

to implement this plan task-by-task.

Goal: Reorganize the 126-file flat lib/ structure into 7 domain-based subdirectories, split oversized files (ai-providers 4.8K LOC, gcs-logger 823 LOC), and consolidate type definitions for improved maintainability and discoverability.

Architecture: Move from a flat, monolithic lib/ directory to a domain-driven organization where related functionality (providers, payment, logging, blockchain, etc.) lives together. Each domain has its own index.ts barrel export and types.ts file. This preserves all functionality while dramatically improving cognitive load and file discovery.

Tech Stack: Next.js 16, TypeScript, vitest, Node.js


Current State

  • 126 files in lib/ (flat structure)
  • ai-providers.ts at 4,885 LOC (dispatcher + provider adapters mixed)
  • gcs-logger.ts at 823 LOC (logging + metrics combined)
  • Scattered domains: Payment files (x402, treasury, allowlists) spread across root
  • No type consolidation: Types buried in implementation files
  • Import complexity: Routes import from multiple files per concern

Target State

lib/
├── providers/          # LLM routing + adapters (split from ai-providers)
├── payment/            # x402 settlement (consolidated)
├── optimization/       # Context compression
├── observability/      # Logging, health, analytics
├── blockchain/         # Chains, RPC, wallets
├── common/             # Cross-cutting utils
├── middleware/         # Rate-limiting, identity injection
└── [~20 single-purpose files]  # Focused utilities (stay in root)

Phase 1: Directory Setup & Type Consolidation

Task 1.1: Create Domain Directories

Files:

  • Create: lib/providers/
  • Create: lib/payment/
  • Create: lib/optimization/
  • Create: lib/observability/
  • Create: lib/blockchain/
  • Create: lib/common/
  • Create: lib/middleware/

Step 1: Create directories

cd /Users/vickyfu/Documents/blockrun-web/blockrun
mkdir -p lib/{providers,payment,optimization,observability,blockchain,common,middleware}

Step 2: Verify directories exist

ls -la lib/ | grep "^d"

Expected output:

drwxr-xr-x  ... common
drwxr-xr-x  ... middleware
drwxr-xr-x  ... observability
drwxr-xr-x  ... optimization
drwxr-xr-x  ... payment
drwxr-xr-x  ... blockchain
drwxr-xr-x  ... providers

Step 3: Commit

git add -A
git commit -m "refactor(lib): create domain-based directory structure"

Task 1.2: Create Provider Domain Types

Files:

  • Create: lib/providers/types.ts
  • Reference: Current lib/models.ts (extract types)

Step 1: Extract type definitions from models.ts

Read the current lib/models.ts to identify types:

  • Model interface
  • ImageModel, AudioModel, VideoModel, etc.
  • BillingMode type
  • NetworkType type
  • Pricing-related types

Step 2: Create lib/providers/types.ts

// lib/providers/types.ts

export interface Model {
  id: string
  name: string
  provider: string
  type: 'chat' | 'image' | 'audio' | 'video'
  pricing: {
    input: number
    output: number
  }
  hidden?: boolean
  fallbackModel?: string
  capabilities: string[]
}

export interface ImageModel {
  id: string
  name: string
  provider: string
  pricing: {
    per_image: number
  }
  maxResolution: string
}

export interface AudioModel {
  id: string
  name: string
  provider: string
  type: 'speech' | 'music' | 'soundfx'
  pricing: {
    per_request: number
  }
}

export interface VideoModel {
  id: string
  name: string
  provider: string
  pricing: {
    per_second: number
  }
  maxDuration: number
}

export type BillingMode = 'free' | 'paid' | 'flat'
export type NetworkType = 'mainnet' | 'testnet'

export interface ModelHealth {
  isHealthy: boolean
  lastChecked: Date
  successRate: number
}

export interface ProviderConfig {
  name: string
  apiKey?: string
  baseUrl?: string
  timeout?: number
}

Step 3: Verify file exists

cat lib/providers/types.ts | head -20

Step 4: Run type check

npm run type-check 2>&1 | head -30

Expected: May have errors at this point (imports not updated yet).

Step 5: Commit

git add lib/providers/types.ts
git commit -m "feat(providers): create domain types file"

Task 1.3: Create Payment Domain Types

Files:

  • Create: lib/payment/types.ts
  • Reference: Current lib/x402.ts, lib/onchain-settle.ts

Step 1: Extract payment types

From lib/x402.ts, identify:

  • PaymentRequirement interface
  • VerifyPaymentResult type
  • SettlementResult type

Step 2: Create lib/payment/types.ts

// lib/payment/types.ts

export interface PaymentRequirement {
  resource: string
  amount: bigint
  currency: 'USDC' | 'SOL' | 'ETH'
  chainId: number
  payTo: string
  expires: number
  nonce: string
}

export interface VerifyPaymentResult {
  valid: boolean
  payer: string
  signature: string
  timestamp: number
  message?: string
}

export interface SettlementResult {
  success: boolean
  txHash?: string
  error?: string
  retryable: boolean
}

export interface EnterpriseAllowlist {
  wallet: string
  provider: string
  asyncSettle?: boolean
}

export interface PayerDenylist {
  wallet: string
  reason: string
  blockedAt: Date
}

export interface TreasuryConfig {
  baseWallet: string
  solanaWallet: string
  supportedChains: number[]
}

Step 3: Verify file exists and check structure

cat lib/payment/types.ts | wc -l

Step 4: Commit

git add lib/payment/types.ts
git commit -m "feat(payment): create domain types file"

Task 1.4: Create Observability Domain Types

Files:

  • Create: lib/observability/types.ts
  • Reference: lib/types/health.ts, lib/gcs-logger.ts

Step 1: Create lib/observability/types.ts

// lib/observability/types.ts

export type HealthStatus = 'healthy' | 'degraded' | 'unhealthy'

export interface ModelHealth {
  modelId: string
  provider: string
  status: HealthStatus
  lastChecked: Date
  successCount: number
  failureCount: number
  successRate: number
}

export interface ProviderHealth {
  provider: string
  status: HealthStatus
  lastChecked: Date
  models: ModelHealth[]
}

export interface SystemHealth {
  status: HealthStatus
  providers: ProviderHealth[]
  timestamp: Date
}

export interface LogEntry {
  timestamp: Date
  modelId: string
  provider: string
  inputTokens: number
  outputTokens: number
  cost: number
  wallet: string
  txHash?: string
}

export interface MetricSnapshot {
  recentCalls: LogEntry[]
  successCount: number
  errorCount: number
  totalCost: number
}

Step 2: Verify file exists

cat lib/observability/types.ts | head -15

Step 3: Commit

git add lib/observability/types.ts
git commit -m "feat(observability): create domain types file"

Task 1.5: Create Blockchain Domain Types

Files:

  • Create: lib/blockchain/types.ts
  • Reference: lib/network-config.ts, lib/wallet-recon.ts

Step 1: Create lib/blockchain/types.ts

// lib/blockchain/types.ts

export interface NetworkConfig {
  name: string
  chainId: number
  rpcUrl: string
  explorerUrl: string
  nativeCurrency: string
}

export interface WalletActivity {
  wallet: string
  timestamp: Date
  txHash: string
  amount: string
  type: 'send' | 'receive'
  token: string
}

export interface WalletReconRecord {
  wallet: string
  totalSpent: number
  totalReceived: number
  balance: number
  lastUpdated: Date
}

export interface ChainPrice {
  symbol: string
  price: number
  timestamp: Date
  source: string
}

export interface PythPriceData {
  symbol: string
  price: number
  confidence: number
  exponent: number
}

Step 2: Verify file exists

cat lib/blockchain/types.ts | head -10

Step 3: Commit

git add lib/blockchain/types.ts
git commit -m "feat(blockchain): create domain types file"

Task 1.6: Create Common & Middleware Types

Files:

  • Create: lib/common/types.ts
  • Create: lib/middleware/types.ts

Step 1: Create lib/common/types.ts

// lib/common/types.ts

export interface RequestContext {
  ip: string
  userAgent: string
  clientId?: string
  wallet?: string
}

export interface CacheEntry<T> {
  value: T
  timestamp: Date
  ttl: number
}

export type ConfigValue = string | number | boolean | string[]

export interface Config {
  [key: string]: ConfigValue
}

Step 2: Create lib/middleware/types.ts

// lib/middleware/types.ts

export interface RateLimitBucket {
  ip: string
  requests: number
  resetAt: Date
}

export interface IdentityContext {
  wallet: string
  isEnterprise: boolean
  isDenied: boolean
}

export interface DiscoveryEntry {
  service: string
  url: string
  cached: boolean
  lastFetch: Date
}

Step 3: Verify both files

ls -lh lib/{common,middleware}/types.ts

Step 4: Commit

git add lib/common/types.ts lib/middleware/types.ts
git commit -m "feat(common,middleware): create domain types files"

Task 1.7: Create Domain Index Files (Barrel Exports)

Files:

  • Create: lib/providers/index.ts
  • Create: lib/payment/index.ts
  • Create: lib/optimization/index.ts
  • Create: lib/observability/index.ts
  • Create: lib/blockchain/index.ts
  • Create: lib/common/index.ts
  • Create: lib/middleware/index.ts

Step 1: Create minimal index files with re-exports (we'll populate later)

cat > lib/providers/index.ts << 'EOF'
// lib/providers/index.ts
// Re-exports will be added as we move provider adapters

export * from './types'
// export { callAIProvider, streamAIProvider } from './index'  // TODO
EOF
cat > lib/payment/index.ts << 'EOF'
// lib/payment/index.ts
// Re-exports will be added as we move payment logic

export * from './types'
// export { verifyPayment, settlePayment } from './index'  // TODO
EOF
cat > lib/optimization/index.ts << 'EOF'
// lib/optimization/index.ts

export * from './types'
// export { compressContext } from './index'  // TODO
EOF
cat > lib/observability/index.ts << 'EOF'
// lib/observability/index.ts

export * from './types'
// export { recordCall, recordHealth } from './index'  // TODO
EOF
cat > lib/blockchain/index.ts << 'EOF'
// lib/blockchain/index.ts

export * from './types'
// export { getNetworkConfig, reconcileWallet } from './index'  // TODO
EOF
cat > lib/common/index.ts << 'EOF'
// lib/common/index.ts

export * from './types'
// export { formatAddress, parseConfig } from './index'  // TODO
EOF
cat > lib/middleware/index.ts << 'EOF'
// lib/middleware/index.ts

export * from './types'
// export { checkRateLimit, injectIdentity } from './index'  // TODO
EOF

Step 2: Verify all index files exist

ls -lh lib/*/index.ts

Expected:

-rw-r--r--  ... lib/blockchain/index.ts
-rw-r--r--  ... lib/common/index.ts
-rw-r--r--  ... lib/middleware/index.ts
-rw-r--r--  ... lib/observability/index.ts
-rw-r--r--  ... lib/optimization/index.ts
-rw-r--r--  ... lib/payment/index.ts
-rw-r--r--  ... lib/providers/index.ts

Step 3: Commit

git add lib/*/index.ts
git commit -m "feat(lib): create domain index files with type re-exports"

Task 1.8: Verify No Breakage Yet

Files:

  • All API routes should still work (imports unchanged)
  • Tests should pass (no moved code yet)

Step 1: Run type check

npm run type-check 2>&1 | grep -i error | head -20

Expected: Some "Cannot find module" errors for moved files (expected, we'll fix in phases 2-6).

Step 2: Run tests (should still pass)

npm run test 2>&1 | tail -20

Expected: Tests pass, no regressions (we haven't moved code yet).

Step 3: Commit progress

git add -A
git commit -m "refactor(lib): phase 1 complete - domain structure ready"

Phase 2: Split Provider Domain (ai-providers.ts)

This is the largest single file (4.8K LOC) — split into focused adapters

Task 2.1: Create Anthropic Adapter

Files:

  • Create: lib/providers/adapters/anthropic.ts
  • Reference: Extract from lib/ai-providers.ts (provider === 'anthropic')

Step 1: Identify all anthropic-related code in ai-providers.ts

grep -n "provider === 'anthropic'" lib/ai-providers.ts | head -5

Step 2: Create lib/providers/adapters/anthropic.ts

// lib/providers/adapters/anthropic.ts

import { Anthropic } from '@anthropic-ai/sdk'
import { Message, MessageParam } from '@anthropic-ai/sdk/resources'

interface CallAnthropicOptions {
  model: string
  messages: MessageParam[]
  maxTokens?: number
  temperature?: number
  tools?: any[]
  systemPrompt?: string
}

export async function callAnthropic(
  options: CallAnthropicOptions
): Promise<Message> {
  const client = new Anthropic({
    apiKey: process.env.ANTHROPIC_API_KEY,
  })

  const response = await client.messages.create({
    model: options.model,
    max_tokens: options.maxTokens || 2048,
    temperature: options.temperature,
    system: options.systemPrompt,
    messages: options.messages,
    tools: options.tools,
  })

  return response
}

export async function* streamAnthropic(
  options: CallAnthropicOptions
): AsyncGenerator<any> {
  const client = new Anthropic({
    apiKey: process.env.ANTHROPIC_API_KEY,
  })

  const stream = client.messages.stream({
    model: options.model,
    max_tokens: options.maxTokens || 2048,
    temperature: options.temperature,
    system: options.systemPrompt,
    messages: options.messages,
    tools: options.tools,
  })

  for await (const chunk of stream) {
    yield chunk
  }
}

Step 3: Verify file exists and has correct structure

head -30 lib/providers/adapters/anthropic.ts

Step 4: Commit

git add lib/providers/adapters/anthropic.ts
git commit -m "feat(providers): extract anthropic adapter from ai-providers"

Task 2.2-2.6: Create Other Provider Adapters

Repeat the pattern for OpenAI, Azure, Bedrock, Gemini adapters (similar to Task 2.1)

For brevity, here's the command to create all stub adapters:

for adapter in openai azure bedrock gemini partners; do
  cat > lib/providers/adapters/${adapter}.ts << 'EOF'
// lib/providers/adapters/${adapter}.ts
// TODO: Extract ${adapter}-specific logic from ai-providers.ts

export async function call${adapter^}(options: any) {
  throw new Error('Not yet implemented')
}

export async function* stream${adapter^}(options: any): AsyncGenerator<any> {
  throw new Error('Not yet implemented')
}
EOF
done

Then fill each file with extracted logic from current lib/ai-providers.ts.

Step 1: Create stub files

mkdir -p lib/providers/adapters
for adapter in openai azure bedrock gemini partners; do
  touch lib/providers/adapters/${adapter}.ts
done
ls -lh lib/providers/adapters/

Step 2: Commit stubs

git add lib/providers/adapters/
git commit -m "feat(providers): create adapter stubs (openai, azure, bedrock, gemini, partners)"

Task 2.3: Move Streaming Logic to lib/providers/streaming.ts

Files:

  • Create: lib/providers/streaming.ts
  • Reference: Extract from lib/ai-stream.ts

Step 1: Copy ai-stream.ts to streaming.ts

cp lib/ai-stream.ts lib/providers/streaming.ts

Step 2: Update imports in streaming.ts (fix relative paths)

sed -i "s|from '\./|from '../|g" lib/providers/streaming.ts

Step 3: Verify file exists

head -20 lib/providers/streaming.ts

Step 4: Commit

git add lib/providers/streaming.ts
git commit -m "refactor(providers): move ai-stream to providers/streaming.ts"

Task 2.4: Move Models to lib/providers/models.ts

Files:

  • Create: lib/providers/models.ts
  • Source: Copy from lib/models.ts

Step 1: Copy models.ts

cp lib/models.ts lib/providers/models.ts

Step 2: Update imports in providers/models.ts

sed -i "s|from '\./|from '../|g" lib/providers/models.ts
sed -i "s|from '\./types|from './types|g" lib/providers/models.ts

Step 3: Verify

head -30 lib/providers/models.ts

Step 4: Commit

git add lib/providers/models.ts
git commit -m "refactor(providers): move models to providers/models.ts"

Task 2.5: Create lib/providers/index.ts Dispatcher

Files:

  • Create: lib/providers/index.ts (main dispatcher)

Step 1: Create dispatcher that routes to adapters

// lib/providers/index.ts

export * from './types'
export * from './models'
export * from './streaming'

import { callAnthropic } from './adapters/anthropic'
// import { callOpenAI } from './adapters/openai'  // TODO
// ... (other adapters)

export async function callAIProvider(model: string, messages: any[], options?: any) {
  const provider = getProviderForModel(model)
  
  switch (provider) {
    case 'anthropic':
      return callAnthropic({ model, messages, ...options })
    // case 'openai':
    //   return callOpenAI({ model, messages, ...options })
    // ... (other providers)
    default:
      throw new Error(`Unknown provider: ${provider}`)
  }
}

export async function* streamAIProvider(
  model: string,
  messages: any[],
  options?: any
): AsyncGenerator<any> {
  const provider = getProviderForModel(model)
  
  switch (provider) {
    case 'anthropic':
      yield* streamAnthropic({ model, messages, ...options })
      break
    // case 'openai':
    //   yield* streamOpenAI({ model, messages, ...options })
    //   break
    // ... (other providers)
    default:
      throw new Error(`Unknown provider: ${provider}`)
  }
}

function getProviderForModel(model: string): string {
  // TODO: Extract from current ai-providers.ts MODEL_MAP
  if (model.startsWith('claude')) return 'anthropic'
  if (model.startsWith('gpt')) return 'openai'
  // ... (etc)
  return 'unknown'
}

Step 2: Verify file

head -50 lib/providers/index.ts

Step 3: Commit

git add lib/providers/index.ts
git commit -m "feat(providers): create main dispatcher in index.ts"

Task 2.6: Update Routes to Use New Provider Structure

Files:

  • Modify: src/app/api/v1/chat/completions/route.ts
  • Modify: src/app/api/v1/images/generations/route.ts
  • Modify: src/app/api/v1/videos/generations/route.ts
  • (any other routes importing from ai-providers)

Step 1: Find all routes using ai-providers

grep -r "from '@/lib/ai-providers" src/app/api --include="*.ts"

Step 2: Update first route (chat/completions)

Replace:

import { callAIProvider, streamAIProvider } from '@/lib/ai-providers'

With:

import { callAIProvider, streamAIProvider } from '@/lib/providers'

Step 3: Update all routes with same import

find src/app/api -name "route.ts" -type f -exec sed -i "s|from '@/lib/ai-providers|from '@/lib/providers|g" {} \;

Step 4: Run tests

npm run test -- src/app/api/v1/chat/completions/route.test.ts 2>&1 | tail -30

Expected: Tests should pass with new import structure.

Step 5: Commit

git add src/app/api
git commit -m "refactor: update routes to import from lib/providers"

Task 2.7: Verify Phase 2 Complete

Step 1: Type check

npm run type-check 2>&1 | grep -c error

Expected: Should have fewer errors than before (provider imports work).

Step 2: Run affected tests

npm run test -- route.test.ts 2>&1 | tail -20

Expected: All tests pass.

Step 3: Live-test chat endpoint

# Start dev server in background
npm run dev &
sleep 3

# Test chat endpoint
curl -X POST http://localhost:3000/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"hi"}]}'

# Kill dev server
kill %1

Expected: Returns valid response (may fail auth, but endpoint works).

Step 4: Commit

git add -A
git commit -m "refactor(lib): phase 2 complete - provider domain organized"

Phase 3: Consolidate Payment Domain

Follow similar pattern to Phase 2 (extract functions into domain)

Task 3.1-3.5: Move Payment Files

Summary:

  1. Extract x402 verification → lib/payment/verification.ts
  2. Extract settlement logic → lib/payment/settlement.ts
  3. Move treasury → lib/payment/treasury.ts
  4. Consolidate allowlists → lib/payment/allowlists.ts
  5. Create dispatcher → lib/payment/index.ts

Process (same as Phase 2):

  • Copy files to payment/
  • Update imports
  • Create domain/index.ts dispatcher
  • Update all routes to use new imports
  • Test
  • Commit

Phase 4-6: Organize Remaining Domains

Follow same pattern as Phases 2-3 for:

  • Phase 4: Observability (logging, health, analytics)
  • Phase 5: Blockchain (networks, RPC, wallets, data)
  • Phase 6: Optimization, Common, Middleware

Each phase: extract functions → create domain files → dispatcher index → update imports → test → commit


Phase 7-9: Bulk Import Updates & Cleanup

Task 7.1: Generate Import Update Script

# Find all files importing from old lib files
grep -r "from '@/lib/" src --include="*.ts" --include="*.tsx" | \
  grep -v "from '@/lib/providers" | \
  grep -v "from '@/lib/payment" | \
  cut -d: -f1 | sort -u > /tmp/files-to-update.txt

wc -l /tmp/files-to-update.txt  # Should be ~71 routes + 52 components = ~120 files

Task 7.2: Batch Update Imports

# Replace old import paths with new ones
sed -i "s|from '@/lib/ai-providers|from '@/lib/providers|g" $(cat /tmp/files-to-update.txt)
sed -i "s|from '@/lib/x402|from '@/lib/payment|g" $(cat /tmp/files-to-update.txt)
sed -i "s|from '@/lib/gcs-logger|from '@/lib/observability/logging|g" $(cat /tmp/files-to-update.txt)
# ... (repeat for all moved files)

Task 7.3: Delete Old Files

# Verify all files have been moved before deleting
diff <(ls lib/*.ts | sort) <(find lib -maxdepth 1 -name "*.ts" | sort)

# Delete old flat structure
rm lib/ai-providers.ts lib/x402.ts lib/gcs-logger.ts lib/ai-stream.ts lib/models.ts
# ... (etc for all moved files)

Phase 10: Code Review & Documentation

Task 10.1: Create ARCHITECTURE.md

# BlockRun lib Architecture

## Structure

lib/ is organized into 7 domain-based modules:

### 1. providers/
LLM provider routing and adapters.
- `index.ts` - Main dispatcher (callAIProvider, streamAIProvider)
- `adapters/` - Provider-specific implementations
- `models.ts` - Model catalog and pricing
- `streaming.ts` - Streaming response handling

### 2. payment/
x402 payment protocol and settlement.
- `index.ts` - Main entry point
- `verification.ts` - Payment verification
- `settlement.ts` - On-chain settlement
- `allowlists.ts` - Enterprise/denylist management
- `treasury.ts` - Treasury wallet management

### 3. observability/
Logging, analytics, and health monitoring.
- `logging.ts` - GCS logging
- `analytics.ts` - BigQuery analytics
- `health.ts` - Health aggregation and circuit breakers
- `metrics.ts` - In-memory metrics

### 4. blockchain/
Blockchain RPC, wallets, and on-chain data.
- `networks.ts` - Network configuration
- `rpc.ts` - Multi-chain RPC routing
- `wallets.ts` - Wallet reconciliation
- `data.ts` - Price feeds, DeFi data

### 5. optimization/
Context compression and cost optimization.
- `index.ts` - Compression orchestrator
- `layers.ts` - 7-layer compression pipeline
- `codebook.ts` - Encoding dictionaries

### 6. common/
Cross-cutting utilities and helpers.
- `utils.ts` - General utilities
- `config.ts` - Runtime configuration
- `storage.ts` - Storage helpers

### 7. middleware/
Request processing and middleware.
- `rate-limit.ts` - Rate limiting
- `identity.ts` - Request identity enrichment
- `discovery.ts` - Service discovery

## Import Example

```typescript
// Before refactor
import { callAIProvider } from '@/lib/ai-providers'
import { verifyPayment } from '@/lib/x402'
import { recordCall } from '@/lib/gcs-logger'

// After refactor
import { callAIProvider } from '@/lib/providers'
import { verifyPayment } from '@/lib/payment'
import { recordCall } from '@/lib/observability/logging'

Benefits

  • Clear separation of concerns - Each domain has a single responsibility
  • Easier navigation - Related files grouped together
  • Better type organization - Types.ts file per domain
  • Reduced cognitive load - Fewer files to understand per task
  • Scalability - Easy to add new sub-domains as needed

---

## Testing Strategy

**After Each Phase:**

1. **Type Check**
   ```bash
   npm run type-check
  1. Unit Tests

    npm run test -- "phase-X" 2>&1 | tail -30
    
  2. Live Test (after imports updated)

    npm run dev &
    sleep 3
    
    # Test key endpoints
    curl http://localhost:3000/api/v1/chat/completions
    curl http://localhost:3000/api/v1/images/generations
    curl http://localhost:3000/api/health
    
    kill %1
    
  3. Code Review

    /code-review medium
    

Success Criteria

✅ After complete refactor:

  1. All 126 lib files organized into 7 domain subdirectories
  2. ai-providers.ts (4.8K LOC) split into <1000 LOC per adapter
  3. gcs-logger.ts (823 LOC) split into logging.ts + metrics.ts
  4. All types consolidated into domain/types.ts files
  5. No cyclic imports
  6. All 71 routes pass tests
  7. All 52 components render without errors
  8. Zero runtime regressions
  9. ARCHITECTURE.md documenting new structure
  10. Code review approval (no maintainability issues)

Rollback Plan

If issues arise at any phase:

  1. Use git revert to undo commits from that phase
  2. Keep old lib/ structure in a backup branch
  3. Tests will catch most issues immediately

Estimated Timeline

  • Phase 1 (Setup & Types): 1-2 days
  • Phase 2 (Provider split): 2-3 days
  • Phase 3 (Payment): 1-2 days
  • Phase 4 (Observability): 1-2 days
  • Phase 5 (Blockchain): 1 day
  • Phase 6 (Remaining): 1 day
  • Phase 7 (Import updates): 1 day
  • Phase 8 (Component imports): 1 day
  • Phase 9 (Cleanup): 1 day
  • Phase 10 (Docs & review): 1 day

Total: 12-18 days (can be accelerated with parallel execution)