database cleanup

deepsource-autofix-76c6eb20
Dan Gowans 2022-09-19 16:09:29 -04:00
parent 8ef305f443
commit 900d91ec46
38 changed files with 967 additions and 63 deletions

View File

@ -0,0 +1,3 @@
import type { RequestHandler } from "express";
export declare const handler: RequestHandler;
export default handler;

View File

@ -0,0 +1,6 @@
export const handler = (_request, response) => {
response.render("admin-cleanup", {
headTitle: "Database Cleanup"
});
};
export default handler;

View File

@ -0,0 +1,10 @@
import type { RequestHandler } from "express";
export const handler: RequestHandler = (_request, response) => {
response.render("admin-cleanup", {
headTitle: "Database Cleanup"
});
};
export default handler;

View File

@ -0,0 +1,3 @@
import type { RequestHandler } from "express";
export declare const handler: RequestHandler;
export default handler;

View File

@ -0,0 +1,10 @@
import { cleanupDatabase } from "../../helpers/lotOccupancyDB/cleanupDatabase.js";
export const handler = async (request, response) => {
const recordCounts = cleanupDatabase(request.session);
response.json({
success: true,
inactivedRecordCount: recordCounts.inactivedRecordCount,
purgedRecordCount: recordCounts.purgedRecordCount
});
};
export default handler;

View File

@ -0,0 +1,15 @@
import type { RequestHandler } from "express";
import { cleanupDatabase } from "../../helpers/lotOccupancyDB/cleanupDatabase.js";
export const handler: RequestHandler = async (request, response) => {
const recordCounts = cleanupDatabase(request.session);
response.json({
success: true,
inactivedRecordCount: recordCounts.inactivedRecordCount,
purgedRecordCount: recordCounts.purgedRecordCount
});
};
export default handler;

View File

@ -36,4 +36,5 @@ export declare function getProperty(propertyName: "settings.workOrders.workOrder
export declare function getProperty(propertyName: "settings.workOrders.workOrderMilestoneDateRecentBeforeDays"): number; export declare function getProperty(propertyName: "settings.workOrders.workOrderMilestoneDateRecentBeforeDays"): number;
export declare function getProperty(propertyName: "settings.workOrders.workOrderMilestoneDateRecentAfterDays"): number; export declare function getProperty(propertyName: "settings.workOrders.workOrderMilestoneDateRecentAfterDays"): number;
export declare function getProperty(propertyName: "settings.workOrders.calendarEmailAddress"): string; export declare function getProperty(propertyName: "settings.workOrders.calendarEmailAddress"): string;
export declare function getProperty(propertyName: "settings.adminCleanup.recordDeleteAgeDays"): number;
export declare const keepAliveMillis: number; export declare const keepAliveMillis: number;

View File

@ -35,6 +35,7 @@ configFallbackValues.set("settings.workOrders.workOrderNumberLength", 6);
configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentBeforeDays", 5); configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentBeforeDays", 5);
configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentAfterDays", 60); configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentAfterDays", 60);
configFallbackValues.set("settings.workOrders.calendarEmailAddress", "no-reply@127.0.0.1"); configFallbackValues.set("settings.workOrders.calendarEmailAddress", "no-reply@127.0.0.1");
configFallbackValues.set("settings.adminCleanup.recordDeleteAgeDays", 60);
export function getProperty(propertyName) { export function getProperty(propertyName) {
const propertyNameSplit = propertyName.split("."); const propertyNameSplit = propertyName.split(".");
let currentObject = config; let currentObject = config;

View File

@ -55,6 +55,8 @@ configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentBefore
configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentAfterDays", 60); configFallbackValues.set("settings.workOrders.workOrderMilestoneDateRecentAfterDays", 60);
configFallbackValues.set("settings.workOrders.calendarEmailAddress", "no-reply@127.0.0.1"); configFallbackValues.set("settings.workOrders.calendarEmailAddress", "no-reply@127.0.0.1");
configFallbackValues.set("settings.adminCleanup.recordDeleteAgeDays", 60);
/* /*
* Set up function overloads * Set up function overloads
*/ */
@ -125,6 +127,8 @@ export function getProperty(
export function getProperty(propertyName: "settings.workOrders.calendarEmailAddress"): string; export function getProperty(propertyName: "settings.workOrders.calendarEmailAddress"): string;
export function getProperty(propertyName: "settings.adminCleanup.recordDeleteAgeDays"): number;
export function getProperty(propertyName: string): unknown { export function getProperty(propertyName: string): unknown {
const propertyNameSplit = propertyName.split("."); const propertyNameSplit = propertyName.split(".");

View File

@ -0,0 +1,6 @@
import type * as recordTypes from "../../types/recordTypes";
export declare const cleanupDatabase: (requestSession: recordTypes.PartialSession) => {
inactivedRecordCount: number;
purgedRecordCount: number;
};
export default cleanupDatabase;

View File

@ -0,0 +1,203 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import * as configFunctions from "../functions.config.js";
export const cleanupDatabase = (requestSession) => {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const recordDelete_timeMillisMin = rightNowMillis -
configFunctions.getProperty("settings.adminCleanup.recordDeleteAgeDays") * 86400 * 1000;
let inactivedRecordCount = 0;
let purgedRecordCount = 0;
inactivedRecordCount += database
.prepare("update WorkOrderComments" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and workOrderId in (select workOrderId from WorkOrders where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from WorkOrderComments where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update WorkOrderLotOccupancies" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and workOrderId in (select workOrderId from WorkOrders where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from WorkOrderLotOccupancies where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update WorkOrderLots" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and workOrderId in (select workOrderId from WorkOrders where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from WorkOrderLots where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update WorkOrderMilestones" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and workOrderId in (select workOrderId from WorkOrders where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from WorkOrderMilestones where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from WorkOrders where recordDelete_timeMillis <= ?" +
" and workOrderId not in (select workOrderId from WorkOrderComments)" +
" and workOrderId not in (select workOrderId from WorkOrderLotOccupancies)" +
" and workOrderId not in (select workOrderId from WorkOrderLots)" +
" and workOrderId not in (select workOrderId from WorkOrderMilestones)")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from WorkOrderMilestoneTypes where recordDelete_timeMillis <= ?" +
" and workOrderMilestoneTypeId not in (select workOrderMilestoneTypeId from WorkOrderMilestones)")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from WorkOrderTypes where recordDelete_timeMillis <= ?" +
" and workOrderTypeId not in (select workOrderTypeId from WorkOrders)")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update LotOccupancyComments" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotOccupancyId in (select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotOccupancyComments where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update LotOccupancyFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotOccupancyId in (select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotOccupancyFields where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update LotOccupancyOccupants" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotOccupancyId in (select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotOccupancyOccupants where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from LotOccupancyFees where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from LotOccupancyTransactions where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from LotOccupancies where recordDelete_timeMillis <= ?" +
" and lotOccupancyId not in (select lotOccupancyId from LotOccupancyComments)" +
" and lotOccupancyId not in (select lotOccupancyId from LotOccupancyFees)" +
" and lotOccupancyId not in (select lotOccupancyId from LotOccupancyFields)" +
" and lotOccupancyId not in (select lotOccupancyId from LotOccupancyOccupants)" +
" and lotOccupancyId not in (select lotOccupancyId from LotOccupancyTransactions)")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update Fees" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and feeCategoryId in (select feeCategoryId from FeeCategories where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from Fees where recordDelete_timeMillis <= ?" +
" and feeId not in (select feeId from LotOccupancyFees)")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from FeeCategories where recordDelete_timeMillis <= ?" +
" and feeCategoryId not in (select feeCategoryId from Fees)")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update OccupancyTypeFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and occupancyTypeId in (select occupancyTypeId from OccupancyTypes where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from OccupancyTypeFields where recordDelete_timeMillis <= ?" +
" and occupancyTypeFieldId not in (select occupancyTypeFieldId from LotOccupancyFields)")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from OccupancyTypes where recordDelete_timeMillis <= ?" +
" and occupancyTypeId not in (select occupancyTypeId from LotOccupancies)" +
" and occupancyTypeId not in (select occupancyTypeId from Fees)")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from LotOccupantTypes where recordDelete_timeMillis <= ?" +
" and lotOccupantTypeId not in (select lotOccupantTypeId from LotOccupancyOccupants)")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update LotComments" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotId in (select lotId from Lots where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotComments where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update LotFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotId in (select lotId from Lots where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotFields where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update Lots" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and mapId in (select mapId from Maps where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from Lots where recordDelete_timeMillis <= ?" +
" and lotId not in (select lotId from LotComments)" +
" and lotId not in (select lotId from LotFields)" +
" and lotId not in (select lotId from LotOccupancies)")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from LotStatuses where recordDelete_timeMillis <= ?" +
" and lotStatusId not in (select lotStatusId from Lots)")
.run(recordDelete_timeMillisMin).changes;
inactivedRecordCount += database
.prepare("update LotTypeFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotTypeId in (select lotTypeId from LotTypes where recordDelete_timeMillis is not null)")
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotTypeFields where recordDelete_timeMillis <= ?" +
" and lotTypeFieldId not in (select lotTypeFieldId from LotFields)")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from LotTypes where recordDelete_timeMillis <= ?" +
" and lotTypeId not in (select lotTypeId from Lots)")
.run(recordDelete_timeMillisMin).changes;
database.close();
return {
inactivedRecordCount,
purgedRecordCount
};
};
export default cleanupDatabase;

View File

@ -0,0 +1,350 @@
import sqlite from "better-sqlite3";
import { lotOccupancyDB as databasePath } from "../../data/databasePaths.js";
import * as configFunctions from "../functions.config.js";
import type * as recordTypes from "../../types/recordTypes";
export const cleanupDatabase = (requestSession: recordTypes.PartialSession) => {
const database = sqlite(databasePath);
const rightNowMillis = Date.now();
const recordDelete_timeMillisMin =
rightNowMillis -
configFunctions.getProperty("settings.adminCleanup.recordDeleteAgeDays") * 86_400 * 1000;
let inactivedRecordCount = 0;
let purgedRecordCount = 0;
// Work Order Comments
inactivedRecordCount += database
.prepare(
"update WorkOrderComments" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and workOrderId in (select workOrderId from WorkOrders where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from WorkOrderComments where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
// Work Order Lot Occupancies
inactivedRecordCount += database
.prepare(
"update WorkOrderLotOccupancies" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and workOrderId in (select workOrderId from WorkOrders where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from WorkOrderLotOccupancies where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
// Work Order Lots
inactivedRecordCount += database
.prepare(
"update WorkOrderLots" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and workOrderId in (select workOrderId from WorkOrders where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from WorkOrderLots where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
// Work Order Milestones
inactivedRecordCount += database
.prepare(
"update WorkOrderMilestones" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and workOrderId in (select workOrderId from WorkOrders where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from WorkOrderMilestones where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
// Work Orders
purgedRecordCount += database
.prepare(
"delete from WorkOrders where recordDelete_timeMillis <= ?" +
" and workOrderId not in (select workOrderId from WorkOrderComments)" +
" and workOrderId not in (select workOrderId from WorkOrderLotOccupancies)" +
" and workOrderId not in (select workOrderId from WorkOrderLots)" +
" and workOrderId not in (select workOrderId from WorkOrderMilestones)"
)
.run(recordDelete_timeMillisMin).changes;
// Work Order Milestone Types
purgedRecordCount += database
.prepare(
"delete from WorkOrderMilestoneTypes where recordDelete_timeMillis <= ?" +
" and workOrderMilestoneTypeId not in (select workOrderMilestoneTypeId from WorkOrderMilestones)"
)
.run(recordDelete_timeMillisMin).changes;
// Work Order Types
purgedRecordCount += database
.prepare(
"delete from WorkOrderTypes where recordDelete_timeMillis <= ?" +
" and workOrderTypeId not in (select workOrderTypeId from WorkOrders)"
)
.run(recordDelete_timeMillisMin).changes;
// Lot Occupancy Comments
inactivedRecordCount += database
.prepare(
"update LotOccupancyComments" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotOccupancyId in (select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotOccupancyComments where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
// Lot Occupancy Fields
inactivedRecordCount += database
.prepare(
"update LotOccupancyFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotOccupancyId in (select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotOccupancyFields where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
// Lot Occupancy Occupants
inactivedRecordCount += database
.prepare(
"update LotOccupancyOccupants" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotOccupancyId in (select lotOccupancyId from LotOccupancies where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotOccupancyOccupants where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
// Lot Occupancy Fees/Transactions
// - Maintain financials, do not delete related.
purgedRecordCount += database
.prepare("delete from LotOccupancyFees where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
purgedRecordCount += database
.prepare("delete from LotOccupancyTransactions where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
// Lot Occupancies
purgedRecordCount += database
.prepare(
"delete from LotOccupancies where recordDelete_timeMillis <= ?" +
" and lotOccupancyId not in (select lotOccupancyId from LotOccupancyComments)" +
" and lotOccupancyId not in (select lotOccupancyId from LotOccupancyFees)" +
" and lotOccupancyId not in (select lotOccupancyId from LotOccupancyFields)" +
" and lotOccupancyId not in (select lotOccupancyId from LotOccupancyOccupants)" +
" and lotOccupancyId not in (select lotOccupancyId from LotOccupancyTransactions)"
)
.run(recordDelete_timeMillisMin).changes;
// Fees
inactivedRecordCount += database
.prepare(
"update Fees" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and feeCategoryId in (select feeCategoryId from FeeCategories where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare(
"delete from Fees where recordDelete_timeMillis <= ?" +
" and feeId not in (select feeId from LotOccupancyFees)"
)
.run(recordDelete_timeMillisMin).changes;
// Fee Categories
purgedRecordCount += database
.prepare(
"delete from FeeCategories where recordDelete_timeMillis <= ?" +
" and feeCategoryId not in (select feeCategoryId from Fees)"
)
.run(recordDelete_timeMillisMin).changes;
// Occupancy Type Fields
inactivedRecordCount += database
.prepare(
"update OccupancyTypeFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and occupancyTypeId in (select occupancyTypeId from OccupancyTypes where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare(
"delete from OccupancyTypeFields where recordDelete_timeMillis <= ?" +
" and occupancyTypeFieldId not in (select occupancyTypeFieldId from LotOccupancyFields)"
)
.run(recordDelete_timeMillisMin).changes;
// Occupancy Types
purgedRecordCount += database
.prepare(
"delete from OccupancyTypes where recordDelete_timeMillis <= ?" +
" and occupancyTypeId not in (select occupancyTypeId from LotOccupancies)" +
" and occupancyTypeId not in (select occupancyTypeId from Fees)"
)
.run(recordDelete_timeMillisMin).changes;
// Lot Occupant Types
purgedRecordCount += database
.prepare(
"delete from LotOccupantTypes where recordDelete_timeMillis <= ?" +
" and lotOccupantTypeId not in (select lotOccupantTypeId from LotOccupancyOccupants)"
)
.run(recordDelete_timeMillisMin).changes;
// Lot Comments
inactivedRecordCount += database
.prepare(
"update LotComments" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotId in (select lotId from Lots where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotComments where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
// Lot Fields
inactivedRecordCount += database
.prepare(
"update LotFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotId in (select lotId from Lots where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare("delete from LotFields where recordDelete_timeMillis <= ?")
.run(recordDelete_timeMillisMin).changes;
// Lots
inactivedRecordCount += database
.prepare(
"update Lots" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and mapId in (select mapId from Maps where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare(
"delete from Lots where recordDelete_timeMillis <= ?" +
" and lotId not in (select lotId from LotComments)" +
" and lotId not in (select lotId from LotFields)" +
" and lotId not in (select lotId from LotOccupancies)"
)
.run(recordDelete_timeMillisMin).changes;
// Lot Statuses
purgedRecordCount += database
.prepare(
"delete from LotStatuses where recordDelete_timeMillis <= ?" +
" and lotStatusId not in (select lotStatusId from Lots)"
)
.run(recordDelete_timeMillisMin).changes;
// Lot Type Fields
inactivedRecordCount += database
.prepare(
"update LotTypeFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where recordDelete_timeMillis is null" +
" and lotTypeId in (select lotTypeId from LotTypes where recordDelete_timeMillis is not null)"
)
.run(requestSession.user.userName, rightNowMillis).changes;
purgedRecordCount += database
.prepare(
"delete from LotTypeFields where recordDelete_timeMillis <= ?" +
" and lotTypeFieldId not in (select lotTypeFieldId from LotFields)"
)
.run(recordDelete_timeMillisMin).changes;
// Lot Types
purgedRecordCount += database
.prepare(
"delete from LotTypes where recordDelete_timeMillis <= ?" +
" and lotTypeId not in (select lotTypeId from Lots)"
)
.run(recordDelete_timeMillisMin).changes;
database.close();
return {
inactivedRecordCount,
purgedRecordCount
};
};
export default cleanupDatabase;

View File

@ -9,6 +9,12 @@ export const deleteFeeCategory = (feeCategoryId, requestSession) => {
" recordDelete_timeMillis = ?" + " recordDelete_timeMillis = ?" +
" where feeCategoryId = ?") " where feeCategoryId = ?")
.run(requestSession.user.userName, rightNowMillis, feeCategoryId); .run(requestSession.user.userName, rightNowMillis, feeCategoryId);
database
.prepare("update Fees" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where feeCategoryId = ?")
.run(requestSession.user.userName, rightNowMillis, feeCategoryId);
database.close(); database.close();
return result.changes > 0; return result.changes > 0;
}; };

View File

@ -21,6 +21,15 @@ export const deleteFeeCategory = (
) )
.run(requestSession.user.userName, rightNowMillis, feeCategoryId); .run(requestSession.user.userName, rightNowMillis, feeCategoryId);
database
.prepare(
"update Fees" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where feeCategoryId = ?"
)
.run(requestSession.user.userName, rightNowMillis, feeCategoryId);
database.close(); database.close();
return result.changes > 0; return result.changes > 0;

View File

@ -9,6 +9,24 @@ export const deleteLotOccupancy = (lotOccupancyId, requestSession) => {
" recordDelete_timeMillis = ?" + " recordDelete_timeMillis = ?" +
" where lotOccupancyId = ?") " where lotOccupancyId = ?")
.run(requestSession.user.userName, rightNowMillis, lotOccupancyId); .run(requestSession.user.userName, rightNowMillis, lotOccupancyId);
database
.prepare("update LotOccupancyComments" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where lotOccupancyId = ?")
.run(requestSession.user.userName, rightNowMillis, lotOccupancyId);
database
.prepare("update LotOccupancyFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where lotOccupancyId = ?")
.run(requestSession.user.userName, rightNowMillis, lotOccupancyId);
database
.prepare("update LotOccupancyOccupants" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where lotOccupancyId = ?")
.run(requestSession.user.userName, rightNowMillis, lotOccupancyId);
database.close(); database.close();
return result.changes > 0; return result.changes > 0;
}; };

View File

@ -21,6 +21,35 @@ export const deleteLotOccupancy = (
) )
.run(requestSession.user.userName, rightNowMillis, lotOccupancyId); .run(requestSession.user.userName, rightNowMillis, lotOccupancyId);
database
.prepare(
"update LotOccupancyComments" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where lotOccupancyId = ?"
)
.run(requestSession.user.userName, rightNowMillis, lotOccupancyId);
database
.prepare(
"update LotOccupancyFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where lotOccupancyId = ?"
)
.run(requestSession.user.userName, rightNowMillis, lotOccupancyId);
database
.prepare(
"update LotOccupancyOccupants" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where lotOccupancyId = ?"
)
.run(requestSession.user.userName, rightNowMillis, lotOccupancyId);
// Do not auto-delete Fees or Transactions. Maintain financials.
database.close(); database.close();
return result.changes > 0; return result.changes > 0;

View File

@ -9,6 +9,12 @@ export const deleteMap = (mapId, requestSession) => {
" recordDelete_timeMillis = ?" + " recordDelete_timeMillis = ?" +
" where mapId = ?") " where mapId = ?")
.run(requestSession.user.userName, rightNowMillis, mapId); .run(requestSession.user.userName, rightNowMillis, mapId);
database
.prepare("update Lots" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where mapId = ?")
.run(requestSession.user.userName, rightNowMillis, mapId);
database.close(); database.close();
return result.changes > 0; return result.changes > 0;
}; };

View File

@ -21,6 +21,15 @@ export const deleteMap = (
) )
.run(requestSession.user.userName, rightNowMillis, mapId); .run(requestSession.user.userName, rightNowMillis, mapId);
database
.prepare(
"update Lots" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where mapId = ?"
)
.run(requestSession.user.userName, rightNowMillis, mapId);
database.close(); database.close();
return result.changes > 0; return result.changes > 0;

View File

@ -10,6 +10,12 @@ export const deleteOccupancyType = (occupancyTypeId, requestSession) => {
" recordDelete_timeMillis = ?" + " recordDelete_timeMillis = ?" +
" where occupancyTypeId = ?") " where occupancyTypeId = ?")
.run(requestSession.user.userName, rightNowMillis, occupancyTypeId); .run(requestSession.user.userName, rightNowMillis, occupancyTypeId);
database
.prepare("update OccupancyTypeFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where occupancyTypeId = ?")
.run(requestSession.user.userName, rightNowMillis, occupancyTypeId);
database.close(); database.close();
clearOccupancyTypesCache(); clearOccupancyTypesCache();
return result.changes > 0; return result.changes > 0;

View File

@ -23,6 +23,15 @@ export const deleteOccupancyType = (
) )
.run(requestSession.user.userName, rightNowMillis, occupancyTypeId); .run(requestSession.user.userName, rightNowMillis, occupancyTypeId);
database
.prepare(
"update OccupancyTypeFields" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where occupancyTypeId = ?"
)
.run(requestSession.user.userName, rightNowMillis, occupancyTypeId)
database.close(); database.close();
clearOccupancyTypesCache(); clearOccupancyTypesCache();

View File

@ -9,6 +9,30 @@ export const deleteWorkOrder = (workOrderId, requestSession) => {
" recordDelete_timeMillis = ?" + " recordDelete_timeMillis = ?" +
" where workOrderId = ?") " where workOrderId = ?")
.run(requestSession.user.userName, rightNowMillis, workOrderId); .run(requestSession.user.userName, rightNowMillis, workOrderId);
database
.prepare("update WorkOrderComments" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where workOrderId = ?")
.run(requestSession.user.userName, rightNowMillis, workOrderId);
database
.prepare("update WorkOrderLotOccupancies" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where workOrderId = ?")
.run(requestSession.user.userName, rightNowMillis, workOrderId);
database
.prepare("update WorkOrderLots" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where workOrderId = ?")
.run(requestSession.user.userName, rightNowMillis, workOrderId);
database
.prepare("update WorkOrderMilestones" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where workOrderId = ?")
.run(requestSession.user.userName, rightNowMillis, workOrderId);
database.close(); database.close();
return result.changes > 0; return result.changes > 0;
}; };

View File

@ -21,6 +21,42 @@ export const deleteWorkOrder = (
) )
.run(requestSession.user.userName, rightNowMillis, workOrderId); .run(requestSession.user.userName, rightNowMillis, workOrderId);
database
.prepare(
"update WorkOrderComments" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where workOrderId = ?"
)
.run(requestSession.user.userName, rightNowMillis, workOrderId);
database
.prepare(
"update WorkOrderLotOccupancies" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where workOrderId = ?"
)
.run(requestSession.user.userName, rightNowMillis, workOrderId);
database
.prepare(
"update WorkOrderLots" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where workOrderId = ?"
)
.run(requestSession.user.userName, rightNowMillis, workOrderId);
database
.prepare(
"update WorkOrderMilestones" +
" set recordDelete_userName = ?," +
" recordDelete_timeMillis = ?" +
" where workOrderId = ?"
)
.run(requestSession.user.userName, rightNowMillis, workOrderId);
database.close(); database.close();
return result.changes > 0; return result.changes > 0;

View File

@ -11,7 +11,7 @@ export const getWorkOrderMilestones = (filters, options, connectedDatabase) => {
}); });
database.function("userFn_dateIntegerToString", dateIntegerToString); database.function("userFn_dateIntegerToString", dateIntegerToString);
database.function("userFn_timeIntegerToString", timeIntegerToString); database.function("userFn_timeIntegerToString", timeIntegerToString);
let sqlWhereClause = " where m.recordDelete_timeMillis is null"; let sqlWhereClause = " where m.recordDelete_timeMillis is null and w.recordDelete_timeMillis is null";
const sqlParameters = []; const sqlParameters = [];
if (filters.workOrderId) { if (filters.workOrderId) {
sqlWhereClause += " and m.workOrderId = ?"; sqlWhereClause += " and m.workOrderId = ?";

View File

@ -46,7 +46,7 @@ export const getWorkOrderMilestones = (
// Filters // Filters
let sqlWhereClause = " where m.recordDelete_timeMillis is null"; let sqlWhereClause = " where m.recordDelete_timeMillis is null and w.recordDelete_timeMillis is null";
const sqlParameters = []; const sqlParameters = [];
if (filters.workOrderId) { if (filters.workOrderId) {

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
(() => {
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
const doCleanup = () => {
cityssm.postJSON(urlPrefix + "/admin/doCleanupDatabase", {}, (responseJSON) => {
if (responseJSON.success) {
bulmaJS.alert({
title: "Database Cleaned Up Successfully",
message: responseJSON.inactivedRecordCount + " records inactivated, " + responseJSON.purgedRecordCount + " permanently deleted.",
contextualColorName: "success"
});
}
else {
bulmaJS.alert({
title: "Error Cleaning Database",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
});
};
document.querySelector("#button--cleanupDatabase").addEventListener("click", () => {
bulmaJS.confirm({
title: "Cleanup Database",
message: "Are you sure you want to cleanup up the database?",
okButton: {
text: "Yes, Cleanup Database",
callbackFunction: doCleanup
}
});
});
})();

View File

@ -0,0 +1,50 @@
/* eslint-disable unicorn/prefer-module */
import type { cityssmGlobal } from "@cityssm/bulma-webapp-js/src/types";
import type { BulmaJS } from "@cityssm/bulma-js/types";
declare const cityssm: cityssmGlobal;
declare const bulmaJS: BulmaJS;
(() => {
const urlPrefix = document.querySelector("main").dataset.urlPrefix;
const doCleanup = () => {
cityssm.postJSON(
urlPrefix + "/admin/doCleanupDatabase",
{},
(responseJSON: {
success: boolean;
errorMessage?: string;
inactivedRecordCount: number;
purgedRecordCount: number;
}) => {
if (responseJSON.success) {
bulmaJS.alert({
title: "Database Cleaned Up Successfully",
message: responseJSON.inactivedRecordCount + " records inactivated, " + responseJSON.purgedRecordCount + " permanently deleted.",
contextualColorName: "success"
});
} else {
bulmaJS.alert({
title: "Error Cleaning Database",
message: responseJSON.errorMessage,
contextualColorName: "danger"
});
}
}
);
};
document.querySelector("#button--cleanupDatabase").addEventListener("click", () => {
bulmaJS.confirm({
title: "Cleanup Database",
message: "Are you sure you want to cleanup up the database?",
okButton: {
text: "Yes, Cleanup Database",
callbackFunction: doCleanup
}
});
});
})();

View File

@ -57,6 +57,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
title: "Delete " + exports.aliases.map, title: "Delete " + exports.aliases.map,
message: "Are you sure you want to delete this " + message: "Are you sure you want to delete this " +
exports.aliases.map.toLowerCase() + exports.aliases.map.toLowerCase() +
" and all related " + exports.aliases.lots.toLowerCase() +
"?", "?",
contextualColorName: "warning", contextualColorName: "warning",
okButton: { okButton: {

View File

@ -86,6 +86,7 @@ declare const bulmaJS: BulmaJS;
message: message:
"Are you sure you want to delete this " + "Are you sure you want to delete this " +
exports.aliases.map.toLowerCase() + exports.aliases.map.toLowerCase() +
" and all related " + exports.aliases.lots.toLowerCase() +
"?", "?",
contextualColorName: "warning", contextualColorName: "warning",
okButton: { okButton: {

View File

@ -0,0 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,a=()=>{cityssm.postJSON(e+"/admin/doCleanupDatabase",{},e=>{e.success?bulmaJS.alert({title:"Database Cleaned Up Successfully",message:e.inactivedRecordCount+" records inactivated, "+e.purgedRecordCount+" permanently deleted.",contextualColorName:"success"}):bulmaJS.alert({title:"Error Cleaning Database",message:e.errorMessage,contextualColorName:"danger"})})};document.querySelector("#button--cleanupDatabase").addEventListener("click",()=>{bulmaJS.confirm({title:"Cleanup Database",message:"Are you sure you want to cleanup up the database?",okButton:{text:"Yes, Cleanup Database",callbackFunction:a}})})})();

View File

@ -1 +1 @@
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,t=document.querySelector("#map--mapId").value,a=""===t,s=document.querySelector("#form--map");s.addEventListener("submit",t=>{t.preventDefault(),cityssm.postJSON(e+"/maps/"+(a?"doCreateMap":"doUpdateMap"),s,t=>{t.success?a?window.location.href=e+"/maps/"+t.mapId+"/edit":bulmaJS.alert({message:exports.aliases.map+" Updated Successfully",contextualColorName:"success"}):bulmaJS.alert({title:"Error Updating "+exports.aliases.map,message:t.errorMessage,contextualColorName:"danger"})})}),a||document.querySelector("#button--deleteMap").addEventListener("click",a=>{a.preventDefault();bulmaJS.confirm({title:"Delete "+exports.aliases.map,message:"Are you sure you want to delete this "+exports.aliases.map.toLowerCase()+"?",contextualColorName:"warning",okButton:{text:"Yes, Delete "+exports.aliases.map+"?",callbackFunction:()=>{cityssm.postJSON(e+"/maps/doDeleteMap",{mapId:t},t=>{t.success?window.location.href=e+"/maps?t="+Date.now():bulmaJS.alert({title:"Error Deleting "+exports.aliases.map,message:t.errorMessage,contextualColorName:"danger"})})}}})})})(); "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=document.querySelector("main").dataset.urlPrefix,t=document.querySelector("#map--mapId").value,a=""===t,s=document.querySelector("#form--map");s.addEventListener("submit",t=>{t.preventDefault(),cityssm.postJSON(e+"/maps/"+(a?"doCreateMap":"doUpdateMap"),s,t=>{t.success?a?window.location.href=e+"/maps/"+t.mapId+"/edit":bulmaJS.alert({message:exports.aliases.map+" Updated Successfully",contextualColorName:"success"}):bulmaJS.alert({title:"Error Updating "+exports.aliases.map,message:t.errorMessage,contextualColorName:"danger"})})}),a||document.querySelector("#button--deleteMap").addEventListener("click",a=>{a.preventDefault();bulmaJS.confirm({title:"Delete "+exports.aliases.map,message:"Are you sure you want to delete this "+exports.aliases.map.toLowerCase()+" and all related "+exports.aliases.lots.toLowerCase()+"?",contextualColorName:"warning",okButton:{text:"Yes, Delete "+exports.aliases.map+"?",callbackFunction:()=>{cityssm.postJSON(e+"/maps/doDeleteMap",{mapId:t},t=>{t.success?window.location.href=e+"/maps?t="+Date.now():bulmaJS.alert({title:"Error Deleting "+exports.aliases.map,message:t.errorMessage,contextualColorName:"danger"})})}}})})})();

View File

@ -43,6 +43,8 @@ import handler_doUpdateLotOccupantType from "../handlers/admin-post/doUpdateLotO
import handler_doMoveLotOccupantTypeUp from "../handlers/admin-post/doMoveLotOccupantTypeUp.js"; import handler_doMoveLotOccupantTypeUp from "../handlers/admin-post/doMoveLotOccupantTypeUp.js";
import handler_doMoveLotOccupantTypeDown from "../handlers/admin-post/doMoveLotOccupantTypeDown.js"; import handler_doMoveLotOccupantTypeDown from "../handlers/admin-post/doMoveLotOccupantTypeDown.js";
import handler_doDeleteLotOccupantType from "../handlers/admin-post/doDeleteLotOccupantType.js"; import handler_doDeleteLotOccupantType from "../handlers/admin-post/doDeleteLotOccupantType.js";
import handler_cleanup from "../handlers/admin-get/cleanup.js";
import handler_doCleanupDatabase from "../handlers/admin-post/doCleanupDatabase.js";
export const router = Router(); export const router = Router();
router.get("/fees", permissionHandlers.adminGetHandler, handler_fees); router.get("/fees", permissionHandlers.adminGetHandler, handler_fees);
router.post("/doAddFeeCategory", permissionHandlers.adminPostHandler, handler_doAddFeeCategory); router.post("/doAddFeeCategory", permissionHandlers.adminPostHandler, handler_doAddFeeCategory);
@ -87,4 +89,6 @@ router.post("/doUpdateLotOccupantType", permissionHandlers.adminPostHandler, han
router.post("/doMoveLotOccupantTypeUp", permissionHandlers.adminPostHandler, handler_doMoveLotOccupantTypeUp); router.post("/doMoveLotOccupantTypeUp", permissionHandlers.adminPostHandler, handler_doMoveLotOccupantTypeUp);
router.post("/doMoveLotOccupantTypeDown", permissionHandlers.adminPostHandler, handler_doMoveLotOccupantTypeDown); router.post("/doMoveLotOccupantTypeDown", permissionHandlers.adminPostHandler, handler_doMoveLotOccupantTypeDown);
router.post("/doDeleteLotOccupantType", permissionHandlers.adminPostHandler, handler_doDeleteLotOccupantType); router.post("/doDeleteLotOccupantType", permissionHandlers.adminPostHandler, handler_doDeleteLotOccupantType);
router.get("/cleanup", permissionHandlers.adminGetHandler, handler_cleanup);
router.post("/doCleanupDatabase", permissionHandlers.adminPostHandler, handler_doCleanupDatabase);
export default router; export default router;

View File

@ -62,6 +62,11 @@ import handler_doMoveLotOccupantTypeUp from "../handlers/admin-post/doMoveLotOcc
import handler_doMoveLotOccupantTypeDown from "../handlers/admin-post/doMoveLotOccupantTypeDown.js"; import handler_doMoveLotOccupantTypeDown from "../handlers/admin-post/doMoveLotOccupantTypeDown.js";
import handler_doDeleteLotOccupantType from "../handlers/admin-post/doDeleteLotOccupantType.js"; import handler_doDeleteLotOccupantType from "../handlers/admin-post/doDeleteLotOccupantType.js";
// Cleanup
import handler_cleanup from "../handlers/admin-get/cleanup.js";
import handler_doCleanupDatabase from "../handlers/admin-post/doCleanupDatabase.js";
export const router = Router(); export const router = Router();
/* /*
@ -70,11 +75,7 @@ export const router = Router();
router.get("/fees", permissionHandlers.adminGetHandler, handler_fees); router.get("/fees", permissionHandlers.adminGetHandler, handler_fees);
router.post( router.post("/doAddFeeCategory", permissionHandlers.adminPostHandler, handler_doAddFeeCategory);
"/doAddFeeCategory",
permissionHandlers.adminPostHandler,
handler_doAddFeeCategory
);
router.post( router.post(
"/doUpdateFeeCategory", "/doUpdateFeeCategory",
@ -102,45 +103,21 @@ router.post(
router.post("/doAddFee", permissionHandlers.adminPostHandler, handler_doAddFee); router.post("/doAddFee", permissionHandlers.adminPostHandler, handler_doAddFee);
router.post( router.post("/doUpdateFee", permissionHandlers.adminPostHandler, handler_doUpdateFee);
"/doUpdateFee",
permissionHandlers.adminPostHandler,
handler_doUpdateFee
);
router.post( router.post("/doMoveFeeUp", permissionHandlers.adminPostHandler, handler_doMoveFeeUp);
"/doMoveFeeUp",
permissionHandlers.adminPostHandler,
handler_doMoveFeeUp
);
router.post( router.post("/doMoveFeeDown", permissionHandlers.adminPostHandler, handler_doMoveFeeDown);
"/doMoveFeeDown",
permissionHandlers.adminPostHandler,
handler_doMoveFeeDown
);
router.post( router.post("/doDeleteFee", permissionHandlers.adminPostHandler, handler_doDeleteFee);
"/doDeleteFee",
permissionHandlers.adminPostHandler,
handler_doDeleteFee
);
/* /*
* Occupancy Type Management * Occupancy Type Management
*/ */
router.get( router.get("/occupancyTypes", permissionHandlers.adminGetHandler, handler_occupancyTypes);
"/occupancyTypes",
permissionHandlers.adminGetHandler,
handler_occupancyTypes
);
router.post( router.post("/doAddOccupancyType", permissionHandlers.adminPostHandler, handler_doAddOccupancyType);
"/doAddOccupancyType",
permissionHandlers.adminPostHandler,
handler_doAddOccupancyType
);
router.post( router.post(
"/doUpdateOccupancyType", "/doUpdateOccupancyType",
@ -206,11 +183,7 @@ router.get("/tables", permissionHandlers.adminGetHandler, handler_tables);
// Config Tables - Work Order Types // Config Tables - Work Order Types
router.post( router.post("/doAddWorkOrderType", permissionHandlers.adminPostHandler, handler_doAddWorkOrderType);
"/doAddWorkOrderType",
permissionHandlers.adminPostHandler,
handler_doAddWorkOrderType
);
router.post( router.post(
"/doUpdateWorkOrderType", "/doUpdateWorkOrderType",
@ -269,23 +242,11 @@ router.post(
// Config Tables - Lot Statuses // Config Tables - Lot Statuses
router.post( router.post("/doAddLotStatus", permissionHandlers.adminPostHandler, handler_doAddLotStatus);
"/doAddLotStatus",
permissionHandlers.adminPostHandler,
handler_doAddLotStatus
);
router.post( router.post("/doUpdateLotStatus", permissionHandlers.adminPostHandler, handler_doUpdateLotStatus);
"/doUpdateLotStatus",
permissionHandlers.adminPostHandler,
handler_doUpdateLotStatus
);
router.post( router.post("/doMoveLotStatusUp", permissionHandlers.adminPostHandler, handler_doMoveLotStatusUp);
"/doMoveLotStatusUp",
permissionHandlers.adminPostHandler,
handler_doMoveLotStatusUp
);
router.post( router.post(
"/doMoveLotStatusDown", "/doMoveLotStatusDown",
@ -293,11 +254,7 @@ router.post(
handler_doMoveLotStatusDown handler_doMoveLotStatusDown
); );
router.post( router.post("/doDeleteLotStatus", permissionHandlers.adminPostHandler, handler_doDeleteLotStatus);
"/doDeleteLotStatus",
permissionHandlers.adminPostHandler,
handler_doDeleteLotStatus
);
// Config Tables - Lot Occupant Types // Config Tables - Lot Occupant Types
@ -331,4 +288,10 @@ router.post(
handler_doDeleteLotOccupantType handler_doDeleteLotOccupantType
); );
// Cleanup
router.get("/cleanup", permissionHandlers.adminGetHandler, handler_cleanup);
router.post("/doCleanupDatabase", permissionHandlers.adminPostHandler, handler_doCleanupDatabase);
export default router; export default router;

View File

@ -48,6 +48,9 @@ export interface Config {
workOrderMilestoneDateRecentAfterDays?: number; workOrderMilestoneDateRecentAfterDays?: number;
calendarEmailAddress?: string; calendarEmailAddress?: string;
}; };
adminCleanup?: {
recordDeleteAgeDays?: number;
};
}; };
} }
interface ConfigApplication { interface ConfigApplication {

View File

@ -48,6 +48,9 @@ export interface Config {
workOrderMilestoneDateRecentAfterDays?: number; workOrderMilestoneDateRecentAfterDays?: number;
calendarEmailAddress?: string; calendarEmailAddress?: string;
}; };
adminCleanup?: {
recordDeleteAgeDays?: number;
};
}; };
} }

View File

@ -21,5 +21,11 @@
<span>Config Table Management</span> <span>Config Table Management</span>
</a> </a>
</li> </li>
<li>
<a class="<%= (headTitle === "Database Cleanup" ? "is-active" : "") %>" href="<%= urlPrefix %>/admin/cleanup">
<span class="icon is-small"><i class="fas fa-fw fa-broom" aria-hidden="true"></i></span>
<span>Database Cleanup</span>
</a>
</li>
</ul> </ul>
</aside> </aside>

View File

@ -0,0 +1,59 @@
<%- include('_header'); -%>
<div class="columns">
<div class="column is-3 is-hidden-mobile">
<%- include('_menu-admin'); -%>
</div>
<div class="column">
<nav class="breadcrumb">
<ul>
<li><a href="<%= urlPrefix %>/dashboard">Home</a></li>
<li>
<a href="#">
<span class="icon is-small"><i class="fas fa-cog" aria-hidden="true"></i></span>
<span>Administrator Tools</span>
</a>
</li>
<li class="is-active">
<a href="#" aria-current="page">
Database Cleanup
</a>
</li>
</ul>
</nav>
<h1 class="title is-1">
Database Cleanup
</h1>
<div class="message is-warning">
<div class="message-header">
Important Note
</div>
<div class="message-body">
<p>
When records are deleted in this application, they are not removed entirely.
This gives systems administrators the ability to recover deleted records.
This also can leave a small amount of garbage behind in the database.
</p>
<p class="mt-2">
This process permanently deletes records that have already been deleted over <%= configFunctions.getProperty("settings.adminCleanup.recordDeleteAgeDays") %> days ago.
Note that no active records will be affected by the cleanup process.
</p>
</div>
</div>
<p class="has-text-right">
<button class="button is-success" id="button--cleanupDatabase" type="button">
Cleanup Database
</button>
</p>
</div>
</div>
<%- include('_footerA'); -%>
<script src="<%= urlPrefix %>/javascripts/adminCleanup.min.js"></script>
<%- include('_footerB'); -%>

View File

@ -180,6 +180,21 @@
</div> </div>
</div> </div>
</div> </div>
<div class="card-content">
<div class="media">
<div class="media-left">
<i class="fas fa-3x fa-fw fa-broom" aria-hidden="true"></i>
</div>
<div class="media-content has-text-black">
<h2 class="title is-4 is-marginless">
<a href="<%= urlPrefix %>/admin/cleanup">Database Cleanup</a>
</h2>
<p>
Permanently delete records that have been previously deleted from the database.
</p>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>