Files
budget/src/Budget.Core/Services/FrequencyCalculator.cs
T
Spencer Twaddle ac3dcc2f31 Security & resource hardening: eliminate CPU/disk attack surface
Addresses production CPU spike incident. Key changes:

- Guard OTel exporter behind OTEL_EXPORTER_OTLP_ENDPOINT env var; filter
  tracing to /api paths only — unconditional export was primary suspect
- Remove /healthz endpoint entirely (unauthenticated, hit DB on every call)
- Replace KnownUserMiddleware with POST /api/users/me called once on login
  from TokenSync — eliminates unconditional DB write on every request
- Add DB indexes: (BudgetId, IsDeleted) on Incomes/Outgos, OwnerUserId on
  Budgets, SharedWithUserId and (IsPending, SharedWithEmail) on BudgetShares
- Move UseRateLimiter() before UseStaticFiles() so all requests are throttled
- Replace full-array reorder with move-by-position (id + newIndex) — bounded
  input, fewer DB writes, better API design
- Lock ForwardedHeaders to 172.20.0.0/16 subnet; fixes KnownNetworks
  deprecation warning (0 warnings in build now)
- Add AsNoTracking() to all read-only queries in Summary/Incomes/OutgosController
- FrequencyCalculator returns 0 for unknown enum values instead of throwing
- Thread.Sleep → await Task.Delay in OIDC startup loop
- AllowedHosts locked to budget.stwaddle.com

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 22:17:18 -05:00

24 lines
811 B
C#

using Budget.Core.Models;
namespace Budget.Core.Services;
public static class FrequencyCalculator
{
public static decimal ToMonthly(decimal amount, Frequency frequency) => frequency switch
{
Frequency.Biennial => amount / 24m,
Frequency.Annually => amount / 12m,
Frequency.Biannually => amount * 2m / 12m,
Frequency.Quarterly => amount * 4m / 12m,
Frequency.EveryTwoMonths => amount * 6m / 12m,
Frequency.Monthly => amount,
Frequency.SemiMonthly => amount * 2m,
Frequency.Biweekly => amount * 26m / 12m,
Frequency.Weekly => amount * 52m / 12m,
_ => 0m,
};
public static decimal ToAnnually(decimal amount, Frequency frequency) =>
ToMonthly(amount, frequency) * 12m;
}