chore: remover seções vazias de mudanças de código

Este commit remove seções vazias de mudanças de código do arquivo de
mudanças. Isso ajuda a manter o histórico de mudanças mais limpo e
organizado, facilitando a leitura e a compreensão das alterações
realizadas no projeto.
This commit is contained in:
Felipe Coutinho
2025-12-16 23:20:47 +00:00
parent 0767636eed
commit e7cb9c9db1
37 changed files with 1350 additions and 920 deletions

View File

@@ -1,6 +1,6 @@
"use server";
import { contas, lancamentos } from "@/db/schema";
import { contas, lancamentos, pagadores, categorias, cartoes } from "@/db/schema";
import {
INITIAL_BALANCE_CONDITION,
INITIAL_BALANCE_NOTE,
@@ -31,6 +31,78 @@ import { and, asc, desc, eq, gte, inArray, sql } from "drizzle-orm";
import { randomUUID } from "node:crypto";
import { z } from "zod";
// ============================================================================
// Authorization Validation Functions
// ============================================================================
async function validatePagadorOwnership(
userId: string,
pagadorId: string | null | undefined
): Promise<boolean> {
if (!pagadorId) return true; // Se não tem pagadorId, não precisa validar
const pagador = await db.query.pagadores.findFirst({
where: and(
eq(pagadores.id, pagadorId),
eq(pagadores.userId, userId)
),
});
return !!pagador;
}
async function validateCategoriaOwnership(
userId: string,
categoriaId: string | null | undefined
): Promise<boolean> {
if (!categoriaId) return true;
const categoria = await db.query.categorias.findFirst({
where: and(
eq(categorias.id, categoriaId),
eq(categorias.userId, userId)
),
});
return !!categoria;
}
async function validateContaOwnership(
userId: string,
contaId: string | null | undefined
): Promise<boolean> {
if (!contaId) return true;
const conta = await db.query.contas.findFirst({
where: and(
eq(contas.id, contaId),
eq(contas.userId, userId)
),
});
return !!conta;
}
async function validateCartaoOwnership(
userId: string,
cartaoId: string | null | undefined
): Promise<boolean> {
if (!cartaoId) return true;
const cartao = await db.query.cartoes.findFirst({
where: and(
eq(cartoes.id, cartaoId),
eq(cartoes.userId, userId)
),
});
return !!cartao;
}
// ============================================================================
// Utility Functions
// ============================================================================
const resolvePeriod = (purchaseDate: string, period?: string | null) => {
if (period && /^\d{4}-\d{2}$/.test(period)) {
return period;
@@ -472,6 +544,42 @@ export async function createLancamentoAction(
const user = await getUser();
const data = createSchema.parse(input);
// Validar propriedade dos recursos referenciados
if (data.pagadorId) {
const isValid = await validatePagadorOwnership(user.id, data.pagadorId);
if (!isValid) {
return { success: false, error: "Pagador não encontrado ou sem permissão." };
}
}
if (data.secondaryPagadorId) {
const isValid = await validatePagadorOwnership(user.id, data.secondaryPagadorId);
if (!isValid) {
return { success: false, error: "Pagador secundário não encontrado ou sem permissão." };
}
}
if (data.categoriaId) {
const isValid = await validateCategoriaOwnership(user.id, data.categoriaId);
if (!isValid) {
return { success: false, error: "Categoria não encontrada." };
}
}
if (data.contaId) {
const isValid = await validateContaOwnership(user.id, data.contaId);
if (!isValid) {
return { success: false, error: "Conta não encontrada." };
}
}
if (data.cartaoId) {
const isValid = await validateCartaoOwnership(user.id, data.cartaoId);
if (!isValid) {
return { success: false, error: "Cartão não encontrado." };
}
}
const period = resolvePeriod(data.purchaseDate, data.period);
const purchaseDate = parseLocalDateString(data.purchaseDate);
const dueDate = data.dueDate ? parseLocalDateString(data.dueDate) : null;
@@ -556,6 +664,42 @@ export async function updateLancamentoAction(
const user = await getUser();
const data = updateSchema.parse(input);
// Validar propriedade dos recursos referenciados
if (data.pagadorId) {
const isValid = await validatePagadorOwnership(user.id, data.pagadorId);
if (!isValid) {
return { success: false, error: "Pagador não encontrado ou sem permissão." };
}
}
if (data.secondaryPagadorId) {
const isValid = await validatePagadorOwnership(user.id, data.secondaryPagadorId);
if (!isValid) {
return { success: false, error: "Pagador secundário não encontrado ou sem permissão." };
}
}
if (data.categoriaId) {
const isValid = await validateCategoriaOwnership(user.id, data.categoriaId);
if (!isValid) {
return { success: false, error: "Categoria não encontrada." };
}
}
if (data.contaId) {
const isValid = await validateContaOwnership(user.id, data.contaId);
if (!isValid) {
return { success: false, error: "Conta não encontrada." };
}
}
if (data.cartaoId) {
const isValid = await validateCartaoOwnership(user.id, data.cartaoId);
if (!isValid) {
return { success: false, error: "Cartão não encontrado." };
}
}
const existing = await db.query.lancamentos.findFirst({
columns: {
id: true,
@@ -1124,12 +1268,12 @@ const massAddTransactionSchema = z.object({
.number({ message: "Informe o valor da transação." })
.min(0, "Informe um valor maior ou igual a zero."),
categoriaId: uuidSchema("Categoria").nullable().optional(),
pagadorId: uuidSchema("Pagador").nullable().optional(),
});
const massAddSchema = z.object({
fixedFields: z.object({
transactionType: z.enum(LANCAMENTO_TRANSACTION_TYPES).optional(),
pagadorId: uuidSchema("Pagador").nullable().optional(),
paymentMethod: z.enum(LANCAMENTO_PAYMENT_METHODS).optional(),
condition: z.enum(LANCAMENTO_CONDITIONS).optional(),
period: z
@@ -1156,6 +1300,46 @@ export async function createMassLancamentosAction(
const user = await getUser();
const data = massAddSchema.parse(input);
// Validar campos fixos
if (data.fixedFields.contaId) {
const isValid = await validateContaOwnership(user.id, data.fixedFields.contaId);
if (!isValid) {
return { success: false, error: "Conta não encontrada." };
}
}
if (data.fixedFields.cartaoId) {
const isValid = await validateCartaoOwnership(user.id, data.fixedFields.cartaoId);
if (!isValid) {
return { success: false, error: "Cartão não encontrado." };
}
}
// Validar cada transação individual
for (let i = 0; i < data.transactions.length; i++) {
const transaction = data.transactions[i];
if (transaction.pagadorId) {
const isValid = await validatePagadorOwnership(user.id, transaction.pagadorId);
if (!isValid) {
return {
success: false,
error: `Pagador não encontrado na transação ${i + 1}.`
};
}
}
if (transaction.categoriaId) {
const isValid = await validateCategoriaOwnership(user.id, transaction.categoriaId);
if (!isValid) {
return {
success: false,
error: `Categoria não encontrada na transação ${i + 1}.`
};
}
}
}
// Default values for non-fixed fields
const defaultTransactionType = LANCAMENTO_TRANSACTION_TYPES[0];
const defaultCondition = LANCAMENTO_CONDITIONS[0];
@@ -1181,7 +1365,7 @@ export async function createMassLancamentosAction(
const condition = data.fixedFields.condition ?? defaultCondition;
const paymentMethod =
data.fixedFields.paymentMethod ?? defaultPaymentMethod;
const pagadorId = data.fixedFields.pagadorId ?? null;
const pagadorId = transaction.pagadorId ?? null;
const contaId =
paymentMethod === "Cartão de crédito"
? null