fix: resolve TODO.md security/perf/test-coverage backlog
Fixes the 13-item codebase health scan backlog: wraps meal-plan generation in a transaction, adds missing userId/GIN indexes, fixes an IPv6-parsing gap in the webhook SSRF guard (and an identical duplicated bug in the AI URL-import path, now consolidated onto one implementation), paginates the collections list, dedupes the AI recipe Zod schemas, wires up Stripe tier sync, rate-limits AI key rotation, gets `pnpm typecheck` actually working, and adds test coverage for the previously-untested admin/webhooks routes. Two flagged issues (collection removeRecipeId IDOR, tier-limit race) turned out to already be fixed/non-issues on inspection — noted in TODO.md rather than silently dropped. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+1
-34
@@ -1,6 +1,6 @@
|
||||
import { db } from "@epicure/db";
|
||||
import { tierDefinitions, userUsage } from "@epicure/db";
|
||||
import { eq, and, sql } from "@epicure/db";
|
||||
import { eq, sql } from "@epicure/db";
|
||||
|
||||
function currentMonth() {
|
||||
const now = new Date();
|
||||
@@ -69,39 +69,6 @@ export async function checkAndIncrementTierLimit(
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated Use checkAndIncrementTierLimit for recipe/aiCall keys to avoid TOCTOU races. */
|
||||
export async function checkTierLimit(
|
||||
userId: string,
|
||||
userTier: "free" | "pro",
|
||||
key: LimitKey
|
||||
): Promise<void> {
|
||||
const [tierDef] = await db
|
||||
.select()
|
||||
.from(tierDefinitions)
|
||||
.where(eq(tierDefinitions.tier, userTier));
|
||||
|
||||
if (!tierDef) return;
|
||||
|
||||
const month = currentMonth();
|
||||
const [usage] = await db
|
||||
.select()
|
||||
.from(userUsage)
|
||||
.where(and(eq(userUsage.userId, userId), eq(userUsage.month, month)));
|
||||
|
||||
const current = usage ?? {
|
||||
aiCallsUsed: 0,
|
||||
recipeCount: 0,
|
||||
storageUsedMb: 0,
|
||||
};
|
||||
|
||||
if (key === "recipe" && current.recipeCount >= tierDef.maxRecipes) {
|
||||
throw new TierLimitError("recipe", userTier);
|
||||
}
|
||||
if (key === "aiCall" && current.aiCallsUsed >= tierDef.aiCallsPerMonth) {
|
||||
throw new TierLimitError("aiCall", userTier);
|
||||
}
|
||||
}
|
||||
|
||||
export async function incrementUsage(
|
||||
userId: string,
|
||||
key: LimitKey,
|
||||
|
||||
Reference in New Issue
Block a user