Files
telegram-bot-workers/ROUTE_ARCHITECTURE.md
kaffa 8fe866c545
Some checks failed
TypeScript CI / build (push) Has been cancelled
chore: anvil.it.com → inouter.com
2026-03-27 16:15:42 +00:00

9.9 KiB

Route Architecture

Before Refactoring

┌─────────────────────────────────────────────────────────────┐
│                       index.ts (921 lines)                  │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │ fetch() Handler                                        │ │
│  │  • /setup-webhook                                     │ │
│  │  • /webhook-info                                      │ │
│  │  • /health                                            │ │
│  │  • /api/deposit/balance                               │ │
│  │  • /api/deposit/deduct                                │ │
│  │  • /api/test                                          │ │
│  │  • /api/contact                                       │ │
│  │  • /webhook (+ handleMessage + handleCallbackQuery)  │ │
│  └───────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │ email() Handler                                        │ │
│  │  • SMS parsing                                        │ │
│  │  • Auto-matching                                      │ │
│  │  • Notifications                                      │ │
│  └───────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │ scheduled() Handler                                    │ │
│  │  • 24h expiration cleanup                             │ │
│  └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

After Refactoring

┌─────────────────────────────────────────────────────────────┐
│                    index.ts (205 lines)                     │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │ fetch() Handler (Router)                               │ │
│  │  • /setup-webhook  ──────────┐                        │ │
│  │  • /webhook-info  ───────────┤                        │ │
│  │  • /health ──────────────────┼──→ routes/health.ts    │ │
│  │  • /api/* ───────────────────┼──→ routes/api.ts       │ │
│  │  • /webhook ─────────────────┴──→ routes/webhook.ts   │ │
│  └───────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │ email() Handler (unchanged)                            │ │
│  └───────────────────────────────────────────────────────┘ │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │ scheduled() Handler (unchanged)                        │ │
│  └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
    ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
    │ health.ts    │  │ api.ts       │  │ webhook.ts   │
    │ (14 lines)   │  │ (318 lines)  │  │ (287 lines)  │
    ├──────────────┤  ├──────────────┤  ├──────────────┤
    │ • status     │  │ • balance    │  │ • message    │
    │ • timestamp  │  │ • deduct     │  │ • callback   │
    │              │  │ • test       │  │ • rate limit │
    │              │  │ • contact    │  │ • commands   │
    └──────────────┘  └──────────────┘  └──────────────┘

Request Flow Examples

1. Telegram Message

User sends message
    ↓
Telegram API → /webhook
    ↓
index.ts:fetch() → routes/webhook.ts:handleWebhook()
    ↓
validateWebhookRequest() (security check)
    ↓
handleMessage()
    ├─ checkRateLimit() (KV-based)
    ├─ getOrCreateUser() (DB)
    ├─ handleCommand() OR generateAIResponse()
    └─ sendMessage() (Telegram API)

2. Deposit Balance Inquiry

namecheap-api → /api/deposit/balance?telegram_id=123
    ↓
index.ts:fetch() → routes/api.ts:handleApiRequest()
    ↓
X-API-Key authentication
    ↓
DB query (users + user_deposits)
    ↓
JSON response { telegram_id, balance }

3. Contact Form Submission

Web form → /api/contact (POST)
    ↓
index.ts:fetch() → routes/api.ts:handleApiRequest()
    ↓
CORS check (hosting.inouter.com)
    ↓
Validation (email format, message length)
    ↓
sendMessage() to admin (Telegram notification)

4. Health Check

Monitoring → /health (GET)
    ↓
index.ts:fetch() → routes/health.ts:handleHealthCheck()
    ↓
JSON response { status: 'ok', timestamp }

Module Dependencies

routes/webhook.ts
├── types.ts (Env, TelegramUpdate)
├── security.ts (validateWebhookRequest, checkRateLimit)
├── telegram.ts (sendMessage, sendMessageWithKeyboard, etc)
├── domain-register.ts (executeDomainRegister)
├── summary-service.ts (addToBuffer, processAndSummarize, generateAIResponse)
└── commands.ts (handleCommand)

routes/api.ts
├── types.ts (Env)
├── telegram.ts (sendMessage)
├── summary-service.ts (addToBuffer, processAndSummarize, generateAIResponse)
└── commands.ts (handleCommand)

routes/health.ts
└── (none - standalone)

index.ts
├── types.ts (Env, EmailMessage)
├── telegram.ts (sendMessage, setWebhook, getWebhookInfo)
├── services/bank-sms-parser.ts (parseBankSMS)
├── services/deposit-matcher.ts (matchPendingDeposit)
├── routes/webhook.ts (handleWebhook)
├── routes/api.ts (handleApiRequest)
└── routes/health.ts (handleHealthCheck)

Code Organization Benefits

1. Separation of Concerns

  • webhook.ts: Telegram-specific logic
  • api.ts: REST API endpoints
  • health.ts: Monitoring
  • index.ts: Routing + email + cron

2. Testability

Each route can be tested independently:

import { handleHealthCheck } from './routes/health';
const response = await handleHealthCheck();
expect(response.status).toBe(200);

3. Maintainability

  • Smaller files (14-318 lines vs 921 lines)
  • Clear responsibilities
  • Easier to locate bugs
  • Safe to modify without affecting other routes

4. Reusability

Route handlers can be:

  • Imported by other modules
  • Wrapped with middleware
  • Tested in isolation
  • Deployed independently (future: multiple workers)

Future Enhancements

Potential Middleware Layer

// src/middleware/auth.ts
export function withAuth(handler: RouteHandler) {
  return async (req, env, url) => {
    if (!validateAuth(req)) {
      return Response.json({ error: 'Unauthorized' }, { status: 401 });
    }
    return handler(req, env, url);
  };
}

// Usage in routes/api.ts
export const handleApiRequest = withAuth(async (req, env, url) => {
  // ... existing logic
});

Route Registration Pattern

// src/router.ts
const routes = {
  '/health': handleHealthCheck,
  '/api/*': handleApiRequest,
  '/webhook': handleWebhook,
};

// index.ts
const handler = routes[pathname] || notFound;
return handler(request, env, url);