mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Add API endpoint to get site usage summary
Summary: The summary includes a count of documents that are approaching limits, in grace period, or delete-only. The endpoint is only accessible to site owners, and is currently unused. A follow-up diff will add usage banners to the site home page, which will use the response from the endpoint to communicate usage information to owners. Test Plan: Browser and server tests. Reviewers: alexmojaki Reviewed By: alexmojaki Differential Revision: https://phab.getgrist.com/D3420
This commit is contained in:
74
app/common/DocLimits.ts
Normal file
74
app/common/DocLimits.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import {ApiError} from 'app/common/ApiError';
|
||||
import {APPROACHING_LIMIT_RATIO, DataLimitStatus, DocumentUsage, getUsageRatio} from 'app/common/DocUsage';
|
||||
import {Features} from 'app/common/Features';
|
||||
import * as moment from 'moment-timezone';
|
||||
|
||||
/**
|
||||
* Error class indicating failure due to limits being exceeded.
|
||||
*/
|
||||
export class LimitExceededError extends ApiError {
|
||||
constructor(message: string) {
|
||||
super(message, 413);
|
||||
}
|
||||
}
|
||||
|
||||
export interface GetDataLimitStatusParams {
|
||||
docUsage: DocumentUsage | null;
|
||||
productFeatures: Features | undefined;
|
||||
gracePeriodStart: Date | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a set of params that includes document usage, current product features, and
|
||||
* a grace-period start (if any), returns the data limit status of a document.
|
||||
*/
|
||||
export function getDataLimitStatus(params: GetDataLimitStatusParams): DataLimitStatus {
|
||||
const {docUsage, productFeatures, gracePeriodStart} = params;
|
||||
const ratio = getDataLimitRatio(docUsage, productFeatures);
|
||||
if (ratio > 1) {
|
||||
const start = gracePeriodStart;
|
||||
const days = productFeatures?.gracePeriodDays;
|
||||
if (start && days && moment().diff(moment(start), 'days') >= days) {
|
||||
return 'deleteOnly';
|
||||
} else {
|
||||
return 'gracePeriod';
|
||||
}
|
||||
} else if (ratio > APPROACHING_LIMIT_RATIO) {
|
||||
return 'approachingLimit';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given `docUsage` and `productFeatures`, returns the highest usage ratio
|
||||
* across all data-related limits (currently only row count and data size).
|
||||
*/
|
||||
export function getDataLimitRatio(
|
||||
docUsage: DocumentUsage | null,
|
||||
productFeatures: Features | undefined
|
||||
): number {
|
||||
if (!docUsage) { return 0; }
|
||||
|
||||
const {rowCount, dataSizeBytes} = docUsage;
|
||||
const maxRows = productFeatures?.baseMaxRowsPerDocument;
|
||||
const maxDataSize = productFeatures?.baseMaxDataSizePerDocument;
|
||||
const rowRatio = getUsageRatio(rowCount, maxRows);
|
||||
const dataSizeRatio = getUsageRatio(dataSizeBytes, maxDataSize);
|
||||
return Math.max(rowRatio, dataSizeRatio);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps `dataLimitStatus` status to an integer and returns it; larger integer
|
||||
* values indicate a more "severe" status.
|
||||
*
|
||||
* Useful for relatively comparing the severity of two statuses.
|
||||
*/
|
||||
export function getSeverity(dataLimitStatus: DataLimitStatus): number {
|
||||
switch (dataLimitStatus) {
|
||||
case null: { return 0; }
|
||||
case 'approachingLimit': { return 1; }
|
||||
case 'gracePeriod': { return 2; }
|
||||
case 'deleteOnly': { return 3; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user