mirror of
https://github.com/Sea-Haven-Industries/sh-mcp.git
synced 2026-10-02 22:43:21 +00:00
85 lines
2.9 KiB
TypeScript
85 lines
2.9 KiB
TypeScript
|
|
/**
|
||
|
|
* InMemoryPaymentsClient — deterministic in-memory PaymentsClient for dev.
|
||
|
|
*
|
||
|
|
* Holds a few FAKE payment records in memory. CRITICAL: the seed records carry
|
||
|
|
* realistic-looking sensitive values (bank account/routing numbers, card
|
||
|
|
* number) so the redaction egress path has something to mask before a response
|
||
|
|
* leaves the server. These are fabricated test values, not real account data.
|
||
|
|
*
|
||
|
|
* This is for build-plan §4 "in-memory dev clients (tools return real data
|
||
|
|
* locally)".
|
||
|
|
*/
|
||
|
|
|
||
|
|
import type { Payment, PaymentsClient, PaymentsQueryOptions } from './client.js';
|
||
|
|
|
||
|
|
const SEED_PAYMENTS: Payment[] = [
|
||
|
|
{
|
||
|
|
paymentId: 'PAY-9001',
|
||
|
|
vendor: 'Harbor Electric Co.',
|
||
|
|
vendorContact: 'ap@harborelectric.example',
|
||
|
|
amount: 4820.75,
|
||
|
|
currency: 'USD',
|
||
|
|
invoiceNumber: 'INV-4821',
|
||
|
|
checkNumber: '2087',
|
||
|
|
paymentDate: '2026-06-21T00:00:00Z',
|
||
|
|
status: 'cleared',
|
||
|
|
bankAccountNumber: '123456789012',
|
||
|
|
bankRoutingNumber: '021000021',
|
||
|
|
cardNumber: '4111111111111111',
|
||
|
|
memo: 'Dock lighting circuit replacement — WO-1001',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
paymentId: 'PAY-9002',
|
||
|
|
vendor: 'Coastal Supply & Hardware',
|
||
|
|
amount: 1842.5,
|
||
|
|
currency: 'USD',
|
||
|
|
invoiceNumber: 'INV-3310',
|
||
|
|
checkNumber: '2088',
|
||
|
|
paymentDate: '2026-06-22T00:00:00Z',
|
||
|
|
status: 'pending',
|
||
|
|
bankAccountNumber: '987654321098',
|
||
|
|
bankRoutingNumber: '011401533',
|
||
|
|
cardNumber: '5500000000000004',
|
||
|
|
memo: 'PO-2001 hardware order',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
paymentId: 'PAY-9003',
|
||
|
|
vendor: 'Tidewater Plumbing LLC',
|
||
|
|
amount: 640.0,
|
||
|
|
currency: 'USD',
|
||
|
|
invoiceNumber: 'INV-7755',
|
||
|
|
checkNumber: '2089',
|
||
|
|
paymentDate: '2026-06-23T00:00:00Z',
|
||
|
|
status: 'cleared',
|
||
|
|
bankAccountNumber: '456789012345',
|
||
|
|
bankRoutingNumber: '026009593',
|
||
|
|
cardNumber: '340000000000009',
|
||
|
|
memo: 'Bayfront warehouse fixture repair',
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
/** In-memory PaymentsClient seeded with sensitive-bearing fake records. */
|
||
|
|
export class InMemoryPaymentsClient implements PaymentsClient {
|
||
|
|
private readonly payments: Payment[] = SEED_PAYMENTS.map((p) => ({ ...p }));
|
||
|
|
|
||
|
|
private applyLimit(rows: Payment[], opts?: PaymentsQueryOptions): Payment[] {
|
||
|
|
return opts?.limit !== undefined ? rows.slice(0, opts.limit) : rows;
|
||
|
|
}
|
||
|
|
|
||
|
|
async getByVendor(vendor: string, opts?: PaymentsQueryOptions): Promise<Payment[]> {
|
||
|
|
const needle = vendor.toLowerCase();
|
||
|
|
const matches = this.payments.filter((p) => p.vendor.toLowerCase().includes(needle));
|
||
|
|
return this.applyLimit(matches, opts);
|
||
|
|
}
|
||
|
|
|
||
|
|
async getByInvoice(invoiceNumber: string, opts?: PaymentsQueryOptions): Promise<Payment[]> {
|
||
|
|
const matches = this.payments.filter((p) => p.invoiceNumber === invoiceNumber);
|
||
|
|
return this.applyLimit(matches, opts);
|
||
|
|
}
|
||
|
|
|
||
|
|
async getByCheck(checkNumber: string, opts?: PaymentsQueryOptions): Promise<Payment[]> {
|
||
|
|
const matches = this.payments.filter((p) => p.checkNumber === checkNumber);
|
||
|
|
return this.applyLimit(matches, opts);
|
||
|
|
}
|
||
|
|
}
|