Files
openmonetis/app/(dashboard)/pre-lancamentos/data.ts
Felipe Coutinho df1d149e4a 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>
2026-01-29 13:16:39 +00:00

171 lines
3.9 KiB
TypeScript

import { and, desc, eq, gte } from "drizzle-orm";
import type {
InboxItem,
SelectOption,
} from "@/components/pre-lancamentos/types";
import {
cartoes,
categorias,
contas,
lancamentos,
preLancamentos,
} from "@/db/schema";
import { db } from "@/lib/db";
import {
buildOptionSets,
buildSluggedFilters,
fetchLancamentoFilterSources,
} from "@/lib/lancamentos/page-helpers";
export async function fetchInboxItems(
userId: string,
status: "pending" | "processed" | "discarded" = "pending",
): Promise<InboxItem[]> {
const items = await db
.select()
.from(preLancamentos)
.where(
and(eq(preLancamentos.userId, userId), eq(preLancamentos.status, status)),
)
.orderBy(desc(preLancamentos.createdAt));
return items;
}
export async function fetchInboxItemById(
userId: string,
itemId: string,
): Promise<InboxItem | null> {
const [item] = await db
.select()
.from(preLancamentos)
.where(
and(eq(preLancamentos.id, itemId), eq(preLancamentos.userId, userId)),
)
.limit(1);
return item ?? null;
}
export async function fetchCategoriasForSelect(
userId: string,
type?: string,
): Promise<SelectOption[]> {
const query = db
.select({ id: categorias.id, name: categorias.name })
.from(categorias)
.where(
type
? and(eq(categorias.userId, userId), eq(categorias.type, type))
: eq(categorias.userId, userId),
)
.orderBy(categorias.name);
return query;
}
export async function fetchContasForSelect(
userId: string,
): Promise<SelectOption[]> {
const items = await db
.select({ id: contas.id, name: contas.name })
.from(contas)
.where(and(eq(contas.userId, userId), eq(contas.status, "ativo")))
.orderBy(contas.name);
return items;
}
export async function fetchCartoesForSelect(
userId: string,
): Promise<(SelectOption & { lastDigits?: string })[]> {
const items = await db
.select({ id: cartoes.id, name: cartoes.name })
.from(cartoes)
.where(and(eq(cartoes.userId, userId), eq(cartoes.status, "ativo")))
.orderBy(cartoes.name);
return items;
}
export async function fetchPendingInboxCount(userId: string): Promise<number> {
const items = await db
.select({ id: preLancamentos.id })
.from(preLancamentos)
.where(
and(
eq(preLancamentos.userId, userId),
eq(preLancamentos.status, "pending"),
),
);
return items.length;
}
/**
* Fetch all data needed for the LancamentoDialog in inbox context
*/
export async function fetchInboxDialogData(userId: string): Promise<{
pagadorOptions: SelectOption[];
splitPagadorOptions: SelectOption[];
defaultPagadorId: string | null;
contaOptions: SelectOption[];
cartaoOptions: SelectOption[];
categoriaOptions: SelectOption[];
estabelecimentos: string[];
}> {
const filterSources = await fetchLancamentoFilterSources(userId);
const sluggedFilters = buildSluggedFilters(filterSources);
const {
pagadorOptions,
splitPagadorOptions,
defaultPagadorId,
contaOptions,
cartaoOptions,
categoriaOptions,
} = buildOptionSets({
...sluggedFilters,
pagadorRows: filterSources.pagadorRows,
});
// Fetch recent establishments (same approach as getRecentEstablishmentsAction)
const threeMonthsAgo = new Date();
threeMonthsAgo.setMonth(threeMonthsAgo.getMonth() - 3);
const recentEstablishments = await db
.select({ name: lancamentos.name })
.from(lancamentos)
.where(
and(
eq(lancamentos.userId, userId),
gte(lancamentos.purchaseDate, threeMonthsAgo),
),
)
.orderBy(desc(lancamentos.purchaseDate));
// Remove duplicates and filter empty names
const filteredNames: string[] = recentEstablishments
.map((r: { name: string }) => r.name)
.filter(
(name: string | null): name is string =>
name != null &&
name.trim().length > 0 &&
!name.toLowerCase().startsWith("pagamento fatura"),
);
const estabelecimentos = Array.from<string>(new Set(filteredNames)).slice(
0,
100,
);
return {
pagadorOptions,
splitPagadorOptions,
defaultPagadorId,
contaOptions,
cartaoOptions,
categoriaOptions,
estabelecimentos,
};
}