tasq/node_modules/agentic-flow/dist/billing/storage/adapters.js

351 lines
10 KiB
JavaScript

/**
* Storage Adapters
* Multiple backend options: Memory, AgentDB, SQLite, PostgreSQL
*/
/**
* In-Memory Storage Adapter (for testing and development)
*/
export class MemoryStorageAdapter {
subscriptions = new Map();
usageRecords = new Map();
coupons = new Map();
invoices = new Map();
events = new Map();
// Subscriptions
async saveSubscription(subscription) {
this.subscriptions.set(subscription.id, { ...subscription });
}
async getSubscription(id) {
return this.subscriptions.get(id) || null;
}
async updateSubscription(subscription) {
this.subscriptions.set(subscription.id, { ...subscription });
}
async deleteSubscription(id) {
this.subscriptions.delete(id);
}
async listSubscriptions(userId) {
return Array.from(this.subscriptions.values()).filter(s => s.userId === userId);
}
// Usage
async saveUsageRecord(record) {
const records = this.usageRecords.get(record.subscriptionId) || [];
records.push({ ...record });
this.usageRecords.set(record.subscriptionId, records);
}
async getUsageRecords(subscriptionId, period) {
const records = this.usageRecords.get(subscriptionId) || [];
return records.filter(r => r.billingPeriod === period);
}
// Coupons
async saveCoupon(coupon) {
this.coupons.set(coupon.code, { ...coupon });
}
async getCoupon(code) {
return this.coupons.get(code) || null;
}
async updateCoupon(coupon) {
this.coupons.set(coupon.code, { ...coupon });
}
async listCoupons() {
return Array.from(this.coupons.values());
}
// Invoices
async saveInvoice(invoice) {
this.invoices.set(invoice.id, { ...invoice });
}
async getInvoice(id) {
return this.invoices.get(id) || null;
}
async listInvoices(userId) {
return Array.from(this.invoices.values()).filter(i => i.userId === userId);
}
// Events
async saveEvent(event) {
const events = this.events.get(event.userId) || [];
events.push({ ...event });
this.events.set(event.userId, events);
}
async getEvents(userId, type) {
const events = this.events.get(userId) || [];
if (type) {
return events.filter(e => e.type === type);
}
return events;
}
// Utility
clear() {
this.subscriptions.clear();
this.usageRecords.clear();
this.coupons.clear();
this.invoices.clear();
this.events.clear();
}
}
/**
* AgentDB Storage Adapter (vector database with semantic search)
*/
export class AgentDBStorageAdapter {
db; // AgentDB instance
collections = {
subscriptions: 'billing_subscriptions',
usage: 'billing_usage',
coupons: 'billing_coupons',
invoices: 'billing_invoices',
events: 'billing_events'
};
constructor(agentDB) {
this.db = agentDB;
}
async initialize() {
// Create collections if they don't exist
for (const collection of Object.values(this.collections)) {
try {
await this.db.createCollection(collection);
}
catch (error) {
// Collection might already exist
}
}
}
// Subscriptions
async saveSubscription(subscription) {
await this.db.upsert(this.collections.subscriptions, {
id: subscription.id,
data: subscription,
metadata: {
userId: subscription.userId,
tier: subscription.tier,
status: subscription.status
}
});
}
async getSubscription(id) {
const result = await this.db.get(this.collections.subscriptions, id);
return result?.data || null;
}
async updateSubscription(subscription) {
await this.saveSubscription(subscription);
}
async deleteSubscription(id) {
await this.db.delete(this.collections.subscriptions, id);
}
async listSubscriptions(userId) {
const results = await this.db.query(this.collections.subscriptions, {
filter: { userId }
});
return results.map((r) => r.data);
}
// Usage
async saveUsageRecord(record) {
await this.db.insert(this.collections.usage, {
id: record.id,
data: record,
metadata: {
subscriptionId: record.subscriptionId,
metric: record.metric,
period: record.billingPeriod
}
});
}
async getUsageRecords(subscriptionId, period) {
const results = await this.db.query(this.collections.usage, {
filter: {
subscriptionId,
'metadata.period': period
}
});
return results.map((r) => r.data);
}
// Coupons
async saveCoupon(coupon) {
await this.db.upsert(this.collections.coupons, {
id: coupon.code,
data: coupon,
metadata: {
type: coupon.type,
active: coupon.active
}
});
}
async getCoupon(code) {
const result = await this.db.get(this.collections.coupons, code);
return result?.data || null;
}
async updateCoupon(coupon) {
await this.saveCoupon(coupon);
}
async listCoupons() {
const results = await this.db.query(this.collections.coupons, {});
return results.map((r) => r.data);
}
// Invoices
async saveInvoice(invoice) {
await this.db.insert(this.collections.invoices, {
id: invoice.id,
data: invoice,
metadata: {
userId: invoice.userId,
status: invoice.status,
amount: invoice.amount
}
});
}
async getInvoice(id) {
const result = await this.db.get(this.collections.invoices, id);
return result?.data || null;
}
async listInvoices(userId) {
const results = await this.db.query(this.collections.invoices, {
filter: { userId }
});
return results.map((r) => r.data);
}
// Events
async saveEvent(event) {
await this.db.insert(this.collections.events, {
id: event.id,
data: event,
metadata: {
userId: event.userId,
type: event.type,
timestamp: event.timestamp
}
});
}
async getEvents(userId, type) {
const filter = { userId };
if (type) {
filter['metadata.type'] = type;
}
const results = await this.db.query(this.collections.events, { filter });
return results.map((r) => r.data);
}
}
/**
* SQLite Storage Adapter
*/
export class SQLiteStorageAdapter {
db; // better-sqlite3 instance
constructor(dbPath) {
// In production, initialize better-sqlite3
// For now, stub implementation
}
async initialize() {
// Create tables
const schema = `
CREATE TABLE IF NOT EXISTS subscriptions (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
data TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS usage_records (
id TEXT PRIMARY KEY,
subscription_id TEXT NOT NULL,
data TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS coupons (
code TEXT PRIMARY KEY,
data TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS invoices (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
data TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS events (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
type TEXT NOT NULL,
data TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
`;
// Execute schema in production
}
// Implement StorageAdapter interface methods
// (Similar to MemoryStorageAdapter but with SQL queries)
async saveSubscription(subscription) {
// SQL: INSERT OR REPLACE INTO subscriptions ...
}
async getSubscription(id) {
// SQL: SELECT * FROM subscriptions WHERE id = ?
return null;
}
async updateSubscription(subscription) {
await this.saveSubscription(subscription);
}
async deleteSubscription(id) {
// SQL: DELETE FROM subscriptions WHERE id = ?
}
async listSubscriptions(userId) {
// SQL: SELECT * FROM subscriptions WHERE user_id = ?
return [];
}
async saveUsageRecord(record) {
// SQL: INSERT INTO usage_records ...
}
async getUsageRecords(subscriptionId, period) {
// SQL: SELECT * FROM usage_records WHERE subscription_id = ?
return [];
}
async saveCoupon(coupon) {
// SQL: INSERT OR REPLACE INTO coupons ...
}
async getCoupon(code) {
// SQL: SELECT * FROM coupons WHERE code = ?
return null;
}
async updateCoupon(coupon) {
await this.saveCoupon(coupon);
}
async listCoupons() {
// SQL: SELECT * FROM coupons
return [];
}
async saveInvoice(invoice) {
// SQL: INSERT INTO invoices ...
}
async getInvoice(id) {
// SQL: SELECT * FROM invoices WHERE id = ?
return null;
}
async listInvoices(userId) {
// SQL: SELECT * FROM invoices WHERE user_id = ?
return [];
}
async saveEvent(event) {
// SQL: INSERT INTO events ...
}
async getEvents(userId, type) {
// SQL: SELECT * FROM events WHERE user_id = ?
return [];
}
}
/**
* Storage Adapter Factory
*/
export class StorageAdapterFactory {
static createMemory() {
return new MemoryStorageAdapter();
}
static createAgentDB(agentDB) {
const adapter = new AgentDBStorageAdapter(agentDB);
adapter.initialize();
return adapter;
}
static createSQLite(dbPath) {
const adapter = new SQLiteStorageAdapter(dbPath);
adapter.initialize();
return adapter;
}
}
//# sourceMappingURL=adapters.js.map