Consolidate server utilities into shared module

- Add lib/server/utils/normalize.ts with normalizeTicker, normalizeTagsOrNull, nowIso, todayIso
- Add lib/server/utils/validation.ts with asRecord, asBoolean, asStringArray, asEnum
- Add lib/server/utils/index.ts re-exporting all utilities
- Remove duplicate lib/server/utils.ts (old file)
- Update all repos and files to use shared utilities
- Remove redundant ?? '' from normalizeTicker calls
- Update watchlist.ts to use normalizeTagsOrNull for null-return tags
This commit is contained in:
2026-03-15 15:56:16 -04:00
parent edf1cfb421
commit 5f0abbb007
14 changed files with 193 additions and 127 deletions

View File

@@ -3,6 +3,7 @@ import type { Holding } from '@/lib/types';
import { recalculateHolding } from '@/lib/server/portfolio';
import { db } from '@/lib/server/db';
import { filing, holding, watchlistItem } from '@/lib/server/db/schema';
import { normalizeTicker, nowIso } from '@/lib/server/utils';
type HoldingRow = typeof holding.$inferSelect;
@@ -30,7 +31,7 @@ function sortByMarketValueDesc(rows: Holding[]) {
function normalizeHoldingInput(input: { ticker: string; shares: number; avgCost: number; currentPrice: number }) {
return {
ticker: input.ticker.trim().toUpperCase(),
ticker: normalizeTicker(input.ticker),
shares: input.shares.toFixed(6),
avg_cost: input.avgCost.toFixed(6),
current_price: input.currentPrice.toFixed(6)
@@ -82,7 +83,7 @@ export async function listUserHoldings(userId: string) {
}
export async function getHoldingByTicker(userId: string, ticker: string) {
const normalizedTicker = ticker.trim().toUpperCase();
const normalizedTicker = normalizeTicker(ticker);
if (!normalizedTicker) {
return null;
}
@@ -104,8 +105,8 @@ export async function upsertHoldingRecord(input: {
currentPrice?: number;
companyName?: string;
}) {
const ticker = input.ticker.trim().toUpperCase();
const now = new Date().toISOString();
const ticker = normalizeTicker(input.ticker);
const now = nowIso();
const [existing] = await db
.select()
@@ -251,8 +252,8 @@ export async function updateHoldingByIdRecord(input: {
shares: shares.toFixed(6),
avg_cost: avgCost.toFixed(6),
current_price: currentPrice.toFixed(6),
updated_at: new Date().toISOString(),
last_price_at: new Date().toISOString()
updated_at: nowIso(),
last_price_at: nowIso()
});
const [updated] = await db