Przejdź do głównej zawartości

Konfiguracja storage

Ksefnik oferuje dwa typy storage: pamięciowy (domyślny) i SQLite. Storage przechowuje faktury, transakcje bankowe i raporty uzgadniania.

InMemoryStorage

Domyślny. Dane znikają po zakończeniu procesu. Idealny do testów, skryptów jednorazowych i pipeline’ów CI.

SqliteStorage

Dane zapisywane na dysku w pliku .db. Persistence między sesjami. Idealny dla biur rachunkowych i powtarzalnych procesów.

ScenariuszStorageDlaczego
Testy jednostkoweInMemoryStorageSzybki, bez efektów ubocznych
Skrypt jednorazowyInMemoryStorageNie potrzebujesz historii
CI/CD pipelineInMemoryStorageKażde uruchomienie zaczyna od zera
Biuro rachunkoweSqliteStoragePorównanie raportów miesiąc do miesiąca
Regularna reconciliationSqliteStoragePrzyrostowe uzgadnianie, bez ponownego pobierania
Praca z CLISqliteStorageStan zachowany między komendami
import { createKsefnik } from '@ksefnik/core';
// InMemoryStorage jest używany domyślnie — nie trzeba go podawać
const ksef = createKsefnik({
config: { nip: '5213456784' },
});
import { createKsefnik } from '@ksefnik/core';
import { SqliteStorage } from '@ksefnik/core/storage';
const ksef = createKsefnik({
config: { nip: '5213456784' },
storage: new SqliteStorage('./ksefnik.db'),
});

Oba typy implementują ten sam interfejs:

interface Storage {
// Faktury
saveInvoices(invoices: Invoice[]): Promise<void>;
getInvoices(filter?: InvoiceFilter): Promise<Invoice[]>;
// Transakcje bankowe
saveTransactions(transactions: BankTransaction[]): Promise<void>;
getTransactions(filter?: TransactionFilter): Promise<BankTransaction[]>;
// Raporty uzgadniania
saveReport(report: ReconciliationReport): Promise<void>;
getReport(id: string): Promise<ReconciliationReport | null>;
getReports(filter?: ReportFilter): Promise<ReconciliationReport[]>;
}
import { createKsefnik } from '@ksefnik/core';
import { SqliteStorage } from '@ksefnik/core/storage';
const ksef = createKsefnik({
config: { nip: '5213456784' },
storage: new SqliteStorage('./ksefnik.db'),
});
// Pobierz faktury i zapisz do storage
const invoices = await ksef.invoices.fetch({
from: '2026-03-01',
to: '2026-03-31',
});
await ksef.storage.saveInvoices(invoices);
// Następnego dnia — odczytaj z storage bez ponownego pobierania z KSeF
const saved = await ksef.storage.getInvoices({
from: '2026-03-01',
to: '2026-03-31',
});
console.log(`Odczytano ${saved.length} faktur z bazy`);
// Po NIP kontrahenta
const fromSupplier = await ksef.storage.getInvoices({
counterpartyNip: '7740001454',
});
// Po zakresie dat
const march = await ksef.storage.getInvoices({
from: '2026-03-01',
to: '2026-03-31',
});
// Po zakresie kwot (w groszach)
const large = await ksef.storage.getInvoices({
amountFrom: 1000000, // od 10 000,00 PLN
amountTo: 5000000, // do 50 000,00 PLN
});
// Tylko przelewy przychodzące
const incoming = await ksef.storage.getTransactions({
direction: 'incoming',
});
// Po banku źródłowym
const mbank = await ksef.storage.getTransactions({
bank: 'mbank',
});
// Po zakresie dat i kwot
const filtered = await ksef.storage.getTransactions({
from: '2026-03-01',
to: '2026-03-31',
amountFrom: 50000, // od 500,00 PLN
amountTo: 200000, // do 2 000,00 PLN
});
// Pobierz ostatni raport
const reports = await ksef.storage.getReports({
limit: 1,
orderBy: 'createdAt',
order: 'desc',
});
// Pobierz raport po ID
const report = await ksef.storage.getReport('report-2026-03-31-abc123');
if (report) {
console.log(`Match rate: ${(report.summary.matchRate * 100).toFixed(1)}%`);
}

Możesz zaimplementować interfejs Storage dla dowolnego backendu:

import type { Storage } from '@ksefnik/core/storage';
class PostgresStorage implements Storage {
constructor(private connectionString: string) {}
async saveInvoices(invoices: Invoice[]): Promise<void> {
// INSERT INTO invoices ...
}
async getInvoices(filter?: InvoiceFilter): Promise<Invoice[]> {
// SELECT * FROM invoices WHERE ...
return [];
}
// ... reszta metod
}
const ksef = createKsefnik({
config: { nip: '5213456784' },
storage: new PostgresStorage('postgresql://localhost/ksefnik'),
});

Przykład: biuro rachunkowe z persistence między sesjami

Dział zatytułowany „Przykład: biuro rachunkowe z persistence między sesjami”
  1. Skonfiguruj SqliteStorage z dedykowanym plikiem per klient:
    const storage = new SqliteStorage(`./dane/${clientNip}.db`);
  2. W poniedziałek: pobierz faktury i transakcje, uruchom reconciliation, zapisz raport.
  3. We wtorek: odczytaj raport bez ponownego pobierania — dane są w bazie.
  4. Na koniec miesiąca: porównaj raporty z marca i lutego, śledząc poprawę match rate.