Shumiland/src/app/api/tariffs/sync/route.ts
Vadym Samoilenko 9b41fa447a
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
feat: complete backend B1-B7 — Payload CMS, ezy payments, leads, deploy
- B1: Next.js 15 + Payload CMS 3.0 + Postgres 16, ESLint, Prettier, Husky, Vitest
- B2: 9 collections, 6 globals, 12 Page Builder blocks, access control, slugify/revalidate hooks
- B3: ezy.com.ua payments, Binotel HMAC webhook, leads API, Telegram bot, Resend email, rate limiting
- B4: Tariffs collection with ezy API sync (cron + manual), dynamic pricing source-of-truth
- B5: 13 test files covering unit libs and all API routes
- B6: Dockerfile multi-stage, docker-compose.prod.yml, nginx.conf SSL, GitHub Actions CI/CD, health endpoint
- B7: docs/admin-guide-ua.md (marketer guide), docs/deploy.md (VPS instructions), README quickstart

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 19:14:54 +01:00

28 lines
942 B
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { timingSafeEqual } from 'crypto'
import { syncTariffs } from '@/lib/syncTariffs'
import { logger } from '@/lib/logger'
const SECRET = process.env['SYNC_SECRET'] ?? ''
function safeCompare(a: string, b: string): boolean {
const aBuf = Buffer.from(a)
const bBuf = Buffer.from(b)
if (aBuf.length !== bBuf.length) return false
return timingSafeEqual(aBuf, bBuf)
}
export async function POST(req: NextRequest): Promise<NextResponse> {
const auth = req.headers.get('authorization') ?? ''
if (!SECRET || !safeCompare(auth, `Bearer ${SECRET}`)) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
try {
const result = await syncTariffs()
return NextResponse.json({ ok: true, ...result })
} catch (err) {
logger.error({ err }, 'Tariffs sync failed')
return NextResponse.json({ error: 'Sync failed' }, { status: 500 })
}
}