mirror of
https://github.com/Sea-Haven-Industries/sh-mcp.git
synced 2026-10-02 17:43:16 +00:00
64 lines
1.7 KiB
TypeScript
64 lines
1.7 KiB
TypeScript
|
|
/**
|
||
|
|
* InMemoryQboClient — deterministic in-memory QboClientInterface for dev.
|
||
|
|
*
|
||
|
|
* Holds a few FAKE QBO vendor records in memory. Each carries a fabricated
|
||
|
|
* taxId so the redaction egress path has a sensitive target to mask before a
|
||
|
|
* response leaves the server. Filters by case-insensitive substring on
|
||
|
|
* displayName and respects maxResults. No OAuth, no network.
|
||
|
|
*
|
||
|
|
* This is for build-plan §4 "in-memory dev clients (tools return real data
|
||
|
|
* locally)".
|
||
|
|
*/
|
||
|
|
|
||
|
|
import type {
|
||
|
|
QboClientInterface,
|
||
|
|
QboVendor,
|
||
|
|
SearchVendorsParams,
|
||
|
|
SearchVendorsResult,
|
||
|
|
} from './client.js';
|
||
|
|
|
||
|
|
const SEED_VENDORS: QboVendor[] = [
|
||
|
|
{
|
||
|
|
id: '101',
|
||
|
|
displayName: 'Harbor Electric Co.',
|
||
|
|
email: 'ap@harborelectric.example',
|
||
|
|
phone: '(631) 555-0142',
|
||
|
|
active: true,
|
||
|
|
balance: 0,
|
||
|
|
taxId: '12-3456789',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: '102',
|
||
|
|
displayName: 'Coastal Supply & Hardware',
|
||
|
|
email: 'billing@coastalsupply.example',
|
||
|
|
phone: '(631) 555-0188',
|
||
|
|
active: true,
|
||
|
|
balance: 1842.5,
|
||
|
|
taxId: '98-7654321',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: '103',
|
||
|
|
displayName: 'Tidewater Plumbing LLC',
|
||
|
|
phone: '(631) 555-0123',
|
||
|
|
active: false,
|
||
|
|
balance: 0,
|
||
|
|
taxId: '45-6789012',
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
/** In-memory QboClientInterface seeded with fake vendors (taxId populated). */
|
||
|
|
export class InMemoryQboClient implements QboClientInterface {
|
||
|
|
async searchVendors(params: SearchVendorsParams): Promise<SearchVendorsResult> {
|
||
|
|
const needle = params.query.trim().toLowerCase();
|
||
|
|
const matched =
|
||
|
|
needle.length === 0
|
||
|
|
? SEED_VENDORS
|
||
|
|
: SEED_VENDORS.filter((v) => v.displayName.toLowerCase().includes(needle));
|
||
|
|
const limit = params.maxResults ?? 20;
|
||
|
|
return {
|
||
|
|
vendors: matched.slice(0, limit),
|
||
|
|
totalCount: matched.length,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|