Przejdź do głównej zawartości

Contributing guide

Ksefnik jest projektem open-source i przyjmujemy kontrybucje. Ten przewodnik opisuje jak skonfigurować środowisko, jakich konwencji przestrzegamy i jak wygląda proces review.

  1. Forkuj repozytorium na GitHubie — kliknij “Fork” na stronie CodeFormers-it/ksefnik.

  2. Sklonuj swojego forka:

    Okno terminala
    git clone https://github.com/YOUR-USER/ksefnik.git
    cd ksefnik
  3. Zainstaluj zależności (wymagany pnpm i Node.js 22+):

    Okno terminala
    pnpm install
  4. Zbuduj wszystkie pakiety:

    Okno terminala
    pnpm build
  5. Uruchom testy — upewnij się, że wszystko przechodzi:

    Okno terminala
    pnpm test
  6. Utwórz branch dla swojej zmiany:

    Okno terminala
    git checkout -b feature/my-feature

Ksefnik to monorepo pnpm workspace. Każdy pakiet ma jasno określoną odpowiedzialność:

@ksefnik/shared

Schematy Zod, typy TypeScript, interfejsy pluginów. Fundament bez zależności runtime (poza zod).

@ksefnik/core

Fasada SDK, silnik uzgadniania (6-pass pipeline), parsery bankowe. Cała logika biznesowa.

@ksefnik/http

Klient HTTP do KSeF API v2 — retry, cache, adapter pattern.

@ksefnik/simulator

Offline mock KSeF API do testów — scenariusze happy path, timeout, expired session.

@ksefnik/mcp

Serwer MCP (Model Context Protocol) — cienka warstwa na @ksefnik/core.

@ksefnik/cli

CLI (Commander.js + @clack/prompts) → kompilowane do standalone binary przez Bun.

ksefnik/
├── packages/
│ ├── shared/ @ksefnik/shared — Schematy Zod, typy, interfejsy pluginów
│ ├── core/ @ksefnik/core — Fasada SDK, silnik uzgadniania, parsery bankowe
│ ├── http/ @ksefnik/http — Klient HTTP do KSeF API v2
│ ├── simulator/ @ksefnik/simulator — Offline mock KSeF API
│ └── mcp/ @ksefnik/mcp — Serwer MCP (cienka warstwa na core)
├── apps/
│ ├── cli/ @ksefnik/cli — CLI → standalone binary
│ └── docs/ Dokumentacja — Astro Starlight
├── pnpm-workspace.yaml
├── package.json
└── vitest.workspace.ts
KomendaOpis
pnpm devWatch mode dla wszystkich pakietów
pnpm buildBudowanie wszystkich pakietów
pnpm testUruchomienie Vitest
pnpm typecheckSprawdzenie typów we wszystkich pakietach

Cały kod jest pisany w TypeScript z włączonym strict mode. Nie używamy any — jeśli typ jest nieznany, używamy unknown i walidujemy przez Zod.

Wszystkie modele domenowe (faktura, transakcja bankowa, wynik dopasowania) to schematy Zod. Typy TypeScript inferujemy z nich:

import { z } from 'zod'
export const InvoiceSchema = z.object({
ksefId: z.string(),
nip: z.string(),
amount: z.number().int(), // grosze!
issueDate: z.string(),
})
export type Invoice = z.infer<typeof InvoiceSchema>

Wszystkie kwoty przechowujemy jako liczby całkowite w groszach (1 PLN = 100 groszy). Nigdy nie używamy float do pieniędzy.

// Dobrze
const amount = 12345 // 123,45 PLN
// Źle
const amount = 123.45

Projekt używa wyłącznie ESM ("type": "module" w package.json). Nie używamy require().

Używamy Prettier bez ESLint. Przed commitem uruchom:

Okno terminala
pnpm prettier --write .
  1. Target branch — wszystkie PR-y celują w main.

  2. CI musi przejść — pipeline sprawdza build, typecheck i testy. PR z czerwonym CI nie przejdzie review.

  3. Review — PRy przegląda @luke-cf (CODEOWNERS). Typowy czas review: 1-2 dni robocze.

  4. Conventional commits — używamy prefiksów w wiadomościach commitów:

    PrefixKiedy
    featNowa funkcjonalność
    fixPoprawka buga
    refactorZmiana kodu bez zmiany zachowania
    docsZmiany w dokumentacji
    testDodanie lub zmiana testów
    choreZmiany w konfiguracji, CI, tooling
    Okno terminala
    git commit -m "feat: add ING CSV parser"
    git commit -m "fix: handle empty NIP in bank transaction"
    git commit -m "docs: add contributing guide"

Poniższe zmiany nie zostaną zaakceptowane — nie dlatego, że są złe, ale dlatego, że wykraczają poza scope projektu:

  • Web dashboard — ksefnik to SDK dla deweloperów, nie aplikacja z UI
  • Integracje z Google Drive / storage — nie rozwiązujemy problemu przechowywania plików
  • Wszystkie 87 reguł walidacji KSeF — implementujemy top 20 o największym znaczeniu biznesowym
  • Migracja na Turborepo — overkill dla 5-6 pakietów, pnpm workspace wystarcza

Pluginy to najlepszy sposób na rozszerzenie ksefnik bez modyfikacji core. Każdy plugin implementuje interfejs KsefPlugin z @ksefnik/shared:

import type { KsefPlugin, ReconciliationPass } from '@ksefnik/shared'
const myPlugin: KsefPlugin = {
name: '@my-org/ksefnik-custom-pass',
version: '1.0.0',
reconciliationPasses: [
{
name: 'payment-pattern-match',
order: 650, // Pluginy: order 600+
async execute(invoices, transactions, existingMatches) {
// Twoja logika dopasowania
return newMatches
},
},
],
}
export default myPlugin
  • Order >= 600 — passy core mają order 100-500. Pluginy uruchamiają się po nich, nigdy nie zastępują wbudowanych passów.
  • Zero DRM — model “plugin by absence” oznacza, że brak pakietu = darmowa wersja. Nie dodawaj sprawdzania licencji ani phone-home.
  • Osobne repozytorium — pluginy żyją poza monorepo ksefnik. Publikujesz je jako osobne pakiety npm.