# Supabase Edge Function

Ключ AstroWay не можна класти у фронтенд: усе, що потрапило в бандл, бачить кожен відвідувач. Edge Function розв'язує це одним файлом: браузер викликає функцію, функція викликає API з ключем із секретів проєкту і повертає лише потрібне. Той самий файл працює в [Lovable](/integrations/lovable/) і в [Bolt](/integrations/bolt/), бо обидва ставлять бекенд на Supabase.

## 1. Функція

```bash frame="terminal"
supabase functions new big-three
```

Замініть `supabase/functions/big-three/index.ts` на:

```ts title="supabase/functions/big-three/index.ts"
const SIGNS = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo',
  'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces'];

const cors = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
};

const signOf = (longitude: number) => SIGNS[Math.floor(longitude / 30)];

Deno.serve(async (req) => {
  if (req.method === 'OPTIONS') return new Response('ok', { headers: cors });

  const { date, time, timezone, latitude, longitude } = await req.json();
  const res = await fetch('https://api.astroway.info/v1/chart', {
    method: 'POST',
    headers: {
      'X-Api-Key': Deno.env.get('ASTROWAY_API_KEY') ?? '',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ date, time, timezone, latitude, longitude }),
  });
  const json = await res.json();
  if (!json.ok) return Response.json({ error: json.error }, { status: res.status, headers: cors });

  const planet = (name: string) => json.data.planets.find((p: { name: string }) => p.name === name);
  return Response.json({
    sun: signOf(planet('Sun').longitude),
    moon: signOf(planet('Moon').longitude),
    rising: signOf(json.data.houses.ascendant),
    offset_used: json.data.input.timezoneOffset,
  }, { headers: cors });
});
```

## 2. Ключ у секретах

Створіть ключ **Тільки сервер** з областю `chart` і бюджетом, як описано в розділі [Ключ для автоматизації](/integrations/), і покладіть його в секрети проєкту, а не в `.env` фронтенду:

```bash frame="terminal"
supabase secrets set ASTROWAY_API_KEY=aw_live_...
supabase functions deploy big-three
```

Секрет доступний функції як `Deno.env.get('ASTROWAY_API_KEY')` і не потрапляє ні в код, ні в браузер. Той самий секрет можна задати в дашборді Supabase: **Edge Functions → Secrets**.

## 3. Виклик зі сторінки

```js
const { data, error } = await supabase.functions.invoke('big-three', {
  body: { date: '1990-05-15', time: '14:30:00', timezone: 'Europe/Kyiv', latitude: 50.45, longitude: 30.52 },
});
// data: { sun: 'Taurus', moon: 'Capricorn', rising: 'Virgo', offset_used: 4 }
```

`supabase-js` сам додає ключ `anon` проєкту, тож функція з перевіркою JWT за замовчуванням приймає виклик без додаткових налаштувань. Помилку API функція передає далі з тим самим статусом і тілом `error`, тож `error.message` можна показати користувачеві як є.

## Що варто знати

- **`timezone` назвою зони.** `Europe/Kyiv`, а не зсув: сервер сам знає, що Київ 1990-05-15 жив за UTC+4. Порожній рядок відхиляється з `400 INVALID_FIELD`, а відсутнє поле означає UTC. Деталі в розділі [Інтеграції без коду](/integrations/).
- **Вартість.** `POST /v1/chart` коштує 20 кредитів. Те саме тіло протягом п'яти хвилин повертається з кешу без списання.
- **Бюджет ключа.** Функцію може викликати будь-хто, хто відкрив ваш сайт. Бюджет на ключі зупинить зациклений чи зловмисний клієнт на числі, яке ви задали, з `429 KEY_BUDGET_EXHAUSTED`.

**Note:**
Перевірено 2026-11-07: функцію запущено локально в Deno 2 (`deno run --allow-net --allow-env`) і викликано тим самим тілом проти продакшену AstroWay. Відповідь: `Taurus`, `Capricorn`, `Virgo`, зсув `4`; порожній `timezone` дав `400`, відсутній ключ `401 MISSING_API_KEY`, `OPTIONS` повернув заголовки CORS. Деплой у справжній проєкт Supabase у перевірку не входив.
