refactor: traduz contratos compartilhados do schema

This commit is contained in:
Felipe Coutinho
2026-03-14 12:50:43 +00:00
parent fa9bf17663
commit ef918a3667
9 changed files with 248 additions and 247 deletions

View File

@@ -1,6 +1,6 @@
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { tokensApi } from "@/db/schema"; import { apiTokens } from "@/db/schema";
import { import {
extractBearerToken, extractBearerToken,
hashToken, hashToken,
@@ -33,11 +33,11 @@ export async function POST(request: Request) {
} }
// Verificar se token não foi revogado // Verificar se token não foi revogado
const tokenRecord = await db.query.tokensApi.findFirst({ const tokenRecord = await db.query.apiTokens.findFirst({
where: and( where: and(
eq(tokensApi.id, payload.tokenId), eq(apiTokens.id, payload.tokenId),
eq(tokensApi.userId, payload.sub), eq(apiTokens.userId, payload.sub),
isNull(tokensApi.revokedAt), isNull(apiTokens.revokedAt),
), ),
}); });
@@ -60,7 +60,7 @@ export async function POST(request: Request) {
// Atualizar hash do token e último uso // Atualizar hash do token e último uso
await db await db
.update(tokensApi) .update(apiTokens)
.set({ .set({
tokenHash: hashToken(result.accessToken), tokenHash: hashToken(result.accessToken),
lastUsedAt: new Date(), lastUsedAt: new Date(),
@@ -69,7 +69,7 @@ export async function POST(request: Request) {
request.headers.get("x-real-ip"), request.headers.get("x-real-ip"),
expiresAt: result.expiresAt, expiresAt: result.expiresAt,
}) })
.where(eq(tokensApi.id, payload.tokenId)); .where(eq(apiTokens.id, payload.tokenId));
return NextResponse.json({ return NextResponse.json({
accessToken: result.accessToken, accessToken: result.accessToken,

View File

@@ -1,7 +1,7 @@
import { headers } from "next/headers"; import { headers } from "next/headers";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { z } from "zod"; import { z } from "zod";
import { tokensApi } from "@/db/schema"; import { apiTokens } from "@/db/schema";
import { import {
generateTokenPair, generateTokenPair,
getTokenPrefix, getTokenPrefix,
@@ -35,7 +35,7 @@ export async function POST(request: Request) {
); );
// Salvar hash do token no banco // Salvar hash do token no banco
await db.insert(tokensApi).values({ await db.insert(apiTokens).values({
id: tokenId, id: tokenId,
userId: session.user.id, userId: session.user.id,
name, name,

View File

@@ -1,7 +1,7 @@
import { and, eq } from "drizzle-orm"; import { and, eq } from "drizzle-orm";
import { headers } from "next/headers"; import { headers } from "next/headers";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { tokensApi } from "@/db/schema"; import { apiTokens } from "@/db/schema";
import { auth } from "@/shared/lib/auth/config"; import { auth } from "@/shared/lib/auth/config";
import { db } from "@/shared/lib/db"; import { db } from "@/shared/lib/db";
@@ -21,10 +21,10 @@ export async function DELETE(_request: Request, { params }: RouteParams) {
} }
// Verificar se token pertence ao usuário // Verificar se token pertence ao usuário
const token = await db.query.tokensApi.findFirst({ const token = await db.query.apiTokens.findFirst({
where: and( where: and(
eq(tokensApi.id, tokenId), eq(apiTokens.id, tokenId),
eq(tokensApi.userId, session.user.id), eq(apiTokens.userId, session.user.id),
), ),
}); });
@@ -37,9 +37,9 @@ export async function DELETE(_request: Request, { params }: RouteParams) {
// Revogar token (soft delete) // Revogar token (soft delete)
await db await db
.update(tokensApi) .update(apiTokens)
.set({ revokedAt: new Date() }) .set({ revokedAt: new Date() })
.where(eq(tokensApi.id, tokenId)); .where(eq(apiTokens.id, tokenId));
return NextResponse.json({ return NextResponse.json({
message: "Token revogado com sucesso", message: "Token revogado com sucesso",

View File

@@ -1,7 +1,7 @@
import { and, desc, eq, isNull } from "drizzle-orm"; import { and, desc, eq, isNull } from "drizzle-orm";
import { headers } from "next/headers"; import { headers } from "next/headers";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { tokensApi } from "@/db/schema"; import { apiTokens } from "@/db/schema";
import { auth } from "@/shared/lib/auth/config"; import { auth } from "@/shared/lib/auth/config";
import { db } from "@/shared/lib/db"; import { db } from "@/shared/lib/db";
@@ -17,19 +17,19 @@ export async function GET() {
// Buscar tokens ativos do usuário // Buscar tokens ativos do usuário
const activeTokens = await db const activeTokens = await db
.select({ .select({
id: tokensApi.id, id: apiTokens.id,
name: tokensApi.name, name: apiTokens.name,
tokenPrefix: tokensApi.tokenPrefix, tokenPrefix: apiTokens.tokenPrefix,
lastUsedAt: tokensApi.lastUsedAt, lastUsedAt: apiTokens.lastUsedAt,
lastUsedIp: tokensApi.lastUsedIp, lastUsedIp: apiTokens.lastUsedIp,
expiresAt: tokensApi.expiresAt, expiresAt: apiTokens.expiresAt,
createdAt: tokensApi.createdAt, createdAt: apiTokens.createdAt,
}) })
.from(tokensApi) .from(apiTokens)
.where( .where(
and(eq(tokensApi.userId, session.user.id), isNull(tokensApi.revokedAt)), and(eq(apiTokens.userId, session.user.id), isNull(apiTokens.revokedAt)),
) )
.orderBy(desc(tokensApi.createdAt)); .orderBy(desc(apiTokens.createdAt));
return NextResponse.json({ tokens: activeTokens }); return NextResponse.json({ tokens: activeTokens });
} catch (error) { } catch (error) {

View File

@@ -1,6 +1,6 @@
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { tokensApi } from "@/db/schema"; import { apiTokens } from "@/db/schema";
import { extractBearerToken, hashToken } from "@/shared/lib/auth/api-token"; import { extractBearerToken, hashToken } from "@/shared/lib/auth/api-token";
import { db } from "@/shared/lib/db"; import { db } from "@/shared/lib/db";
@@ -29,10 +29,10 @@ export async function POST(request: Request) {
const tokenHash = hashToken(token); const tokenHash = hashToken(token);
// Buscar token no banco // Buscar token no banco
const tokenRecord = await db.query.tokensApi.findFirst({ const tokenRecord = await db.query.apiTokens.findFirst({
where: and( where: and(
eq(tokensApi.tokenHash, tokenHash), eq(apiTokens.tokenHash, tokenHash),
isNull(tokensApi.revokedAt), isNull(apiTokens.revokedAt),
), ),
}); });
@@ -50,12 +50,12 @@ export async function POST(request: Request) {
null; null;
await db await db
.update(tokensApi) .update(apiTokens)
.set({ .set({
lastUsedAt: new Date(), lastUsedAt: new Date(),
lastUsedIp: clientIp, lastUsedIp: clientIp,
}) })
.where(eq(tokensApi.id, tokenRecord.id)); .where(eq(apiTokens.id, tokenRecord.id));
return NextResponse.json({ return NextResponse.json({
valid: true, valid: true,

View File

@@ -1,7 +1,7 @@
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { z } from "zod"; import { z } from "zod";
import { preLancamentos, tokensApi } from "@/db/schema"; import { apiTokens, inboxItems } from "@/db/schema";
import { extractBearerToken, hashToken } from "@/shared/lib/auth/api-token"; import { extractBearerToken, hashToken } from "@/shared/lib/auth/api-token";
import { db } from "@/shared/lib/db"; import { db } from "@/shared/lib/db";
import { inboxBatchSchema } from "@/shared/lib/schemas/inbox"; import { inboxBatchSchema } from "@/shared/lib/schemas/inbox";
@@ -59,10 +59,10 @@ export async function POST(request: Request) {
const tokenHash = hashToken(token); const tokenHash = hashToken(token);
// Buscar token no banco // Buscar token no banco
const tokenRecord = await db.query.tokensApi.findFirst({ const tokenRecord = await db.query.apiTokens.findFirst({
where: and( where: and(
eq(tokensApi.tokenHash, tokenHash), eq(apiTokens.tokenHash, tokenHash),
isNull(tokensApi.revokedAt), isNull(apiTokens.revokedAt),
), ),
}); });
@@ -91,7 +91,7 @@ export async function POST(request: Request) {
for (const item of items) { for (const item of items) {
try { try {
const [inserted] = await db const [inserted] = await db
.insert(preLancamentos) .insert(inboxItems)
.values({ .values({
userId: tokenRecord.userId, userId: tokenRecord.userId,
sourceApp: item.sourceApp, sourceApp: item.sourceApp,
@@ -103,7 +103,7 @@ export async function POST(request: Request) {
parsedAmount: item.parsedAmount?.toString(), parsedAmount: item.parsedAmount?.toString(),
status: "pending", status: "pending",
}) })
.returning({ id: preLancamentos.id }); .returning({ id: inboxItems.id });
results.push({ results.push({
clientId: item.clientId, clientId: item.clientId,
@@ -126,12 +126,12 @@ export async function POST(request: Request) {
null; null;
await db await db
.update(tokensApi) .update(apiTokens)
.set({ .set({
lastUsedAt: new Date(), lastUsedAt: new Date(),
lastUsedIp: clientIp, lastUsedIp: clientIp,
}) })
.where(eq(tokensApi.id, tokenRecord.id)); .where(eq(apiTokens.id, tokenRecord.id));
const successCount = results.filter((r) => r.success).length; const successCount = results.filter((r) => r.success).length;
const failCount = results.filter((r) => !r.success).length; const failCount = results.filter((r) => !r.success).length;

View File

@@ -1,7 +1,7 @@
import { and, eq, isNull } from "drizzle-orm"; import { and, eq, isNull } from "drizzle-orm";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { z } from "zod"; import { z } from "zod";
import { preLancamentos, tokensApi } from "@/db/schema"; import { apiTokens, inboxItems } from "@/db/schema";
import { extractBearerToken, hashToken } from "@/shared/lib/auth/api-token"; import { extractBearerToken, hashToken } from "@/shared/lib/auth/api-token";
import { db } from "@/shared/lib/db"; import { db } from "@/shared/lib/db";
import { inboxItemSchema } from "@/shared/lib/schemas/inbox"; import { inboxItemSchema } from "@/shared/lib/schemas/inbox";
@@ -52,10 +52,10 @@ export async function POST(request: Request) {
const tokenHash = hashToken(token); const tokenHash = hashToken(token);
// Buscar token no banco // Buscar token no banco
const tokenRecord = await db.query.tokensApi.findFirst({ const tokenRecord = await db.query.apiTokens.findFirst({
where: and( where: and(
eq(tokensApi.tokenHash, tokenHash), eq(apiTokens.tokenHash, tokenHash),
isNull(tokensApi.revokedAt), isNull(apiTokens.revokedAt),
), ),
}); });
@@ -80,7 +80,7 @@ export async function POST(request: Request) {
// Inserir item na inbox // Inserir item na inbox
const [inserted] = await db const [inserted] = await db
.insert(preLancamentos) .insert(inboxItems)
.values({ .values({
userId: tokenRecord.userId, userId: tokenRecord.userId,
sourceApp: data.sourceApp, sourceApp: data.sourceApp,
@@ -92,7 +92,7 @@ export async function POST(request: Request) {
parsedAmount: data.parsedAmount?.toString(), parsedAmount: data.parsedAmount?.toString(),
status: "pending", status: "pending",
}) })
.returning({ id: preLancamentos.id }); .returning({ id: inboxItems.id });
// Atualizar último uso do token // Atualizar último uso do token
const clientIp = const clientIp =
@@ -101,12 +101,12 @@ export async function POST(request: Request) {
null; null;
await db await db
.update(tokensApi) .update(apiTokens)
.set({ .set({
lastUsedAt: new Date(), lastUsedAt: new Date(),
lastUsedIp: clientIp, lastUsedIp: clientIp,
}) })
.where(eq(tokensApi.id, tokenRecord.id)); .where(eq(apiTokens.id, tokenRecord.id));
return NextResponse.json( return NextResponse.json(
{ {

View File

@@ -121,18 +121,18 @@ export const passkey = pgTable("passkey", {
}), }),
}); });
export const preferenciasUsuario = pgTable("preferencias_usuario", { export const userPreferences = pgTable("preferencias_usuario", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
userId: text("user_id") userId: text("user_id")
.notNull() .notNull()
.unique() .unique()
.references(() => user.id, { onDelete: "cascade" }), .references(() => user.id, { onDelete: "cascade" }),
extratoNoteAsColumn: boolean("extrato_note_as_column") statementNoteAsColumn: boolean("extrato_note_as_column")
.notNull() .notNull()
.default(false), .default(false),
systemFont: text("system_font").notNull().default("ai-sans"), systemFont: text("system_font").notNull().default("ai-sans"),
moneyFont: text("money_font").notNull().default("ai-sans"), moneyFont: text("money_font").notNull().default("ai-sans"),
lancamentosColumnOrder: jsonb("lancamentos_column_order").$type< transactionsColumnOrder: jsonb("lancamentos_column_order").$type<
string[] | null string[] | null
>(), >(),
dashboardWidgets: jsonb("dashboard_widgets").$type<{ dashboardWidgets: jsonb("dashboard_widgets").$type<{
@@ -155,7 +155,7 @@ export const preferenciasUsuario = pgTable("preferencias_usuario", {
// ===================== PUBLIC TABLES ===================== // ===================== PUBLIC TABLES =====================
export const contas = pgTable( export const financialAccounts = pgTable(
"contas", "contas",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -189,7 +189,7 @@ export const contas = pgTable(
}), }),
); );
export const categorias = pgTable( export const categories = pgTable(
"categorias", "categorias",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -214,7 +214,7 @@ export const categorias = pgTable(
}), }),
); );
export const pagadores = pgTable( export const payers = pgTable(
"pagadores", "pagadores",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -257,13 +257,13 @@ export const pagadores = pgTable(
}), }),
); );
export const compartilhamentosPagador = pgTable( export const payerShares = pgTable(
"compartilhamentos_pagador", "compartilhamentos_pagador",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
pagadorId: uuid("pagador_id") payerId: uuid("pagador_id")
.notNull() .notNull()
.references(() => pagadores.id, { onDelete: "cascade" }), .references(() => payers.id, { onDelete: "cascade" }),
sharedWithUserId: text("shared_with_user_id") sharedWithUserId: text("shared_with_user_id")
.notNull() .notNull()
.references(() => user.id, { onDelete: "cascade" }), .references(() => user.id, { onDelete: "cascade" }),
@@ -279,13 +279,14 @@ export const compartilhamentosPagador = pgTable(
.defaultNow(), .defaultNow(),
}, },
(table) => ({ (table) => ({
uniqueCompartilhamentoPagador: uniqueIndex( uniquePayerShare: uniqueIndex("compartilhamentos_pagador_unique").on(
"compartilhamentos_pagador_unique", table.payerId,
).on(table.pagadorId, table.sharedWithUserId), table.sharedWithUserId,
),
}), }),
); );
export const cartoes = pgTable( export const cards = pgTable(
"cartoes", "cartoes",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -306,9 +307,9 @@ export const cartoes = pgTable(
userId: text("user_id") userId: text("user_id")
.notNull() .notNull()
.references(() => user.id, { onDelete: "cascade" }), .references(() => user.id, { onDelete: "cascade" }),
contaId: uuid("conta_id") accountId: uuid("conta_id")
.notNull() .notNull()
.references(() => contas.id, { .references(() => financialAccounts.id, {
onDelete: "cascade", onDelete: "cascade",
onUpdate: "cascade", onUpdate: "cascade",
}), }),
@@ -321,7 +322,7 @@ export const cartoes = pgTable(
}), }),
); );
export const faturas = pgTable( export const invoices = pgTable(
"faturas", "faturas",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -336,7 +337,7 @@ export const faturas = pgTable(
userId: text("user_id") userId: text("user_id")
.notNull() .notNull()
.references(() => user.id, { onDelete: "cascade" }), .references(() => user.id, { onDelete: "cascade" }),
cartaoId: uuid("cartao_id").references(() => cartoes.id, { cardId: uuid("cartao_id").references(() => cards.id, {
onDelete: "cascade", onDelete: "cascade",
onUpdate: "cascade", onUpdate: "cascade",
}), }),
@@ -346,14 +347,14 @@ export const faturas = pgTable(
table.userId, table.userId,
table.period, table.period,
), ),
cartaoIdPeriodIdx: index("faturas_cartao_id_period_idx").on( cardIdPeriodIdx: index("faturas_cartao_id_period_idx").on(
table.cartaoId, table.cardId,
table.period, table.period,
), ),
}), }),
); );
export const orcamentos = pgTable( export const budgets = pgTable(
"orcamentos", "orcamentos",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -368,7 +369,7 @@ export const orcamentos = pgTable(
userId: text("user_id") userId: text("user_id")
.notNull() .notNull()
.references(() => user.id, { onDelete: "cascade" }), .references(() => user.id, { onDelete: "cascade" }),
categoriaId: uuid("categoria_id").references(() => categorias.id, { categoryId: uuid("categoria_id").references(() => categories.id, {
onDelete: "cascade", onDelete: "cascade",
onUpdate: "cascade", onUpdate: "cascade",
}), }),
@@ -381,13 +382,13 @@ export const orcamentos = pgTable(
}), }),
); );
export const anotacoes = pgTable("anotacoes", { export const notes = pgTable("anotacoes", {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
title: text("titulo"), title: text("titulo"),
description: text("descricao"), description: text("descricao"),
type: text("tipo").notNull().default("nota"), // "nota" ou "tarefa" type: text("tipo").notNull().default("nota"), // "nota" ou "tarefa"
tasks: text("tasks"), // JSON stringificado com array de tarefas tasks: text("tasks"), // JSON stringificado com array de tarefas
arquivada: boolean("arquivada").notNull().default(false), archived: boolean("arquivada").notNull().default(false),
createdAt: timestamp("created_at", { createdAt: timestamp("created_at", {
mode: "date", mode: "date",
withTimezone: true, withTimezone: true,
@@ -399,7 +400,7 @@ export const anotacoes = pgTable("anotacoes", {
.references(() => user.id, { onDelete: "cascade" }), .references(() => user.id, { onDelete: "cascade" }),
}); });
export const insightsSalvos = pgTable( export const savedInsights = pgTable(
"insights_salvos", "insights_salvos",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -432,7 +433,7 @@ export const insightsSalvos = pgTable(
// ===================== OPENMONETIS COMPANION ===================== // ===================== OPENMONETIS COMPANION =====================
export const tokensApi = pgTable( export const apiTokens = pgTable(
"tokens_api", "tokens_api",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -456,7 +457,7 @@ export const tokensApi = pgTable(
}), }),
); );
export const preLancamentos = pgTable( export const inboxItems = pgTable(
"pre_lancamentos", "pre_lancamentos",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -484,7 +485,7 @@ export const preLancamentos = pgTable(
status: text("status").notNull().default("pending"), // pending, processed, discarded status: text("status").notNull().default("pending"), // pending, processed, discarded
// Referência ao lançamento criado (se processado) // Referência ao lançamento criado (se processado)
lancamentoId: uuid("lancamento_id").references(() => lancamentos.id, { transactionId: uuid("lancamento_id").references(() => transactions.id, {
onDelete: "set null", onDelete: "set null",
}), }),
@@ -518,7 +519,7 @@ export const preLancamentos = pgTable(
}), }),
); );
export const antecipacoesParcelas = pgTable( export const installmentAnticipations = pgTable(
"antecipacoes_parcelas", "antecipacoes_parcelas",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -533,13 +534,13 @@ export const antecipacoesParcelas = pgTable(
discount: numeric("desconto", { precision: 12, scale: 2 }) discount: numeric("desconto", { precision: 12, scale: 2 })
.notNull() .notNull()
.default("0"), .default("0"),
lancamentoId: uuid("lancamento_id") transactionId: uuid("lancamento_id")
.notNull() .notNull()
.references(() => lancamentos.id, { onDelete: "cascade" }), .references(() => transactions.id, { onDelete: "cascade" }),
pagadorId: uuid("pagador_id").references(() => pagadores.id, { payerId: uuid("pagador_id").references(() => payers.id, {
onDelete: "cascade", onDelete: "cascade",
}), }),
categoriaId: uuid("categoria_id").references(() => categorias.id, { categoryId: uuid("categoria_id").references(() => categories.id, {
onDelete: "cascade", onDelete: "cascade",
}), }),
note: text("anotacao"), note: text("anotacao"),
@@ -568,10 +569,10 @@ export type RecurringSeriesTemplate = {
amount: string; amount: string;
transactionType: string; transactionType: string;
paymentMethod: string; paymentMethod: string;
categoriaId: string | null; categoryId: string | null;
contaId: string | null; accountId: string | null;
cartaoId: string | null; cardId: string | null;
pagadorId: string | null; payerId: string | null;
note: string | null; note: string | null;
condition: string; condition: string;
}; };
@@ -610,9 +611,9 @@ export const recurringSeries = pgTable(
}), }),
); );
// ===================== LANCAMENTOS ===================== // ===================== TRANSACTIONS =====================
export const lancamentos = pgTable( export const transactions = pgTable(
"lancamentos", "lancamentos",
{ {
id: uuid("id").primaryKey().default(sql`gen_random_uuid()`), id: uuid("id").primaryKey().default(sql`gen_random_uuid()`),
@@ -633,7 +634,7 @@ export const lancamentos = pgTable(
isDivided: boolean("dividido").default(false), isDivided: boolean("dividido").default(false),
isAnticipated: boolean("antecipado").default(false), isAnticipated: boolean("antecipado").default(false),
anticipationId: uuid("antecipacao_id").references( anticipationId: uuid("antecipacao_id").references(
() => antecipacoesParcelas.id, () => installmentAnticipations.id,
{ onDelete: "set null" }, { onDelete: "set null" },
), ),
createdAt: timestamp("created_at", { createdAt: timestamp("created_at", {
@@ -645,19 +646,19 @@ export const lancamentos = pgTable(
userId: text("user_id") userId: text("user_id")
.notNull() .notNull()
.references(() => user.id, { onDelete: "cascade" }), .references(() => user.id, { onDelete: "cascade" }),
cartaoId: uuid("cartao_id").references(() => cartoes.id, { cardId: uuid("cartao_id").references(() => cards.id, {
onDelete: "cascade", onDelete: "cascade",
onUpdate: "cascade", onUpdate: "cascade",
}), }),
contaId: uuid("conta_id").references(() => contas.id, { accountId: uuid("conta_id").references(() => financialAccounts.id, {
onDelete: "cascade", onDelete: "cascade",
onUpdate: "cascade", onUpdate: "cascade",
}), }),
categoriaId: uuid("categoria_id").references(() => categorias.id, { categoryId: uuid("categoria_id").references(() => categories.id, {
onDelete: "cascade", onDelete: "cascade",
onUpdate: "cascade", onUpdate: "cascade",
}), }),
pagadorId: uuid("pagador_id").references(() => pagadores.id, { payerId: uuid("pagador_id").references(() => payers.id, {
onDelete: "cascade", onDelete: "cascade",
onUpdate: "cascade", onUpdate: "cascade",
}), }),
@@ -681,8 +682,8 @@ export const lancamentos = pgTable(
table.transactionType, table.transactionType,
), ),
// Índice para queries por pagador + period (invoice/breakdown queries) // Índice para queries por pagador + period (invoice/breakdown queries)
pagadorIdPeriodIdx: index("lancamentos_pagador_id_period_idx").on( payerIdPeriodIdx: index("lancamentos_pagador_id_period_idx").on(
table.pagadorId, table.payerId,
table.period, table.period,
), ),
// Índice para queries ordenadas por data de compra // Índice para queries ordenadas por data de compra
@@ -700,8 +701,8 @@ export const lancamentos = pgTable(
table.condition, table.condition,
), ),
// Índice para queries de cartão específico // Índice para queries de cartão específico
cartaoIdPeriodIdx: index("lancamentos_cartao_id_period_idx").on( cardIdPeriodIdx: index("lancamentos_cartao_id_period_idx").on(
table.cartaoId, table.cardId,
table.period, table.period,
), ),
}), }),
@@ -710,17 +711,17 @@ export const lancamentos = pgTable(
export const userRelations = relations(user, ({ many, one }) => ({ export const userRelations = relations(user, ({ many, one }) => ({
accounts: many(account), accounts: many(account),
sessions: many(session), sessions: many(session),
anotacoes: many(anotacoes), notes: many(notes),
cartoes: many(cartoes), cards: many(cards),
categorias: many(categorias), categories: many(categories),
contas: many(contas), financialAccounts: many(financialAccounts),
faturas: many(faturas), invoices: many(invoices),
lancamentos: many(lancamentos), transactions: many(transactions),
orcamentos: many(orcamentos), budgets: many(budgets),
pagadores: many(pagadores), payers: many(payers),
antecipacoesParcelas: many(antecipacoesParcelas), installmentAnticipations: many(installmentAnticipations),
tokensApi: many(tokensApi), apiTokens: many(apiTokens),
preLancamentos: many(preLancamentos), inboxItems: many(inboxItems),
recurringSeries: many(recurringSeries), recurringSeries: many(recurringSeries),
})); }));
@@ -738,145 +739,145 @@ export const sessionRelations = relations(session, ({ one }) => ({
}), }),
})); }));
export const contasRelations = relations(contas, ({ one, many }) => ({ export const financialAccountsRelations = relations(
user: one(user, { financialAccounts,
fields: [contas.userId], ({ one, many }) => ({
references: [user.id], user: one(user, {
}), fields: [financialAccounts.userId],
cartoes: many(cartoes),
lancamentos: many(lancamentos),
}));
export const categoriasRelations = relations(categorias, ({ one, many }) => ({
user: one(user, {
fields: [categorias.userId],
references: [user.id],
}),
lancamentos: many(lancamentos),
orcamentos: many(orcamentos),
}));
export const pagadoresRelations = relations(pagadores, ({ one, many }) => ({
user: one(user, {
fields: [pagadores.userId],
references: [user.id],
}),
lancamentos: many(lancamentos),
compartilhamentos: many(compartilhamentosPagador),
}));
export const compartilhamentosPagadorRelations = relations(
compartilhamentosPagador,
({ one }) => ({
pagador: one(pagadores, {
fields: [compartilhamentosPagador.pagadorId],
references: [pagadores.id],
}),
sharedWithUser: one(user, {
fields: [compartilhamentosPagador.sharedWithUserId],
references: [user.id],
}),
createdByUser: one(user, {
fields: [compartilhamentosPagador.createdByUserId],
references: [user.id], references: [user.id],
}), }),
cards: many(cards),
transactions: many(transactions),
}), }),
); );
export const cartoesRelations = relations(cartoes, ({ one, many }) => ({ export const categoriesRelations = relations(categories, ({ one, many }) => ({
user: one(user, { user: one(user, {
fields: [cartoes.userId], fields: [categories.userId],
references: [user.id], references: [user.id],
}), }),
conta: one(contas, { transactions: many(transactions),
fields: [cartoes.contaId], budgets: many(budgets),
references: [contas.id],
}),
faturas: many(faturas),
lancamentos: many(lancamentos),
})); }));
export const faturasRelations = relations(faturas, ({ one }) => ({ export const payersRelations = relations(payers, ({ one, many }) => ({
user: one(user, { user: one(user, {
fields: [faturas.userId], fields: [payers.userId],
references: [user.id], references: [user.id],
}), }),
cartao: one(cartoes, { transactions: many(transactions),
fields: [faturas.cartaoId], shares: many(payerShares),
references: [cartoes.id],
}),
})); }));
export const orcamentosRelations = relations(orcamentos, ({ one }) => ({ export const payerSharesRelations = relations(payerShares, ({ one }) => ({
user: one(user, { payer: one(payers, {
fields: [orcamentos.userId], fields: [payerShares.payerId],
references: [payers.id],
}),
sharedWithUser: one(user, {
fields: [payerShares.sharedWithUserId],
references: [user.id], references: [user.id],
}), }),
categoria: one(categorias, { createdByUser: one(user, {
fields: [orcamentos.categoriaId], fields: [payerShares.createdByUserId],
references: [categorias.id],
}),
}));
export const anotacoesRelations = relations(anotacoes, ({ one }) => ({
user: one(user, {
fields: [anotacoes.userId],
references: [user.id], references: [user.id],
}), }),
})); }));
export const insightsSalvosRelations = relations(insightsSalvos, ({ one }) => ({ export const cardsRelations = relations(cards, ({ one, many }) => ({
user: one(user, { user: one(user, {
fields: [insightsSalvos.userId], fields: [cards.userId],
references: [user.id],
}),
financialAccount: one(financialAccounts, {
fields: [cards.accountId],
references: [financialAccounts.id],
}),
invoices: many(invoices),
transactions: many(transactions),
}));
export const invoicesRelations = relations(invoices, ({ one }) => ({
user: one(user, {
fields: [invoices.userId],
references: [user.id],
}),
card: one(cards, {
fields: [invoices.cardId],
references: [cards.id],
}),
}));
export const budgetsRelations = relations(budgets, ({ one }) => ({
user: one(user, {
fields: [budgets.userId],
references: [user.id],
}),
category: one(categories, {
fields: [budgets.categoryId],
references: [categories.id],
}),
}));
export const notesRelations = relations(notes, ({ one }) => ({
user: one(user, {
fields: [notes.userId],
references: [user.id], references: [user.id],
}), }),
})); }));
export const tokensApiRelations = relations(tokensApi, ({ one }) => ({ export const savedInsightsRelations = relations(savedInsights, ({ one }) => ({
user: one(user, { user: one(user, {
fields: [tokensApi.userId], fields: [savedInsights.userId],
references: [user.id], references: [user.id],
}), }),
})); }));
export const preLancamentosRelations = relations(preLancamentos, ({ one }) => ({ export const apiTokensRelations = relations(apiTokens, ({ one }) => ({
user: one(user, { user: one(user, {
fields: [preLancamentos.userId], fields: [apiTokens.userId],
references: [user.id], references: [user.id],
}), }),
lancamento: one(lancamentos, {
fields: [preLancamentos.lancamentoId],
references: [lancamentos.id],
}),
})); }));
export const lancamentosRelations = relations(lancamentos, ({ one }) => ({ export const inboxItemsRelations = relations(inboxItems, ({ one }) => ({
user: one(user, { user: one(user, {
fields: [lancamentos.userId], fields: [inboxItems.userId],
references: [user.id], references: [user.id],
}), }),
cartao: one(cartoes, { transaction: one(transactions, {
fields: [lancamentos.cartaoId], fields: [inboxItems.transactionId],
references: [cartoes.id], references: [transactions.id],
}), }),
conta: one(contas, { }));
fields: [lancamentos.contaId],
references: [contas.id], export const transactionsRelations = relations(transactions, ({ one }) => ({
user: one(user, {
fields: [transactions.userId],
references: [user.id],
}), }),
categoria: one(categorias, { card: one(cards, {
fields: [lancamentos.categoriaId], fields: [transactions.cardId],
references: [categorias.id], references: [cards.id],
}), }),
pagador: one(pagadores, { financialAccount: one(financialAccounts, {
fields: [lancamentos.pagadorId], fields: [transactions.accountId],
references: [pagadores.id], references: [financialAccounts.id],
}), }),
anticipation: one(antecipacoesParcelas, { category: one(categories, {
fields: [lancamentos.anticipationId], fields: [transactions.categoryId],
references: [antecipacoesParcelas.id], references: [categories.id],
}),
payer: one(payers, {
fields: [transactions.payerId],
references: [payers.id],
}),
anticipation: one(installmentAnticipations, {
fields: [transactions.anticipationId],
references: [installmentAnticipations.id],
}), }),
recurringSeries: one(recurringSeries, { recurringSeries: one(recurringSeries, {
fields: [lancamentos.recurringSeriesId], fields: [transactions.recurringSeriesId],
references: [recurringSeries.id], references: [recurringSeries.id],
}), }),
})); }));
@@ -888,28 +889,28 @@ export const recurringSeriesRelations = relations(
fields: [recurringSeries.userId], fields: [recurringSeries.userId],
references: [user.id], references: [user.id],
}), }),
lancamentos: many(lancamentos), transactions: many(transactions),
}), }),
); );
export const antecipacoesParcRelations = relations( export const installmentAnticipationsRelations = relations(
antecipacoesParcelas, installmentAnticipations,
({ one, many }) => ({ ({ one, many }) => ({
user: one(user, { user: one(user, {
fields: [antecipacoesParcelas.userId], fields: [installmentAnticipations.userId],
references: [user.id], references: [user.id],
}), }),
lancamento: one(lancamentos, { transaction: one(transactions, {
fields: [antecipacoesParcelas.lancamentoId], fields: [installmentAnticipations.transactionId],
references: [lancamentos.id], references: [transactions.id],
}), }),
pagador: one(pagadores, { payer: one(payers, {
fields: [antecipacoesParcelas.pagadorId], fields: [installmentAnticipations.payerId],
references: [pagadores.id], references: [payers.id],
}), }),
categoria: one(categorias, { category: one(categories, {
fields: [antecipacoesParcelas.categoriaId], fields: [installmentAnticipations.categoryId],
references: [categorias.id], references: [categories.id],
}), }),
}), }),
); );
@@ -919,23 +920,23 @@ export type NewUser = typeof user.$inferInsert;
export type Account = typeof account.$inferSelect; export type Account = typeof account.$inferSelect;
export type Session = typeof session.$inferSelect; export type Session = typeof session.$inferSelect;
export type Verification = typeof verification.$inferSelect; export type Verification = typeof verification.$inferSelect;
export type PreferenciasUsuario = typeof preferenciasUsuario.$inferSelect; export type UserPreferences = typeof userPreferences.$inferSelect;
export type NovasPreferenciasUsuario = typeof preferenciasUsuario.$inferInsert; export type NewUserPreferences = typeof userPreferences.$inferInsert;
export type CompartilhamentoPagador = export type PayerShare = typeof payerShares.$inferSelect;
typeof compartilhamentosPagador.$inferSelect; export type FinancialAccount = typeof financialAccounts.$inferSelect;
export type Conta = typeof contas.$inferSelect; export type Category = typeof categories.$inferSelect;
export type Categoria = typeof categorias.$inferSelect; export type Payer = typeof payers.$inferSelect;
export type Pagador = typeof pagadores.$inferSelect; export type Card = typeof cards.$inferSelect;
export type Cartao = typeof cartoes.$inferSelect; export type Invoice = typeof invoices.$inferSelect;
export type Fatura = typeof faturas.$inferSelect; export type Budget = typeof budgets.$inferSelect;
export type Orcamento = typeof orcamentos.$inferSelect; export type Note = typeof notes.$inferSelect;
export type Anotacao = typeof anotacoes.$inferSelect; export type SavedInsight = typeof savedInsights.$inferSelect;
export type InsightSalvo = typeof insightsSalvos.$inferSelect; export type Transaction = typeof transactions.$inferSelect;
export type Lancamento = typeof lancamentos.$inferSelect; export type InstallmentAnticipation =
export type AntecipacaoParcela = typeof antecipacoesParcelas.$inferSelect; typeof installmentAnticipations.$inferSelect;
export type TokenApi = typeof tokensApi.$inferSelect; export type ApiToken = typeof apiTokens.$inferSelect;
export type NovoTokenApi = typeof tokensApi.$inferInsert; export type NewApiToken = typeof apiTokens.$inferInsert;
export type PreLancamento = typeof preLancamentos.$inferSelect; export type InboxItem = typeof inboxItems.$inferSelect;
export type NovoPreLancamento = typeof preLancamentos.$inferInsert; export type NewInboxItem = typeof inboxItems.$inferInsert;
export type RecurringSeries = typeof recurringSeries.$inferSelect; export type RecurringSeries = typeof recurringSeries.$inferSelect;
export type NewRecurringSeries = typeof recurringSeries.$inferInsert; export type NewRecurringSeries = typeof recurringSeries.$inferInsert;

View File

@@ -24,28 +24,28 @@ export function handleActionError(error: unknown): ActionResult {
* Configuration for revalidation after mutations * Configuration for revalidation after mutations
*/ */
export const revalidateConfig = { export const revalidateConfig = {
cartoes: ["/cards", "/accounts", "/transactions"], cards: ["/cards", "/accounts", "/transactions"],
contas: ["/accounts", "/transactions"], accounts: ["/accounts", "/transactions"],
categorias: ["/categories"], categories: ["/categories"],
estabelecimentos: ["/reports/establishments", "/transactions"], establishments: ["/reports/establishments", "/transactions"],
orcamentos: ["/budgets"], budgets: ["/budgets"],
pagadores: ["/payers"], payers: ["/payers"],
anotacoes: ["/notes", "/notes/arquivadas", "/dashboard"], notes: ["/notes", "/notes/archived", "/dashboard"],
lancamentos: ["/transactions", "/accounts"], transactions: ["/transactions", "/accounts"],
inbox: ["/inbox", "/transactions", "/dashboard"], inbox: ["/inbox", "/transactions", "/dashboard"],
recorrentes: ["/transactions", "/dashboard"], recurring: ["/transactions", "/dashboard"],
} as const; } as const;
/** Entities whose mutations should invalidate the dashboard cache */ /** Entities whose mutations should invalidate the dashboard cache */
const DASHBOARD_ENTITIES: ReadonlySet<string> = new Set([ const DASHBOARD_ENTITIES: ReadonlySet<string> = new Set([
"lancamentos", "transactions",
"contas", "accounts",
"cartoes", "cards",
"orcamentos", "budgets",
"pagadores", "payers",
"anotacoes", "notes",
"inbox", "inbox",
"recorrentes", "recurring",
]); ]);
/** /**