# eSesja Analytics API v2.0 - Dokumentacja Endpointów

## 📚 Spis treści
1. [Informacje ogólne](#informacje-ogólne)
2. [Autentykacja i zabezpieczenia](#autentykacja-i-zabezpieczenia)
3. [Endpointy Radnych](#endpointy-radnych)
4. [Endpointy Głosowań](#endpointy-głosowań)
5. [Endpointy Statystyk](#endpointy-statystyk)
6. [Endpointy Posiedzeń](#endpointy-posiedzeń)
7. [Endpointy Pomocnicze](#endpointy-pomocnicze)
8. [Kody błędów](#kody-błędów)

---

## Informacje ogólne

### Base URL
```
https://api.twoja-domena.pl
```

### Format odpowiedzi
Wszystkie odpowiedzi są w formacie JSON:

**Sukces:**
```json
{
  "success": true,
  "data": { ... },
  "pagination": { ... }  // opcjonalnie
}
```

**Błąd:**
```json
{
  "success": false,
  "error": "Error Name",
  "message": "Opis błędu"
}
```

### Rate Limiting
- **Limit:** 100 requestów na 15 minut
- **Nagłówki odpowiedzi:**
  - `X-RateLimit-Limit`: Maksymalna liczba requestów
  - `X-RateLimit-Remaining`: Pozostałe requesty
  - `X-RateLimit-Reset`: Czas resetu limitu (timestamp)

---

## Autentykacja i zabezpieczenia

### CORS
API akceptuje requesty tylko z domen zdefiniowanych w konfiguracji.

**Wymagane nagłówki:**
```http
Origin: https://twoja-domena.pl
Referer: https://twoja-domena.pl/...
```

### API Key (opcjonalny)
Jeśli skonfigurowano `API_SECRET_KEY`, dodaj nagłówek:
```http
X-API-Key: your_secret_key_here
```

---

## Endpointy Radnych

### 1. Lista wszystkich radnych
```http
GET /api/radni
```

**Parametry query:**
- `kadencja` (string, optional) - Filtruj po kadencji
- `ugrupowanie` (int, optional) - Filtruj po ID ugrupowania
- `aktywny` (boolean, optional) - true/false

**Przykład:**
```bash
curl https://api.twoja-domena.pl/api/radni?kadencja=2024-2029
```

**Odpowiedź:**
```json
{
  "success": true,
  "count": 25,
  "data": [
    {
      "id_osoby": 1,
      "imie_nazwisko": "Jan Kowalski",
      "kadencja": "2024-2029",
      "przynaleznosc_id": 2,
      "ugrupowanie": "Koalicja Obywatelska",
      "aktywny": 1,
      "token": "abc123"
    }
  ]
}
```

---

### 2. Profil radnego
```http
GET /api/radni/:id
```

**Przykład:**
```bash
curl https://api.twoja-domena.pl/api/radni/1
```

**Odpowiedź:**
```json
{
  "success": true,
  "data": {
    "id_osoby": 1,
    "imie_nazwisko": "Jan Kowalski",
    "kadencja": "2024-2029",
    "ugrupowanie": "Koalicja Obywatelska",
    "liczba_glosow": 542,
    "liczba_posiedzen": 89
  }
}
```

---

### 3. Głosowania radnego
```http
GET /api/radni/:id/glosowania
```

**Parametry:**
- `page` (int, default: 1)
- `limit` (int, default: 20)
- `kadencja` (string, optional)
- `organ` (int, optional)

**Przykład:**
```bash
curl "https://api.twoja-domena.pl/api/radni/1/glosowania?page=1&limit=10"
```

---

### 4. Profil głosowania radnego (statystyki)
```http
GET /api/radni/:id/profil-glosowania
```

**Odpowiedź:**
```json
{
  "success": true,
  "data": {
    "za": 420,
    "przeciw": 45,
    "wstrzymujacy": 12,
    "nieobecny": 50,
    "brak_glosu": 15,
    "za_procent": 77.49,
    "przeciw_procent": 8.30
  }
}
```

---

### 5. Frekwencja radnego
```http
GET /api/radni/:id/frekwencja
```

**Odpowiedź:**
```json
{
  "success": true,
  "data": {
    "liczba_posiedzen": 89,
    "obecnosci": 85,
    "nieobecnosci": 4,
    "frekwencja_procent": 95.51
  }
}
```

---

### 6. Frekwencja w czasie (miesięcznie)
```http
GET /api/radni/:id/frekwencja-czas
```

**Odpowiedź:**
```json
{
  "success": true,
  "data": [
    {
      "miesiac": "2024-01",
      "liczba_posiedzen": 4,
      "obecnosci": 4,
      "frekwencja_procent": 100.00
    },
    {
      "miesiac": "2024-02",
      "liczba_posiedzen": 5,
      "obecnosci": 4,
      "frekwencja_procent": 80.00
    }
  ]
}
```

---

### 7. Zgodność z ugrupowaniem
```http
GET /api/radni/:id/zgodnosc-grupa
```

**Odpowiedź:**
```json
{
  "success": true,
  "data": {
    "wszystkie_glosowania": 450,
    "zgodne": 385,
    "zgodnosc_procent": 85.56
  }
}
```

---

### 8. Koalicje głosujące (z kim głosuje zgodnie)
```http
GET /api/radni/:id/koalicje
```

**Parametry:**
- `limit` (int, default: 10)
- `kadencja` (string, optional)

**Odpowiedź:**
```json
{
  "success": true,
  "data": [
    {
      "id_osoby": 5,
      "imie_nazwisko": "Anna Nowak",
      "ugrupowanie": "Koalicja Obywatelska",
      "wspolne_glosowania": 420,
      "zgodne": 395,
      "zgodnosc_procent": 94.05
    }
  ]
}
```

---

### 9. Oponenci (z kim nie głosuje)
```http
GET /api/radni/:id/oponenci
```

---

### 10. Głosowania samotne
```http
GET /api/radni/:id/glosowania-samotne
```

Zwraca głosowania gdzie radny był jedynym "za", "przeciw" lub "wstrzymującym się".

---

### 11. Głosowania kluczowe
```http
GET /api/radni/:id/glosowania-kluczowe
```

Zwraca głosowania gdzie głos radnego był decydujący (różnica 1 głos).

---

### 12. Głosowania buntownicze
```http
GET /api/radni/:id/glosowania-buntownicze
```

Zwraca głosowania gdzie radny głosował inaczej niż jego ugrupowanie.

---

## Endpointy Głosowań

### 1. Lista głosowań
```http
GET /api/glosowania
```

**Parametry:**
- `page` (int, default: 1)
- `limit` (int, default: 20, max: 100)
- `kadencja` (string, optional)
- `organ` (int, optional)
- `data_od` (date, optional) - Format: YYYY-MM-DD
- `data_do` (date, optional) - Format: YYYY-MM-DD
- `wynik` (string, optional) - "przyjęto" lub "odrzucono"
- `kontrowersyjnosc_min` (int, optional) - 0-100
- `search` (string, optional) - Wyszukiwanie w tytule

**Przykład:**
```bash
curl "https://api.twoja-domena.pl/api/glosowania?kadencja=2024-2029&kontrowersyjnosc_min=30"
```

---

### 2. Szczegóły głosowania
```http
GET /api/glosowania/:id
```

---

### 3. Rozkład głosów
```http
GET /api/glosowania/:id/glosy
```

**Parametry:**
- `ugrupowanie` (boolean, optional) - true = grupuj po ugrupowaniach

**Przykład:**
```bash
curl "https://api.twoja-domena.pl/api/glosowania/123/glosy?ugrupowanie=true"
```

**Odpowiedź (grupowane):**
```json
{
  "success": true,
  "grouped": true,
  "data": {
    "Koalicja Obywatelska": [
      {
        "glos": "za",
        "id_osoby": 1,
        "imie_nazwisko": "Jan Kowalski"
      }
    ],
    "PiS": [...]
  }
}
```

---

### 4. Załączniki do głosowania
```http
GET /api/glosowania/:id/zalaczniki
```

---

### 5. Utwórz link do udostępnienia
```http
POST /api/glosowania/:id/udostepnij
```

**Body (JSON):**
```json
{
  "id_osoby": 5  // opcjonalnie - ID radnego do podświetlenia
}
```

**Odpowiedź:**
```json
{
  "success": true,
  "data": {
    "link": "a1b2c3d4e5f6g7h8",
    "url": "/share/a1b2c3d4e5f6g7h8"
  }
}
```

---

### 6. Pobierz udostępnione głosowanie
```http
GET /api/glosowania/share/:link
```

**Uwaga:** Ten endpoint nie wymaga zabezpieczeń CORS - działa publicznie.

---

## Endpointy Statystyk

### 1. Dashboard
```http
GET /api/statystyki/dashboard
```

**Odpowiedź:**
```json
{
  "success": true,
  "data": {
    "liczba_posiedzen": 89,
    "liczba_glosow": 542,
    "liczba_radnych": 25,
    "srednia_frekwencja": "92.50"
  }
}
```

---

### 2. Ranking frekwencji
```http
GET /api/statystyki/ranking-frekwencji
```

**Parametry:**
- `kadencja` (string, optional)
- `limit` (int, default: 20)

---

### 3. Ranking buntowników
```http
GET /api/statystyki/ranking-buntownikow
```

Radni najczęściej głosujący w mniejszości.

---

### 4. Ranking lojalistów
```http
GET /api/statystyki/ranking-lojalistow
```

Radni najczęściej głosujący w większości.

---

### 5. Najbardziej kontrowersyjne głosowania
```http
GET /api/statystyki/najbardziej-kontrowersyjne
```

---

### 6. Najbardziej jednomyślne głosowania
```http
GET /api/statystyki/najbardziej-jednomyslne
```

---

### 7. Aktywność organów
```http
GET /api/statystyki/aktywnosc-organow
```

**Odpowiedź:**
```json
{
  "success": true,
  "data": [
    {
      "id_organu": 1,
      "nazwa": "Rada Miasta",
      "typ": "Rada",
      "liczba_posiedzen": 45,
      "liczba_glosow": 380,
      "srednia_glosow_na_posiedzenie": 8.44
    }
  ]
}
```

---

### 8. Frekwencja w czasie
```http
GET /api/statystyki/frekwencja-czas
```

---

### 9. Top koalicje
```http
GET /api/statystyki/top-koalicje
```

Pary radnych najczęściej głosujących zgodnie.

---

## Endpointy Posiedzeń

### 1. Lista posiedzeń
```http
GET /api/posiedzenia
```

**Parametry:**
- `page`, `limit`, `kadencja`, `organ`, `data_od`, `data_do`

---

### 2. Szczegóły posiedzenia
```http
GET /api/posiedzenia/:id
```

---

### 3. Punkty porządku posiedzenia
```http
GET /api/posiedzenia/:id/punkty
```

---

### 4. Obecności na posiedzeniu
```http
GET /api/posiedzenia/:id/obecnosci
```

---

## Endpointy Pomocnicze

### 1. Lista ugrupowań
```http
GET /api/utils/ugrupowania
```

---

### 2. Lista organów
```http
GET /api/utils/organy
```

---

### 3. Lista kadencji
```http
GET /api/utils/kadencje
```

---

### 4. Statystyki systemu
```http
GET /api/utils/stats
```

**Odpowiedź:**
```json
{
  "success": true,
  "data": {
    "radni": 25,
    "glosowania": 542,
    "posiedzenia": 89,
    "zalaczniki": 1250
  }
}
```

---

## Kody błędów

| Kod | Nazwa | Opis |
|-----|-------|------|
| 200 | OK | Sukces |
| 400 | Bad Request | Nieprawidłowe parametry |
| 401 | Unauthorized | Brak lub nieprawidłowy API Key |
| 403 | Forbidden | Nieautoryzowane źródło requestu (CORS) |
| 404 | Not Found | Zasób nie istnieje |
| 429 | Too Many Requests | Przekroczono rate limit |
| 500 | Internal Server Error | Błąd serwera |

---

## Przykłady użycia

### JavaScript (Fetch API)
```javascript
const response = await fetch('https://api.twoja-domena.pl/api/radni/1', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json'
  }
});

const data = await response.json();
console.log(data);
```

### Axios
```javascript
import axios from 'axios';

const { data } = await axios.get('https://api.twoja-domena.pl/api/radni/1');
console.log(data);
```

### Python
```python
import requests

response = requests.get('https://api.twoja-domena.pl/api/radni/1')
data = response.json()
print(data)
```

---

**Wersja:** 2.0.0  
**Data:** 2025-12-25
