feat(server-ts): utils/dates → TypeScript (.mts); utils/ dir now TS (Phase 2)
dates.mts (ESM, typed) joins money.mts — the two most-required server leaves are now TypeScript. Added .cts to the server tsconfig for the CJS-module migration path. typecheck:server clean; suite 225 + probe 17/17. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
200c6373f5
commit
3f9a6cf23e
|
|
@ -22,7 +22,7 @@ const {
|
||||||
accountingActiveSql,
|
accountingActiveSql,
|
||||||
applyBankPaymentAsSourceOfTruth,
|
applyBankPaymentAsSourceOfTruth,
|
||||||
} = require('../services/paymentAccountingService');
|
} = require('../services/paymentAccountingService');
|
||||||
const { localDateString, todayLocal } = require('../utils/dates');
|
const { localDateString, todayLocal } = require('../utils/dates.mts');
|
||||||
const { roundMoney, sumMoney, toCents, fromCents } = require('../utils/money.mts');
|
const { roundMoney, sumMoney, toCents, fromCents } = require('../utils/money.mts');
|
||||||
|
|
||||||
// ── GET /api/bills ────────────────────────────────────────────────────────────
|
// ── GET /api/bills ────────────────────────────────────────────────────────────
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const {
|
||||||
regenerateToken,
|
regenerateToken,
|
||||||
revokeToken,
|
revokeToken,
|
||||||
} = require('../services/calendarFeedService');
|
} = require('../services/calendarFeedService');
|
||||||
const { localDateString } = require('../utils/dates');
|
const { localDateString } = require('../utils/dates.mts');
|
||||||
const { roundMoney, sumMoney, fromCents } = require('../utils/money.mts');
|
const { roundMoney, sumMoney, fromCents } = require('../utils/money.mts');
|
||||||
|
|
||||||
function clampDay(year, month, day) {
|
function clampDay(year, month, day) {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const {
|
||||||
const { learnMerchantRuleFromMatch } = require('../services/billMerchantRuleService');
|
const { learnMerchantRuleFromMatch } = require('../services/billMerchantRuleService');
|
||||||
const { markMatched, markUnmatched } = require('../services/transactionMatchState');
|
const { markMatched, markUnmatched } = require('../services/transactionMatchState');
|
||||||
const { serializePayment } = require('../services/paymentValidation');
|
const { serializePayment } = require('../services/paymentValidation');
|
||||||
const { todayLocal } = require('../utils/dates');
|
const { todayLocal } = require('../utils/dates.mts');
|
||||||
|
|
||||||
function sendMatchError(res, err, fallbackMessage = 'Match operation failed') {
|
function sendMatchError(res, err, fallbackMessage = 'Match operation failed') {
|
||||||
if (err.status) {
|
if (err.status) {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const {
|
||||||
markProvisionalManualPaymentsOverridden,
|
markProvisionalManualPaymentsOverridden,
|
||||||
reactivatePaymentsOverriddenBy,
|
reactivatePaymentsOverriddenBy,
|
||||||
} = require('../services/paymentAccountingService');
|
} = require('../services/paymentAccountingService');
|
||||||
const { todayLocal } = require('../utils/dates');
|
const { todayLocal } = require('../utils/dates.mts');
|
||||||
const { fromCents } = require('../utils/money.mts');
|
const { fromCents } = require('../utils/money.mts');
|
||||||
|
|
||||||
// SQL_NOT_DELETED is a compile-time constant SQL fragment, never user-supplied.
|
// SQL_NOT_DELETED is a compile-time constant SQL fragment, never user-supplied.
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const { checkForUpdates } = require('../services/updateCheckService');
|
||||||
const { getStatus: getBankSyncWorkerStatus } = require('../services/bankSyncWorker');
|
const { getStatus: getBankSyncWorkerStatus } = require('../services/bankSyncWorker');
|
||||||
const { getBankSyncConfig } = require('../services/bankSyncConfigService');
|
const { getBankSyncConfig } = require('../services/bankSyncConfigService');
|
||||||
const { accountingActiveSql } = require('../services/paymentAccountingService');
|
const { accountingActiveSql } = require('../services/paymentAccountingService');
|
||||||
const { localDateString } = require('../utils/dates');
|
const { localDateString } = require('../utils/dates.mts');
|
||||||
|
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let pkg;
|
let pkg;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const {
|
||||||
findOrCreateCategory,
|
findOrCreateCategory,
|
||||||
} = require('../services/merchantStoreMatchService');
|
} = require('../services/merchantStoreMatchService');
|
||||||
const { categorizeTransaction } = require('../services/spendingService');
|
const { categorizeTransaction } = require('../services/spendingService');
|
||||||
const { todayLocal } = require('../utils/dates');
|
const { todayLocal } = require('../utils/dates.mts');
|
||||||
const { roundMoney } = require('../utils/money.mts');
|
const { roundMoney } = require('../utils/money.mts');
|
||||||
|
|
||||||
const MATCH_STATUSES = new Set(['unmatched', 'matched', 'ignored']);
|
const MATCH_STATUSES = new Set(['unmatched', 'matched', 'ignored']);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
const { normalizeMerchant } = require('./subscriptionService');
|
const { normalizeMerchant } = require('./subscriptionService');
|
||||||
const { getUserSettings } = require('./userSettings');
|
const { getUserSettings } = require('./userSettings');
|
||||||
const { applyBankPaymentAsSourceOfTruth } = require('./paymentAccountingService');
|
const { applyBankPaymentAsSourceOfTruth } = require('./paymentAccountingService');
|
||||||
const { localDateString } = require('../utils/dates');
|
const { localDateString } = require('../utils/dates.mts');
|
||||||
const { fromCents } = require('../utils/money.mts');
|
const { fromCents } = require('../utils/money.mts');
|
||||||
|
|
||||||
// Word-boundary merchant match — requires the rule to appear as complete word(s)
|
// Word-boundary merchant match — requires the rule to appear as complete word(s)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
const { monthKey } = require('../utils/dates');
|
const { monthKey } = require('../utils/dates.mts');
|
||||||
const { toCents, fromCents } = require('../utils/money.mts');
|
const { toCents, fromCents } = require('../utils/money.mts');
|
||||||
const VALID_VISIBILITY = ['default', 'all', 'ranges', 'none'];
|
const VALID_VISIBILITY = ['default', 'all', 'ranges', 'none'];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ const { getDb } = require('../db/database');
|
||||||
const { getCycleRange } = require('./statusService');
|
const { getCycleRange } = require('./statusService');
|
||||||
const { accountingActiveSql } = require('./paymentAccountingService');
|
const { accountingActiveSql } = require('./paymentAccountingService');
|
||||||
const { getUserSettings } = require('./userSettings');
|
const { getUserSettings } = require('./userSettings');
|
||||||
const { localDateString } = require('../utils/dates');
|
const { localDateString } = require('../utils/dates.mts');
|
||||||
const { roundMoney, fromCents } = require('../utils/money.mts');
|
const { roundMoney, fromCents } = require('../utils/money.mts');
|
||||||
|
|
||||||
const MONTHS_BACK = 3;
|
const MONTHS_BACK = 3;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ const {
|
||||||
markNotificationSuccess,
|
markNotificationSuccess,
|
||||||
markNotificationTestSuccess,
|
markNotificationTestSuccess,
|
||||||
} = require('./statusRuntime');
|
} = require('./statusRuntime');
|
||||||
const { localDateString } = require('../utils/dates');
|
const { localDateString } = require('../utils/dates.mts');
|
||||||
const { fromCents } = require('../utils/money.mts');
|
const { fromCents } = require('../utils/money.mts');
|
||||||
|
|
||||||
// ── Push notification channels ────────────────────────────────────────────────
|
// ── Push notification channels ────────────────────────────────────────────────
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { normalizeMerchant } = require('./subscriptionService');
|
const { normalizeMerchant } = require('./subscriptionService');
|
||||||
const { localDateString } = require('../utils/dates');
|
const { localDateString } = require('../utils/dates.mts');
|
||||||
const { toCents, fromCents } = require('../utils/money.mts');
|
const { toCents, fromCents } = require('../utils/money.mts');
|
||||||
|
|
||||||
// Spending = unmatched outflows (amount < 0) that haven't been ignored.
|
// Spending = unmatched outflows (amount < 0) that haven't been ignored.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const { billingCycleForCycleType, insertBill, validateBillData } = require('./billsService');
|
const { billingCycleForCycleType, insertBill, validateBillData } = require('./billsService');
|
||||||
const { localDateString, todayLocal } = require('../utils/dates');
|
const { localDateString, todayLocal } = require('../utils/dates.mts');
|
||||||
const { roundMoney, sumMoney, mulMoney, fromCents } = require('../utils/money.mts');
|
const { roundMoney, sumMoney, mulMoney, fromCents } = require('../utils/money.mts');
|
||||||
|
|
||||||
const SUBSCRIPTION_TYPES = [
|
const SUBSCRIPTION_TYPES = [
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ const { computeBalanceDelta, applyBalanceDelta } = require('./billsService');
|
||||||
const { computeAmountSuggestionsBatch } = require('./amountSuggestionService');
|
const { computeAmountSuggestionsBatch } = require('./amountSuggestionService');
|
||||||
const { accountingActiveSql } = require('./paymentAccountingService');
|
const { accountingActiveSql } = require('./paymentAccountingService');
|
||||||
const { normalizeMerchant } = require('./subscriptionService');
|
const { normalizeMerchant } = require('./subscriptionService');
|
||||||
const { localDateString } = require('../utils/dates');
|
const { localDateString } = require('../utils/dates.mts');
|
||||||
const { sumMoney, roundMoney, fromCents } = require('../utils/money.mts');
|
const { sumMoney, roundMoney, fromCents } = require('../utils/money.mts');
|
||||||
|
|
||||||
const DEFAULT_PENDING_DAYS = 3;
|
const DEFAULT_PENDING_DAYS = 3;
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,12 @@
|
||||||
"types": ["node"]
|
"types": ["node"]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"utils/**/*.ts", "utils/**/*.mts",
|
"utils/**/*.ts", "utils/**/*.mts", "utils/**/*.cts",
|
||||||
"services/**/*.ts", "services/**/*.mts",
|
"services/**/*.ts", "services/**/*.mts", "services/**/*.cts",
|
||||||
"routes/**/*.ts", "routes/**/*.mts",
|
"routes/**/*.ts", "routes/**/*.mts", "routes/**/*.cts",
|
||||||
"middleware/**/*.ts", "middleware/**/*.mts",
|
"middleware/**/*.ts", "middleware/**/*.mts", "middleware/**/*.cts",
|
||||||
"db/**/*.ts", "db/**/*.mts",
|
"db/**/*.ts", "db/**/*.mts", "db/**/*.cts",
|
||||||
"workers/**/*.ts", "workers/**/*.mts",
|
"workers/**/*.ts", "workers/**/*.mts", "workers/**/*.cts",
|
||||||
"server.mts"
|
"server.mts", "server.cts"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server-side local-date helpers.
|
* Server-side local-date helpers.
|
||||||
*
|
*
|
||||||
* Bill due dates and payment dates are stored as plain YYYY-MM-DD strings in
|
* Bill due dates and payment dates are stored as plain YYYY-MM-DD strings in
|
||||||
* the server's local timezone (the client computes "today" the same way in
|
* the server's local timezone (the client computes "today" the same way in
|
||||||
* client/pages/TrackerPage.jsx → localDateString). Never derive a calendar
|
* client/pages/TrackerPage.tsx → localDateString). Never derive a calendar
|
||||||
* date from Date.toISOString() — that yields the UTC date, which disagrees
|
* date from Date.toISOString() — that yields the UTC date, which disagrees
|
||||||
* with local time around midnight and month boundaries.
|
* with local time around midnight and month boundaries.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** YYYY-MM-DD in local time. */
|
/** YYYY-MM-DD in local time. */
|
||||||
function localDateString(date = new Date()) {
|
export function localDateString(date: Date = new Date()): string {
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||||
const day = String(date.getDate()).padStart(2, '0');
|
const day = String(date.getDate()).padStart(2, '0');
|
||||||
|
|
@ -19,25 +17,23 @@ function localDateString(date = new Date()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** { year, month } (1-based month) in local time. */
|
/** { year, month } (1-based month) in local time. */
|
||||||
function localYearMonth(date = new Date()) {
|
export function localYearMonth(date: Date = new Date()): { year: number; month: number } {
|
||||||
return { year: date.getFullYear(), month: date.getMonth() + 1 };
|
return { year: date.getFullYear(), month: date.getMonth() + 1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** YYYY-MM-DD in local time, `days` days before `from`. */
|
/** YYYY-MM-DD in local time, `days` days before `from`. */
|
||||||
function localDateStringDaysAgo(days, from = new Date()) {
|
export function localDateStringDaysAgo(days: number, from: Date = new Date()): string {
|
||||||
const d = new Date(from);
|
const d = new Date(from);
|
||||||
d.setDate(d.getDate() - days);
|
d.setDate(d.getDate() - days);
|
||||||
return localDateString(d);
|
return localDateString(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Today as YYYY-MM-DD in local time. Alias of localDateString(). */
|
/** Today as YYYY-MM-DD in local time. Alias of localDateString(). */
|
||||||
function todayLocal() {
|
export function todayLocal(): string {
|
||||||
return localDateString(new Date());
|
return localDateString(new Date());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** YYYY-MM month key in local time (e.g. "2026-06"). */
|
/** YYYY-MM month key in local time (e.g. "2026-06"). */
|
||||||
function monthKey(date = new Date()) {
|
export function monthKey(date: Date = new Date()): string {
|
||||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
|
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { localDateString, localYearMonth, localDateStringDaysAgo, todayLocal, monthKey };
|
|
||||||
|
|
@ -12,7 +12,7 @@ const {
|
||||||
markWorkerStarted,
|
markWorkerStarted,
|
||||||
markWorkerSuccess,
|
markWorkerSuccess,
|
||||||
} = require('../services/statusRuntime');
|
} = require('../services/statusRuntime');
|
||||||
const { localDateString, localDateStringDaysAgo } = require('../utils/dates');
|
const { localDateString, localDateStringDaysAgo } = require('../utils/dates.mts');
|
||||||
|
|
||||||
const DAILY_CRON_HOUR = 6;
|
const DAILY_CRON_HOUR = 6;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue