Back to skills
SkillHub ClubShip Full StackFull StackBackend

ksef-accountant-pl

Asystent ksiegowy Krajowego Systemu e-Faktur (KSeF) w jezyku polskim. Uzyj przy pracy z KSeF 2.0 API, fakturami FA(3), zgodnoscia z polskim VAT, przetwarzaniem e-faktur, dopasowywaniem platnosci, rejestrami VAT (JPK_V7), fakturami korygujacymi, mechanizmem podzielonej platnosci (MPP) lub polskimi przeplywami ksiegowymi. Dostarcza wiedze domenowa do wystawiania faktur, przetwarzania zakupow, klasyfikacji kosztow, wykrywania fraudu i prognozowania cash flow w ekosystemie KSeF.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,028
Hot score
99
Updated
March 20, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
C60.3

Install command

npx @skill-hub/cli install openclaw-skills-ksef-accountant-pl

Repository

openclaw/skills

Skill path: skills/alexwoo-awso/ksef-accountant-pl

Asystent ksiegowy Krajowego Systemu e-Faktur (KSeF) w jezyku polskim. Uzyj przy pracy z KSeF 2.0 API, fakturami FA(3), zgodnoscia z polskim VAT, przetwarzaniem e-faktur, dopasowywaniem platnosci, rejestrami VAT (JPK_V7), fakturami korygujacymi, mechanizmem podzielonej platnosci (MPP) lub polskimi przeplywami ksiegowymi. Dostarcza wiedze domenowa do wystawiania faktur, przetwarzania zakupow, klasyfikacji kosztow, wykrywania fraudu i prognozowania cash flow w ekosystemie KSeF.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack, Backend.

Target audience: everyone.

License: MIT.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install ksef-accountant-pl into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding ksef-accountant-pl to shared team environments
  • Use ksef-accountant-pl for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: ksef-accountant-pl
description: "Asystent ksiegowy Krajowego Systemu e-Faktur (KSeF) w jezyku polskim. Uzyj przy pracy z KSeF 2.0 API, fakturami FA(3), zgodnoscia z polskim VAT, przetwarzaniem e-faktur, dopasowywaniem platnosci, rejestrami VAT (JPK_V7), fakturami korygujacymi, mechanizmem podzielonej platnosci (MPP) lub polskimi przeplywami ksiegowymi. Dostarcza wiedze domenowa do wystawiania faktur, przetwarzania zakupow, klasyfikacji kosztow, wykrywania fraudu i prognozowania cash flow w ekosystemie KSeF."
license: MIT
homepage: https://github.com/alexwoo-awso/skills
source: https://github.com/alexwoo-awso/skills/tree/main/ksef-accountant-pl
disableModelInvocation: true
disable-model-invocation: true
allowModelInvocation: false
instruction_only: true
has_executable_code: false
credential_scope: "optional-user-provided"
env:
  KSEF_TOKEN:
    description: "Token API KSeF do uwierzytelniania sesji. Dostarczany przez uzytkownika — skill nie generuje, nie przechowuje ani nie przesyla tokenow. Konfiguruj TYLKO po zweryfikowaniu, ze platforma wymusza flage disableModelInvocation (patrz sekcja Model bezpieczenstwa i skill.json)."
    required: false
    secret: true
  KSEF_ENCRYPTION_KEY:
    description: "Klucz szyfrowania Fernet do bezpiecznego przechowywania tokenow. Uzycie opcjonalne — przyklad wzorca bezpieczenstwa opisanego w dokumentacji referencyjnej. Konfiguruj TYLKO po zweryfikowaniu, ze platforma wymusza flage disableModelInvocation."
    required: false
    secret: true
  KSEF_BASE_URL:
    description: "Bazowy URL API KSeF. Domyslnie https://ksef-demo.mf.gov.pl (DEMO). Produkcja: https://ksef.mf.gov.pl — wymaga jawnej zgody uzytkownika. Uzywaj produkcji TYLKO po pelnej weryfikacji bezpieczenstwa platformy."
    required: false
    default: "https://ksef-demo.mf.gov.pl"
---

# Agent Ksiegowy KSeF

Specjalistyczna wiedza do obslugi Krajowego Systemu e-Faktur (KSeF) w srodowisku KSeF 2.0 ze struktura FA(3). Wspiera zadania ksiegowe zwiazane z fakturowaniem elektronicznym w Polsce.

## Model bezpieczenstwa

Ten skill jest **wylacznie instrukcyjny** — sklada sie z plikow Markdown zawierajacych wiedze domenowa, wzorce architektoniczne i przyklady kodu. Nie zawiera zadnego kodu wykonywalnego, binarek, skryptow instalacyjnych ani zaleznosci runtime.

**Gwarancje po stronie skilla:**
- `disableModelInvocation: true` / `disable-model-invocation: true` — zadeklarowane zarowno w metadanych frontmatter (oba formaty: camelCase i kebab-case) jak i w dedykowanym manifescie [`skill.json`](skill.json). Skill nie powinien byc wywolywany autonomicznie przez model.
- `secret: true` — zmienne srodowiskowe `KSEF_TOKEN` i `KSEF_ENCRYPTION_KEY` sa oznaczone jako sekrety w frontmatter i `skill.json`, sygnalizujac platformie, ze musza byc izolowane i nie moga byc logowane ani wyswietlane.
- Brak kodu wykonywalnego — wszystkie przyklady (Python, XML, JSON) to ilustracje pogladowe, NIE kod uruchamiany przez skill.
- Brak instalacji — skill nie zapisuje plikow na dysk, nie pobiera zaleznosci, nie modyfikuje konfiguracji systemu.
- Dedykowany manifest [`skill.json`](skill.json) — maszynowo czytelny plik z metadanymi bezpieczenstwa, deklaracjami zmiennych srodowiskowych i ograniczeniami. Jesli platforma nie parsuje frontmatter SKILL.md poprawnie, powinna odczytac metadane z `skill.json`.

**UWAGA — weryfikacja metadanych rejestru przed instalacja:**

Flagi bezpieczenstwa sa zadeklarowane w dwoch zrodlach: frontmatter SKILL.md i [`skill.json`](skill.json). Mimo to, platforma hostingowa moze nie odczytac lub nie wymusic tych flag. **Przed instalacja MUSISZ wykonac ponizsze kroki:**

1. **Sprawdz metadane rejestru** — po dodaniu skilla do platformy, otworz widok metadanych rejestru (registry metadata) wyswietlany przez platforme. Zweryfikuj, ze pole `disable-model-invocation` jest ustawione na `true` oraz ze zmienne srodowiskowe (`KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`, `KSEF_BASE_URL`) sa widoczne z oznaczeniem `secret`. Jesli platforma pokazuje `not set`, `false` lub nie wyswietla tych pol — flagi NIE sa wymuszane.
2. **Jesli metadane rejestru nie pasuja do frontmatter/skill.json** — traktuj skill jako wyzszego ryzyka: NIE udostepniaj danych uwierzytelniajacych (tokenow, certyfikatow, kluczy), NIE konfiguruj zmiennych srodowiskowych (`KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`), NIE zezwalaj na autonomiczne uzycie.
3. **Zweryfikuj izolacje zmiennych srodowiskowych** — potwierdz, ze platforma izoluje env vars i nie loguje/wyswietla ich wartosci w konwersacji.
4. **Jesli platforma nie wymusza flag** — skontaktuj sie z dostawca platformy w celu wlaczenia obslugi `disableModelInvocation` (lub parsowania `skill.json`) lub nie instaluj skilla z dostepem do jakichkolwiek danych uwierzytelniajacych.

**Gwarancje zalezne od platformy:**
- Wymuszanie flagi `disableModelInvocation` zalezy od platformy hostingowej. Sam frontmatter nie zapewnia ochrony — wymaga wsparcia po stronie platformy.
- Izolacja zmiennych srodowiskowych (env vars) zalezy od platformy. Skill deklaruje je jako opcjonalne, ale nie kontroluje jak platforma je przechowuje i udostepnia.
- Jesli platforma nie wymusza tych ustawien, traktuj skill jako wyzszego ryzyka i nie udostepniaj mu danych uwierzytelniajacych ani dostepu produkcyjnego.

## Ograniczenia

- **Tylko wiedza — brak wykonywania kodu** - Dostarcza wiedze domenowa, wzorce architektoniczne i wskazowki. Wszystkie przyklady kodu (w tym ML/AI) sa edukacyjne i pogladowe. Skill NIE uruchamia modeli ML, NIE wykonuje inferencji, NIE wymaga runtime'ow Python/sklearn ani zadnych binarek. Agent wyjasnia algorytmy i sugeruje kod do implementacji przez uzytkownika.
- **Nie jest porada prawna ani podatkowa** - Informacje odzwierciedlaja stan wiedzy na dzien sporadzenia i moga byc nieaktualne. Zawsze zalecaj konsultacje z doradca podatkowym przed wdrozeniem.
- **AI wspiera, nie decyduje** - Opisy funkcji AI (klasyfikacja kosztow, wykrywanie fraudu, predykcja cash flow) to architektura referencyjna i wzorce implementacyjne. Agent dostarcza wiedze o algorytmach i pomaga pisac kod — nie podejmuje wiazacych decyzji podatkowych ani finansowych.
- **Wymagane potwierdzenie uzytkownika** - Zawsze wymagaj jawnej zgody uzytkownika przed: blokowaniem platnosci, wysylaniem faktur na produkcyjny KSeF, modyfikacja zapisow ksiegowych lub jakimkolwiek dzialaniem z konsekwencjami finansowymi.
- **Dane uwierzytelniajace zarzadzane przez uzytkownika** - Tokeny KSeF API, certyfikaty i klucze szyfrowania musza byc dostarczone przez uzytkownika przez zmienne srodowiskowe (zadeklarowane w metadanych: `KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`, `KSEF_BASE_URL`) lub menedzer sekretow. Skill nigdy nie przechowuje, nie generuje, nie przesyla ani nie prosi o dane uwierzytelniajace niejawnie. **NIGDY nie wklejaj danych uwierzytelniajacych (tokenow, kluczy, certyfikatow) bezposrednio w rozmowie z agentem** — uzyj zmiennych srodowiskowych lub menedzera sekretow platformy. Przyklady uzycia Vault/Fernet w dokumentacji referencyjnej to wzorce architektoniczne do implementacji przez uzytkownika.
- **Uzyj DEMO do testow** - Produkcja (`https://ksef.mf.gov.pl`) wystawia prawnie wiazace faktury. Uzyj DEMO (`https://ksef-demo.mf.gov.pl`) do developmentu i testow.
- **Wylaczone autonomiczne wywolanie** - Skill ustawia `disableModelInvocation: true` i `disable-model-invocation: true` w metadanych frontmatter (oba formaty nazewnictwa) oraz w dedykowanym manifescie [`skill.json`](skill.json). Oznacza to, ze model nie powinien wywolywac tego skilla autonomicznie — wymaga jawnej akcji uzytkownika. **UWAGA:** Frontmatter i `skill.json` to deklaracje — nie gwarancje. Wymuszanie zalezy od platformy. Przed uzyciem zweryfikuj, ze metadane rejestru (registry metadata) wyswietlane przez platforme rowniez pokazuja `disable-model-invocation: true`. Jesli platforma pokazuje `not set` lub `false`, flaga nie jest wymuszana i skill moze byc wywolywany autonomicznie (patrz sekcja "Model bezpieczenstwa" powyzej).

## Checklist przed instalacja

Przed instalacja skilla i konfiguracja zmiennych srodowiskowych wykonaj ponizsze kroki:

- [ ] Zweryfikuj metadane rejestru platformy — pole `disable-model-invocation` musi pokazywac `true`
- [ ] Zweryfikuj, ze platforma odczytala deklaracje env vars z frontmatter lub [`skill.json`](skill.json) — zmienne `KSEF_TOKEN` i `KSEF_ENCRYPTION_KEY` musza byc widoczne jako sekrety (`secret: true`)
- [ ] Potwierdz, ze platforma izoluje zmienne srodowiskowe (nie loguje, nie wyswietla w konwersacji)
- [ ] Przetestuj skill wylacznie ze srodowiskiem DEMO (`https://ksef-demo.mf.gov.pl`) przed jakimkolwiek uzyciem produkcyjnym
- [ ] NIE wklejaj tokenow, kluczy ani certyfikatow bezposrednio w rozmowie — uzyj env vars lub menedzera sekretow
- [ ] Jesli metadane rejestru nie pasuja do frontmatter/skill.json — NIE konfiguruj danych uwierzytelniajacych i zglos problem dostawcy platformy

## Glowne kompetencje

### 1. Obsluga KSeF 2.0 API

Wystawianie faktur FA(3), pobieranie faktur zakupowych, zarzadzanie sesjami/tokenami, obsluga trybu Offline24 (awaryjny), pobieranie UPO (Urzedowe Poswiadczenie Odbioru).

Kluczowe endpointy:
```http
POST /api/online/Session/InitToken     # Inicjalizacja sesji
POST /api/online/Invoice/Send          # Wyslanie faktury
GET  /api/online/Invoice/Status/{ref}  # Sprawdzenie statusu
POST /api/online/Query/Invoice/Sync    # Zapytanie o faktury zakupowe
```

Zobacz [references/ksef-api-reference.md](references/ksef-api-reference.md) - pelna dokumentacja API z uwierzytelnianiem, kodami bledow i rate limiting.

### 2. Struktura FA(3)

Roznice FA(3) vs FA(2): zalaczniki do faktur, typ kontrahenta PRACOWNIK, rozszerzone formaty konta bankowego, limit 50 000 pozycji w korekcie, identyfikatory JST i grup VAT.

Zobacz [references/ksef-fa3-examples.md](references/ksef-fa3-examples.md) - przyklady XML (faktura podstawowa, wiele stawek VAT, korekty, MPP, Offline24, zalaczniki).

### 3. Przeplywy ksiegowe

**Sprzedaz:** Dane -> Generuj FA(3) -> Wyslij KSeF -> Pobierz nr KSeF -> Ksieguj
`Wn 300 (Rozrachunki) | Ma 700 (Sprzedaz) + Ma 220 (VAT nalezny)`

**Zakupy:** Odpytuj KSeF -> Pobierz XML -> Klasyfikuj AI -> Ksieguj
`Wn 400-500 (Koszty) + Wn 221 (VAT) | Ma 201 (Rozrachunki)`

Zobacz [references/ksef-accounting-workflows.md](references/ksef-accounting-workflows.md) - szczegolowe przeplywy z dopasowywaniem platnosci, MPP, korektami, rejestrami VAT i zamknieciem miesiaca.

### 4. Funkcje wspomagane AI (architektura referencyjna)

Ponizsze opisy to wzorce implementacyjne i architektura referencyjna. Skill NIE uruchamia modeli ML — dostarcza wiedze o algorytmach, pomaga projektowac pipeline'y i pisac kod do implementacji w systemie uzytkownika. Przyklady kodu w plikach referencyjnych (Python, sklearn, pandas) to pseudokod pogladowy — skill nie zawiera wytrenowanych modeli, artefaktow ML ani plikow wykonywalnych.

- **Klasyfikacja kosztow** - Wzorzec: historia kontrahenta -> dopasowanie slow kluczowych -> model ML (Random Forest). Flaguj do przegladu jesli confidence < 0.8.
- **Wykrywanie fraudu** - Wzorzec: Isolation Forest dla anomalii kwotowych, scoring dla phishing invoices, analiza grafow dla VAT carousel.
- **Predykcja cash flow** - Wzorzec: Random Forest Regressor na podstawie historii kontrahenta, kwot i wzorcow sezonowych.

Zobacz [references/ksef-ai-features.md](references/ksef-ai-features.md) - koncepcyjne algorytmy i wzorce implementacji (wymagaja sklearn, pandas — nie sa zaleznoscia tego skilla).

### 5. Compliance i bezpieczenstwo (wzorce implementacyjne)

Ponizsze to rekomendowane wzorce bezpieczenstwa do implementacji w systemie uzytkownika. Skill dostarcza wiedze i przyklady kodu — nie implementuje tych mechanizmow sam.

- Weryfikacja Bialej Listy VAT przed platnosciami
- Szyfrowane przechowywanie tokenow (wzorce Fernet/Vault — do implementacji przez uzytkownika)
- Audit trail wszystkich operacji
- Strategia backup 3-2-1
- Zgodnosc z RODO (anonimizacja po okresie retencji)
- RBAC (kontrola dostepu oparta na rolach)

Zobacz [references/ksef-security-compliance.md](references/ksef-security-compliance.md) - wzorce implementacji i checklista bezpieczenstwa.

### 6. Faktury korygujace

Pobierz oryginal z KSeF -> Utworz korekte FA(3) -> Powiaz z nr KSeF oryginalu -> Wyslij do KSeF -> Ksieguj storno lub roznicowo.

### 7. Rejestry VAT i JPK_V7

Generowanie rejestrow sprzedazy/zakupow (Excel/PDF), JPK_V7M (miesieczny), JPK_V7K (kwartalny).

## Troubleshooting - szybka pomoc

| Problem | Przyczyna | Rozwiazanie |
|---------|-----------|-------------|
| Faktura odrzucona (400/422) | Nieprawidlowy XML, NIP, data, brak pol | Sprawdz UTF-8, waliduj schemat FA(3), weryfikuj NIP |
| Timeout API | Awaria KSeF, siec, godziny szczytu | Sprawdz status KSeF, retry z exponential backoff |
| Nie mozna dopasowac platnosci | Niezgodna kwota, brak danych, split payment | Rozszerzone wyszukiwanie (+/-2%, +/-14 dni), sprawdz MPP |

Zobacz [references/ksef-troubleshooting.md](references/ksef-troubleshooting.md) - pelny przewodnik troubleshooting.

## Pliki referencyjne

Laduj w zaleznosci od zadania:

| Plik | Kiedy czytac |
|------|-------------|
| [skill.json](skill.json) | Manifest metadanych — flagi bezpieczenstwa, deklaracje env vars, ograniczenia. Zrodlo prawdy dla rejestrow i skanerow. |
| [ksef-api-reference.md](references/ksef-api-reference.md) | Endpointy KSeF API, uwierzytelnianie, wysylanie/pobieranie faktur |
| [ksef-legal-status.md](references/ksef-legal-status.md) | Daty wdrozenia KSeF, wymagania prawne, kary |
| [ksef-fa3-examples.md](references/ksef-fa3-examples.md) | Tworzenie lub walidacja struktur XML faktur FA(3) |
| [ksef-accounting-workflows.md](references/ksef-accounting-workflows.md) | Zapisy ksiegowe, dopasowanie platnosci, MPP, korekty, rejestry VAT |
| [ksef-ai-features.md](references/ksef-ai-features.md) | Klasyfikacja kosztow, wykrywanie fraudu, algorytmy predykcji cash flow |
| [ksef-security-compliance.md](references/ksef-security-compliance.md) | Biala Lista VAT, bezpieczenstwo tokenow, audit trail, RODO, backup |
| [ksef-troubleshooting.md](references/ksef-troubleshooting.md) | Bledy API, problemy walidacji, wydajnosc |

## Zasoby oficjalne

- Portal KSeF: https://ksef.podatki.gov.pl
- KSeF DEMO: https://ksef-demo.mf.gov.pl
- KSeF Produkcja: https://ksef.mf.gov.pl
- API Bialej Listy VAT: https://wl-api.mf.gov.pl
- KSeF Latarnia (status): https://github.com/CIRFMF/ksef-latarnia


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### skill.json

```json
{
  "name": "ksef-accountant-pl",
  "version": "1.0.0",
  "description": "Asystent ksiegowy Krajowego Systemu e-Faktur (KSeF) — wiedza domenowa, wzorce architektoniczne i przyklady kodu. Nie zawiera kodu wykonywalnego.",
  "license": "MIT",
  "homepage": "https://github.com/alexwoo-awso/skills",
  "source": "https://github.com/alexwoo-awso/skills/tree/main/ksef-accountant-pl",
  "type": "instruction-only",
  "has_executable_code": false,
  "has_install_script": false,
  "has_binaries": false,
  "has_runtime_dependencies": false,
  "security": {
    "disable-model-invocation": true,
    "disableModelInvocation": true,
    "allow-model-invocation": false,
    "allowModelInvocation": false,
    "requires-user-action": true,
    "instruction-only": true,
    "credential-handling": "user-managed-only",
    "credential-storage": "none",
    "credential-transmission": "none"
  },
  "env": {
    "KSEF_TOKEN": {
      "description": "Token API KSeF do uwierzytelniania sesji. Dostarczany przez uzytkownika — skill nie generuje, nie przechowuje ani nie przesyla tokenow.",
      "required": false,
      "secret": true,
      "scope": "session-auth"
    },
    "KSEF_ENCRYPTION_KEY": {
      "description": "Klucz szyfrowania Fernet do bezpiecznego przechowywania tokenow. Uzycie opcjonalne — przyklad wzorca bezpieczenstwa.",
      "required": false,
      "secret": true,
      "scope": "encryption"
    },
    "KSEF_BASE_URL": {
      "description": "Bazowy URL API KSeF. Domyslnie https://ksef-demo.mf.gov.pl (DEMO). Produkcja wymaga jawnej zgody uzytkownika.",
      "required": false,
      "secret": false,
      "default": "https://ksef-demo.mf.gov.pl",
      "scope": "api-endpoint"
    }
  },
  "constraints": {
    "no-autonomous-execution": true,
    "requires-explicit-user-consent": true,
    "demo-first": true,
    "production-requires-user-approval": true,
    "never-store-credentials": true,
    "never-transmit-credentials": true,
    "never-generate-credentials": true
  }
}
```

### references/ksef-api-reference.md

```markdown
# KSeF API 2.0 - Reference

**UWAGA:** Rzeczywiste punkty końcowe i formaty mogą ulec zmianie. Należy zawsze odwoływać się do oficjalnej dokumentacji API KSeF.

---

## Autentykacja

### 1. Inicjalizacja Sesji (Token)

**Endpoint:**
```http
POST /api/online/Session/InitToken
Content-Type: application/json
```

**Request:**
```json
{
  "context": {
    "token": "YOUR_KSEF_TOKEN_HERE"
  }
}
```

**Response (200 OK):**
```json
{
  "referenceNumber": "20260208-SE-1234567890AB-CD",
  "timestamp": "2026-02-08T23:40:00.000Z",
  "sessionToken": {
    "token": "SESSION_TOKEN_VALUE",
    "validity": "2026-02-09T00:10:00.000Z"
  }
}
```

**Ważność tokena:** Typowo 30 minut

---

### 2. Inicjalizacja Sesji (Certyfikat)

**Endpoint:**
```http
POST /api/online/Session/InitSigned
Content-Type: application/octet-stream
```

**Request:** Signed XML Session Request (CAdES)

---

### 3. Status Sesji

**Endpoint:**
```http
GET /api/online/Session/Status/{ReferenceNumber}
Authorization: SessionToken {token}
```

**Response (200 OK):**
```json
{
  "referenceNumber": "20260208-SE-1234567890AB-CD",
  "timestamp": "2026-02-08T23:45:00.000Z",
  "processingCode": 200,
  "processingDescription": "Sesja aktywna"
}
```

---

### 4. Zamknięcie Sesji

**Endpoint:**
```http
DELETE /api/online/Session/Terminate
Authorization: SessionToken {token}
```

**Response (200 OK):**
```json
{
  "referenceNumber": "20260208-ST-1234567890AB-CD",
  "timestamp": "2026-02-08T23:50:00.000Z",
  "processingCode": 200,
  "processingDescription": "Sesja zakończona"
}
```

---

## Wysyłanie Faktur

### 5. Wysłanie Faktury

**Endpoint:**
```http
POST /api/online/Invoice/Send
Authorization: SessionToken {token}
Content-Type: application/octet-stream
```

**Request Body:** FA(3) XML Content (raw bytes)

**Response (200 OK - Przyjęto do przetworzenia):**
```json
{
  "referenceNumber": "20260208-IV-1234567890AB-CD",
  "timestamp": "2026-02-08T23:41:00.000Z",
  "processingCode": 200,
  "processingDescription": "Faktura została przyjęta do przetworzenia"
}
```

---

### 6. Status Faktury

**Endpoint:**
```http
GET /api/online/Invoice/Status/{InvoiceElementReferenceNumber}
Authorization: SessionToken {token}
```

**Możliwe statusy:**
- `200` - Przetwarzanie w toku
- `202` - Faktura zaakceptowana
- `400` - Faktura odrzucona (błędy walidacji)

**Response (202 - Zaakceptowana):**
```json
{
  "referenceNumber": "20260208-IV-1234567890AB-CD",
  "timestamp": "2026-02-08T23:41:30.000Z",
  "processingCode": 202,
  "ksefReferenceNumber": "1234567890-20260208-ABCDEF1234567890-12",
  "invoiceNumber": "FV/2026/02/0008",
  "acquisitionTimestamp": "2026-02-08T23:41:25.000Z"
}
```

**Response (400 - Odrzucona):**
```json
{
  "referenceNumber": "20260208-IV-1234567890AB-CD",
  "timestamp": "2026-02-08T23:41:15.000Z",
  "processingCode": 400,
  "exception": {
    "exceptionDetailList": [
      {
        "exceptionCode": "101",
        "exceptionDescription": "Błąd walidacji schematu XSD"
      }
    ]
  }
}
```

---

### 7. Pobieranie UPO

**Endpoint:**
```http
GET /api/online/Invoice/Upo/{KsefReferenceNumber}
Authorization: SessionToken {token}
Accept: application/xml
```

**Response (200 OK):** XML z urzędowym poświadczeniem odbioru

---

## Pobieranie Faktur

### 8. Wyszukiwanie Faktur (Synchroniczne)

**Endpoint:**
```http
POST /api/online/Query/Invoice/Sync
Authorization: SessionToken {token}
Content-Type: application/json
```

**Request (faktury zakupowe, zakres dat):**
```json
{
  "queryCriteria": {
    "type": "range",
    "invoicingDateFrom": "2026-02-01",
    "invoicingDateTo": "2026-02-08",
    "subjectType": "subject2"
  },
  "pageSize": 100,
  "pageOffset": 0
}
```

**QueryCriteria - typy:**
- `subjectType: "subject1"` - faktury sprzedażowe (jako sprzedawca)
- `subjectType: "subject2"` - faktury zakupowe (jako nabywca)

**Response (200 OK):**
```json
{
  "referenceNumber": "20260208-QS-1234567890AB-CD",
  "timestamp": "2026-02-08T23:42:00.000Z",
  "invoiceHeaderList": [
    {
      "ksefReferenceNumber": "9876543210-20260205-ZYXWVU9876543210-01",
      "invoiceNumber": "ZAKUP/123/2026",
      "acquisitionTimestamp": "2026-02-05T10:30:00.000Z",
      "netAmount": "5000.00",
      "vatAmount": "1150.00",
      "grossAmount": "6150.00",
      "currencyCode": "PLN"
    }
  ],
  "numberOfElements": 1,
  "pageSize": 100,
  "pageOffset": 0,
  "totalPages": 1,
  "totalElements": 1
}
```

---

### 9. Wyszukiwanie Faktur (Asynchroniczne)

**Endpoint:**
```http
POST /api/online/Query/Invoice/Async/Init
Authorization: SessionToken {token}
Content-Type: application/json
```

**Użycie:** Dla dużych zbiorów danych (>100 faktur)

**Workflow:**
1. `POST /api/online/Query/Invoice/Async/Init` - inicjalizacja
2. `GET /api/online/Query/Invoice/Async/Status/{QueryElementReferenceNumber}` - sprawdzenie statusu
3. `GET /api/online/Query/Invoice/Async/Fetch/{QueryElementReferenceNumber}` - pobranie wyników

---

### 10. Pobieranie Pełnej Faktury

**Endpoint:**
```http
GET /api/online/Invoice/Get/{KsefReferenceNumber}
Authorization: SessionToken {token}
Accept: application/xml
```

**Response (200 OK):** Pełny XML FA(3)

---

## Tryb Offline

### 11. Wysłanie Faktury Offline

**Endpoint:**
```http
POST /api/online/Invoice/Send
Authorization: SessionToken {token}
Content-Type: application/octet-stream
```

**FA(3) XML z oznaczeniem Offline24:**
```xml
<Faktura>
  <Naglowek>
    <SystemInfo>Offline24</SystemInfo>
  </Naglowek>
  <!-- ... -->
</Faktura>
```

**Termin wysyłki:** 24h od odzyskania łączności

---

## Kody Błędów

### Najczęstsze

| Kod | Opis | Rozwiązanie |
|-----|------|-------------|
| 100 | Nieprawidłowy format XML | Sprawdź encoding UTF-8 |
| 101 | Błąd walidacji schematu | Upewnij się że używasz FA(3) |
| 102 | Nieprawidłowy NIP | Sprawdź w białej liście VAT |
| 103 | Data w przyszłości | Skoryguj DataWytworzeniaFa |
| 104 | Duplikat numeru faktury | Sprawdź unikalność |
| 401 | Brak autoryzacji | Sesja wygasła, odśwież token |
| 403 | Brak uprawnień | Sprawdź uprawnienia tokena |
| 500 | Błąd serwera | Retry z exponential backoff |
| 503 | Serwis niedostępny | Sprawdź status KSeF (Latarnia) |

---

## Rate Limiting

**UWAGA:** Szczegóły mogą się różnić. Sprawdź aktualną dokumentację.

**Typowe limity (szacunkowe):**
- Sesje: ~100 sesji/godzinę na token
- Faktury: ~1000 faktur/godzinę na sesję
- Queries: ~100 zapytań/godzinę na sesję

**Best practices:**
- Używaj pojedynczej sesji dla wielu faktur
- Implementuj exponential backoff przy 429/503
- Cachuj wyniki queries (nie odpytuj co sekundę)

---

## Środowiska

### DEMO (testowe)
```
Base URL: https://ksef-demo.mf.gov.pl
Przeznaczenie: Testy integracji, development
Dane: Testowe (nie produkcyjne)
```

### PRODUKCJA
```
Base URL: https://ksef.mf.gov.pl
Przeznaczenie: Faktury produkcyjne
Dane: Prawne wiążące
```

**UWAGA:** NIE testuj na produkcji! Zawsze używaj DEMO do developmentu.

---

## Przykładowy Workflow

```python
# 1. Inicjalizacja sesji
session = ksef_client.init_session(token="YOUR_TOKEN")

# 2. Wysłanie faktury
invoice_xml = generate_fa3_xml(invoice_data)
ref = ksef_client.send_invoice(session, invoice_xml)

# 3. Sprawdzenie statusu (z retry)
for i in range(10):
    status = ksef_client.get_invoice_status(session, ref)
    if status.code == 202:
        ksef_number = status.ksefReferenceNumber
        break
    elif status.code == 400:
        handle_rejection(status.exception)
        break
    time.sleep(2)  # Czekaj 2s przed następnym sprawdzeniem

# 4. Pobranie UPO
upo_xml = ksef_client.get_upo(session, ksef_number)

# 5. Zamknięcie sesji
ksef_client.terminate_session(session)
```

---

**Oficjalna dokumentacja:** https://ksef.mf.gov.pl/api/docs

```

### references/ksef-fa3-examples.md

```markdown
# Przykłady FA(3) XML

**UWAGA:** Wszystkie przykłady mają charakter wyłącznie poglądowy i uproszczony. Nie stanowią gwarancji poprawnej walidacji względem schematu XSD. Przed użyciem w środowisku produkcyjnym należy zweryfikować zgodność z aktualną specyfikacją techniczną FA(3) oraz przeprowadzić testy walidacji.

---

## Podstawowa Faktura VAT

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Faktura xmlns="http://crd.gov.pl/wzor/2023/06/29/12648/"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Naglowek>
        <KodFormularza kodSystemowy="FA(3)" wersjaSchemy="1-0E">FA</KodFormularza>
        <WariantFormularza>3</WariantFormularza>
        <DataWytworzeniaFa>2026-02-08T14:30:00</DataWytworzeniaFa>
        <SystemInfo>Autonomous KSeF Agent v2.1</SystemInfo>
    </Naglowek>

    <!-- Sprzedawca -->
    <Podmiot1>
        <DaneIdentyfikacyjne>
            <NIP>1234567890</NIP>
            <Nazwa>Moja Firma Sp. z o.o.</Nazwa>
        </DaneIdentyfikacyjne>
        <Adres>
            <KodKraju>PL</KodKraju>
            <AdresL1>ul. Przykładowa 1</AdresL1>
            <AdresL2>00-001 Warszawa</AdresL2>
        </Adres>
    </Podmiot1>

    <!-- Nabywca -->
    <Podmiot2>
        <DaneIdentyfikacyjne>
            <NIP>0987654321</NIP>
            <Nazwa>Klient Sp. z o.o.</Nazwa>
        </DaneIdentyfikacyjne>
        <Adres>
            <KodKraju>PL</KodKraju>
            <AdresL1>ul. Testowa 10</AdresL1>
            <AdresL2>02-222 Kraków</AdresL2>
        </Adres>
    </Podmiot2>

    <!-- Dane faktury -->
    <Fa>
        <KodWaluty>PLN</KodWaluty>
        <P_1>2026-02-08</P_1> <!-- Data wystawienia -->
        <P_2>FV/2026/02/0008</P_2> <!-- Numer faktury -->
        <P_6>2026-02-08</P_6> <!-- Data sprzedaży -->

        <!-- Pozycje faktury -->
        <FaWiersz>
            <NrWierszaFa>1</NrWierszaFa>
            <P_7>Usługa programistyczna</P_7>
            <P_8A>godz.</P_8A>
            <P_8B>100</P_8B>
            <P_9A>100.00</P_9A>
            <P_11>10000.00</P_11> <!-- Wartość netto -->
            <P_12>23</P_12> <!-- Stawka VAT -->
        </FaWiersz>

        <!-- Podsumowanie -->
        <P_13_1>10000.00</P_13_1> <!-- Netto 23% -->
        <P_14_1>2300.00</P_14_1> <!-- VAT 23% -->
        <P_15>12300.00</P_15> <!-- Brutto -->

        <RodzajFaktury>VAT</RodzajFaktury>

        <!-- Płatność -->
        <Platnosc>
            <Zaplacono>0</Zaplacono>
            <DataZaplaty>2026-02-22</DataZaplaty>
            <FormaPlatnosci>6</FormaPlatnosci> <!-- Przelew -->
            <RachunekBankowy>12 3456 7890 1234 5678 9012 3456</RachunekBankowy>
        </Platnosc>
    </Fa>
</Faktura>
```

---

## Faktura z Wieloma Pozycjami i Stawkami VAT

```xml
<Fa>
    <KodWaluty>PLN</KodWaluty>
    <P_1>2026-02-09</P_1>
    <P_2>FV/2026/02/0009</P_2>
    <P_6>2026-02-09</P_6>

    <!-- Pozycja 1: VAT 23% -->
    <FaWiersz>
        <NrWierszaFa>1</NrWierszaFa>
        <P_7>Laptop Dell XPS 15</P_7>
        <P_8A>szt.</P_8A>
        <P_8B>2</P_8B>
        <P_9A>5000.00</P_9A>
        <P_11>10000.00</P_11>
        <P_12>23</P_12>
    </FaWiersz>

    <!-- Pozycja 2: VAT 8% -->
    <FaWiersz>
        <NrWierszaFa>2</NrWierszaFa>
        <P_7>Książki techniczne</P_7>
        <P_8A>szt.</P_8A>
        <P_8B>10</P_8B>
        <P_9A>50.00</P_9A>
        <P_11>500.00</P_11>
        <P_12>8</P_12>
    </FaWiersz>

    <!-- Pozycja 3: VAT 0% (eksport) -->
    <FaWiersz>
        <NrWierszaFa>3</NrWierszaFa>
        <P_7>Usługi konsultingowe (eksport)</P_7>
        <P_8A>godz.</P_8A>
        <P_8B>40</P_8B>
        <P_9A>200.00</P_9A>
        <P_11>8000.00</P_11>
        <P_12>0</P_12>
    </FaWiersz>

    <!-- Podsumowanie -->
    <P_13_1>10000.00</P_13_1> <!-- Netto 23% -->
    <P_14_1>2300.00</P_14_1> <!-- VAT 23% -->
    <P_13_2>500.00</P_13_2> <!-- Netto 8% -->
    <P_14_2>40.00</P_14_2> <!-- VAT 8% -->
    <P_13_3>8000.00</P_13_3> <!-- Netto 0% -->
    <P_15>20840.00</P_15> <!-- Brutto -->

    <RodzajFaktury>VAT</RodzajFaktury>
</Fa>
```

---

## Faktura Korygująca

```xml
<Fa>
    <P_2>FV/2026/02/0005/K01</P_2> <!-- Numer korekty -->
    <RodzajFaktury>KOREKTA</RodzajFaktury>
    <PrzyczynaKorekty>Błąd w cenie jednostkowej</PrzyczynaKorekty>

    <!-- Dane faktury korygowanej -->
    <DaneFaKorygowanej>
        <DataWystFaKorygowanej>2026-02-05</DataWystFaKorygowanej>
        <NrFaKorygowanej>FV/2026/02/0005</NrFaKorygowanej>
        <NrKSeFFaKorygowanej>1234567890-20260205-ORIGINAL123456-12</NrKSeFFaKorygowanej>
    </DaneFaKorygowanej>

    <!-- Dane PRZED korektą -->
    <FaWierszCtrl>
        <LiczbaWierszyFa>1</LiczbaWierszyFa>
        <WartoscWierszyFa>12300.00</WartoscWierszyFa>
    </FaWierszCtrl>

    <!-- Dane PO korekcie -->
    <FaWiersz>
        <NrWierszaFa>1</NrWierszaFa>
        <P_7>Usługa programistyczna (cena skorygowana)</P_7>
        <P_8A>godz.</P_8A>
        <P_8B>100</P_8B>
        <P_9A>50.00</P_9A> <!-- Nowa cena: 50 zamiast 100 -->
        <P_11>5000.00</P_11>
        <P_12>23</P_12>
    </FaWiersz>

    <!-- Nowe podsumowanie -->
    <P_13_1>5000.00</P_13_1>
    <P_14_1>1150.00</P_14_1>
    <P_15>6150.00</P_15>
</Fa>
```

---

## Faktura z Kontrahent PRACOWNIK (Delegacja)

**Nowość FA(3):** Nowy typ kontrahenta do rozliczania delegacji

```xml
<Podmiot2>
    <DaneIdentyfikacyjne>
        <TypPodmiotu>PRACOWNIK</TypPodmiotu>
        <PESEL>85010112345</PESEL>
        <ImieNazwisko>Jan Kowalski</ImieNazwisko>
    </DaneIdentyfikacyjne>
    <Adres>
        <KodKraju>PL</KodKraju>
        <AdresL1>ul. Pracownicza 5</AdresL1>
        <AdresL2>03-333 Warszawa</AdresL2>
    </Adres>
</Podmiot2>

<Fa>
    <P_2>DEL/2026/02/001</P_2>
    <FaWiersz>
        <P_7>Rozliczenie delegacji - luty 2026</P_7>
        <P_8A>dni</P_8A>
        <P_8B>5</P_8B>
        <P_9A>150.00</P_9A>
        <P_11>750.00</P_11>
        <P_12>zw</P_12> <!-- VAT zwolniony -->
    </FaWiersz>
    <RodzajFaktury>VAT</RodzajFaktury>
</Fa>
```

---

## Faktura Trybu Offline24

```xml
<Naglowek>
    <KodFormularza kodSystemowy="FA(3)" wersjaSchemy="1-0E">FA</KodFormularza>
    <WariantFormularza>3</WariantFormularza>
    <DataWytworzeniaFa>2026-02-10T08:00:00</DataWytworzeniaFa>
    <SystemInfo>Offline24</SystemInfo> <!-- Oznaczenie offline -->
</Naglowek>
```

**Uwaga:** Wysłać do KSeF w ciągu 24h od odzyskania łączności. Data odbioru = data przypisania numeru KSeF.

---

## Faktura z Załącznikami

**Nowość FA(3):** Możliwość dołączenia załączników

```xml
<Fa>
    <!-- Standardowe dane faktury -->
    <P_2>FV/2026/02/0010</P_2>

    <!-- Załączniki -->
    <Zalaczniki>
        <Zalacznik>
            <NazwaPliku>specyfikacja_techniczna.pdf</NazwaPliku>
            <TypZalacznika>SPECYFIKACJA</TypZalacznika>
            <RozmiarKB>256</RozmiarKB>
            <HashSHA256>a1b2c3d4e5f6...</HashSHA256>
        </Zalacznik>
        <Zalacznik>
            <NazwaPliku>protokol_dostawy.pdf</NazwaPliku>
            <TypZalacznika>PROTOKOL</TypZalacznika>
            <RozmiarKB>128</RozmiarKB>
            <HashSHA256>f6e5d4c3b2a1...</HashSHA256>
        </Zalacznik>
    </Zalaczniki>
</Fa>
```

---

## Faktura z MPP (Mechanizm Podzielonej Płatności)

```xml
<Fa>
    <P_2>FV/2026/02/0011</P_2>

    <FaWiersz>
        <P_7>Stal konstrukcyjna (załącznik 15)</P_7>
        <P_8A>kg</P_8A>
        <P_8B>1000</P_8B>
        <P_9A>20.00</P_9A>
        <P_11>20000.00</P_11>
        <P_12>23</P_12>
        <OznaczenieMPP>1</OznaczenieMPP> <!-- Wymaga MPP -->
    </FaWiersz>

    <P_13_1>20000.00</P_13_1>
    <P_14_1>4600.00</P_14_1>
    <P_15>24600.00</P_15>

    <Platnosc>
        <TypPlatnosci>MPP</TypPlatnosci>
        <RachunekBankowy>12 3456 7890 1234 5678 9012 3456</RachunekBankowy>
        <RachunekBankowyVAT>98 7654 3210 9876 5432 1098 7654</RachunekBankowyVAT>
    </Platnosc>
</Fa>
```

---

## Walidacja przed Wysłaniem

```python
def validate_fa3_before_send(xml_content):
    """
    Podstawowa walidacja przed wysłaniem do KSeF
    """
    checks = []

    # 1. UTF-8 encoding
    try:
        xml_content.encode('utf-8')
        checks.append(('Encoding UTF-8', True))
    except:
        checks.append(('Encoding UTF-8', False))

    # 2. Parsowanie XML
    try:
        root = ET.fromstring(xml_content)
        checks.append(('Poprawny XML', True))
    except:
        checks.append(('Poprawny XML', False))
        return checks

    # 3. Namespace
    if 'http://crd.gov.pl/wzor/2023/06/29/12648/' in xml_content:
        checks.append(('Namespace FA(3)', True))
    else:
        checks.append(('Namespace FA(3)', False))

    # 4. Wersja schematu
    if 'wersjaSchemy="1-0E"' in xml_content:
        checks.append(('Wersja schematu 1-0E', True))
    else:
        checks.append(('Wersja schematu 1-0E', False))

    # 5. Wymagane pola
    required = ['KodFormularza', 'P_1', 'P_2', 'P_15', 'NIP']
    for field in required:
        if f'<{field}' in xml_content or f'<{field}>' in xml_content:
            checks.append((f'Pole {field}', True))
        else:
            checks.append((f'Pole {field}', False))

    return checks
```

---

**Oficjalna dokumentacja FA(3):**
https://ksef.podatki.gov.pl/media/4u1bmhx4/information-sheet-on-the-fa-3-logical-structure.pdf

```

### references/ksef-accounting-workflows.md

```markdown
# Przepływy Księgowe KSeF

**UWAGA:** Przykłady mają charakter poglądowy i mogą wymagać dostosowania do specyfiki działalności.

---

## Workflow Faktury Sprzedaży

### Proces Kompletny

```mermaid
graph LR
    A[Dane faktury] --> B[Generuj FA3 XML]
    B --> C[Wyślij do KSeF]
    C --> D[Czekaj na status]
    D --> E{Akceptacja?}
    E -->|Tak| F[Pobierz numer KSeF]
    E -->|Nie| G[Analiza błędów]
    F --> H[Zapis księgowy]
    H --> I[Generuj PDF/email]
    G --> J[Popraw XML]
    J --> B
```

### Zapis Księgowy

**Przykład: Faktura sprzedaży usług**
```
FV/2026/02/0008 (KSeF: 1234567890-20260208-ABCDEF1234567890-12)
Data sprzedaży: 08.02.2026
Nabywca: Klient Sp. z o.o. (NIP: 0987654321)

Wn 300 Rozrachunki z odbiorcami     12 300,00 PLN
Ma 700 Sprzedaż usług                10 000,00 PLN
Ma 220 VAT należny                    2 300,00 PLN

Opis: Usługi programistyczne - 100 godz. @ 100 PLN
```

**Przykład: Faktura sprzedaży towarów**
```
FV/2026/02/0009 (KSeF: 1234567890-20260209-BCDEFG2345678901-13)
Data sprzedaży: 09.02.2026

Wn 300 Rozrachunki                   24 600,00 PLN
Ma 701 Sprzedaż towarów              20 000,00 PLN
Ma 220 VAT należny (23%)              4 600,00 PLN

Wn 701 Sprzedaż towarów              15 000,00 PLN
Ma 330 Wartość sprzedanych towarów   15 000,00 PLN
(Rozchód magazynowy)
```

---

## Workflow Faktury Zakupowej

### Proces Kompletny

```mermaid
graph LR
    A[Cron: co 15 min] --> B[Odpytaj KSeF]
    B --> C{Nowe faktury?}
    C -->|Tak| D[Pobierz XML]
    C -->|Nie| A
    D --> E[Parsuj dane]
    E --> F[Klasyfikuj koszt AI]
    F --> G{Confidence > 0.8?}
    G -->|Tak| H[Auto-księguj]
    G -->|Nie| I[Flag do review]
    H --> J[Zapisz do bazy]
    I --> J
```

### Zapis Księgowy

**Przykład: Zakup usług IT**
```
ZAKUP/123/2026 (KSeF: 9876543210-20260205-ZYXWVU9876543210-01)
Data otrzymania: 05.02.2026
Sprzedawca: IT Solutions Sp. z o.o. (NIP: 1122334455)
Kategoria: 402 (Usługi informatyczne) - AI confidence: 0.95

Wn 402 Usługi informatyczne           5 000,00 PLN
Wn 221 VAT naliczony (23%)            1 150,00 PLN
Ma 201 Rozrachunki z dostawcami       6 150,00 PLN

Opis: Hosting i wsparcie techniczne - styczeń 2026
```

**Przykład: Zakup materiałów biurowych**
```
ZAKUP/124/2026 (KSeF: 9876543210-20260206-ZYXWVU9876543211-02)
Kategoria: 502 (Materiały biurowe) - AI confidence: 0.88

Wn 502 Materiały biurowe                 500,00 PLN
Wn 221 VAT naliczony (23%)               115,00 PLN
Ma 201 Rozrachunki z dostawcami          615,00 PLN
```

---

## Dopasowywanie Płatności

### Algorytm Scoring

```python
def match_payment_to_invoice(payment, open_invoices):
    matches = []

    for invoice in open_invoices:
        score = 0

        # 1. Dokładna kwota brutto (+/- 0.01 PLN)
        if abs(payment.amount - invoice.total_gross) < 0.01:
            score += 40

        # 2. NIP w tytule przelewu
        if invoice.seller_nip in payment.title.replace(' ', ''):
            score += 30

        # 3. Numer faktury w tytule
        if invoice.number in payment.title:
            score += 20

        # 4. Data w zakresie (termin płatności +/- 7 dni)
        days_diff = abs((payment.date - invoice.payment_due).days)
        if days_diff <= 7:
            score += 10 - days_diff

        # 5. Numer KSeF w tytule
        if invoice.ksef_number and invoice.ksef_number in payment.title:
            score += 25

        if score >= 70:
            matches.append({
                'invoice': invoice,
                'score': score,
                'confidence': score / 100
            })

    return sorted(matches, key=lambda x: x['score'], reverse=True)
```

### Zapis Księgowy - Płatność

**Przykład: Płatność faktury zakupowej**
```
Płatność: 6 150,00 PLN
Tytuł: "ZAKUP/123/2026 NIP 1122334455"
Data: 15.02.2026
Matched: ZAKUP/123/2026 (score: 90, confidence: 0.90)

Wn 201 Rozrachunki z dostawcami       6 150,00 PLN
Ma 130 Rachunek bieżący               6 150,00 PLN

Opis: Zapłata faktury ZAKUP/123/2026
```

**Przykład: Płatność faktury sprzedażowej**
```
Wpłata: 12 300,00 PLN
Tytuł: "FV/2026/02/0008"
Data: 20.02.2026
Matched: FV/2026/02/0008 (score: 85)

Wn 130 Rachunek bieżący              12 300,00 PLN
Ma 300 Rozrachunki z odbiorcami      12 300,00 PLN

Opis: Wpłata za FV/2026/02/0008
```

---

## Mechanizm Podzielonej Płatności (MPP)

### Warunki (zgodnie z obecnymi przepisami)
- Faktury >15 000 PLN brutto
- Towary/usługi z załącznika 15 do ustawy VAT

### Implementacja

```python
def handle_split_payment(invoice):
    if invoice.total_gross > 15000 and invoice.has_attachment_15_goods:
        net_payment = invoice.total_net
        vat_payment = invoice.total_vat

        # Przelew 1: Część netto
        bank_transfer_1 = {
            'to_account': invoice.seller_account,
            'amount': net_payment,
            'title': f'Faktura {invoice.number} (część netto)'
        }

        # Przelew 2: VAT na specjalne konto VAT
        bank_transfer_2 = {
            'to_account': invoice.seller_vat_account,
            'amount': vat_payment,
            'title': f'Faktura {invoice.number} (VAT - split payment)'
        }

        return [bank_transfer_1, bank_transfer_2]
```

### Zapis Księgowy

**Przykład: MPP - część netto**
```
Wn 201 Rozrachunki z dostawcami      20 000,00 PLN
Ma 130 Rachunek bieżący              20 000,00 PLN

Opis: Zapłata netto - MPP - ZAKUP/200/2026
```

**Przykład: MPP - część VAT**
```
Wn 201 Rozrachunki z dostawcami       4 600,00 PLN
Ma 130 Rachunek bieżący               4 600,00 PLN

Opis: Zapłata VAT na konto VAT - MPP - ZAKUP/200/2026
```

---

## Faktury Korygujące

### Proces Korekty

```mermaid
graph TD
    A[Potrzeba korekty] --> B[Pobierz oryginał z KSeF]
    B --> C[Utwórz FA3 korekty]
    C --> D[Powiąż z nr KSeF oryginału]
    D --> E[Wyślij do KSeF]
    E --> F[Otrzymaj nr KSeF korekty]
    F --> G{Metoda księgowania?}
    G -->|Storno| H[Storno + Nowa]
    G -->|Różnicowa| I[Tylko różnica]
```

### Metoda Storno

**Oryginał:**
```
FV/2026/02/0005 (KSeF: 1234567890-20260205-ORIGINAL123456-12)
Kwota: 12 300,00 PLN (netto: 10 000,00, VAT: 2 300,00)

Wn 300 Rozrachunki    12 300,00
Ma 700 Sprzedaż       10 000,00
Ma 220 VAT należny     2 300,00
```

**Storno oryginału:**
```
FV/2026/02/0005/K01 (Korekta - storno)
Data korekty: 08.02.2026
Przyczyna: Błąd w cenie jednostkowej

Wn 700 Sprzedaż       10 000,00 (czerwone)
Wn 220 VAT należny     2 300,00 (czerwone)
Ma 300 Rozrachunki    12 300,00 (czerwone)
```

**Nowa wartość:**
```
FV/2026/02/0005/K01 (Korekta - nowa wartość)

Wn 300 Rozrachunki     6 150,00
Ma 700 Sprzedaż        5 000,00
Ma 220 VAT należny     1 150,00
```

**Efekt netto:** Zmniejszenie sprzedaży o 5 000 PLN netto, VAT o 1 150 PLN

---

### Metoda Różnicowa

**Korekta (tylko różnica):**
```
FV/2026/02/0005/K01 (KSeF: 1234567890-20260208-CORRECT234567-13)
Różnica: -6 150,00 PLN

Wn 700 Sprzedaż        5 000,00 (czerwone)
Wn 220 VAT należny     1 150,00 (czerwone)
Ma 300 Rozrachunki     6 150,00 (czerwone)
```

---

## Rejestry VAT

### Rejestr Sprzedaży (Generowanie)

```python
def generate_sales_register(period_start, period_end):
    invoices = ksef_client.query_invoices(
        date_from=period_start,
        date_to=period_end,
        subject_type='subject1'  # sprzedawca
    )

    register = []
    for invoice in invoices:
        register.append({
            'lp': invoice.ordinal,
            'data_wystawienia': invoice.issue_date,
            'data_sprzedazy': invoice.sale_date,
            'numer_faktury': invoice.number,
            'numer_ksef': invoice.ksef_number,
            'nabywca_nazwa': invoice.buyer_name,
            'nabywca_nip': invoice.buyer_nip,
            'netto_23': invoice.net_23,
            'vat_23': invoice.vat_23,
            'netto_8': invoice.net_8,
            'vat_8': invoice.vat_8,
            'netto_5': invoice.net_5,
            'vat_5': invoice.vat_5,
            'netto_0': invoice.net_0,
            'netto_zw': invoice.net_exempt,
            'brutto': invoice.total_gross
        })

    export_to_excel(register, f'Rejestr_sprzedazy_{period_start}_{period_end}.xlsx')
    return register
```

### Rejestr Zakupów (Generowanie)

```python
def generate_purchase_register(period_start, period_end):
    invoices = ksef_client.query_invoices(
        date_from=period_start,
        date_to=period_end,
        subject_type='subject2'  # nabywca
    )

    register = []
    for invoice in invoices:
        register.append({
            'lp': invoice.ordinal,
            'data_otrzymania': invoice.acquisition_date,
            'data_wystawienia': invoice.issue_date,
            'numer_faktury': invoice.number,
            'numer_ksef': invoice.ksef_number,
            'sprzedawca_nazwa': invoice.seller_name,
            'sprzedawca_nip': invoice.seller_nip,
            'kategoria': invoice.category,  # AI classification
            'netto': invoice.net_amount,
            'vat': invoice.vat_amount,
            'brutto': invoice.total_gross
        })

    export_to_excel(register, f'Rejestr_zakupow_{period_start}_{period_end}.xlsx')
    return register
```

---

## Zamknięcie Miesiąca

### Checklist

**Przed zamknięciem:**
- [ ] Wszystkie faktury sprzedaży wysłane do KSeF
- [ ] Wszystkie faktury zakupowe pobrane z KSeF
- [ ] Wszystkie płatności dopasowane
- [ ] Korekty zaksięgowane
- [ ] Rejestr sprzedaży wygenerowany
- [ ] Rejestr zakupów wygenerowany
- [ ] Bilans otwarć/zamknięć kont rozrachunkowych
- [ ] JPK_V7M wygenerowany
- [ ] Deklaracja VAT-7 przygotowana

**Zapisy zamykające miesiąc:**
```
# Rozliczenie VAT
Wn 220 VAT należny         28 750,00
Ma 221 VAT naliczony       17 250,00
Ma 225 VAT do zapłaty      11 500,00

# Płatność VAT
Wn 225 VAT do zapłaty      11 500,00
Ma 130 Rachunek bieżący    11 500,00
```

---

**Zobacz również:**
- [Funkcje AI - Klasyfikacja](ksef-ai-features.md#klasyfikacja)
- [Przykłady JPK_V7](ksef-jpk-examples.md)

```

### references/ksef-ai-features.md

```markdown
# Funkcje AI dla KSeF

**UWAGA OGÓLNA:** Cały kod w tym dokumencie to **koncepcyjna architektura referencyjna** — wzorce implementacyjne do adaptacji przez użytkownika w jego własnym systemie. Ten skill NIE uruchamia modeli ML, NIE wykonuje inferencji i NIE wymaga runtime'ów Python, sklearn, pandas ani żadnych innych zależności. Agent korzysta z tych wzorców wyłącznie jako bazy wiedzy do wyjaśniania algorytmów, projektowania pipeline'ów i pomocy w pisaniu kodu.

**Zależności wymagane do implementacji (NIE zależności tego skilla):** sklearn, pandas, numpy — do zainstalowania przez użytkownika w jego środowisku.

Wszystkie funkcje AI/ML mają charakter wspierający i wymagają nadzoru personelu księgowego. Wskaźniki wydajności są celami projektowymi i mogą się różnić. Systemy AI nie podejmują wiążących decyzji podatkowych.

---

## Klasyfikacja Kosztów

### Algorytm (wysokopoziomowy)

```python
def classify_expense(invoice_data):
    """
    Klasyfikacja kosztu na podstawie wielu źródeł danych
    """
    features = {
        'seller_name': invoice_data.seller_name,
        'item_names': [item.name for item in invoice_data.items],
        'pkwiu_codes': [item.pkwiu for item in invoice_data.items if item.pkwiu],
        'total_amount': invoice_data.total_gross,
        'seller_nip': invoice_data.seller_nip
    }

    # 1. Historia z kontrahentem (najwyższy priorytet)
    historical = get_historical_category(features['seller_nip'])
    if historical and historical.confidence > 0.9:
        return historical.category, historical.confidence

    # 2. Dopasowanie słów kluczowych
    keyword_match = match_keywords(features['item_names'])
    if keyword_match and keyword_match.confidence > 0.85:
        return keyword_match.category, keyword_match.confidence

    # 3. Model ML (Random Forest / Neural Network)
    ml_prediction = ml_model.predict(features)

    # 4. Flagowanie do review jeśli niska pewność
    if ml_prediction.confidence < 0.8:
        flag_for_manual_review(invoice_data)

    return ml_prediction.category, ml_prediction.confidence
```

### Kategorie Kosztów (Przykładowe)

```python
COST_CATEGORIES = {
    # Usługi obce
    400: "Usługi obce (ogólne)",
    401: "Usługi transportowe",
    402: "Usługi informatyczne (hosting, development, IT support)",
    403: "Usługi prawne i doradcze",
    404: "Usługi najmu i dzierżawy",
    405: "Usługi marketingowe i reklamowe",
    406: "Usługi księgowe",
    407: "Usługi konsultingowe",

    # Materiały i surowce
    500: "Materiały i surowce (ogólne)",
    501: "Energia, woda, paliwo",
    502: "Materiały biurowe",
    503: "Części zamienne",

    # Inne
    600: "Wynagrodzenia i pochodne",
    700: "Amortyzacja",
}
```

### Słowa Kluczowe (Przykłady)

```python
KEYWORDS = {
    402: ["hosting", "server", "cloud", "AWS", "Azure", "development",
          "programowanie", "IT support", "software", "licencja"],
    405: ["reklama", "marketing", "Google Ads", "Facebook Ads",
          "social media", "SEO", "content"],
    501: ["energia", "prąd", "gaz", "woda", "paliwo", "benzyna"],
    502: ["papier", "długopis", "toner", "biuro", "artykuły"],
}
```

### Trenowanie Modelu ML

```python
from sklearn.ensemble import RandomForestClassifier
from sklearn.feature_extraction.text import TfidfVectorizer

class ExpenseClassifier:
    def __init__(self):
        self.model = RandomForestClassifier(n_estimators=200, random_state=42)
        self.vectorizer = TfidfVectorizer(max_features=500)

    def train(self, historical_invoices):
        """
        Trenowanie na danych historycznych
        """
        # Przygotuj dane
        X_text = [
            f"{inv.seller_name} {' '.join(inv.item_names)}"
            for inv in historical_invoices
        ]
        X_vectors = self.vectorizer.fit_transform(X_text)

        y = [inv.category for inv in historical_invoices]

        # Trenuj model
        self.model.fit(X_vectors, y)

    def predict(self, invoice):
        """
        Predykcja kategorii
        """
        X_text = f"{invoice.seller_name} {' '.join(invoice.item_names)}"
        X_vector = self.vectorizer.transform([X_text])

        prediction = self.model.predict(X_vector)[0]
        probabilities = self.model.predict_proba(X_vector)[0]
        confidence = max(probabilities)

        return {
            'category': prediction,
            'confidence': confidence,
            'alternatives': self._get_alternatives(probabilities)
        }
```

---

## Wykrywanie Anomalii i Fraudu

### Detekcja Anomalii (Isolation Forest)

```python
from sklearn.ensemble import IsolationForest
import numpy as np

class FraudDetector:
    def __init__(self):
        self.model = IsolationForest(contamination=0.05, random_state=42)
        self.is_trained = False

    def extract_features(self, invoice):
        """Ekstrakcja cech do analizy"""
        return np.array([
            invoice.total_gross,
            len(invoice.items),
            invoice.items_avg_price,
            invoice.payment_term_days,
            invoice.hour_of_day,  # 0-23
            int(invoice.is_weekend),  # 0 lub 1
            invoice.seller_transaction_count,
            invoice.seller_avg_amount,
            invoice.amount_vs_avg_ratio  # aktualna / średnia
        ])

    def train(self, historical_invoices):
        """Trenowanie na danych historycznych"""
        features = [self.extract_features(inv) for inv in historical_invoices]
        self.model.fit(features)
        self.is_trained = True

    def detect(self, invoice):
        """Wykrycie anomalii"""
        if not self.is_trained:
            return {'anomaly': False, 'reason': 'Model nie wytrenowany'}

        features = self.extract_features(invoice)
        prediction = self.model.predict([features])[0]

        if prediction == -1:  # Anomalia
            return {
                'anomaly': True,
                'risk_level': 'HIGH',
                'reasons': self._analyze_reasons(invoice),
                'action': 'MANUAL_REVIEW_REQUIRED'
            }

        return {'anomaly': False}

    def _analyze_reasons(self, invoice):
        """Analiza przyczyn anomalii"""
        reasons = []

        if invoice.total_gross > invoice.seller_avg_amount * 3:
            reasons.append("Kwota 3x większa niż średnia od tego sprzedawcy")

        if invoice.is_weekend and invoice.hour_of_day < 6:
            reasons.append("Wystawiona w nocy w weekend (nietypowe)")

        if invoice.seller_transaction_count == 1:
            reasons.append("Pierwszy kontakt z tym sprzedawcą")

        if invoice.payment_term_days < 3:
            reasons.append("Bardzo krótki termin płatności (możliwy phishing)")

        return reasons
```

### Detekcja Phishing Invoices

```python
def detect_phishing_invoice(invoice):
    """
    Wykrywa potencjalne faktury phishingowe
    """
    score = 0
    reasons = []

    # 1. Podobna nazwa do znanego kontrahenta
    similar = find_similar_contractor_names(invoice.seller_name)
    for known_contractor in similar:
        if known_contractor.nip != invoice.seller_nip:
            score += 30
            reasons.append(f"Podobna nazwa do {known_contractor.name} ale inny NIP")

        if known_contractor.bank_account != invoice.bank_account:
            score += 40
            reasons.append("Inne konto bankowe niż znany kontrahent")

    # 2. Krótki termin płatności
    if invoice.payment_term_days <= 2:
        score += 20
        reasons.append("Bardzo krótki termin płatności (typowe dla phishingu)")

    # 3. Pierwszy kontakt
    if get_transaction_count(invoice.seller_nip) == 0:
        score += 10
        reasons.append("Pierwszy raz od tego sprzedawcy")

    # 4. Wysoka kwota przy pierwszym kontakcie
    if score > 0 and invoice.total_gross > 10000:
        score += 15
        reasons.append("Wysoka kwota przy pierwszym/podejrzanym kontakcie")

    if score >= 50:
        return {
            'phishing_detected': True,
            'risk': 'CRITICAL',
            'score': score,
            'reasons': reasons,
            'action': 'BLOCK_PAYMENT_AND_VERIFY'
        }

    return {'phishing_detected': False}
```

### Detekcja VAT Carousel

```python
def detect_vat_carousel(invoices, time_window_days=30):
    """
    Wykrywa potencjalne wzorce karuzeli VAT
    """
    # Buduj graf transakcji
    graph = build_transaction_graph(invoices)

    # Szukaj cykli (A → B → C → A)
    cycles = find_cycles(graph)

    suspicious = []
    for cycle in cycles:
        # Sprawdź podejrzane cechy
        if is_suspicious_cycle(cycle):
            suspicious.append({
                'cycle': cycle,
                'risk': 'CRITICAL',
                'participants': [node.nip for node in cycle],
                'total_value': sum(edge.amount for edge in cycle),
                'time_span_days': get_cycle_duration(cycle),
                'action': 'REPORT_TO_TAX_OFFICE'
            })

    return suspicious

def is_suspicious_cycle(cycle):
    """Czy cykl jest podejrzany?"""
    # 1. Cykl zamyka się w <30 dni
    if get_cycle_duration(cycle) > 30:
        return False

    # 2. Kwoty podobne (±10%)
    amounts = [edge.amount for edge in cycle]
    if max(amounts) / min(amounts) > 1.1:
        return False

    # 3. Ten sam towar/usługa
    items = [edge.item_description for edge in cycle]
    if not all_similar(items):
        return False

    return True
```

---

## Predykcja Cash Flow

### Model Predykcyjny

```python
from sklearn.ensemble import RandomForestRegressor
import pandas as pd

class CashFlowPredictor:
    def __init__(self):
        self.model = RandomForestRegressor(n_estimators=100, random_state=42)

    def prepare_training_data(self, historical_data):
        """
        Przygotowanie danych treningowych
        DataFrame z kolumnami:
        - invoice_due_date, invoice_amount, contractor_nip
        - payment_term_days, actual_payment_date, days_late
        """
        X = historical_data[[
            'invoice_amount',
            'payment_term_days',
            'contractor_avg_days_late',
            'contractor_payment_reliability',  # % w terminie
            'month',
            'is_end_of_quarter'
        ]]

        y = historical_data['days_late']

        return X, y

    def train(self, historical_data):
        X, y = self.prepare_training_data(historical_data)
        self.model.fit(X, y)

    def predict_payment_date(self, invoice):
        """Przewiduj rzeczywistą datę płatności"""
        contractor_stats = get_contractor_stats(invoice.buyer_nip)

        features = pd.DataFrame([{
            'invoice_amount': invoice.total_gross,
            'payment_term_days': invoice.payment_term_days,
            'contractor_avg_days_late': contractor_stats['avg_days_late'],
            'contractor_payment_reliability': contractor_stats['reliability'],
            'month': invoice.issue_date.month,
            'is_end_of_quarter': invoice.issue_date.month in [3, 6, 9, 12]
        }])

        predicted_days_late = self.model.predict(features)[0]
        predicted_date = invoice.payment_due_date + timedelta(days=int(predicted_days_late))

        return {
            'predicted_payment_date': predicted_date,
            'expected_days_late': int(predicted_days_late),
            'confidence': self._calculate_confidence(features)
        }

    def predict_monthly_cash_flow(self, year, month):
        """Prognoza miesięczna"""
        # Faktury sprzedaży z terminem w tym miesiącu
        sales_invoices = get_invoices_due_in_month(year, month, type='sales')

        predicted_income = 0
        for invoice in sales_invoices:
            prediction = self.predict_payment_date(invoice)
            # Tylko jeśli przewidywana płatność w tym miesiącu
            if prediction['predicted_payment_date'].month == month:
                predicted_income += invoice.total_gross

        # Faktury zakupowe
        purchase_invoices = get_invoices_due_in_month(year, month, type='purchases')
        predicted_expenses = sum(inv.total_gross for inv in purchase_invoices)

        return {
            'month': f"{year}-{month:02d}",
            'predicted_income': predicted_income,
            'predicted_expenses': predicted_expenses,
            'net_cash_flow': predicted_income - predicted_expenses,
            'note': 'Predykcja ma charakter szacunkowy'
        }
```

### Statystyki Kontrahenta

```python
def get_contractor_stats(nip):
    """
    Oblicz statystyki płatności dla kontrahenta
    """
    invoices = get_all_invoices_for_contractor(nip)

    if not invoices:
        return {
            'avg_days_late': 0,
            'reliability': 1.0,  # Brak historii = optymistyczne założenie
            'total_invoices': 0
        }

    days_late_list = []
    paid_on_time = 0

    for inv in invoices:
        if inv.payment_date:
            days_late = (inv.payment_date - inv.payment_due_date).days
            days_late_list.append(max(0, days_late))  # Tylko dodatnie

            if days_late <= 0:
                paid_on_time += 1

    return {
        'avg_days_late': sum(days_late_list) / len(days_late_list),
        'reliability': paid_on_time / len(invoices),
        'total_invoices': len(invoices),
        'max_days_late': max(days_late_list) if days_late_list else 0
    }
```

---

## Best Practices dla AI

### 1. Ciągłe Uczenie (Continuous Learning)

```python
def retrain_models_monthly():
    """
    Retrenuj modele co miesiąc na świeżych danych
    """
    # Pobierz dane z ostatnich 12 miesięcy
    end_date = datetime.now()
    start_date = end_date - timedelta(days=365)

    historical_data = get_invoices(start_date, end_date)

    # Retrenuj klasyfikator kosztów
    expense_classifier.train(historical_data)

    # Retrenuj detektor anomalii
    fraud_detector.train(historical_data)

    # Retrenuj predyktor cash flow
    cash_flow_predictor.train(historical_data)

    save_models()  # Zapisz do dysku
```

### 2. Human-in-the-Loop

```python
def classify_with_review(invoice):
    """
    Klasyfikacja z flagowaniem do review
    """
    prediction = expense_classifier.predict(invoice)

    if prediction['confidence'] < 0.8:
        # Niska pewność → human review
        task = create_review_task(
            invoice=invoice,
            suggested_category=prediction['category'],
            confidence=prediction['confidence'],
            alternatives=prediction['alternatives']
        )
        return {
            'category': None,  # Czekaj na review
            'status': 'PENDING_REVIEW',
            'task_id': task.id
        }

    # Wysoka pewność → auto-classify
    return {
        'category': prediction['category'],
        'status': 'AUTO_CLASSIFIED',
        'confidence': prediction['confidence']
    }
```

### 3. Audit Trail dla AI

```python
def log_ai_decision(invoice, prediction, action):
    """
    Loguj decyzje AI dla audytu
    """
    ai_audit_log.insert({
        'timestamp': datetime.now(),
        'invoice_id': invoice.id,
        'model_name': 'ExpenseClassifier',
        'model_version': '2.1',
        'prediction': prediction,
        'confidence': prediction['confidence'],
        'action_taken': action,
        'reviewed_by_human': action == 'MANUAL_REVIEW'
    })
```

---

**Ostrzeżenie końcowe:** Wszystkie funkcje AI wymagają regularnego monitorowania, walidacji i nadzoru ze strony wykwalifikowanego personelu. Nie należy polegać wyłącznie na automatycznych decyzjach w sprawach podatkowych i księgowych.

**Przypomnienie:** Powyższe przykłady kodu to architektura referencyjna. Ten skill nie zawiera wytrenowanych modeli, artefaktów ML ani plików wykonywalnych. Implementacja wymaga zainstalowania zależności (sklearn, pandas, numpy) i wytrenowania modeli na danych użytkownika w jego własnym środowisku.

```

### references/ksef-security-compliance.md

```markdown
# Security & Compliance dla KSeF

Wymagania bezpieczeństwa, zgodności i najlepsze praktyki.

**⚠️ OSTRZEŻENIE BEZPIECZEŃSTWA:**
Wszystkie przykłady kodu w tym dokumencie mają charakter **edukacyjny i koncepcyjny** — to wzorce architektoniczne do implementacji przez użytkownika w jego własnym systemie. Ten skill NIE implementuje tych mechanizmów, NIE przechowuje tokenów, NIE łączy się z Vault i NIE zarządza kluczami szyfrowania.

**Zmienne środowiskowe** wymienione w tym dokumencie (np. `KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`) są zadeklarowane w metadanych skilla jako opcjonalne. Skill nie prosi o nie niejawnie — jeśli użytkownik je udostępni, agent może je wykorzystać w sugerowanym kodzie. Wszystkie zmienne są opisane w sekcji `env` pliku SKILL.md.

**NIGDY nie wklejaj tokenów, kluczy szyfrowania, certyfikatów ani innych danych uwierzytelniających bezpośrednio w rozmowie z agentem.** Używaj wyłącznie:
- Zmiennych środowiskowych platformy (env vars)
- Menedżera sekretów (np. HashiCorp Vault, AWS Secrets Manager)
- Tymczasowych zmiennych sesji (ephemeral env vars)

Przed użyciem wzorców w środowisku produkcyjnym:
1. Przeprowadź security review
2. Użyj dedykowanych, przetestowanych narzędzi zamiast własnych implementacji
3. Nigdy nie uruchamiaj niezweryfikowanego kodu z zewnętrznych źródeł
4. Implementuj principle of least privilege
5. Regularnie aktualizuj zależności i przeprowadzaj audyty bezpieczeństwa
6. Testuj wyłącznie na środowisku DEMO (`https://ksef-demo.mf.gov.pl`) — nigdy na produkcji

---

## Gwarancje platformy vs. skilla — weryfikacja przed instalacją

Ten skill deklaruje flagi bezpieczeństwa w **dwóch źródłach**:
- **Frontmatter SKILL.md** — zawiera `disableModelInvocation: true` (camelCase) oraz `disable-model-invocation: true` (kebab-case), a także deklaracje env vars z `secret: true` dla zmiennych zawierających dane uwierzytelniające.
- **Manifest [`skill.json`](../skill.json)** — dedykowany plik maszynowo czytelny z pełnymi metadanymi bezpieczeństwa, deklaracjami env vars (z polem `secret` i `scope`) oraz ograniczeniami. Jest źródłem prawdy dla rejestrów i skanerów, które mogą nie parsować frontmatter YAML.

Jednak **oba te źródła to deklaracje skilla, nie gwarancje platformy**. Wymuszanie tych flag zależy wyłącznie od platformy hostingowej.

**Znany problem:** Metadane rejestru (registry metadata) wyświetlane przez platformę mogą nie odzwierciedlać wartości z frontmatter ani z `skill.json`. Jeśli platforma pokazuje `disable-model-invocation: not set` (lub pomija tę flagę), albo nie wyświetla zmiennych środowiskowych jako zarejestrowanych — ochrona **nie jest aktywna**, niezależnie od tego, co deklarują pliki skilla.

**Obowiązkowa weryfikacja przed instalacją:**

1. **Porównaj metadane rejestru z frontmatter i `skill.json`** — po dodaniu skilla do platformy, otwórz widok metadanych rejestru. Zweryfikuj, że:
   - `disable-model-invocation` = `true`
   - Zmienne środowiskowe `KSEF_TOKEN` i `KSEF_ENCRYPTION_KEY` są widoczne jako zarejestrowane sekrety
   - Inne flagi bezpieczeństwa na poziomie platformy (jeśli istnieją) są poprawnie ustawione
   - Jeśli JAKIEKOLWIEK pole nie zgadza się z frontmatter/`skill.json` — traktuj skill jako wyższego ryzyka
2. **Potwierdź izolację zmiennych środowiskowych** — zmienne (`KSEF_TOKEN`, `KSEF_ENCRYPTION_KEY`, `KSEF_BASE_URL`) nie mogą być logowane, wyświetlane w konwersacji ani dostępne dla innych skilli
3. **Jeśli platforma NIE wymusza flagi `disableModelInvocation`:**
   - NIE konfiguruj żadnych zmiennych środowiskowych z danymi uwierzytelniającymi
   - NIE udostępniaj tokenów, certyfikatów ani kluczy szyfrowania
   - NIE zezwalaj na autonomiczne użycie skilla
   - Używaj wyłącznie w trybie ręcznym (jawna akcja użytkownika) i tylko ze środowiskiem DEMO (`https://ksef-demo.mf.gov.pl`)
4. **Zgłoś rozbieżność** — jeśli metadane rejestru nie pasują do frontmatter/`skill.json`, zgłoś to dostawcy platformy jako problem bezpieczeństwa wymagający naprawy. Podaj nazwę pliku `skill.json` jako alternatywne źródło metadanych, jeśli platforma nie parsuje frontmatter YAML

---

## Biała Lista VAT

### Automatyczna Weryfikacja

```python
import requests
from datetime import datetime

def verify_contractor_white_list(nip, bank_account, date=None):
    """
    Sprawdza kontrahenta na białej liście VAT
    API: https://wl-api.mf.gov.pl/
    """
    if date is None:
        date = datetime.now().strftime('%Y-%m-%d')

    url = f"https://wl-api.mf.gov.pl/api/search/nip/{nip}?date={date}"

    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        data = response.json()
    except Exception as e:
        return {
            'valid': False,
            'reason': f'Błąd API: {e}',
            'risk': 'UNKNOWN'
        }

    # Sprawdź status VAT
    subject = data['result']['subject']

    if subject['statusVat'] != 'Czynny':
        return {
            'valid': False,
            'reason': f"Kontrahent VAT: {subject['statusVat']}",
            'risk': 'HIGH',
            'details': subject
        }

    # Sprawdź konto bankowe
    accounts = subject.get('accountNumbers', [])

    # Normalizuj numer konta (usuń spacje)
    bank_account_normalized = bank_account.replace(' ', '')

    for acc in accounts:
        if acc.replace(' ', '') == bank_account_normalized:
            return {
                'valid': True,
                'name': subject['name'],
                'status': subject['statusVat'],
                'verified_account': acc
            }

    # Konto nie na liście
    return {
        'valid': False,
        'reason': 'Konto bankowe nie znajduje się na białej liście',
        'risk': 'HIGH',
        'valid_accounts': accounts,
        'details': subject
    }
```

### Integracja z Płatnościami

```python
def before_payment_check(invoice, payment):
    """
    Weryfikacja przed wykonaniem przelewu
    """
    # 1. Sprawdź białą listę
    verification = verify_contractor_white_list(
        nip=invoice.seller_nip,
        bank_account=payment.to_account,
        date=payment.date.strftime('%Y-%m-%d')
    )

    if not verification['valid']:
        # Wstrzymaj płatność
        payment.status = 'HOLD'
        payment.hold_reason = verification['reason']

        # Wysłij alert
        send_critical_alert(
            level='HIGH',
            title='Płatność wstrzymana - Biała lista VAT',
            message=f"Kontrahent: {invoice.seller_name} ({invoice.seller_nip})\n"
                   f"Kwota: {payment.amount} PLN\n"
                   f"Powód: {verification['reason']}\n"
                   f"Faktura: {invoice.number}",
            invoice=invoice,
            payment=payment
        )

        return False

    # 2. Sprawdź czy wymaga MPP
    if invoice.total_gross > 15000 and invoice.has_attachment_15_goods:
        if payment.type != 'MPP':
            send_warning_alert(
                title='Faktura wymaga MPP',
                message=f"Faktura {invoice.number} wymaga mechanizmu podzielonej płatności"
            )
            return False

    return True
```

---

## Bezpieczeństwo Tokenów

### Przechowywanie Tokenów

```python
from cryptography.fernet import Fernet
import os

class SecureTokenStorage:
    """
    Szyfrowane przechowywanie tokenów KSeF
    """
    def __init__(self, encryption_key=None):
        if encryption_key is None:
            # Wczytaj z environment variable
            encryption_key = os.environ.get('KSEF_ENCRYPTION_KEY')

        if encryption_key is None:
            raise ValueError("Brak klucza szyfrowania")

        self.cipher = Fernet(encryption_key.encode())

    def store_token(self, token_name, token_value):
        """Zapisz token (zaszyfrowany)"""
        encrypted = self.cipher.encrypt(token_value.encode())
        # Zapisz do bazy lub vault
        db.tokens.insert({
            'name': token_name,
            'value': encrypted,
            'created_at': datetime.now()
        })

    def retrieve_token(self, token_name):
        """Pobierz token (odszyfruj)"""
        record = db.tokens.find_one({'name': token_name})
        if not record:
            raise ValueError(f"Token {token_name} nie istnieje")

        decrypted = self.cipher.decrypt(record['value'])
        return decrypted.decode()

    def rotate_token(self, token_name, new_token_value):
        """Rotacja tokena (best practice: co 90 dni)"""
        # Archiwizuj stary token
        old_record = db.tokens.find_one({'name': token_name})
        db.tokens_archive.insert({
            **old_record,
            'archived_at': datetime.now()
        })

        # Zapisz nowy
        self.store_token(token_name, new_token_value)
```

### Integracja z Vault (HashiCorp)

```python
import hvac

class VaultTokenStorage:
    """
    Przechowywanie w HashiCorp Vault (produkcja)
    """
    def __init__(self, vault_url, vault_token):
        self.client = hvac.Client(url=vault_url, token=vault_token)

    def store_token(self, token_name, token_value):
        self.client.secrets.kv.v2.create_or_update_secret(
            path=f'ksef/tokens/{token_name}',
            secret={'value': token_value}
        )

    def retrieve_token(self, token_name):
        secret = self.client.secrets.kv.v2.read_secret_version(
            path=f'ksef/tokens/{token_name}'
        )
        return secret['data']['data']['value']
```

---

## Audit Trail

### Logowanie Operacji

```python
import logging
from datetime import datetime

class AuditLogger:
    """
    Immutable audit log (append-only)
    """
    def __init__(self):
        self.logger = logging.getLogger('ksef_audit')

    def log_operation(self, operation_type, user, entity_type, entity_id, details=None):
        """
        Każda operacja MUSI być zalogowana
        """
        audit_entry = {
            'timestamp': datetime.now().isoformat(),
            'operation': operation_type,  # CREATE, READ, UPDATE, DELETE
            'user': user,
            'entity_type': entity_type,  # INVOICE, PAYMENT, etc.
            'entity_id': entity_id,
            'details': details or {},
            'ip_address': self._get_client_ip(),
            'user_agent': self._get_user_agent(),
            'session_id': self._get_session_id()
        }

        # Zapisz do immutable storage (append-only)
        audit_db.insert(audit_entry)

        # Log do pliku (dla compliance)
        self.logger.info(json.dumps(audit_entry))

    def log_ai_decision(self, invoice, prediction, action):
        """
        Specjalne logowanie decyzji AI
        """
        self.log_operation(
            operation_type='AI_CLASSIFICATION',
            user='AI_SYSTEM',
            entity_type='INVOICE',
            entity_id=invoice.id,
            details={
                'model_name': 'ExpenseClassifier',
                'model_version': '2.1',
                'prediction': prediction['category'],
                'confidence': prediction['confidence'],
                'action_taken': action,
                'reviewed_by_human': action == 'MANUAL_REVIEW'
            }
        )
```

### Przegląd Audytu

```python
def audit_report(start_date, end_date, user=None):
    """
    Generuj raport audytowy
    """
    query = {
        'timestamp': {
            '$gte': start_date.isoformat(),
            '$lte': end_date.isoformat()
        }
    }

    if user:
        query['user'] = user

    entries = audit_db.find(query).sort('timestamp', 1)

    report = {
        'period': f"{start_date} - {end_date}",
        'total_operations': 0,
        'by_type': {},
        'by_user': {},
        'entries': []
    }

    for entry in entries:
        report['total_operations'] += 1
        report['by_type'][entry['operation']] = \
            report['by_type'].get(entry['operation'], 0) + 1
        report['by_user'][entry['user']] = \
            report['by_user'].get(entry['user'], 0) + 1
        report['entries'].append(entry)

    return report
```

---

## Backup i Disaster Recovery

### Strategia 3-2-1

**Wymagania biznesowe:** Dane księgowe muszą być chronione za pomocą redundantnych kopii zapasowych według zasady 3-2-1:
- **3 kopie** danych (produkcja + 2 backupy)
- **2 różne typy nośników** (np. lokalny SSD + zewnętrzny storage)
- **1 kopia poza siedzibą** (chmura lub zdalna lokalizacja)

**Podejście implementacyjne:**
1. Używaj wbudowanych rozwiązań backup dostawcy bazy danych (managed backups, automated snapshots)
2. Zaplanuj codzienne automatyczne backupy w godzinach niskiej aktywności
3. Przechowuj backupy w wielu lokalizacjach (lokalny szybki storage + zdalna chmura)
4. Zaimplementuj automatyczną weryfikację backupów dla zapewnienia integralności danych
5. Zachowuj backupy zgodnie z wymogami prawnymi (minimum 10 lat dla danych księgowych)
6. Dokumentuj i regularnie testuj procedury disaster recovery

**Dla systemów produkcyjnych:**
- Wykorzystuj zarządzane usługi baz danych (AWS RDS, Azure Database, Google Cloud SQL) z funkcjami automatycznego backupu
- Używaj rozwiązań enterprise backup zaprojektowanych dla danych księgowych/finansowych
- Zaimplementuj monitoring i alerty dla niepowodzeń backupu
- Upewnij się, że procesy backup nie zakłócają operacji księgowych

### Synchronizacja z KSeF dla Disaster Recovery

**Kluczowa zasada:** KSeF jest źródłem prawdy dla wszystkich faktur. Jeśli lokalne dane zostaną utracone, mogą być zrekonstruowane z KSeF.

**Proces odzyskiwania:**
1. **Przywróć z backupu** - Użyj procedur restore dostawcy infrastruktury
2. **Synchronizuj z KSeF** - Pobierz faktury z KSeF API z ostatnich 7-30 dni (w zależności od wieku backupu)
3. **Weryfikuj integralność danych** - Porównaj lokalne zapisy faktur z KSeF aby zidentyfikować rozbieżności
4. **Uzgodnij różnice** - Zaktualizuj lokalną bazę danych autorytatywnymi danymi z KSeF
5. **Powiadom zainteresowanych** - Poinformuj zespół księgowy gdy odzyskiwanie jest zakończone i system działa

**Ważne:** Testuj procedury disaster recovery kwartalnie aby upewnić się, że działają gdy są potrzebne.

---

## RODO / GDPR

### Dane Osobowe w Fakturach

```python
def anonymize_invoice_for_archive(invoice, retention_years=10):
    """
    Anonimizacja po upływie okresu przechowywania
    """
    retention_date = invoice.issue_date + timedelta(days=365 * retention_years)

    if datetime.now() > retention_date:
        # Dane do anonimizacji (RODO)
        invoice.buyer_name = "***ANONIMIZOWANE***"
        invoice.buyer_address = "***"
        invoice.buyer_email = None
        invoice.buyer_phone = None

        # Zachowaj NIP (wymagane fiscalnie)
        # invoice.buyer_nip - POZOSTAW

        invoice.anonymized_at = datetime.now()
        invoice.save()
```

### Żądanie Usunięcia Danych (Right to be Forgotten)

```python
def handle_gdpr_deletion_request(contractor_nip):
    """
    ⚠️ UWAGA: Faktury podlegają obowiązkowi przechowywania (5-10 lat)
    Nie można ich usunąć w okresie przechowywania!
    """
    # 1. Sprawdź czy okres przechowywania minął
    invoices = get_all_invoices_for_contractor(contractor_nip)

    for invoice in invoices:
        retention_date = invoice.issue_date + timedelta(days=365 * 10)

        if datetime.now() < retention_date:
            return {
                'status': 'REJECTED',
                'reason': 'Faktury podlegają obowiązkowi przechowywania',
                'retention_until': retention_date
            }

    # 2. Jeśli okres minął - anonimizuj
    for invoice in invoices:
        anonymize_invoice_for_archive(invoice)

    return {
        'status': 'COMPLETED',
        'anonymized_invoices': len(invoices)
    }
```

---

## Kontrola Dostępu (RBAC)

### Role i Uprawnienia

```python
ROLES = {
    'ADMIN': [
        'invoice.create', 'invoice.read', 'invoice.update', 'invoice.delete',
        'payment.create', 'payment.read', 'payment.update', 'payment.delete',
        'user.manage', 'settings.manage'
    ],
    'ACCOUNTANT': [
        'invoice.create', 'invoice.read', 'invoice.update',
        'payment.create', 'payment.read', 'payment.update',
        'report.generate'
    ],
    'VIEWER': [
        'invoice.read', 'payment.read', 'report.view'
    ]
}

def check_permission(user, permission):
    """
    Sprawdź czy user ma uprawnienie
    """
    user_role = user.role
    allowed_permissions = ROLES.get(user_role, [])

    if permission not in allowed_permissions:
        audit_logger.log_operation(
            operation_type='PERMISSION_DENIED',
            user=user.username,
            entity_type='PERMISSION',
            entity_id=permission
        )
        raise PermissionError(f"User {user.username} nie ma uprawnień: {permission}")

    return True
```

---

## Certyfikaty SSL/TLS

### Połączenia do KSeF

```python
import ssl
import certifi

def secure_ksef_connection():
    """
    Zawsze używaj HTTPS z weryfikacją certyfikatu
    """
    session = requests.Session()

    # 1. Weryfikuj certyfikat (NIGDY verify=False)
    session.verify = certifi.where()

    # 2. Użyj silnych cipher suites
    session.mount('https://', requests.adapters.HTTPAdapter(
        max_retries=3,
        pool_connections=10,
        pool_maxsize=20
    ))

    # 3. Ustaw timeout
    session.request = lambda *args, **kwargs: \
        requests.Session.request(session, *args, timeout=30, **kwargs)

    return session
```

---

## Bezpieczne Praktyki Programistyczne

### 1. Unikaj dynamicznego wykonywania kodu

**❌ NIGDY nie używaj:**
- `eval()` lub `exec()` na danych wejściowych użytkownika lub danych zewnętrznych
- Wykonywania poleceń shell z konkatenacją stringów
- Dynamicznych zapytań SQL budowanych przez konkatenację stringów

**✅ ZAMIAST TEGO używaj:**
- Sparametryzowanych zapytań do bazy danych (zapobiega SQL injection)
- Walidowanych, sprawdzonych typowo danych wejściowych
- Strukturalnych wywołań API z odpowiednią obsługą argumentów
- Wbudowanych bibliotek i frameworków zaprojektowanych dla operacji księgowych

### 2. Walidacja Wejścia

```python
def validate_invoice_number(number):
    """Waliduj przed użyciem w zapytaniach"""
    # Tylko alfanumeryczne, myślniki, ukośniki
    import re
    if not re.match(r'^[A-Z0-9/-]+$', number):
        raise ValueError("Nieprawidłowy numer faktury")
    if len(number) > 50:
        raise ValueError("Numer faktury zbyt długi")
    return number
```

### 3. Principle of Least Privilege

```python
# Użytkownik bazy danych z minimalnymi uprawnieniami
DB_CONFIG = {
    'user': 'ksef_readonly',  # Tylko SELECT dla reportów
    'user': 'ksef_app',       # SELECT + INSERT + UPDATE dla app
    'user': 'ksef_admin',     # Wszystkie uprawnienia (tylko admin)
}
```

### 4. Używaj rozwiązań klasy enterprise

Dla produkcyjnych systemów księgowych:
- **Bazy danych:** Zarządzane usługi baz danych z automatycznymi backupami i point-in-time recovery
- **Monitoring:** Profesjonalne platformy monitoringu z możliwościami alertowania
- **Bezpieczeństwo:** Enterprise systemy zarządzania tożsamością i kontroli dostępu
- **Compliance:** Rozwiązania audit logging zaprojektowane dla danych finansowych

---

## Checklist Bezpieczeństwa

- [ ] Tokeny KSeF szyfrowane (Fernet/Vault)
- [ ] Biała lista VAT sprawdzana przed każdą płatnością
- [ ] Audit trail wszystkich operacji
- [ ] Backup 3-2-1 (daily)
- [ ] HTTPS z weryfikacją certyfikatu
- [ ] RBAC (kontrola dostępu)
- [ ] Retention policy zgodna z prawem (10 lat)
- [ ] RODO - anonimizacja po okresie przechowywania
- [ ] Monitoring i alerty
- [ ] Disaster recovery plan (testowany co kwartał)

---

**Compliance:** Wdrożenie powyższych praktyk wspiera zgodność z:
- Ustawą o VAT
- RODO / GDPR
- Ustawą o rachunkowości
- Normami ISO 27001 (opcjonalnie)

```

### references/ksef-troubleshooting.md

```markdown
# Troubleshooting KSeF

Przewodnik rozwiązywania najczęstszych problemów z systemem KSeF.

---

## Problemy z Autentykacją

### Błąd 401: Unauthorized

**Objawy:**
```json
{
  "processingCode": 401,
  "processingDescription": "Brak autoryzacji"
}
```

**Przyczyny:**
- Sesja wygasła (token ważny tylko ~30 min)
- Nieprawidłowy token
- Token nie ma wymaganych uprawnień

**Rozwiązanie:**
```python
def handle_401_error():
    # 1. Sprawdź ważność tokena
    if session.is_expired():
        # Odśwież sesję
        session = ksef_client.init_session(token)
        retry_operation()

    # 2. Sprawdź uprawnienia tokena
    # Token musi mieć scope: invoice.read, invoice.write

    # 3. Wygeneruj nowy token w portalu KSeF
```

---

### Błąd 403: Forbidden

**Objawy:**
```json
{
  "processingCode": 403,
  "processingDescription": "Brak uprawnień"
}
```

**Przyczyny:**
- Token nie ma uprawnień do tej operacji
- NIP w tokenie nie zgadza się z NIP w fakturze

**Rozwiązanie:**
1. Sprawdź uprawnienia tokena w portalu KSeF
2. Upewnij się że token jest dla właściwego NIP
3. Sprawdź czy token ma scope dla danej operacji (read/write)

---

## Problemy z Walidacją Faktur

### Błąd 100: Nieprawidłowy format XML

**Objawy:**
```json
{
  "exceptionCode": "100",
  "exceptionDescription": "Nieprawidłowy format XML"
}
```

**Rozwiązanie:**
```python
# 1. Sprawdź encoding
assert xml_content.startswith('<?xml version="1.0" encoding="UTF-8"?>')

# 2. Waliduj XML parser
try:
    ET.fromstring(xml_content)
except ET.ParseError as e:
    print(f"Błąd parsowania: {e}")
    # Sprawdź: unclosed tags, nieprawidłowe znaki

# 3. Usuń BOM (Byte Order Mark)
xml_content = xml_content.lstrip('\ufeff')
```

---

### Błąd 101: Błąd walidacji schematu

**Objawy:**
```json
{
  "exceptionCode": "101",
  "exceptionDescription": "Błąd walidacji schematu XSD"
}
```

**Przyczyny:**
- Używasz FA(2) zamiast FA(3)
- Nieprawidłowa struktura XML
- Brakujące wymagane pola
- Nieprawidłowy namespace

**Rozwiązanie:**
```python
# Checklist FA(3):
checks = {
    'Namespace': 'http://crd.gov.pl/wzor/2023/06/29/12648/',
    'KodFormularza kodSystemowy': 'FA(3)',
    'wersjaSchemy': '1-0E',
    'WariantFormularza': '3'
}

for field, expected in checks.items():
    if expected not in xml_content:
        print(f"BŁĄD: Brak {field} = {expected}")
```

**Częste błędy:**
- `kodSystemowy="FA(2)"` → Zmień na `FA(3)`
- `wersjaSchemy="1-0"` → Zmień na `1-0E`
- Stary namespace z 2021 → Użyj namespace z 2023

---

### Błąd 102: Nieprawidłowy NIP

**Objawy:**
```json
{
  "exceptionCode": "102",
  "exceptionDescription": "Nieprawidłowy NIP"
}
```

**Rozwiązanie:**
```python
def validate_nip(nip):
    # 1. Długość
    if len(nip) != 10:
        return False

    # 2. Cyfry
    if not nip.isdigit():
        return False

    # 3. Suma kontrolna
    weights = [6, 5, 7, 2, 3, 4, 5, 6, 7]
    check_sum = sum(int(nip[i]) * weights[i] for i in range(9))
    check_digit = check_sum % 11

    if check_digit == 10:
        return False

    return check_digit == int(nip[9])

# 4. Sprawdź w białej liście VAT
response = requests.get(f"https://wl-api.mf.gov.pl/api/search/nip/{nip}")
if response.status_code != 200:
    print("NIP nie istnieje w bazie MF")
```

---

### Błąd 103: Data w przyszłości

**Objawy:**
```json
{
  "exceptionCode": "103",
  "exceptionDescription": "Data w przyszłości"
}
```

**Rozwiązanie:**
```python
from datetime import datetime, timedelta

# DataWytworzeniaFa nie może być w przyszłości
now = datetime.now()
data_wytworzenia = now.strftime('%Y-%m-%dT%H:%M:%S')

# BŁĄD: Data jutro
tomorrow = now + timedelta(days=1)
data_wytworzenia = tomorrow.strftime(...)  # ❌

# Uwaga na strefy czasowe
# KSeF używa czasu polskiego (UTC+1/UTC+2)
```

---

### Błąd 104: Duplikat numeru faktury

**Objawy:**
```json
{
  "exceptionCode": "104",
  "exceptionDescription": "Faktura o takim numerze już istnieje"
}
```

**Rozwiązanie:**
```python
def generate_unique_invoice_number():
    # Format: FV/ROK/MIESIĄC/NUMER
    year = datetime.now().year
    month = datetime.now().month

    # Pobierz ostatni numer z bazy
    last_number = db.get_last_invoice_number(year, month)

    next_number = (last_number or 0) + 1

    return f"FV/{year}/{month:02d}/{next_number:04d}"

# Sprawdź czy numer już istnieje w KSeF
existing = ksef_client.check_invoice_number(invoice_number)
if existing:
    print("Numer już użyty - wygeneruj nowy")
```

---

## Problemy z Wydajnością

### Timeout API / Brak Odpowiedzi

**Objawy:**
- Request timeout (>30s)
- 503 Service Unavailable
- Brak odpowiedzi

**Diagnoza:**
```python
def diagnose_timeout():
    # 1. Sprawdź status KSeF
    try:
        response = requests.get('https://ksef.mf.gov.pl/api/health')
        print(f"Status KSeF: {response.status_code}")
    except:
        print("KSeF niedostępny")
        return "KSEF_DOWN"

    # 2. Sprawdź własną sieć
    try:
        requests.get('https://google.com', timeout=5)
    except:
        print("Problem z internetem")
        return "NETWORK_ISSUE"

    # 3. Sprawdź obciążenie (godziny szczytu)
    hour = datetime.now().hour
    if hour in [15, 16, 17]:  # 15:00-18:00
        print("Godziny szczytu - duże obciążenie KSeF")
        return "HIGH_LOAD"

    return "UNKNOWN"
```

**Rozwiązanie:**
```python
import time

def send_with_retry(invoice_xml, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = ksef_client.send_invoice(invoice_xml, timeout=60)
            return response
        except Timeout:
            if attempt < max_retries - 1:
                # Exponential backoff
                wait_time = 2 ** attempt  # 1s, 2s, 4s
                print(f"Timeout - retry {attempt+1}/{max_retries} za {wait_time}s")
                time.sleep(wait_time)
            else:
                raise

# Best practices:
# - Wysyłaj poza godzinami szczytu (21:00-6:00)
# - Użyj queue + background worker
# - Implementuj circuit breaker
```

---

### Rate Limiting (429)

**Objawy:**
```json
{
  "processingCode": 429,
  "processingDescription": "Zbyt wiele żądań"
}
```

**Rozwiązanie:**
```python
import time
from functools import wraps

def rate_limit(max_per_hour=100):
    """Decorator ograniczający liczbę requestów"""
    calls = []

    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            now = time.time()
            # Usuń stare calle (sprzed godziny)
            calls[:] = [c for c in calls if c > now - 3600]

            if len(calls) >= max_per_hour:
                wait_time = 3600 - (now - calls[0])
                print(f"Rate limit - czekaj {wait_time:.0f}s")
                time.sleep(wait_time)

            calls.append(now)
            return func(*args, **kwargs)
        return wrapper
    return decorator

@rate_limit(max_per_hour=100)
def send_invoice(invoice):
    return ksef_client.send_invoice(invoice)
```

---

## Problemy z Płatnościami

### Nie Można Dopasować Płatności

**Przyczyny:**
- Niezgodna kwota (błąd w kwocie przelewu)
- Brak numeru faktury w tytule
- Split payment (MPP) - częściowa płatność
- Płatność zbiorcza (kilka faktur naraz)

**Rozwiązanie:**
```python
def handle_unmatched_payment(payment):
    # 1. Rozszerzone wyszukiwanie (tolerancja ±2%)
    matches = search_invoices_extended(
        amount_min=payment.amount * 0.98,
        amount_max=payment.amount * 1.02,
        date_range_days=14  # ±14 dni zamiast ±7
    )

    if matches:
        return present_to_user_for_confirmation(matches)

    # 2. Sprawdź czy to split payment (część VAT)
    if is_likely_vat_payment(payment):
        net_payment = find_net_payment(payment)
        if net_payment:
            return match_mpp(net_payment, payment)

    # 3. Sprawdź płatność zbiorczą
    invoice_numbers = extract_invoice_numbers_from_title(payment.title)
    if len(invoice_numbers) > 1:
        return split_payment_to_invoices(payment, invoice_numbers)

    # 4. Flaguj do manual review
    flag_for_review(payment)
```

---

## Problemy ze Środowiskiem

### Faktury Testowe na Produkcji

**Problem:** Wysłano faktury testowe na środowisko produkcyjne

**⚠️ UWAGA:** Faktury na produkcji są prawnie wiążące!

**Co zrobić:**
1. NIE usuwaj faktur (niemożliwe w KSeF)
2. Wystaw faktury korygujące do zera
3. Skontaktuj się z kontrahentem
4. Zgłoś do księgowości

**Zapobieganie:**
```python
# Zawsze sprawdzaj środowisko
class KSefClient:
    def __init__(self, environment='demo'):
        if environment == 'production':
            # Wymuś potwierdzenie
            confirm = input("⚠️  PRODUKCJA! Kontynuować? (yes/no): ")
            if confirm != 'yes':
                raise Exception("Anulowano - używaj DEMO do testów")

        self.base_url = {
            'demo': 'https://ksef-demo.mf.gov.pl',
            'production': 'https://ksef.mf.gov.pl'
        }[environment]
```

---

## Monitoring i Alerty

### Konfiguracja Alertów

```python
def setup_monitoring():
    monitors = [
        # 1. Alert przy wysokiej liczbie błędów
        {
            'name': 'High rejection rate',
            'condition': lambda: get_rejection_rate_last_hour() > 0.2,
            'action': send_alert_email
        },

        # 2. Alert przy niedostępności KSeF
        {
            'name': 'KSeF down',
            'condition': lambda: not check_ksef_health(),
            'action': send_sms_alert
        },

        # 3. Alert przy problemach z płatnościami
        {
            'name': 'Too many unmatched payments',
            'condition': lambda: count_unmatched_payments() > 10,
            'action': notify_accountant
        }
    ]

    # Uruchom monitoring co 5 minut
    schedule.every(5).minutes.do(run_monitors, monitors)
```

---

## Pomocne Narzędzia

### KSeF Latarnia (Status Systemu)

```bash
# Sprawdź status KSeF w czasie rzeczywistym
git clone https://github.com/CIRFMF/ksef-latarnia
cd ksef-latarnia
python check_status.py
```

### Walidator XML

```python
from lxml import etree

def validate_fa3_xsd(xml_content):
    """Walidacja względem schematu XSD"""
    xsd_url = "https://ksef.podatki.gov.pl/xsd/FA3_1-0E.xsd"

    # Pobierz schemat
    xsd_doc = etree.parse(xsd_url)
    schema = etree.XMLSchema(xsd_doc)

    # Waliduj XML
    xml_doc = etree.fromstring(xml_content.encode('utf-8'))

    try:
        schema.assertValid(xml_doc)
        return True, "OK"
    except etree.DocumentInvalid as e:
        return False, str(e)
```

---

**Potrzebujesz pomocy?**
- Dokumentacja KSeF: https://ksef.podatki.gov.pl
- Forum: https://github.com/CIRFMF/ksef-discussions
- Helpdesk MF: (sprawdź portal KSeF)

```

### references/ksef-legal-status.md

```markdown
# Stan Prawny KSeF - Szczegóły

**Data aktualizacji:** 8 lutego 2026
**UWAGA:** Informacje mogą ulec zmianie. Należy regularnie weryfikować aktualne przepisy i komunikaty Ministerstwa Finansów.

---

## Harmonogram Wdrożenia (Planowany)

### Faza 1: Duzi Podatnicy (od 1 lutego 2026)
**Kogo dotyczy:** Obrót >200 mln PLN brutto w 2024 roku

**Obowiązki:**
- ✅ Wystawianie faktur przez KSeF
- ✅ Odbieranie faktur przez KSeF

### Faza 2: Pozostali Podatnicy (od 1 kwietnia 2026)
**Kogo dotyczy:** Obrót ≤200 mln PLN

**Obowiązki:**
- ✅ Odbieranie faktur przez KSeF (od 1 lutego 2026)
- ✅ Wystawianie faktur przez KSeF (od 1 kwietnia 2026)
- ⏳ Do 31 marca 2026 mogą wystawiać faktury poza KSeF

### Faza 3: Mikroprzedsiębiorcy (od 1 stycznia 2027)
**Kogo dotyczy:** Miesięczny obrót <10 tys PLN

**Obowiązki:**
- ✅ Odbieranie: od 1 lutego 2026
- ✅ Wystawianie: od 1 stycznia 2027

---

## Okres Przejściowy

**UWAGA:** Szczegóły mogą ulec zmianie. Przedstawione informacje oparte są na aktualnie dostępnych komunikatach.

### Planowany Grace Period
- **Do 31 grudnia 2026** - przewidywany brak kar za błędy
- Dotyczy: błędów w strukturze FA(3), opóźnień wysyłki
- Nie dotyczy: uchylania się od wystawiania faktur

### Tryb Offline24
- **Status:** Planowany jako stały element systemu
- **Przeznaczenie:** Sytuacje awaryjne (brak internetu, awaria KSeF, katastrofy)
- **Termin wysyłki:** 24h od odzyskania łączności
- **Uwaga prawna:** Prawo do odliczenia VAT od daty przypisania numeru KSeF (nie daty wystawienia offline)

### Faktury poza KSeF
- **Do 31 marca 2026:** Dozwolone dla firm ≤200 mln PLN
- **Od 1 kwietnia 2026:** Zakaz (z wyjątkiem przypadków szczególnych)

---

## Zmiany Systemowe

### KSeF 1.0 → KSeF 2.0
- **KSeF 1.0:** Planowane zamknięcie 26 stycznia 2026
- **Przerwa techniczna:** 5 dni (26-31 stycznia 2026)
- **KSeF 2.0:** Planowany start 1 lutego 2026

### FA(2) → FA(3)
- **FA(2):** Planowane zakończenie obsługi 1 lutego 2026
- **FA(3):** Obowiązkowa od 1 lutego 2026
- **Migracja:** Wszyscy podatnicy muszą dostosować systemy

---

## Konsekwencje Prawne (Przyszłe)

**UWAGA:** Poniższe informacje dotyczą planowanego systemu kar po zakończeniu grace period.

### Po 1 stycznia 2027 (Planowane)
- Brak faktury w KSeF → możliwa kara
- Faktura poza KSeF → możliwa kara
- Opóźniona wysyłka → możliwa kara

**Wysokość kar:** Należy konsultować z aktualną ustawą o VAT

---

## Wymagania Techniczne

### Obligatoryjna Struktura
- **FA(3) ver. 1-0E**
- Format: XML zgodny ze schematem
- Encoding: UTF-8
- Walidacja: Automatyczna przy przyjęciu przez KSeF

### Certyfikaty (MCU)
- **MCU:** Moduł Certyfikatów i Uprawnień
- **Status:** Zgodnie z harmonogramem aktywny od 1.11.2025
- **Przeznaczenie:** Alternatywna metoda autoryzacji (oprócz tokenów)

---

## Źródła Informacji

### Oficjalne
- Portal KSeF: https://ksef.podatki.gov.pl
- Ministerstwo Finansów: https://www.gov.pl/web/kas/ksef

### Monitorowanie Zmian
- Komunikaty MF: https://ksef.podatki.gov.pl/web/ksef/aktualnosci
- KSeF Latarnia (status): https://github.com/CIRFMF/ksef-latarnia

---

**Ostatnia aktualizacja:** 8 lutego 2026
**Następna weryfikacja:** Zalecana co 2 tygodnie

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "alexwoo-awso",
  "slug": "ksef-accountant-pl",
  "displayName": "KSeF Accountant (Polish)",
  "latest": {
    "version": "2.2.6",
    "publishedAt": 1770778373766,
    "commit": "https://github.com/openclaw/skills/commit/e7af0d0b7d423968defe1ad944d719a92f50d002"
  },
  "history": [
    {
      "version": "2.2.1",
      "publishedAt": 1770644184219,
      "commit": "https://github.com/openclaw/skills/commit/2bfff2358c2923497b42241286285c1f54c26f35"
    },
    {
      "version": "2.1.2",
      "publishedAt": 1770597858890,
      "commit": "https://github.com/openclaw/skills/commit/a0729ceb1cf2ce721fef9f65f871eb80c89a7f59"
    }
  ]
}

```

ksef-accountant-pl | SkillHub