From 67ad4b9d028bf576157a82bffac9e3dbfe513907 Mon Sep 17 00:00:00 2001 From: Felipe Coutinho Date: Sat, 14 Mar 2026 12:50:55 +0000 Subject: [PATCH] refactor: alinha features financeiras ao novo naming --- .../accounts/[accountId]/statement/page.tsx | 70 ++++----- src/app/(dashboard)/budgets/loading.tsx | 2 +- .../cards/[cardId]/invoice/page.tsx | 108 ++++++------- .../categories/[categoryId]/page.tsx | 52 +++---- src/app/(dashboard)/inbox/page.tsx | 12 +- src/app/(dashboard)/settings/page.tsx | 12 +- src/features/accounts/actions.ts | 135 +++++++++------- .../accounts/components/account-dialog.tsx | 8 +- .../components/account-form-fields.tsx | 10 +- .../components/account-statement-card.tsx | 2 +- .../accounts/components/accounts-page.tsx | 4 +- .../accounts/components/transfer-dialog.tsx | 14 +- src/features/accounts/queries.ts | 132 ++++++++-------- src/features/accounts/statement-queries.ts | 75 ++++----- src/features/auth/components/signup-form.tsx | 2 +- src/features/budgets/actions.ts | 87 +++++------ .../budgets/components/budget-card.tsx | 2 +- .../budgets/components/budget-dialog.tsx | 12 +- src/features/budgets/components/types.ts | 2 +- src/features/budgets/queries.ts | 76 +++++---- src/features/cards/actions.ts | 41 ++--- src/features/cards/components/card-dialog.tsx | 6 +- .../cards/components/card-form-fields.tsx | 10 +- src/features/cards/components/card-item.tsx | 6 +- src/features/cards/components/cards-page.tsx | 2 +- src/features/cards/components/types.ts | 10 +- src/features/cards/queries.ts | 147 ++++++++---------- src/features/categories/actions.ts | 50 +++--- .../categories/components/category-dialog.tsx | 2 +- .../components/category-icon-badge.tsx | 1 + .../categories/components/category-icon.tsx | 2 +- src/features/categories/queries.ts | 8 +- src/features/inbox/actions.ts | 77 +++++---- src/features/inbox/components/inbox-page.tsx | 46 +++--- src/features/inbox/components/types.ts | 2 +- src/features/inbox/queries.ts | 130 ++++++++-------- src/features/invoices/actions.ts | 116 +++++++------- .../components/invoice-summary-card.tsx | 10 +- src/features/invoices/queries.ts | 52 +++---- src/features/notes/actions.ts | 44 +++--- src/features/notes/components/note-dialog.tsx | 2 +- src/features/notes/components/notes-page.tsx | 11 +- src/features/notes/components/types.ts | 2 +- src/features/notes/queries.ts | 34 ++-- src/features/settings/actions.ts | 64 ++++---- .../components/delete-account-form.tsx | 2 +- .../settings/components/passkeys-form.tsx | 4 +- .../settings/components/preferences-form.tsx | 16 +- src/features/settings/queries.ts | 38 ++--- src/shared/lib/accounts/constants.ts | 12 +- src/shared/lib/categories/defaults.ts | 10 +- 51 files changed, 876 insertions(+), 898 deletions(-) diff --git a/src/app/(dashboard)/accounts/[accountId]/statement/page.tsx b/src/app/(dashboard)/accounts/[accountId]/statement/page.tsx index bddd877..7f5771c 100644 --- a/src/app/(dashboard)/accounts/[accountId]/statement/page.tsx +++ b/src/app/(dashboard)/accounts/[accountId]/statement/page.tsx @@ -9,20 +9,20 @@ import { fetchAccountSummary, } from "@/features/accounts/statement-queries"; import { fetchUserPreferences } from "@/features/settings/queries"; -import { LancamentosPage as LancamentosSection } from "@/features/transactions/components/page/transactions-page"; +import { TransactionsPage as LancamentosSection } from "@/features/transactions/components/page/transactions-page"; import { - buildLancamentoWhere, + buildTransactionWhere, buildOptionSets, buildSluggedFilters, buildSlugMaps, - extractLancamentoSearchFilters, + extractTransactionSearchFilters, getSingleParam, - mapLancamentosData, + mapTransactionsData, type ResolvedSearchParams, } from "@/features/transactions/page-helpers"; import { - fetchLancamentoFilterSources, fetchRecentEstablishments, + fetchTransactionFilterSources, } from "@/features/transactions/queries"; import MonthNavigation from "@/shared/components/month-picker/month-navigation"; import { Button } from "@/shared/components/ui/button"; @@ -41,7 +41,7 @@ const capitalize = (value: string) => value.length > 0 ? value[0]?.toUpperCase().concat(value.slice(1)) : value; export default async function Page({ params, searchParams }: PageProps) { - const { accountId: contaId } = await params; + const { accountId } = await params; const userId = await getUserId(); const resolvedSearchParams = searchParams ? await searchParams : undefined; @@ -52,9 +52,9 @@ export default async function Page({ params, searchParams }: PageProps) { year, } = parsePeriodParam(periodoParamRaw); - const searchFilters = extractLancamentoSearchFilters(resolvedSearchParams); + const searchFilters = extractTransactionSearchFilters(resolvedSearchParams); - const account = await fetchAccountData(userId, contaId); + const account = await fetchAccountData(userId, accountId); if (!account) { notFound(); @@ -67,16 +67,16 @@ export default async function Page({ params, searchParams }: PageProps) { estabelecimentos, userPreferences, ] = await Promise.all([ - fetchLancamentoFilterSources(userId), + fetchTransactionFilterSources(userId), loadLogoOptions(), - fetchAccountSummary(userId, contaId, selectedPeriod), + fetchAccountSummary(userId, accountId, selectedPeriod), fetchRecentEstablishments(userId), fetchUserPreferences(userId), ]); const sluggedFilters = buildSluggedFilters(filterSources); const slugMaps = buildSlugMaps(sluggedFilters); - const filters = buildLancamentoWhere({ + const filters = buildTransactionWhere({ userId, period: selectedPeriod, filters: searchFilters, @@ -84,9 +84,9 @@ export default async function Page({ params, searchParams }: PageProps) { accountId: account.id, }); - const lancamentoRows = await fetchAccountLancamentos(filters); + const transactionRows = await fetchAccountLancamentos(filters); - const lancamentosData = mapLancamentosData(lancamentoRows); + const transactionData = mapTransactionsData(transactionRows); const { openingBalance, currentBalance, totalIncomes, totalExpenses } = accountSummary; @@ -105,18 +105,18 @@ export default async function Page({ params, searchParams }: PageProps) { }; const { - pagadorOptions, - splitPagadorOptions, - defaultPagadorId, - contaOptions, - cartaoOptions, - categoriaOptions, - pagadorFilterOptions, - categoriaFilterOptions, - contaCartaoFilterOptions, + payerOptions, + splitPayerOptions, + defaultPayerId, + accountOptions, + cardOptions, + categoryOptions, + payerFilterOptions, + categoryFilterOptions, + accountCardFilterOptions, } = buildOptionSets({ ...sluggedFilters, - pagadorRows: filterSources.pagadorRows, + payerRows: filterSources.payerRows, limitContaId: account.id, }); @@ -157,21 +157,21 @@ export default async function Page({ params, searchParams }: PageProps) {
diff --git a/src/app/(dashboard)/budgets/loading.tsx b/src/app/(dashboard)/budgets/loading.tsx index 0f72aad..e44ea8c 100644 --- a/src/app/(dashboard)/budgets/loading.tsx +++ b/src/app/(dashboard)/budgets/loading.tsx @@ -24,7 +24,7 @@ export default function OrcamentosLoading() {
{Array.from({ length: 6 }).map((_, i) => (
- {/* Categoria com ícone */} + {/* Category com ícone */}
diff --git a/src/app/(dashboard)/cards/[cardId]/invoice/page.tsx b/src/app/(dashboard)/cards/[cardId]/invoice/page.tsx index 6a6ebb1..998da3d 100644 --- a/src/app/(dashboard)/cards/[cardId]/invoice/page.tsx +++ b/src/app/(dashboard)/cards/[cardId]/invoice/page.tsx @@ -1,29 +1,29 @@ import { RiPencilLine } from "@remixicon/react"; import { notFound } from "next/navigation"; -import type { Conta } from "@/db/schema"; +import type { FinancialAccount } from "@/db/schema"; import { CardDialog } from "@/features/cards/components/card-dialog"; import type { Card } from "@/features/cards/components/types"; import { InvoiceSummaryCard } from "@/features/invoices/components/invoice-summary-card"; import { fetchCardData, - fetchCardLancamentos, + fetchCardTransactions, fetchInvoiceData, } from "@/features/invoices/queries"; import { fetchUserPreferences } from "@/features/settings/queries"; -import { LancamentosPage as LancamentosSection } from "@/features/transactions/components/page/transactions-page"; +import { TransactionsPage as LancamentosSection } from "@/features/transactions/components/page/transactions-page"; import { - buildLancamentoWhere, buildOptionSets, buildSluggedFilters, buildSlugMaps, - extractLancamentoSearchFilters, + buildTransactionWhere, + extractTransactionSearchFilters, getSingleParam, - mapLancamentosData, + mapTransactionsData, type ResolvedSearchParams, } from "@/features/transactions/page-helpers"; import { - fetchLancamentoFilterSources, fetchRecentEstablishments, + fetchTransactionFilterSources, } from "@/features/transactions/queries"; import MonthNavigation from "@/shared/components/month-picker/month-navigation"; import { Button } from "@/shared/components/ui/button"; @@ -39,7 +39,7 @@ type PageProps = { }; export default async function Page({ params, searchParams }: PageProps) { - const { cardId: cartaoId } = await params; + const { cardId } = await params; const userId = await getUserId(); const resolvedSearchParams = searchParams ? await searchParams : undefined; @@ -50,9 +50,9 @@ export default async function Page({ params, searchParams }: PageProps) { year, } = parsePeriodParam(periodoParamRaw); - const searchFilters = extractLancamentoSearchFilters(resolvedSearchParams); + const searchFilters = extractTransactionSearchFilters(resolvedSearchParams); - const card = await fetchCardData(userId, cartaoId); + const card = await fetchCardData(userId, cardId); if (!card) { notFound(); @@ -65,16 +65,16 @@ export default async function Page({ params, searchParams }: PageProps) { estabelecimentos, userPreferences, ] = await Promise.all([ - fetchLancamentoFilterSources(userId), + fetchTransactionFilterSources(userId), loadLogoOptions(), - fetchInvoiceData(userId, cartaoId, selectedPeriod), + fetchInvoiceData(userId, cardId, selectedPeriod), fetchRecentEstablishments(userId), fetchUserPreferences(userId), ]); const sluggedFilters = buildSluggedFilters(filterSources); const slugMaps = buildSlugMaps(sluggedFilters); - const filters = buildLancamentoWhere({ + const filters = buildTransactionWhere({ userId, period: selectedPeriod, filters: searchFilters, @@ -82,35 +82,39 @@ export default async function Page({ params, searchParams }: PageProps) { cardId: card.id, }); - const lancamentoRows = await fetchCardLancamentos(filters); + const transactionRows = await fetchCardTransactions(filters); - const lancamentosData = mapLancamentosData(lancamentoRows); + const transactionData = mapTransactionsData(transactionRows); const { - pagadorOptions, - splitPagadorOptions, - defaultPagadorId, - contaOptions, - cartaoOptions, - categoriaOptions, - pagadorFilterOptions, - categoriaFilterOptions, - contaCartaoFilterOptions, + payerOptions, + splitPayerOptions, + defaultPayerId, + accountOptions, + cardOptions, + categoryOptions, + payerFilterOptions, + categoryFilterOptions, + accountCardFilterOptions, } = buildOptionSets({ ...sluggedFilters, - pagadorRows: filterSources.pagadorRows, + payerRows: filterSources.payerRows, limitCartaoId: card.id, }); - const accountOptions = filterSources.contaRows.map((conta: Conta) => ({ - id: conta.id, - name: conta.name ?? "Conta", - logo: conta.logo ?? null, - })); + const cardDialogAccounts = filterSources.accountRows.map( + (financialAccount: FinancialAccount) => ({ + id: financialAccount.id, + name: financialAccount.name ?? "FinancialAccount", + logo: financialAccount.logo ?? null, + }), + ); - const contaName = - filterSources.contaRows.find((conta: Conta) => conta.id === card.contaId) - ?.name ?? "Conta"; + const accountName = + filterSources.accountRows.find( + (financialAccount: FinancialAccount) => + financialAccount.id === card.accountId, + )?.name ?? "FinancialAccount"; const cardDialogData: Card = { id: card.id, @@ -125,9 +129,9 @@ export default async function Page({ params, searchParams }: PageProps) { card.limit !== null && card.limit !== undefined ? Number(card.limit) : null, - contaId: card.contaId, - contaName, - limitInUse: null, + accountId: card.accountId, + accountName, + limitInUse: 0, limitAvailable: null, }; @@ -145,7 +149,7 @@ export default async function Page({ params, searchParams }: PageProps) {
diff --git a/src/app/(dashboard)/categories/[categoryId]/page.tsx b/src/app/(dashboard)/categories/[categoryId]/page.tsx index 91cade9..2c06b75 100644 --- a/src/app/(dashboard)/categories/[categoryId]/page.tsx +++ b/src/app/(dashboard)/categories/[categoryId]/page.tsx @@ -2,14 +2,14 @@ import { notFound } from "next/navigation"; import { CategoryDetailHeader } from "@/features/categories/components/category-detail-header"; import { fetchCategoryDetails } from "@/features/dashboard/categories/category-details-queries"; import { fetchUserPreferences } from "@/features/settings/queries"; -import { LancamentosPage } from "@/features/transactions/components/page/transactions-page"; +import { TransactionsPage } from "@/features/transactions/components/page/transactions-page"; import { buildOptionSets, buildSluggedFilters, } from "@/features/transactions/page-helpers"; import { - fetchLancamentoFilterSources, fetchRecentEstablishments, + fetchTransactionFilterSources, } from "@/features/transactions/queries"; import MonthNavigation from "@/shared/components/month-picker/month-navigation"; import { getUserId } from "@/shared/lib/auth/server"; @@ -42,7 +42,7 @@ export default async function Page({ params, searchParams }: PageProps) { const [detail, filterSources, estabelecimentos, userPreferences] = await Promise.all([ fetchCategoryDetails(userId, categoryId, selectedPeriod), - fetchLancamentoFilterSources(userId), + fetchTransactionFilterSources(userId), fetchRecentEstablishments(userId), fetchUserPreferences(userId), ]); @@ -53,18 +53,18 @@ export default async function Page({ params, searchParams }: PageProps) { const sluggedFilters = buildSluggedFilters(filterSources); const { - pagadorOptions, - splitPagadorOptions, - defaultPagadorId, - contaOptions, - cartaoOptions, - categoriaOptions, - pagadorFilterOptions, - categoriaFilterOptions, - contaCartaoFilterOptions, + payerOptions, + splitPayerOptions, + defaultPayerId, + accountOptions, + cardOptions, + categoryOptions, + payerFilterOptions, + categoryFilterOptions, + accountCardFilterOptions, } = buildOptionSets({ ...sluggedFilters, - pagadorRows: filterSources.pagadorRows, + payerRows: filterSources.payerRows, }); const currentPeriodLabel = displayPeriod(detail.period); @@ -82,23 +82,23 @@ export default async function Page({ params, searchParams }: PageProps) { percentageChange={detail.percentageChange} transactionCount={detail.transactions.length} /> - ); diff --git a/src/app/(dashboard)/inbox/page.tsx b/src/app/(dashboard)/inbox/page.tsx index b535760..a464b9c 100644 --- a/src/app/(dashboard)/inbox/page.tsx +++ b/src/app/(dashboard)/inbox/page.tsx @@ -24,12 +24,12 @@ export default async function Page() { pendingItems={pendingItems} processedItems={processedItems} discardedItems={discardedItems} - pagadorOptions={dialogData.pagadorOptions} - splitPagadorOptions={dialogData.splitPagadorOptions} - defaultPagadorId={dialogData.defaultPagadorId} - contaOptions={dialogData.contaOptions} - cartaoOptions={dialogData.cartaoOptions} - categoriaOptions={dialogData.categoriaOptions} + payerOptions={dialogData.payerOptions} + splitPayerOptions={dialogData.splitPayerOptions} + defaultPayerId={dialogData.defaultPayerId} + accountOptions={dialogData.accountOptions} + cardOptions={dialogData.cardOptions} + categoryOptions={dialogData.categoryOptions} estabelecimentos={dialogData.estabelecimentos} appLogoMap={appLogoMap} /> diff --git a/src/app/(dashboard)/settings/page.tsx b/src/app/(dashboard)/settings/page.tsx index 4d5fe5a..b3a5f67 100644 --- a/src/app/(dashboard)/settings/page.tsx +++ b/src/app/(dashboard)/settings/page.tsx @@ -9,7 +9,7 @@ import { PreferencesForm } from "@/features/settings/components/preferences-form import { UpdateEmailForm } from "@/features/settings/components/update-email-form"; import { UpdateNameForm } from "@/features/settings/components/update-name-form"; import { UpdatePasswordForm } from "@/features/settings/components/update-password-form"; -import { fetchAjustesPageData } from "@/features/settings/queries"; +import { fetchSettingsPageData } from "@/features/settings/queries"; import { Card } from "@/shared/components/ui/card"; import { Tabs, @@ -32,7 +32,7 @@ export default async function Page() { const userEmail = session.user.email || ""; const { authProvider, userPreferences, userApiTokens } = - await fetchAjustesPageData(session.user.id); + await fetchSettingsPageData(session.user.id); return (
@@ -71,11 +71,11 @@ export default async function Page() {

diff --git a/src/features/accounts/actions.ts b/src/features/accounts/actions.ts index d36f4f4..1139acc 100644 --- a/src/features/accounts/actions.ts +++ b/src/features/accounts/actions.ts @@ -2,7 +2,12 @@ import { and, eq } from "drizzle-orm"; import { z } from "zod"; -import { categorias, contas, lancamentos, pagadores } from "@/db/schema"; +import { + categories, + financialAccounts, + payers, + transactions, +} from "@/db/schema"; import { INITIAL_BALANCE_CATEGORY_NAME, INITIAL_BALANCE_CONDITION, @@ -17,7 +22,7 @@ import { } from "@/shared/lib/actions/helpers"; import { getUser } from "@/shared/lib/auth/server"; import { db } from "@/shared/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/shared/lib/payers/constants"; +import { PAYER_ROLE_ADMIN } from "@/shared/lib/payers/constants"; import { noteSchema, uuidSchema } from "@/shared/lib/schemas/common"; import { TRANSFER_CATEGORY_NAME, @@ -67,10 +72,10 @@ const accountBaseSchema = z.object({ const createAccountSchema = accountBaseSchema; const updateAccountSchema = accountBaseSchema.extend({ - id: uuidSchema("Conta"), + id: uuidSchema("FinancialAccount"), }); const deleteAccountSchema = z.object({ - id: uuidSchema("Conta"), + id: uuidSchema("FinancialAccount"), }); type AccountCreateInput = z.infer; @@ -91,7 +96,7 @@ export async function createAccountAction( await db.transaction(async (tx: typeof db) => { const [createdAccount] = await tx - .insert(contas) + .insert(financialAccounts) .values({ name: data.name, accountType: data.accountType, @@ -103,7 +108,7 @@ export async function createAccountAction( excludeInitialBalanceFromIncome: data.excludeInitialBalanceFromIncome, userId: user.id, }) - .returning({ id: contas.id, name: contas.name }); + .returning({ id: financialAccounts.id, name: financialAccounts.name }); if (!createdAccount) { throw new Error("Não foi possível criar a conta."); @@ -114,37 +119,37 @@ export async function createAccountAction( } const [category, adminPagador] = await Promise.all([ - tx.query.categorias.findFirst({ + tx.query.categories.findFirst({ columns: { id: true }, where: and( - eq(categorias.userId, user.id), - eq(categorias.name, INITIAL_BALANCE_CATEGORY_NAME), + eq(categories.userId, user.id), + eq(categories.name, INITIAL_BALANCE_CATEGORY_NAME), ), }), - tx.query.pagadores.findFirst({ + tx.query.payers.findFirst({ columns: { id: true }, where: and( - eq(pagadores.userId, user.id), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), + eq(payers.userId, user.id), + eq(payers.role, PAYER_ROLE_ADMIN), ), }), ]); if (!category) { throw new Error( - 'Categoria "Saldo inicial" não encontrada. Crie-a antes de definir um saldo inicial.', + 'Category "Saldo inicial" não encontrada. Crie-a antes de definir um saldo inicial.', ); } if (!adminPagador) { throw new Error( - "Pagador com papel administrador não encontrado. Crie um pagador admin antes de definir um saldo inicial.", + "Payer com papel administrador não encontrado. Crie um pagador admin antes de definir um saldo inicial.", ); } const { date, period } = getTodayInfo(); - await tx.insert(lancamentos).values({ + await tx.insert(transactions).values({ condition: INITIAL_BALANCE_CONDITION, name: `Saldo inicial - ${createdAccount.name}`, paymentMethod: INITIAL_BALANCE_PAYMENT_METHOD, @@ -155,17 +160,17 @@ export async function createAccountAction( period, isSettled: true, userId: user.id, - contaId: createdAccount.id, - categoriaId: category.id, - pagadorId: adminPagador.id, + accountId: createdAccount.id, + categoryId: category.id, + payerId: adminPagador.id, }); }); - revalidateForEntity("contas"); + revalidateForEntity("accounts"); return { success: true, - message: "Conta criada com sucesso.", + message: "FinancialAccount criada com sucesso.", }; } catch (error) { return handleActionError(error); @@ -182,7 +187,7 @@ export async function updateAccountAction( const logoFile = normalizeFilePath(data.logo); const [updated] = await db - .update(contas) + .update(financialAccounts) .set({ name: data.name, accountType: data.accountType, @@ -193,21 +198,26 @@ export async function updateAccountAction( excludeFromBalance: data.excludeFromBalance, excludeInitialBalanceFromIncome: data.excludeInitialBalanceFromIncome, }) - .where(and(eq(contas.id, data.id), eq(contas.userId, user.id))) + .where( + and( + eq(financialAccounts.id, data.id), + eq(financialAccounts.userId, user.id), + ), + ) .returning(); if (!updated) { return { success: false, - error: "Conta não encontrada.", + error: "FinancialAccount não encontrada.", }; } - revalidateForEntity("contas"); + revalidateForEntity("accounts"); return { success: true, - message: "Conta atualizada com sucesso.", + message: "FinancialAccount atualizada com sucesso.", }; } catch (error) { return handleActionError(error); @@ -222,22 +232,27 @@ export async function deleteAccountAction( const data = deleteAccountSchema.parse(input); const [deleted] = await db - .delete(contas) - .where(and(eq(contas.id, data.id), eq(contas.userId, user.id))) - .returning({ id: contas.id }); + .delete(financialAccounts) + .where( + and( + eq(financialAccounts.id, data.id), + eq(financialAccounts.userId, user.id), + ), + ) + .returning({ id: financialAccounts.id }); if (!deleted) { return { success: false, - error: "Conta não encontrada.", + error: "FinancialAccount não encontrada.", }; } - revalidateForEntity("contas"); + revalidateForEntity("accounts"); return { success: true, - message: "Conta removida com sucesso.", + message: "FinancialAccount removida com sucesso.", }; } catch (error) { return handleActionError(error); @@ -246,8 +261,8 @@ export async function deleteAccountAction( // Transfer between accounts const transferSchema = z.object({ - fromAccountId: uuidSchema("Conta de origem"), - toAccountId: uuidSchema("Conta de destino"), + fromAccountId: uuidSchema("FinancialAccount de origem"), + toAccountId: uuidSchema("FinancialAccount de destino"), amount: z .string() .trim() @@ -265,7 +280,7 @@ const transferSchema = z.object({ .min(1, "Informe o período."), }); -type TransferInput = z.infer; +type TransferInput = z.input; export async function transferBetweenAccountsAction( input: TransferInput, @@ -288,64 +303,64 @@ export async function transferBetweenAccountsAction( await db.transaction(async (tx: typeof db) => { // Verify both accounts exist and belong to the user const [fromAccount, toAccount] = await Promise.all([ - tx.query.contas.findFirst({ + tx.query.financialAccounts.findFirst({ columns: { id: true, name: true }, where: and( - eq(contas.id, data.fromAccountId), - eq(contas.userId, user.id), + eq(financialAccounts.id, data.fromAccountId), + eq(financialAccounts.userId, user.id), ), }), - tx.query.contas.findFirst({ + tx.query.financialAccounts.findFirst({ columns: { id: true, name: true }, where: and( - eq(contas.id, data.toAccountId), - eq(contas.userId, user.id), + eq(financialAccounts.id, data.toAccountId), + eq(financialAccounts.userId, user.id), ), }), ]); if (!fromAccount) { - throw new Error("Conta de origem não encontrada."); + throw new Error("FinancialAccount de origem não encontrada."); } if (!toAccount) { - throw new Error("Conta de destino não encontrada."); + throw new Error("FinancialAccount de destino não encontrada."); } // Get the transfer category - const transferCategory = await tx.query.categorias.findFirst({ + const transferCategory = await tx.query.categories.findFirst({ columns: { id: true }, where: and( - eq(categorias.userId, user.id), - eq(categorias.name, TRANSFER_CATEGORY_NAME), + eq(categories.userId, user.id), + eq(categories.name, TRANSFER_CATEGORY_NAME), ), }); if (!transferCategory) { throw new Error( - `Categoria "${TRANSFER_CATEGORY_NAME}" não encontrada. Por favor, crie esta categoria antes de fazer transferências.`, + `Category "${TRANSFER_CATEGORY_NAME}" não encontrada. Por favor, crie esta categoria antes de fazer transferências.`, ); } // Get the admin payer - const adminPagador = await tx.query.pagadores.findFirst({ + const adminPagador = await tx.query.payers.findFirst({ columns: { id: true }, where: and( - eq(pagadores.userId, user.id), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), + eq(payers.userId, user.id), + eq(payers.role, PAYER_ROLE_ADMIN), ), }); if (!adminPagador) { throw new Error( - "Pagador administrador não encontrado. Por favor, crie um pagador admin.", + "Payer administrador não encontrado. Por favor, crie um pagador admin.", ); } const transferNote = `de ${fromAccount.name} -> ${toAccount.name}`; // Create outgoing transaction (transfer from source account) - await tx.insert(lancamentos).values({ + await tx.insert(transactions).values({ condition: TRANSFER_CONDITION, name: TRANSFER_ESTABLISHMENT_SAIDA, paymentMethod: TRANSFER_PAYMENT_METHOD, @@ -356,14 +371,14 @@ export async function transferBetweenAccountsAction( period: data.period, isSettled: true, userId: user.id, - contaId: fromAccount.id, - categoriaId: transferCategory.id, - pagadorId: adminPagador.id, + accountId: fromAccount.id, + categoryId: transferCategory.id, + payerId: adminPagador.id, transferId, }); // Create incoming transaction (transfer to destination account) - await tx.insert(lancamentos).values({ + await tx.insert(transactions).values({ condition: TRANSFER_CONDITION, name: TRANSFER_ESTABLISHMENT_ENTRADA, paymentMethod: TRANSFER_PAYMENT_METHOD, @@ -374,15 +389,15 @@ export async function transferBetweenAccountsAction( period: data.period, isSettled: true, userId: user.id, - contaId: toAccount.id, - categoriaId: transferCategory.id, - pagadorId: adminPagador.id, + accountId: toAccount.id, + categoryId: transferCategory.id, + payerId: adminPagador.id, transferId, }); }); - revalidateForEntity("contas"); - revalidateForEntity("lancamentos"); + revalidateForEntity("accounts"); + revalidateForEntity("transactions"); return { success: true, diff --git a/src/features/accounts/components/account-dialog.tsx b/src/features/accounts/components/account-dialog.tsx index 5b3e267..3a1d8c8 100644 --- a/src/features/accounts/components/account-dialog.tsx +++ b/src/features/accounts/components/account-dialog.tsx @@ -33,10 +33,10 @@ import { AccountFormFields } from "./account-form-fields"; import type { Account, AccountFormValues } from "./types"; const DEFAULT_ACCOUNT_TYPES = [ - "Conta Corrente", - "Conta Poupança", + "FinancialAccount Corrente", + "FinancialAccount Poupança", "Carteira Digital", - "Conta Investimento", + "FinancialAccount Investimento", "Pré-Pago | VR/VA", ] as const; @@ -167,7 +167,7 @@ export function AccountDialog({ const accountId = account?.id; if (mode === "update" && !accountId) { - const message = "Conta inválida."; + const message = "FinancialAccount inválida."; setErrorMessage(message); toast.error(message); return; diff --git a/src/features/accounts/components/account-form-fields.tsx b/src/features/accounts/components/account-form-fields.tsx index 0cbc1b7..89fddd3 100644 --- a/src/features/accounts/components/account-form-fields.tsx +++ b/src/features/accounts/components/account-form-fields.tsx @@ -110,10 +110,7 @@ export function AccountFormFields({
onChange("excludeFromBalance", checked ? "true" : "false") } @@ -130,10 +127,7 @@ export function AccountFormFields({
onChange( "excludeInitialBalanceFromIncome", diff --git a/src/features/accounts/components/account-statement-card.tsx b/src/features/accounts/components/account-statement-card.tsx index 2da6565..3b878b0 100644 --- a/src/features/accounts/components/account-statement-card.tsx +++ b/src/features/accounts/components/account-statement-card.tsx @@ -142,7 +142,7 @@ export function AccountStatementCard({ />
- {/* Informações da Conta */} + {/* Informações da FinancialAccount */}
} title={ - isArchived - ? "Nenhuma conta arquivada" - : "Nenhuma conta cadastrada" + isArchived ? "Nenhuma conta archived" : "Nenhuma conta cadastrada" } description={ isArchived diff --git a/src/features/accounts/components/transfer-dialog.tsx b/src/features/accounts/components/transfer-dialog.tsx index 4bb7502..b161457 100644 --- a/src/features/accounts/components/transfer-dialog.tsx +++ b/src/features/accounts/components/transfer-dialog.tsx @@ -4,7 +4,7 @@ import { useState, useTransition } from "react"; import { toast } from "sonner"; import { transferBetweenAccountsAction } from "@/features/accounts/actions"; import type { AccountData } from "@/features/accounts/queries"; -import { ContaCartaoSelectContent } from "@/features/transactions/components/select-items"; +import { AccountCardSelectContent } from "@/features/transactions/components/select-items"; import { PeriodPicker } from "@/shared/components/period-picker"; import { Button } from "@/shared/components/ui/button"; import { CurrencyInput } from "@/shared/components/ui/currency-input"; @@ -157,12 +157,12 @@ export function TransferDialog({
- + updateField("categoriaId", value)} + value={formState.categoryId} + onValueChange={(value) => updateField("categoryId", value)} > diff --git a/src/features/budgets/components/types.ts b/src/features/budgets/components/types.ts index 9860f89..83ad6e3 100644 --- a/src/features/budgets/components/types.ts +++ b/src/features/budgets/components/types.ts @@ -14,7 +14,7 @@ export type Budget = { }; export type BudgetFormValues = { - categoriaId: string; + categoryId: string; period: string; amount: string; }; diff --git a/src/features/budgets/queries.ts b/src/features/budgets/queries.ts index 0e852c2..c013aaa 100644 --- a/src/features/budgets/queries.ts +++ b/src/features/budgets/queries.ts @@ -1,14 +1,14 @@ import { and, asc, eq, inArray, isNull, or, sql, sum } from "drizzle-orm"; import { - categorias, - lancamentos, - type Orcamento, - orcamentos, - pagadores, + type Budget, + budgets, + categories, + payers, + transactions, } from "@/db/schema"; import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX } from "@/shared/lib/accounts/constants"; import { db } from "@/shared/lib/db"; -import { PAGADOR_ROLE_ADMIN } from "@/shared/lib/payers/constants"; +import { PAYER_ROLE_ADMIN } from "@/shared/lib/payers/constants"; const toNumber = (value: string | number | null | undefined) => { if (typeof value === "number") return value; @@ -46,28 +46,28 @@ export async function fetchBudgetsForUser( categoriesOptions: CategoryOption[]; }> { const [budgetRows, categoryRows] = await Promise.all([ - db.query.orcamentos.findMany({ + db.query.budgets.findMany({ where: and( - eq(orcamentos.userId, userId), - eq(orcamentos.period, selectedPeriod), + eq(budgets.userId, userId), + eq(budgets.period, selectedPeriod), ), with: { - categoria: true, + category: true, }, }), - db.query.categorias.findMany({ + db.query.categories.findMany({ columns: { id: true, name: true, icon: true, }, - where: and(eq(categorias.userId, userId), eq(categorias.type, "despesa")), - orderBy: asc(categorias.name), + where: and(eq(categories.userId, userId), eq(categories.type, "despesa")), + orderBy: asc(categories.name), }), ]); const categoryIds = budgetRows - .map((budget: Orcamento) => budget.categoriaId) + .map((budget) => budget.categoryId) .filter((id: string | null): id is string => Boolean(id)); let totalsByCategory = new Map(); @@ -75,50 +75,48 @@ export async function fetchBudgetsForUser( if (categoryIds.length > 0) { const totals = await db .select({ - categoriaId: lancamentos.categoriaId, - totalAmount: sum(lancamentos.amount).as("totalAmount"), + categoryId: transactions.categoryId, + totalAmount: sum(transactions.amount).as("totalAmount"), }) - .from(lancamentos) - .innerJoin(pagadores, eq(lancamentos.pagadorId, pagadores.id)) + .from(transactions) + .innerJoin(payers, eq(transactions.payerId, payers.id)) .where( and( - eq(lancamentos.userId, userId), - eq(lancamentos.period, selectedPeriod), - eq(lancamentos.transactionType, "Despesa"), - eq(pagadores.role, PAGADOR_ROLE_ADMIN), - inArray(lancamentos.categoriaId, categoryIds), + eq(transactions.userId, userId), + eq(transactions.period, selectedPeriod), + eq(transactions.transactionType, "Despesa"), + eq(payers.role, PAYER_ROLE_ADMIN), + inArray(transactions.categoryId, categoryIds), or( - isNull(lancamentos.note), - sql`${lancamentos.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`}`, + isNull(transactions.note), + sql`${transactions.note} NOT LIKE ${`${ACCOUNT_AUTO_INVOICE_NOTE_PREFIX}%`}`, ), ), ) - .groupBy(lancamentos.categoriaId); + .groupBy(transactions.categoryId); totalsByCategory = new Map( totals.map( - (row: { categoriaId: string | null; totalAmount: string | null }) => [ - row.categoriaId ?? "", + (row: { categoryId: string | null; totalAmount: string | null }) => [ + row.categoryId ?? "", Math.abs(toNumber(row.totalAmount)), ], ), ); } - const budgets = budgetRows - .map((budget: Orcamento) => ({ + const budgetList = budgetRows + .map((budget) => ({ id: budget.id, amount: toNumber(budget.amount), - spent: totalsByCategory.get(budget.categoriaId ?? "") ?? 0, + spent: totalsByCategory.get(budget.categoryId ?? "") ?? 0, period: budget.period, createdAt: budget.createdAt.toISOString(), - category: budget.categoria - ? { - id: budget.categoria.id, - name: budget.categoria.name, - icon: budget.categoria.icon, - } - : null, + category: (() => { + type Cat = { id: string; name: string; icon: string | null }; + const cat = budget.category as Cat | null | undefined; + return cat ? { id: cat.id, name: cat.name, icon: cat.icon } : null; + })(), })) .sort((a, b) => (a.category?.name ?? "").localeCompare(b.category?.name ?? "", "pt-BR", { @@ -132,5 +130,5 @@ export async function fetchBudgetsForUser( icon: category.icon, })); - return { budgets, categoriesOptions }; + return { budgets: budgetList, categoriesOptions }; } diff --git a/src/features/cards/actions.ts b/src/features/cards/actions.ts index 0513d8d..fa95f49 100644 --- a/src/features/cards/actions.ts +++ b/src/features/cards/actions.ts @@ -2,7 +2,7 @@ import { and, eq } from "drizzle-orm"; import { z } from "zod"; -import { cartoes, contas } from "@/db/schema"; +import { cards, financialAccounts } from "@/db/schema"; import { type ActionResult, handleActionError, @@ -40,7 +40,7 @@ const cardBaseSchema = z.object({ .string({ message: "Selecione um logo." }) .trim() .min(1, "Selecione um logo."), - contaId: uuidSchema("Conta"), + accountId: uuidSchema("FinancialAccount"), }); const createCardSchema = cardBaseSchema; @@ -55,14 +55,17 @@ type CardCreateInput = z.infer; type CardUpdateInput = z.infer; type CardDeleteInput = z.infer; -async function assertAccountOwnership(userId: string, contaId: string) { - const account = await db.query.contas.findFirst({ +async function assertAccountOwnership(userId: string, accountId: string) { + const account = await db.query.financialAccounts.findFirst({ columns: { id: true }, - where: and(eq(contas.id, contaId), eq(contas.userId, userId)), + where: and( + eq(financialAccounts.id, accountId), + eq(financialAccounts.userId, userId), + ), }); if (!account) { - throw new Error("Conta vinculada não encontrada."); + throw new Error("FinancialAccount vinculada não encontrada."); } } @@ -73,11 +76,11 @@ export async function createCardAction( const user = await getUser(); const data = createCardSchema.parse(input); - await assertAccountOwnership(user.id, data.contaId); + await assertAccountOwnership(user.id, data.accountId); const logoFile = normalizeFilePath(data.logo); - await db.insert(cartoes).values({ + await db.insert(cards).values({ name: data.name, brand: data.brand, status: data.status, @@ -86,11 +89,11 @@ export async function createCardAction( note: data.note ?? null, limit: formatDecimalForDb(data.limit), logo: logoFile, - contaId: data.contaId, + accountId: data.accountId, userId: user.id, }); - revalidateForEntity("cartoes"); + revalidateForEntity("cards"); return { success: true, message: "Cartão criado com sucesso." }; } catch (error) { @@ -105,12 +108,12 @@ export async function updateCardAction( const user = await getUser(); const data = updateCardSchema.parse(input); - await assertAccountOwnership(user.id, data.contaId); + await assertAccountOwnership(user.id, data.accountId); const logoFile = normalizeFilePath(data.logo); const [updated] = await db - .update(cartoes) + .update(cards) .set({ name: data.name, brand: data.brand, @@ -120,9 +123,9 @@ export async function updateCardAction( note: data.note ?? null, limit: formatDecimalForDb(data.limit), logo: logoFile, - contaId: data.contaId, + accountId: data.accountId, }) - .where(and(eq(cartoes.id, data.id), eq(cartoes.userId, user.id))) + .where(and(eq(cards.id, data.id), eq(cards.userId, user.id))) .returning(); if (!updated) { @@ -132,7 +135,7 @@ export async function updateCardAction( }; } - revalidateForEntity("cartoes"); + revalidateForEntity("cards"); return { success: true, message: "Cartão atualizado com sucesso." }; } catch (error) { @@ -148,9 +151,9 @@ export async function deleteCardAction( const data = deleteCardSchema.parse(input); const [deleted] = await db - .delete(cartoes) - .where(and(eq(cartoes.id, data.id), eq(cartoes.userId, user.id))) - .returning({ id: cartoes.id }); + .delete(cards) + .where(and(eq(cards.id, data.id), eq(cards.userId, user.id))) + .returning({ id: cards.id }); if (!deleted) { return { @@ -159,7 +162,7 @@ export async function deleteCardAction( }; } - revalidateForEntity("cartoes"); + revalidateForEntity("cards"); return { success: true, message: "Cartão removido com sucesso." }; } catch (error) { diff --git a/src/features/cards/components/card-dialog.tsx b/src/features/cards/components/card-dialog.tsx index 9e5eb29..bc6bcb8 100644 --- a/src/features/cards/components/card-dialog.tsx +++ b/src/features/cards/components/card-dialog.tsx @@ -70,7 +70,7 @@ const buildInitialValues = ({ limit: formatLimitInput(card?.limit ?? null), note: card?.note ?? "", logo: selectedLogo, - contaId: card?.contaId ?? accounts[0]?.id ?? "", + accountId: card?.accountId ?? accounts[0]?.id ?? "", }; }; @@ -146,7 +146,7 @@ export function CardDialog({ return; } - if (!formState.contaId) { + if (!formState.accountId) { const message = "Selecione a conta vinculada."; setErrorMessage(message); toast.error(message); @@ -163,7 +163,7 @@ export function CardDialog({ limit: rawLimit ? Number(rawLimit) : null, note: formState.note.trim() || null, logo: formState.logo, - contaId: formState.contaId, + accountId: formState.accountId, }; if (!payload.logo) { diff --git a/src/features/cards/components/card-form-fields.tsx b/src/features/cards/components/card-form-fields.tsx index e600283..47be2aa 100644 --- a/src/features/cards/components/card-form-fields.tsx +++ b/src/features/cards/components/card-form-fields.tsx @@ -160,10 +160,10 @@ export function CardFormFields({
- +