refactor: remover código morto e exports não utilizados

Remove 6 componentes não utilizados (dashboard-grid, expenses/income
by category widgets, installment analysis panels, fatura-warning-dialog).

Remove funções/tipos não utilizados: successResult, generateApiToken,
validateApiToken, getTodayUTC/Local, formatDateForDb, getDateInfo,
calculatePercentage, roundToDecimals, safeParseInt/Float, isPeriodValid,
getLastPeriods, normalizeWhitespace, formatCurrency wrapper,
InboxItemInput, InboxBatchInput, ProcessInboxInput, DiscardInboxInput,
LancamentosColumnId, 5 funções de anticipation-helpers.

Redireciona imports de formatCurrency para lib/lancamentos/formatting-helpers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-02-26 17:19:33 +00:00
parent c7eabc513e
commit 8de22b9930
22 changed files with 8 additions and 1014 deletions

View File

@@ -5,16 +5,6 @@ export type ActionResult<TData = void> =
| { success: true; message: string; data?: TData }
| { success: false; error: string };
/**
* Success result helper
*/
export function successResult<TData = void>(
message: string,
data?: TData,
): ActionResult<TData> {
return { success: true, message, data };
}
/**
* Error result helper
*/

View File

@@ -144,14 +144,6 @@ export function generateTokenId(): string {
return crypto.randomUUID();
}
/**
* Generate a random API token with prefix
*/
export function generateApiToken(): string {
const randomPart = crypto.randomBytes(32).toString("base64url");
return `os_${randomPart}`;
}
/**
* Hash a token using SHA-256
*/
@@ -236,18 +228,6 @@ export function extractBearerToken(authHeader: string | null): string | null {
return match ? match[1] : null;
}
/**
* Validate an API token and return the payload
* @deprecated Use validateHashToken for os_xxx tokens
*/
export function validateApiToken(token: string): JwtPayload | null {
const payload = verifyJwt(token);
if (!payload || payload.type !== "api_access") {
return null;
}
return payload;
}
/**
* Validate a hash-based API token (os_xxx format)
* Returns the token hash for database lookup

View File

@@ -1,47 +1,5 @@
import type { Lancamento } from "@/db/schema";
import type { EligibleInstallment } from "./anticipation-types";
/**
* Calcula o valor total de antecipação baseado nas parcelas selecionadas
*/
export function calculateTotalAnticipationAmount(
installments: EligibleInstallment[],
): number {
return installments.reduce((sum, inst) => sum + Number(inst.amount), 0);
}
/**
* Valida se o período de antecipação é válido
* O período não pode ser anterior ao período da primeira parcela selecionada
*/
export function validateAnticipationPeriod(
period: string,
installments: EligibleInstallment[],
): boolean {
if (installments.length === 0) return false;
const earliestPeriod = installments.reduce((earliest, inst) => {
return inst.period < earliest ? inst.period : earliest;
}, installments[0].period);
return period >= earliestPeriod;
}
/**
* Formata os números das parcelas antecipadas em uma string legível
* Exemplo: "1, 2, 3" ou "5, 6, 7, 8"
*/
export function getAnticipatedInstallmentNumbers(
installments: EligibleInstallment[],
): string {
const numbers = installments
.map((inst) => inst.currentInstallment)
.filter((num): num is number => num !== null)
.sort((a, b) => a - b)
.join(", ");
return numbers;
}
/**
* Formata o resumo de parcelas antecipadas
* Exemplo: "Parcelas 1-3 de 12" ou "Parcela 5 de 12"
@@ -67,7 +25,7 @@ export function formatAnticipatedInstallmentsRange(
// Se as parcelas são consecutivas
const isConsecutive = numbers.every((num, i) => {
if (i === 0) return true;
return num === numbers[i - 1]! + 1;
return num === (numbers[i - 1] ?? 0) + 1;
});
if (isConsecutive) {
@@ -77,27 +35,6 @@ export function formatAnticipatedInstallmentsRange(
}
}
/**
* Verifica se uma antecipação pode ser cancelada
* Só pode cancelar se o lançamento de antecipação não foi pago
*/
export function canCancelAnticipation(lancamento: Lancamento): boolean {
return lancamento.isSettled !== true;
}
/**
* Ordena parcelas por número da parcela atual
*/
export function sortInstallmentsByNumber(
installments: EligibleInstallment[],
): EligibleInstallment[] {
return [...installments].sort((a, b) => {
const aNum = a.currentInstallment ?? 0;
const bNum = b.currentInstallment ?? 0;
return aNum - bNum;
});
}
/**
* Calcula quantas parcelas restam após uma antecipação
*/
@@ -108,18 +45,6 @@ export function calculateRemainingInstallments(
return Math.max(0, totalInstallments - anticipatedCount);
}
/**
* Valida se as parcelas selecionadas pertencem à mesma série
*/
export function validateInstallmentsSameSeries(
installments: EligibleInstallment[],
_seriesId: string,
): boolean {
// Esta validação será feita no servidor com os dados completos
// Aqui apenas retorna true como placeholder
return installments.length > 0;
}
/**
* Gera descrição automática para o lançamento de antecipação
*/

View File

@@ -14,8 +14,6 @@ export const LANCAMENTOS_REORDERABLE_COLUMN_IDS = [
"contaCartao",
] as const;
export type LancamentosColumnId = (typeof LANCAMENTOS_REORDERABLE_COLUMN_IDS)[number];
export const LANCAMENTOS_COLUMN_LABELS: Record<string, string> = {
name: "Estabelecimento",
transactionType: "Transação",

View File

@@ -1,4 +1,3 @@
import { currencyFormatter } from "@/lib/lancamentos/formatting-helpers";
import { calculatePercentageChange } from "@/lib/utils/math";
import { buildPeriodRange, MONTH_NAMES, parsePeriod } from "@/lib/utils/period";
import type { DateRangeValidation } from "./types";
@@ -95,17 +94,6 @@ export function validateDateRange(
}
}
/**
* Formats a number as Brazilian currency (R$ X.XXX,XX)
* Uses the shared currencyFormatter from formatting-helpers
*
* @param value - Numeric value to format
* @returns Formatted currency string
*/
export function formatCurrency(value: number): string {
return currencyFormatter.format(value);
}
/**
* Formats percentage change for display
* Format: "±X%" or "±X.X%" (one decimal if < 10%)

View File

@@ -14,6 +14,3 @@ export const inboxItemSchema = z.object({
export const inboxBatchSchema = z.object({
items: z.array(inboxItemSchema).min(1).max(50),
});
export type InboxItemInput = z.infer<typeof inboxItemSchema>;
export type InboxBatchInput = z.infer<typeof inboxBatchSchema>;

View File

@@ -61,57 +61,6 @@ export function parseLocalDateString(dateString: string): Date {
);
}
/**
* Gets today's date in UTC
* @returns Date object set to today at midnight UTC
*/
export function getTodayUTC(): Date {
const now = new Date();
const year = now.getUTCFullYear();
const month = now.getUTCMonth();
const day = now.getUTCDate();
return new Date(Date.UTC(year, month, day));
}
/**
* Gets today's date in local timezone
* @returns Date object set to today at midnight local time
*/
export function getTodayLocal(): Date {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
const day = now.getDate();
return new Date(year, month, day);
}
/**
* Gets today's period in YYYY-MM format (UTC)
* @returns Period string
*/
export function getTodayPeriodUTC(): string {
const now = new Date();
const year = now.getUTCFullYear();
const month = now.getUTCMonth();
return `${year}-${String(month + 1).padStart(2, "0")}`;
}
/**
* Formats date as YYYY-MM-DD string
* @param date - Date to format
* @returns Formatted date string
*/
export function formatDateForDb(date: Date): string {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
/**
* Gets today's date as YYYY-MM-DD string
* @returns Formatted date string
@@ -224,27 +173,5 @@ export function getGreeting(date: Date = new Date()): string {
return "Boa noite";
}
// ============================================================================
// DATE INFORMATION
// ============================================================================
/**
* Gets information about a date
* @param date - Date to analyze (defaults to now)
* @returns Object with date information
*/
export function getDateInfo(date: Date = new Date()) {
return {
date,
year: date.getFullYear(),
month: date.getMonth() + 1,
monthName: MONTH_NAMES[date.getMonth()],
day: date.getDate(),
weekday: WEEKDAY_NAMES[date.getDay()],
friendlyDisplay: friendlyDate(date),
greeting: getGreeting(date),
};
}
// Re-export MONTH_NAMES for convenience
export { MONTH_NAMES };

View File

@@ -24,28 +24,3 @@ export function calculatePercentageChange(
// Protege contra valores absurdos (retorna null se > 1 milhão %)
return Number.isFinite(change) && Math.abs(change) < 1000000 ? change : null;
}
/**
* Calculates percentage of part relative to total
* @param part - Part value
* @param total - Total value
* @returns Percentage (0-100)
*/
export function calculatePercentage(part: number, total: number): number {
if (total === 0) {
return 0;
}
return (part / total) * 100;
}
/**
* Rounds number to specified decimal places
* @param value - Value to round
* @param decimals - Number of decimal places (default 2)
* @returns Rounded number
*/
export function roundToDecimals(value: number, decimals: number = 2): number {
const multiplier = 10 ** decimals;
return Math.round(value * multiplier) / multiplier;
}

View File

@@ -25,44 +25,3 @@ export function safeToNumber(value: unknown, defaultValue: number = 0): number {
const parsed = Number(value);
return Number.isNaN(parsed) ? defaultValue : parsed;
}
/**
* Safely parses integer from unknown value
* @param value - Value to parse
* @param defaultValue - Default value if parsing fails
* @returns Parsed integer or default value
*/
export function safeParseInt(value: unknown, defaultValue: number = 0): number {
if (typeof value === "number") {
return Math.trunc(value);
}
if (typeof value === "string") {
const parsed = Number.parseInt(value, 10);
return Number.isNaN(parsed) ? defaultValue : parsed;
}
return defaultValue;
}
/**
* Safely parses float from unknown value
* @param value - Value to parse
* @param defaultValue - Default value if parsing fails
* @returns Parsed float or default value
*/
export function safeParseFloat(
value: unknown,
defaultValue: number = 0,
): number {
if (typeof value === "number") {
return value;
}
if (typeof value === "string") {
const parsed = Number.parseFloat(value);
return Number.isNaN(parsed) ? defaultValue : parsed;
}
return defaultValue;
}

View File

@@ -29,8 +29,6 @@ export const MONTH_NAMES = [
"dezembro",
] as const;
export type MonthName = (typeof MONTH_NAMES)[number];
// ============================================================================
// CORE PARSING & FORMATTING (YYYY-MM format)
// ============================================================================
@@ -63,20 +61,6 @@ export function formatPeriod(year: number, month: number): string {
return `${year}-${String(month).padStart(2, "0")}`;
}
/**
* Validates if period string is valid
* @param period - Period string to validate
* @returns True if valid, false otherwise
*/
export function isPeriodValid(period: string): boolean {
try {
parsePeriod(period);
return true;
} catch {
return false;
}
}
// ============================================================================
// PERIOD NAVIGATION
// ============================================================================
@@ -139,22 +123,6 @@ export function addMonthsToPeriod(period: string, offset: number): string {
return formatPeriod(nextYear, nextMonth);
}
/**
* Gets the last N periods including the current one
* @param current - Current period in YYYY-MM format
* @param length - Number of periods to return
* @returns Array of period strings
*/
export function getLastPeriods(current: string, length: number): string[] {
const periods: string[] = [];
for (let offset = length - 1; offset >= 0; offset -= 1) {
periods.push(addMonthsToPeriod(current, -offset));
}
return periods;
}
// ============================================================================
// PERIOD COMPARISON & RANGES
// ============================================================================

View File

@@ -23,15 +23,6 @@ export function normalizeFilePath(path: string | null | undefined): string {
return path?.split("/").filter(Boolean).pop() ?? "";
}
/**
* Normalizes whitespace in string (replaces multiple spaces with single space)
* @param value - String to normalize
* @returns String with normalized whitespace
*/
export function normalizeWhitespace(value: string): string {
return value.replace(/\s+/g, " ").trim();
}
/**
* Normalizes icon input - trims and returns null if empty
* @param icon - Icon string to normalize