mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-23 07:42:10 +00:00
hard delete tiems in the database
This commit is contained in:
parent
b0f4083297
commit
d7c8edd598
@ -79,6 +79,26 @@ class DatabaseService<TBaseModel extends BaseModel> {
|
||||
private model!: TBaseModel;
|
||||
private modelName!: string;
|
||||
|
||||
|
||||
private _hardDeleteItemByColumnName : string = '';
|
||||
public get hardDeleteItemByColumnName() : string {
|
||||
return this._hardDeleteItemByColumnName;
|
||||
}
|
||||
public set hardDeleteItemByColumnName(v : string) {
|
||||
this._hardDeleteItemByColumnName = v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private _hardDeleteItemsOlderThanDays : number = 0;
|
||||
public get hardDeleteItemsOlderThanDays() : number {
|
||||
return this._hardDeleteItemsOlderThanDays;
|
||||
}
|
||||
public set hardDeleteItemsOlderThanDays(v : number) {
|
||||
this._hardDeleteItemsOlderThanDays = v;
|
||||
}
|
||||
|
||||
|
||||
public constructor(
|
||||
modelType: { new (): TBaseModel },
|
||||
postgresDatabase?: PostgresDatabase
|
||||
@ -92,6 +112,11 @@ class DatabaseService<TBaseModel extends BaseModel> {
|
||||
}
|
||||
}
|
||||
|
||||
public hardDeleteItemsOlderThanInDays(columnName: string, olderThan: number) {
|
||||
this.hardDeleteItemByColumnName = columnName;
|
||||
this.hardDeleteItemsOlderThanDays = olderThan;
|
||||
}
|
||||
|
||||
public getModel(): TBaseModel {
|
||||
return this.model;
|
||||
}
|
||||
|
@ -68,6 +68,9 @@ import WorkflowService from './WorkflowService';
|
||||
import WorkflowVariablesService from './WorkflowVariableService';
|
||||
import WorkflowLogService from './WorkflowLogService';
|
||||
|
||||
// SMS Log Servce
|
||||
import SmsLogService from './SmsLogService';
|
||||
|
||||
export default [
|
||||
UserService,
|
||||
ProbeService,
|
||||
@ -118,4 +121,6 @@ export default [
|
||||
WorkflowService,
|
||||
WorkflowVariablesService,
|
||||
WorkflowLogService,
|
||||
|
||||
SmsLogService
|
||||
];
|
||||
|
@ -5,6 +5,7 @@ import DatabaseService from './DatabaseService';
|
||||
export class Service extends DatabaseService<Model> {
|
||||
public constructor(postgresDatabase?: PostgresDatabase) {
|
||||
super(Model, postgresDatabase);
|
||||
this.hardDeleteItemsOlderThanInDays("createdAt", 30);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ const Detail: Function = (props: ComponentProps): ReactElement => {
|
||||
};
|
||||
|
||||
const getUSDCentsField: Function = (usdCents: number): ReactElement => {
|
||||
return <div>{usdCents / 100} USD</div>;
|
||||
return <div className='text-gray-900'>{usdCents / 100} USD</div>;
|
||||
};
|
||||
|
||||
const getField: Function = (field: Field, index: number): ReactElement => {
|
||||
|
@ -11,6 +11,7 @@ import PageComponentProps from '../PageComponentProps';
|
||||
import DashboardSideMenu from './SideMenu';
|
||||
import FieldType from 'CommonUI/src/Components/Types/FieldType';
|
||||
import FormFieldSchemaType from 'CommonUI/src/Components/Forms/Types/FormFieldSchemaType';
|
||||
import { BILLING_ENABLED } from 'CommonUI/src/Config';
|
||||
|
||||
const Settings: FunctionComponent<PageComponentProps> = (
|
||||
_props: PageComponentProps
|
||||
@ -41,7 +42,7 @@ const Settings: FunctionComponent<PageComponentProps> = (
|
||||
sideMenu={<DashboardSideMenu />}
|
||||
>
|
||||
{/* API Key View */}
|
||||
<CardModelDetail
|
||||
{BILLING_ENABLED ? <CardModelDetail
|
||||
name="Current Balance"
|
||||
cardProps={{
|
||||
title: 'Current Balance',
|
||||
@ -56,9 +57,9 @@ const Settings: FunctionComponent<PageComponentProps> = (
|
||||
fields: [
|
||||
{
|
||||
field: {
|
||||
smsOrCallCurrentBalanceInUSD: true,
|
||||
smsOrCallCurrentBalanceInUSDCents: true,
|
||||
},
|
||||
fieldType: FieldType.Number,
|
||||
fieldType: FieldType.USDCents,
|
||||
title: 'SMS or Call Current Balance',
|
||||
description:
|
||||
'This is your current balance for SMS or Call. It is in USD. ',
|
||||
@ -67,7 +68,7 @@ const Settings: FunctionComponent<PageComponentProps> = (
|
||||
],
|
||||
modelId: DashboardNavigation.getProjectId()?.toString(),
|
||||
}}
|
||||
/>
|
||||
/> : <></>}
|
||||
|
||||
<CardModelDetail
|
||||
name="Enable Notifications"
|
||||
@ -130,7 +131,7 @@ const Settings: FunctionComponent<PageComponentProps> = (
|
||||
}}
|
||||
/>
|
||||
|
||||
<CardModelDetail
|
||||
{BILLING_ENABLED ? <CardModelDetail
|
||||
name="Auto Recharge"
|
||||
cardProps={{
|
||||
title: 'Auto Recharge',
|
||||
@ -291,7 +292,7 @@ const Settings: FunctionComponent<PageComponentProps> = (
|
||||
],
|
||||
modelId: DashboardNavigation.getProjectId()?.toString(),
|
||||
}}
|
||||
/>
|
||||
/> : <></>}
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
@ -155,12 +155,12 @@ const DashboardSideMenu: FunctionComponent = (): ReactElement => {
|
||||
/>
|
||||
<SideMenuItem
|
||||
link={{
|
||||
title: 'Call and SMS',
|
||||
title: 'Notification Settings',
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.SETTINGS_CALL_SMS] as Route
|
||||
),
|
||||
}}
|
||||
icon={IconProp.Call}
|
||||
icon={IconProp.Settings}
|
||||
/>
|
||||
<SideMenuItem
|
||||
link={{
|
||||
|
@ -16,6 +16,9 @@ import Page from 'CommonUI/src/Components/Page/Page';
|
||||
import Pill from 'CommonUI/src/Components/Pill/Pill';
|
||||
import SmsStatus from 'Common/Types/SmsStatus';
|
||||
import { Green, Red } from 'Common/Types/BrandColors';
|
||||
import { BILLING_ENABLED } from 'CommonUI/src/Config';
|
||||
import Column from 'CommonUI/src/Components/ModelTable/Column';
|
||||
import Columns from 'CommonUI/src/Components/ModelTable/Columns';
|
||||
|
||||
const SMSLogs: FunctionComponent<PageComponentProps> = (
|
||||
_props: PageComponentProps
|
||||
@ -26,6 +29,70 @@ const SMSLogs: FunctionComponent<PageComponentProps> = (
|
||||
const [smsModelTitle, setSmsModalTitle] = useState<string>('');
|
||||
const [smsModelDescription, setSmsModalDescription] = useState<string>('');
|
||||
|
||||
|
||||
const modelTableColumns: Columns<SmsLog> = [{
|
||||
field: {
|
||||
_id: true,
|
||||
},
|
||||
title: 'Log ID',
|
||||
type: FieldType.Text,
|
||||
isFilterable: true,
|
||||
},
|
||||
{
|
||||
field: {
|
||||
toNumber: true,
|
||||
},
|
||||
isFilterable: true,
|
||||
|
||||
title: 'To Number',
|
||||
type: FieldType.Phone,
|
||||
},
|
||||
{
|
||||
field: {
|
||||
createdAt: true,
|
||||
},
|
||||
title: 'Sent at',
|
||||
type: FieldType.DateTime,
|
||||
isFilterable: true,
|
||||
},
|
||||
|
||||
{
|
||||
field: {
|
||||
status: true,
|
||||
},
|
||||
title: 'Status',
|
||||
type: FieldType.Text,
|
||||
getElement: (item: JSONObject): ReactElement => {
|
||||
if (item['status']) {
|
||||
return (
|
||||
<Pill
|
||||
isMinimal={false}
|
||||
color={
|
||||
item['status'] ===
|
||||
SmsStatus.Success
|
||||
? Green
|
||||
: Red
|
||||
}
|
||||
text={item['status'] as string}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <></>;
|
||||
},
|
||||
isFilterable: true,
|
||||
}];
|
||||
|
||||
if(BILLING_ENABLED){
|
||||
modelTableColumns.push({
|
||||
field: {
|
||||
smsCostInUSDCents: true,
|
||||
},
|
||||
title: 'SMS Cost',
|
||||
type: FieldType.USDCents,
|
||||
} as Column<SmsLog>);
|
||||
}
|
||||
|
||||
return (
|
||||
<Page
|
||||
title={'Project Settings'}
|
||||
@ -117,66 +184,7 @@ const SMSLogs: FunctionComponent<PageComponentProps> = (
|
||||
}
|
||||
showRefreshButton={true}
|
||||
showFilterButton={true}
|
||||
columns={[
|
||||
{
|
||||
field: {
|
||||
_id: true,
|
||||
},
|
||||
title: 'Log ID',
|
||||
type: FieldType.Text,
|
||||
isFilterable: true,
|
||||
},
|
||||
{
|
||||
field: {
|
||||
toNumber: true,
|
||||
},
|
||||
isFilterable: true,
|
||||
|
||||
title: 'To Number',
|
||||
type: FieldType.Phone,
|
||||
},
|
||||
{
|
||||
field: {
|
||||
createdAt: true,
|
||||
},
|
||||
title: 'Sent at',
|
||||
type: FieldType.DateTime,
|
||||
isFilterable: true,
|
||||
},
|
||||
{
|
||||
field: {
|
||||
smsCostInUSDCents: true,
|
||||
},
|
||||
title: 'SMS Cost',
|
||||
type: FieldType.USDCents,
|
||||
},
|
||||
{
|
||||
field: {
|
||||
status: true,
|
||||
},
|
||||
title: 'Status',
|
||||
type: FieldType.Text,
|
||||
getElement: (item: JSONObject): ReactElement => {
|
||||
if (item['status']) {
|
||||
return (
|
||||
<Pill
|
||||
isMinimal={false}
|
||||
color={
|
||||
item['status'] ===
|
||||
SmsStatus.Success
|
||||
? Green
|
||||
: Red
|
||||
}
|
||||
text={item['status'] as string}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <></>;
|
||||
},
|
||||
isFilterable: true,
|
||||
},
|
||||
]}
|
||||
columns={modelTableColumns}
|
||||
/>
|
||||
|
||||
{showViewSmsTextModal && (
|
||||
|
@ -155,6 +155,7 @@ export default class SmsService {
|
||||
});
|
||||
}
|
||||
} catch (e: any) {
|
||||
smsLog.smsCostInUSDCents = 0;
|
||||
smsLog.status = SmsStatus.Error;
|
||||
smsLog.statusMessage =
|
||||
e && e.message ? e.message.toString() : e.toString();
|
||||
|
@ -35,3 +35,41 @@ RunCron(
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
RunCron(
|
||||
'HardDelete:HardDeleteOlderItemsInDatabase',
|
||||
{ schedule: IsDevelopment ? EVERY_MINUTE : EVERY_DAY, runOnStartup: false },
|
||||
async () => {
|
||||
for (const service of Services) {
|
||||
if (service instanceof DatabaseService) {
|
||||
|
||||
if(!service.hardDeleteItemByColumnName || !service.hardDeleteItemsOlderThanDays) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// Retain data for 30 days for accidental deletion, and then hard delete.
|
||||
await service.hardDeleteBy({
|
||||
query: {
|
||||
[service.hardDeleteItemByColumnName]: QueryHelper.lessThan(
|
||||
OneUptimeDate.getSomeDaysAgo(service.hardDeleteItemsOlderThanDays)
|
||||
),
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
limit: LIMIT_MAX,
|
||||
skip: 0,
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user