From fintech-pro
Payments, compliance, auditing, reconciliation, fraud detection, ledger. Use when building or reviewing financial technology systems.
How this skill is triggered — by the user, by Claude, or both
Slash command
/fintech-pro:fintech-proThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Build production financial systems: payment processing, double-entry ledger, compliance (KYC/AML), reconciliation, fraud detection, and audit trails.
Build production financial systems: payment processing, double-entry ledger, compliance (KYC/AML), reconciliation, fraud detection, and audit trails.
Use this when:
Use this ESPECIALLY when:
Don't skip when:
-- Every transaction is a debit AND a credit
CREATE TABLE ledger_entries (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
transaction_id UUID NOT NULL REFERENCES transactions(id),
account_id UUID NOT NULL REFERENCES accounts(id),
entry_type TEXT NOT NULL CHECK (entry_type IN ('debit', 'credit')),
amount BIGINT NOT NULL, -- Cents (integer math, no floats)
currency TEXT NOT NULL DEFAULT 'USD',
description TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE transactions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
status TEXT NOT NULL CHECK (status IN ('pending', 'settled', 'failed', 'reversed')),
idempotency_key TEXT UNIQUE, -- Prevent double processing
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
settled_at TIMESTAMPTZ
);
CREATE INDEX idx_ledger_account ON ledger_entries(account_id, created_at DESC);
CREATE INDEX idx_ledger_transaction ON ledger_entries(transaction_id);
CREATE INDEX idx_transactions_idempotency ON transactions(idempotency_key);
async function processPayment(request: PaymentRequest): Promise<PaymentResult> {
// Idempotency check (safe retry)
const existing = await db.transactions.findUnique({
where: { idempotency_key: request.idempotencyKey }
})
if (existing) return existing // Return same result, don't re-process
// Validate
const account = await db.accounts.findUnique({ where: { id: request.accountId } })
if (account.balance < request.amount) throw AppError.badRequest('Insufficient funds')
// Process in transaction
const transaction = await db.$transaction(async (tx) => {
// Debit sender
await tx.ledgerEntries.create({
data: { account_id: senderId, entry_type: 'debit', amount: request.amount }
})
// Credit receiver
await tx.ledgerEntries.create({
data: { account_id: receiverId, entry_type: 'credit', amount: request.amount }
})
// Update balances
await tx.accounts.update({ where: { id: senderId }, data: { balance: { decrement: request.amount } } })
await tx.accounts.update({ where: { id: receiverId }, data: { balance: { increment: request.amount } } })
return tx.transactions.create({
data: { idempotency_key: request.idempotencyKey, status: 'settled' }
})
})
return transaction
}
// Compare internal records with external (bank, Stripe, etc.)
async function reconcile(date: Date): Promise<ReconciliationResult> {
const internal = await db.ledgerEntries.findMany({
where: { created_at: { gte: date, lt: addDays(date, 1) } }
})
const external = await stripe.balanceTransactions.list({ created: { gte: date.unix() } })
const differences: Difference[] = []
for (const ext of external) {
const match = internal.find(i => i.idempotency_key === ext.id)
if (!match) differences.push({ source: 'external', transaction: ext.id, amount: ext.amount })
}
if (differences.length > 0) {
await alertFinance(`Reconciliation mismatch for ${date}: ${differences.length} differences`)
}
return { date, internalCount: internal.length, externalCount: external.length, differences }
}
-- Immutable audit log (append-only)
CREATE TABLE audit_log (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
entity_type TEXT NOT NULL, -- 'account', 'transaction', 'user'
entity_id UUID NOT NULL,
action TEXT NOT NULL, -- 'created', 'updated', 'deleted', 'status_change'
changes JSONB, -- { before: {}, after: {} }
actor_id UUID NOT NULL,
ip_address INET,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- Make it immutable via trigger (no updates/deletes)
CREATE FUNCTION prevent_audit_modification() RETURNS trigger AS $$
BEGIN
RAISE EXCEPTION 'Audit log is immutable';
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_audit_immutable
BEFORE UPDATE OR DELETE ON audit_log
FOR EACH ROW EXECUTE FUNCTION prevent_audit_modification();
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
npx claudepluginhub haj1t/senior-dev-squad-skills --plugin fintech-pro