Initial import of verae-middleware from zapier monorepo
This commit is contained in:
commit
c6f7d93bbb
66 changed files with 6590 additions and 0 deletions
137
src/store/tenants.js
Normal file
137
src/store/tenants.js
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
* @fileoverview Tenant and API key persistence.
|
||||
* @module store/tenants
|
||||
*/
|
||||
|
||||
import { getStore, persist } from './db.js';
|
||||
import { generateApiKey } from '../lib/tokens.js';
|
||||
import { PLAN_LIMITS } from '../config.js';
|
||||
import { createDebugger } from '../debug/logger.js';
|
||||
|
||||
const log = createDebugger('billing');
|
||||
|
||||
/**
|
||||
* @typedef {Object} Tenant
|
||||
* @property {string} id
|
||||
* @property {string} name
|
||||
* @property {string} plan
|
||||
* @property {string} veraeUsername
|
||||
* @property {string} veraePassword
|
||||
* @property {object|null} contract
|
||||
* @property {object} [metadata]
|
||||
* @property {string} createdAt
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string} tenantId
|
||||
* @returns {Tenant|null}
|
||||
*/
|
||||
export function getTenant(tenantId) {
|
||||
return getStore().tenants[tenantId] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} apiKey
|
||||
* @returns {Tenant|null}
|
||||
*/
|
||||
export function getTenantByApiKey(apiKey) {
|
||||
const store = getStore();
|
||||
const tenantId = store.apiKeys[apiKey];
|
||||
return tenantId ? store.tenants[tenantId] ?? null : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Tenant[]}
|
||||
*/
|
||||
export function listTenants() {
|
||||
return Object.values(getStore().tenants);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Tenant} tenant
|
||||
* @returns {Tenant}
|
||||
*/
|
||||
export function upsertTenant(tenant) {
|
||||
const store = getStore();
|
||||
store.tenants[tenant.id] = tenant;
|
||||
persist();
|
||||
log.debug('tenant upserted', { tenantId: tenant.id, plan: tenant.plan });
|
||||
return tenant;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a tenant and bind a new API key.
|
||||
*
|
||||
* @param {object} params
|
||||
* @param {string} params.id
|
||||
* @param {string} params.name
|
||||
* @param {string} [params.plan='free']
|
||||
* @param {string} params.veraeUsername
|
||||
* @param {string} params.veraePassword
|
||||
* @param {object|null} [params.contract=null]
|
||||
* @param {string} [params.apiKey]
|
||||
* @param {object} [params.metadata]
|
||||
* @returns {{ tenant: Tenant, apiKey: string }}
|
||||
*/
|
||||
export function createTenant({
|
||||
id,
|
||||
name,
|
||||
plan = 'free',
|
||||
veraeUsername,
|
||||
veraePassword,
|
||||
contract = null,
|
||||
apiKey = generateApiKey(),
|
||||
metadata = {},
|
||||
}) {
|
||||
const store = getStore();
|
||||
/** @type {Tenant} */
|
||||
const tenant = {
|
||||
id,
|
||||
name,
|
||||
plan,
|
||||
veraeUsername,
|
||||
veraePassword,
|
||||
contract,
|
||||
metadata,
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
|
||||
store.tenants[id] = tenant;
|
||||
store.apiKeys[apiKey] = id;
|
||||
persist();
|
||||
|
||||
log.info('tenant created', { tenantId: id, plan, audience: metadata.audience });
|
||||
return { tenant, apiKey };
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve effective limits for a tenant (plan defaults or enterprise contract).
|
||||
*
|
||||
* @param {Tenant} tenant
|
||||
* @returns {{
|
||||
* timestamps: number|null,
|
||||
* verifications: number|null,
|
||||
* batch: boolean,
|
||||
* batchMaxItems: number|null,
|
||||
* requestsPerMinute: number,
|
||||
* allowOverage: boolean,
|
||||
* overageRates: object
|
||||
* }}
|
||||
*/
|
||||
export function resolveLimits(tenant) {
|
||||
if (tenant.plan === 'enterprise' && tenant.contract) {
|
||||
return {
|
||||
timestamps: tenant.contract.includedTimestamps ?? null,
|
||||
verifications: tenant.contract.includedVerifications ?? null,
|
||||
batch: tenant.contract.batch !== false,
|
||||
batchMaxItems: tenant.contract.batchMaxItems ?? null,
|
||||
requestsPerMinute:
|
||||
tenant.contract.requestsPerMinute ?? PLAN_LIMITS.enterprise.requestsPerMinute,
|
||||
allowOverage: tenant.contract.allowOverage ?? false,
|
||||
overageRates: tenant.contract.overageRates ?? {},
|
||||
};
|
||||
}
|
||||
|
||||
const base = PLAN_LIMITS[tenant.plan] ?? PLAN_LIMITS.free;
|
||||
return { ...base, allowOverage: false, overageRates: {} };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue