refactor(sidebar): reorganizar navegação e aplicar formatação Biome
- Simplifica estrutura da sidebar combinando seções "Visão Geral" e "Gestão Financeira"
- Renomeia itens de relatórios para maior clareza ("Tendências", "Uso de Cartões")
- Aplica correções de formatação do Biome (ordenação de imports, quebras de linha)
- Remove código comentado não utilizado
- Adiciona migração 0014 do Drizzle
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import { and, eq, isNull, ne } from "drizzle-orm";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { headers } from "next/headers";
|
||||
import { z } from "zod";
|
||||
import { tokensApi, pagadores } from "@/db/schema";
|
||||
import { pagadores, tokensApi } from "@/db/schema";
|
||||
import { auth } from "@/lib/auth/config";
|
||||
import { db, schema } from "@/lib/db";
|
||||
import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants";
|
||||
|
||||
@@ -11,10 +11,10 @@ import {
|
||||
cartoes,
|
||||
categorias,
|
||||
contas,
|
||||
insightsSalvos,
|
||||
lancamentos,
|
||||
orcamentos,
|
||||
pagadores,
|
||||
insightsSalvos,
|
||||
} from "@/db/schema";
|
||||
import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX } from "@/lib/accounts/constants";
|
||||
import { getUser } from "@/lib/auth/server";
|
||||
@@ -752,7 +752,10 @@ export async function saveInsightsAction(
|
||||
modelId,
|
||||
data: JSON.stringify(data),
|
||||
})
|
||||
.returning({ id: insightsSalvos.id, createdAt: insightsSalvos.createdAt });
|
||||
.returning({
|
||||
id: insightsSalvos.id,
|
||||
createdAt: insightsSalvos.createdAt,
|
||||
});
|
||||
|
||||
const insertedRecord = result[0];
|
||||
if (!insertedRecord) {
|
||||
|
||||
@@ -4,8 +4,8 @@ import { and, asc, desc, eq, inArray, isNull, or } from "drizzle-orm";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
categorias,
|
||||
antecipacoesParcelas,
|
||||
categorias,
|
||||
lancamentos,
|
||||
pagadores,
|
||||
} from "@/db/schema";
|
||||
@@ -320,10 +320,7 @@ export async function getInstallmentAnticipationsAction(
|
||||
eq(antecipacoesParcelas.lancamentoId, lancamentos.id),
|
||||
)
|
||||
.leftJoin(pagadores, eq(antecipacoesParcelas.pagadorId, pagadores.id))
|
||||
.leftJoin(
|
||||
categorias,
|
||||
eq(antecipacoesParcelas.categoriaId, categorias.id),
|
||||
)
|
||||
.leftJoin(categorias, eq(antecipacoesParcelas.categoriaId, categorias.id))
|
||||
.where(
|
||||
and(
|
||||
eq(antecipacoesParcelas.seriesId, validatedSeriesId),
|
||||
|
||||
@@ -2,10 +2,10 @@ import { and, desc, eq, type SQL } from "drizzle-orm";
|
||||
import {
|
||||
cartoes,
|
||||
categorias,
|
||||
compartilhamentosPagador,
|
||||
contas,
|
||||
lancamentos,
|
||||
pagadores,
|
||||
compartilhamentosPagador,
|
||||
user as usersTable,
|
||||
} from "@/db/schema";
|
||||
import { db } from "@/lib/db";
|
||||
@@ -30,7 +30,10 @@ export async function fetchPagadorShares(
|
||||
userEmail: usersTable.email,
|
||||
})
|
||||
.from(compartilhamentosPagador)
|
||||
.innerJoin(usersTable, eq(compartilhamentosPagador.sharedWithUserId, usersTable.id))
|
||||
.innerJoin(
|
||||
usersTable,
|
||||
eq(compartilhamentosPagador.sharedWithUserId, usersTable.id),
|
||||
)
|
||||
.where(eq(compartilhamentosPagador.pagadorId, pagadorId));
|
||||
|
||||
return shareRows.map((share) => ({
|
||||
|
||||
@@ -4,7 +4,7 @@ import { randomBytes } from "node:crypto";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { z } from "zod";
|
||||
import { pagadores, compartilhamentosPagador, user } from "@/db/schema";
|
||||
import { compartilhamentosPagador, pagadores, user } from "@/db/schema";
|
||||
import { handleActionError, revalidateForEntity } from "@/lib/actions/helpers";
|
||||
import type { ActionResult } from "@/lib/actions/types";
|
||||
import { getUser } from "@/lib/auth/server";
|
||||
@@ -287,7 +287,9 @@ export async function deletePagadorShareAction(
|
||||
};
|
||||
}
|
||||
|
||||
await db.delete(compartilhamentosPagador).where(eq(compartilhamentosPagador.id, data.shareId));
|
||||
await db
|
||||
.delete(compartilhamentosPagador)
|
||||
.where(eq(compartilhamentosPagador.id, data.shareId));
|
||||
|
||||
revalidate();
|
||||
revalidatePath(`/pagadores/${existing.pagadorId}`);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { and, desc, eq, gte } from "drizzle-orm";
|
||||
import type {
|
||||
InboxItem,
|
||||
@@ -9,8 +7,8 @@ import {
|
||||
cartoes,
|
||||
categorias,
|
||||
contas,
|
||||
preLancamentos,
|
||||
lancamentos,
|
||||
preLancamentos,
|
||||
} from "@/db/schema";
|
||||
import { db } from "@/lib/db";
|
||||
import {
|
||||
@@ -26,7 +24,9 @@ export async function fetchInboxItems(
|
||||
const items = await db
|
||||
.select()
|
||||
.from(preLancamentos)
|
||||
.where(and(eq(preLancamentos.userId, userId), eq(preLancamentos.status, status)))
|
||||
.where(
|
||||
and(eq(preLancamentos.userId, userId), eq(preLancamentos.status, status)),
|
||||
)
|
||||
.orderBy(desc(preLancamentos.createdAt));
|
||||
|
||||
return items;
|
||||
@@ -39,7 +39,9 @@ export async function fetchInboxItemById(
|
||||
const [item] = await db
|
||||
.select()
|
||||
.from(preLancamentos)
|
||||
.where(and(eq(preLancamentos.id, itemId), eq(preLancamentos.userId, userId)))
|
||||
.where(
|
||||
and(eq(preLancamentos.id, itemId), eq(preLancamentos.userId, userId)),
|
||||
)
|
||||
.limit(1);
|
||||
|
||||
return item ?? null;
|
||||
@@ -91,7 +93,10 @@ export async function fetchPendingInboxCount(userId: string): Promise<number> {
|
||||
.select({ id: preLancamentos.id })
|
||||
.from(preLancamentos)
|
||||
.where(
|
||||
and(eq(preLancamentos.userId, userId), eq(preLancamentos.status, "pending")),
|
||||
and(
|
||||
eq(preLancamentos.userId, userId),
|
||||
eq(preLancamentos.status, "pending"),
|
||||
),
|
||||
);
|
||||
|
||||
return items.length;
|
||||
|
||||
@@ -2,7 +2,7 @@ import { RiBankCard2Line } from "@remixicon/react";
|
||||
import PageDescription from "@/components/page-description";
|
||||
|
||||
export const metadata = {
|
||||
title: "Relatório de Cartões | Opensheets",
|
||||
title: "Uso de Cartões | Opensheets",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
@@ -14,7 +14,7 @@ export default function RootLayout({
|
||||
<section className="space-y-6 px-6">
|
||||
<PageDescription
|
||||
icon={<RiBankCard2Line />}
|
||||
title="Relatório de Cartões"
|
||||
title="Uso de Cartões"
|
||||
subtitle="Análise detalhada do uso dos seus cartões de crédito."
|
||||
/>
|
||||
{children}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { RiFileChartLine } from "@remixicon/react";
|
||||
import PageDescription from "@/components/page-description";
|
||||
|
||||
export const metadata = {
|
||||
title: "Relatórios | Opensheets",
|
||||
title: "Tendências | Opensheets",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
@@ -14,7 +14,7 @@ export default function RootLayout({
|
||||
<section className="space-y-6 px-6">
|
||||
<PageDescription
|
||||
icon={<RiFileChartLine />}
|
||||
title="Relatórios de Categorias"
|
||||
title="Tendências"
|
||||
subtitle="Acompanhe a evolução dos seus gastos e receitas por categoria ao longo do tempo."
|
||||
/>
|
||||
{children}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { and, eq, isNull } from "drizzle-orm";
|
||||
import { NextResponse } from "next/server";
|
||||
import { tokensApi } from "@/db/schema";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { headers } from "next/headers";
|
||||
import { NextResponse } from "next/server";
|
||||
import { z } from "zod";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { headers } from "next/headers";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { desc, eq } from "drizzle-orm";
|
||||
import { headers } from "next/headers";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { and, eq, isNull } from "drizzle-orm";
|
||||
import { NextResponse } from "next/server";
|
||||
import { tokensApi } from "@/db/schema";
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
|
||||
|
||||
import { and, eq, isNull } from "drizzle-orm";
|
||||
import { NextResponse } from "next/server";
|
||||
import { z } from "zod";
|
||||
import { tokensApi, preLancamentos } from "@/db/schema";
|
||||
import { preLancamentos, tokensApi } from "@/db/schema";
|
||||
import { extractBearerToken, hashToken } from "@/lib/auth/api-token";
|
||||
import { db } from "@/lib/db";
|
||||
import { inboxBatchSchema } from "@/lib/schemas/inbox";
|
||||
@@ -103,7 +101,6 @@ export async function POST(request: Request) {
|
||||
notificationTimestamp: item.notificationTimestamp,
|
||||
parsedName: item.parsedName,
|
||||
parsedAmount: item.parsedAmount?.toString(),
|
||||
parsedTransactionType: item.parsedTransactionType,
|
||||
status: "pending",
|
||||
})
|
||||
.returning({ id: preLancamentos.id });
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
|
||||
|
||||
import { and, eq, isNull } from "drizzle-orm";
|
||||
import { NextResponse } from "next/server";
|
||||
import { z } from "zod";
|
||||
import { tokensApi, preLancamentos } from "@/db/schema";
|
||||
import { preLancamentos, tokensApi } from "@/db/schema";
|
||||
import { extractBearerToken, hashToken } from "@/lib/auth/api-token";
|
||||
import { db } from "@/lib/db";
|
||||
import { inboxItemSchema } from "@/lib/schemas/inbox";
|
||||
@@ -92,7 +90,6 @@ export async function POST(request: Request) {
|
||||
notificationTimestamp: data.notificationTimestamp,
|
||||
parsedName: data.parsedName,
|
||||
parsedAmount: data.parsedAmount?.toString(),
|
||||
parsedTransactionType: data.parsedTransactionType,
|
||||
status: "pending",
|
||||
})
|
||||
.returning({ id: preLancamentos.id });
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { RiCalendarCheckLine, RiLoader4Line } from "@remixicon/react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { getInstallmentAnticipationsAction } from "@/app/(dashboard)/lancamentos/anticipation-actions";
|
||||
import {
|
||||
@@ -52,14 +52,8 @@ export function AnticipationHistoryDialog({
|
||||
onOpenChange,
|
||||
);
|
||||
|
||||
// Buscar antecipações ao abrir o dialog
|
||||
useEffect(() => {
|
||||
if (dialogOpen) {
|
||||
loadAnticipations();
|
||||
}
|
||||
}, [dialogOpen, loadAnticipations]);
|
||||
|
||||
const loadAnticipations = async () => {
|
||||
// Define loadAnticipations before it's used in useEffect
|
||||
const loadAnticipations = useCallback(async () => {
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
@@ -80,7 +74,14 @@ export function AnticipationHistoryDialog({
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
}, [seriesId]);
|
||||
|
||||
// Buscar antecipações ao abrir o dialog
|
||||
useEffect(() => {
|
||||
if (dialogOpen) {
|
||||
loadAnticipations();
|
||||
}
|
||||
}, [dialogOpen, loadAnticipations]);
|
||||
|
||||
const handleCanceled = () => {
|
||||
// Recarregar lista após cancelamento
|
||||
|
||||
@@ -24,7 +24,6 @@ import {
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { cn } from "@/lib/utils/ui";
|
||||
import type { InboxItem } from "./types";
|
||||
|
||||
interface InboxCardProps {
|
||||
@@ -41,7 +40,6 @@ export function InboxCard({
|
||||
onViewDetails,
|
||||
}: InboxCardProps) {
|
||||
const amount = item.parsedAmount ? parseFloat(item.parsedAmount) : null;
|
||||
const isReceita = item.parsedTransactionType === "Receita";
|
||||
|
||||
// O timestamp vem do app Android em horário local mas salvo como UTC
|
||||
// Precisamos interpretar o valor UTC como se fosse horário de Brasília
|
||||
@@ -78,16 +76,7 @@ export function InboxCard({
|
||||
</span>
|
||||
</CardTitle>
|
||||
{amount !== null && (
|
||||
<MoneyValues
|
||||
amount={isReceita ? amount : -amount}
|
||||
showPositiveSign={isReceita}
|
||||
className={cn(
|
||||
"text-sm",
|
||||
isReceita
|
||||
? "text-green-600 dark:text-green-400"
|
||||
: "text-foreground",
|
||||
)}
|
||||
/>
|
||||
<MoneyValues amount={amount} className="text-sm" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import { format } from "date-fns";
|
||||
import { ptBR } from "date-fns/locale";
|
||||
import MoneyValues from "@/components/money-values";
|
||||
import { TypeBadge } from "@/components/type-badge";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
@@ -15,7 +14,6 @@ import {
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { cn } from "@/lib/utils/ui";
|
||||
import type { InboxItem } from "./types";
|
||||
|
||||
interface InboxDetailsDialogProps {
|
||||
@@ -32,7 +30,6 @@ export function InboxDetailsDialog({
|
||||
if (!item) return null;
|
||||
|
||||
const amount = item.parsedAmount ? parseFloat(item.parsedAmount) : null;
|
||||
const isReceita = item.parsedTransactionType === "Receita";
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
@@ -86,30 +83,11 @@ export function InboxDetailsDialog({
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-muted-foreground">Valor</span>
|
||||
{amount !== null ? (
|
||||
<MoneyValues
|
||||
amount={isReceita ? amount : -amount}
|
||||
showPositiveSign={isReceita}
|
||||
className={cn(
|
||||
"text-sm",
|
||||
isReceita
|
||||
? "text-green-600 dark:text-green-400"
|
||||
: "text-foreground",
|
||||
)}
|
||||
/>
|
||||
<MoneyValues amount={amount} className="text-sm" />
|
||||
) : (
|
||||
<span className="text-muted-foreground">Não extraído</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-muted-foreground">Tipo</span>
|
||||
{item.parsedTransactionType ? (
|
||||
<TypeBadge type={item.parsedTransactionType} />
|
||||
) : (
|
||||
<span className="text-muted-foreground">
|
||||
Não identificado
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -139,9 +139,6 @@ export function InboxPage({
|
||||
? String(Math.abs(Number(itemToProcess.parsedAmount)))
|
||||
: null;
|
||||
|
||||
const defaultTransactionType =
|
||||
itemToProcess?.parsedTransactionType === "Receita" ? "Receita" : "Despesa";
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex w-full flex-col gap-6">
|
||||
@@ -182,7 +179,6 @@ export function InboxPage({
|
||||
defaultPurchaseDate={defaultPurchaseDate}
|
||||
defaultName={defaultName}
|
||||
defaultAmount={defaultAmount}
|
||||
defaultTransactionType={defaultTransactionType}
|
||||
forceShowTransactionType
|
||||
onSuccess={handleLancamentoSuccess}
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import type { SelectOption as LancamentoSelectOption } from "@/components/lancamentos/types";
|
||||
|
||||
export interface InboxItem {
|
||||
@@ -11,7 +9,6 @@ export interface InboxItem {
|
||||
notificationTimestamp: Date;
|
||||
parsedName: string | null;
|
||||
parsedAmount: string | null;
|
||||
parsedTransactionType: string | null;
|
||||
status: string;
|
||||
lancamentoId: string | null;
|
||||
processedAt: Date | null;
|
||||
@@ -25,7 +22,6 @@ export interface ProcessInboxInput {
|
||||
name: string;
|
||||
amount: number;
|
||||
purchaseDate: string;
|
||||
transactionType: "Despesa" | "Receita";
|
||||
condition: string;
|
||||
paymentMethod: string;
|
||||
categoriaId: string;
|
||||
|
||||
@@ -53,7 +53,7 @@ export function AppSidebar({
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
className="data-[slot=sidebar-menu-button]:px-1.5! hover:bg-transparent active:bg-transparent pt-4 justify-center hover:scale-105 transition-all duration-200"
|
||||
className="data-[slot=sidebar-menu-button]:px-1.5! hover:bg-transparent active:bg-transparent pt-4 justify-center hover:scale-105 transition-all duration-200"
|
||||
>
|
||||
<a href="/dashboard">
|
||||
<LogoContent />
|
||||
|
||||
@@ -85,18 +85,13 @@ export function createSidebarNavData(
|
||||
return {
|
||||
navMain: [
|
||||
{
|
||||
title: "Visão Geral",
|
||||
title: "Gestão Financeira",
|
||||
items: [
|
||||
{
|
||||
title: "Dashboard",
|
||||
url: "/dashboard",
|
||||
icon: RiDashboardLine,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Gestão Financeira",
|
||||
items: [
|
||||
{
|
||||
title: "Lançamentos",
|
||||
url: "/lancamentos",
|
||||
@@ -164,11 +159,6 @@ export function createSidebarNavData(
|
||||
url: "/categorias",
|
||||
icon: RiPriceTag3Line,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Análise e Anotações",
|
||||
items: [
|
||||
{
|
||||
title: "Anotações",
|
||||
url: "/anotacoes",
|
||||
@@ -182,23 +172,23 @@ export function createSidebarNavData(
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Análise",
|
||||
items: [
|
||||
{
|
||||
title: "Insights",
|
||||
url: "/insights",
|
||||
icon: RiSparklingLine,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Relatórios",
|
||||
items: [
|
||||
{
|
||||
title: "Categorias",
|
||||
title: "Tendências",
|
||||
url: "/relatorios/categorias",
|
||||
icon: RiFileChartLine,
|
||||
},
|
||||
{
|
||||
title: "Cartões",
|
||||
title: "Uso de Cartões",
|
||||
url: "/relatorios/cartoes",
|
||||
icon: RiBankCard2Line,
|
||||
},
|
||||
@@ -206,11 +196,6 @@ export function createSidebarNavData(
|
||||
},
|
||||
],
|
||||
navSecondary: [
|
||||
// {
|
||||
// title: "Changelog",
|
||||
// url: "/changelog",
|
||||
// icon: RiGitCommitLine,
|
||||
// },
|
||||
{
|
||||
title: "Ajustes",
|
||||
url: "/ajustes",
|
||||
|
||||
@@ -113,9 +113,11 @@ export function NavMain({ sections }: { sections: NavSection[] }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
{sections.map((section) => (
|
||||
{sections.map((section, index) => (
|
||||
<SidebarGroup key={section.title}>
|
||||
<SidebarGroupLabel>{section.title}</SidebarGroupLabel>
|
||||
<SidebarGroupLabel className="text-xs text-muted-foreground/60">
|
||||
{section.title}
|
||||
</SidebarGroupLabel>
|
||||
<SidebarGroupContent>
|
||||
<SidebarMenu>
|
||||
{section.items.map((item) => {
|
||||
|
||||
@@ -451,7 +451,6 @@ export const preLancamentos = pgTable(
|
||||
// Dados parseados (editáveis pelo usuário antes de processar)
|
||||
parsedName: text("parsed_name"), // Nome do estabelecimento
|
||||
parsedAmount: numeric("parsed_amount", { precision: 12, scale: 2 }),
|
||||
parsedTransactionType: text("parsed_transaction_type"), // Despesa, Receita
|
||||
|
||||
// Status de processamento
|
||||
status: text("status").notNull().default("pending"), // pending, processed, discarded
|
||||
@@ -527,7 +526,9 @@ export const antecipacoesParcelas = pgTable(
|
||||
.defaultNow(),
|
||||
},
|
||||
(table) => ({
|
||||
seriesIdIdx: index("antecipacoes_parcelas_series_id_idx").on(table.seriesId),
|
||||
seriesIdIdx: index("antecipacoes_parcelas_series_id_idx").on(
|
||||
table.seriesId,
|
||||
),
|
||||
userIdIdx: index("antecipacoes_parcelas_user_id_idx").on(table.userId),
|
||||
}),
|
||||
);
|
||||
|
||||
1
drizzle/0014_yielding_jack_flag.sql
Normal file
1
drizzle/0014_yielding_jack_flag.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE "pre_lancamentos" DROP COLUMN "parsed_transaction_type";
|
||||
File diff suppressed because it is too large
Load Diff
2129
drizzle/meta/0014_snapshot.json
Normal file
2129
drizzle/meta/0014_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,104 +1,111 @@
|
||||
{
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1762993507299,
|
||||
"tag": "0000_flashy_manta",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "7",
|
||||
"when": 1765199006435,
|
||||
"tag": "0001_young_mister_fear",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1765200545692,
|
||||
"tag": "0002_slimy_flatman",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1767102605526,
|
||||
"tag": "0003_green_korg",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1767104066872,
|
||||
"tag": "0004_acoustic_mach_iv",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1767106121811,
|
||||
"tag": "0005_adorable_bruce_banner",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "7",
|
||||
"when": 1767107487318,
|
||||
"tag": "0006_youthful_mister_fear",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "7",
|
||||
"when": 1767118780033,
|
||||
"tag": "0007_sturdy_kate_bishop",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 8,
|
||||
"version": "7",
|
||||
"when": 1767125796314,
|
||||
"tag": "0008_fat_stick",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "7",
|
||||
"when": 1768925100873,
|
||||
"tag": "0009_add_dashboard_widgets",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 10,
|
||||
"version": "7",
|
||||
"when": 1769369834242,
|
||||
"tag": "0010_lame_psynapse",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"version": "7",
|
||||
"when": 1769447087678,
|
||||
"tag": "0011_remove_unused_inbox_columns",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "7",
|
||||
"when": 1769533200000,
|
||||
"tag": "0012_rename_tables_to_portuguese",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"version": "7",
|
||||
"when": 1769523352777,
|
||||
"tag": "0013_fancy_rick_jones",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1762993507299,
|
||||
"tag": "0000_flashy_manta",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 1,
|
||||
"version": "7",
|
||||
"when": 1765199006435,
|
||||
"tag": "0001_young_mister_fear",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 2,
|
||||
"version": "7",
|
||||
"when": 1765200545692,
|
||||
"tag": "0002_slimy_flatman",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 3,
|
||||
"version": "7",
|
||||
"when": 1767102605526,
|
||||
"tag": "0003_green_korg",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 4,
|
||||
"version": "7",
|
||||
"when": 1767104066872,
|
||||
"tag": "0004_acoustic_mach_iv",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 5,
|
||||
"version": "7",
|
||||
"when": 1767106121811,
|
||||
"tag": "0005_adorable_bruce_banner",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 6,
|
||||
"version": "7",
|
||||
"when": 1767107487318,
|
||||
"tag": "0006_youthful_mister_fear",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 7,
|
||||
"version": "7",
|
||||
"when": 1767118780033,
|
||||
"tag": "0007_sturdy_kate_bishop",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 8,
|
||||
"version": "7",
|
||||
"when": 1767125796314,
|
||||
"tag": "0008_fat_stick",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 9,
|
||||
"version": "7",
|
||||
"when": 1768925100873,
|
||||
"tag": "0009_add_dashboard_widgets",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 10,
|
||||
"version": "7",
|
||||
"when": 1769369834242,
|
||||
"tag": "0010_lame_psynapse",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"version": "7",
|
||||
"when": 1769447087678,
|
||||
"tag": "0011_remove_unused_inbox_columns",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "7",
|
||||
"when": 1769533200000,
|
||||
"tag": "0012_rename_tables_to_portuguese",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"version": "7",
|
||||
"when": 1769523352777,
|
||||
"tag": "0013_fancy_rick_jones",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 14,
|
||||
"version": "7",
|
||||
"when": 1769619226903,
|
||||
"tag": "0014_yielding_jack_flag",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import crypto from "node:crypto";
|
||||
|
||||
const JWT_SECRET =
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { betterAuth } from "better-auth";
|
||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
||||
import type { GoogleProfile } from "better-auth/social-providers";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { headers } from "next/headers";
|
||||
import { redirect } from "next/navigation";
|
||||
import { auth } from "@/lib/auth/config";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { eq } from "drizzle-orm";
|
||||
import { categorias } from "@/db/schema";
|
||||
import type { CategoryType } from "@/lib/categorias/constants";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { calculatePercentageChange } from "@/lib/utils/math";
|
||||
import { safeToNumber } from "@/lib/utils/number";
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import type { SelectOption } from "@/components/lancamentos/types";
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import type { LancamentoItem } from "@/components/lancamentos/types";
|
||||
import { getTodayDateString } from "@/lib/utils/date";
|
||||
import { derivePeriodFromDate } from "@/lib/utils/period";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { readdir } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { pagadores, compartilhamentosPagador, user as usersTable } from "@/db/schema";
|
||||
import {
|
||||
compartilhamentosPagador,
|
||||
pagadores,
|
||||
user as usersTable,
|
||||
} from "@/db/schema";
|
||||
import { db } from "@/lib/db";
|
||||
|
||||
export type PagadorWithAccess = typeof pagadores.$inferSelect & {
|
||||
@@ -24,7 +28,10 @@ export async function fetchPagadoresWithAccess(
|
||||
ownerEmail: usersTable.email,
|
||||
})
|
||||
.from(compartilhamentosPagador)
|
||||
.innerJoin(pagadores, eq(compartilhamentosPagador.pagadorId, pagadores.id))
|
||||
.innerJoin(
|
||||
pagadores,
|
||||
eq(compartilhamentosPagador.pagadorId, pagadores.id),
|
||||
)
|
||||
.leftJoin(usersTable, eq(pagadores.userId, usersTable.id))
|
||||
.where(eq(compartilhamentosPagador.sharedWithUserId, userId)),
|
||||
]);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { DEFAULT_PAGADOR_AVATAR } from "./constants";
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { format } from "date-fns";
|
||||
import { ptBR } from "date-fns/locale";
|
||||
import { and, eq, inArray, isNull, or, sql } from "drizzle-orm";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { and, eq, inArray, isNull, or, sql } from "drizzle-orm";
|
||||
import { categorias, lancamentos, pagadores } from "@/db/schema";
|
||||
import { ACCOUNT_AUTO_INVOICE_NOTE_PREFIX } from "@/lib/accounts/constants";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { currencyFormatter } from "@/lib/lancamentos/formatting-helpers";
|
||||
import { calculatePercentageChange } from "@/lib/utils/math";
|
||||
import { buildPeriodRange, MONTH_NAMES, parsePeriod } from "@/lib/utils/period";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
export const inboxItemSchema = z.object({
|
||||
@@ -10,7 +8,6 @@ export const inboxItemSchema = z.object({
|
||||
notificationTimestamp: z.string().transform((val) => new Date(val)),
|
||||
parsedName: z.string().optional(),
|
||||
parsedAmount: z.coerce.number().optional(),
|
||||
parsedTransactionType: z.enum(["Despesa", "Receita"]).optional(),
|
||||
clientId: z.string().optional(), // ID local do app para rastreamento
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
import { type ClassValue, clsx } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user