Initial import of verae-middleware from zapier monorepo
This commit is contained in:
commit
16c439bb7b
67 changed files with 6630 additions and 0 deletions
102
src/store/usage.js
Normal file
102
src/store/usage.js
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* @fileoverview Per-tenant usage metering counters.
|
||||
* @module store/usage
|
||||
*/
|
||||
|
||||
import { getStore, persist } from './db.js';
|
||||
import { getTenant, resolveLimits } from './tenants.js';
|
||||
import { createDebugger } from '../debug/logger.js';
|
||||
|
||||
const log = createDebugger('billing');
|
||||
|
||||
/**
|
||||
* @returns {string} YYYY-MM period key
|
||||
*/
|
||||
function currentPeriod() {
|
||||
const d = new Date();
|
||||
return `${d.getUTCFullYear()}-${String(d.getUTCMonth() + 1).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} tenantId
|
||||
* @returns {{ period: string, timestamps: number, verifications: number, statusChecks: number, batchTimestamps: number, overage: object }}
|
||||
*/
|
||||
function emptyUsage(tenantId) {
|
||||
return {
|
||||
tenantId,
|
||||
period: currentPeriod(),
|
||||
timestamps: 0,
|
||||
verifications: 0,
|
||||
statusChecks: 0,
|
||||
batchTimestamps: 0,
|
||||
overage: { timestamps: 0, verifications: 0 },
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get usage for tenant, rolling period if month changed.
|
||||
* @param {string} tenantId
|
||||
* @returns {ReturnType<typeof emptyUsage>}
|
||||
*/
|
||||
export function getUsage(tenantId) {
|
||||
const store = getStore();
|
||||
let usage = store.usage[tenantId];
|
||||
const period = currentPeriod();
|
||||
|
||||
if (!usage || usage.period !== period) {
|
||||
usage = emptyUsage(tenantId);
|
||||
store.usage[tenantId] = usage;
|
||||
}
|
||||
|
||||
return usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public summary for /auth/me.
|
||||
* @param {string} tenantId
|
||||
* @returns {object}
|
||||
*/
|
||||
export function getUsageSummary(tenantId) {
|
||||
const usage = getUsage(tenantId);
|
||||
const tenant = getTenant(tenantId);
|
||||
const limits = tenant ? resolveLimits(tenant) : null;
|
||||
|
||||
return {
|
||||
period: usage.period,
|
||||
timestamps: usage.timestamps,
|
||||
verifications: usage.verifications,
|
||||
statusChecks: usage.statusChecks,
|
||||
batchTimestamps: usage.batchTimestamps,
|
||||
limits: limits
|
||||
? {
|
||||
timestamps: limits.timestamps,
|
||||
verifications: limits.verifications,
|
||||
batch: limits.batch,
|
||||
batchMaxItems: limits.batchMaxItems,
|
||||
}
|
||||
: null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment a usage metric.
|
||||
*
|
||||
* @param {string} tenantId
|
||||
* @param {string} metric - e.g. `timestamps`, `verifications`, `statusChecks`, `batchTimestamps`, `overage.timestamps`
|
||||
* @param {number} [amount=1]
|
||||
* @returns {void}
|
||||
*/
|
||||
export function incrementUsage(tenantId, metric, amount = 1) {
|
||||
const usage = getUsage(tenantId);
|
||||
|
||||
if (metric.startsWith('overage.')) {
|
||||
const key = metric.slice('overage.'.length);
|
||||
usage.overage[key] = (usage.overage[key] ?? 0) + amount;
|
||||
} else {
|
||||
usage[metric] = (usage[metric] ?? 0) + amount;
|
||||
}
|
||||
|
||||
getStore().usage[tenantId] = usage;
|
||||
persist();
|
||||
log.debug('usage incremented', { tenantId, metric, amount, value: usage[metric] ?? usage.overage });
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue