fix: corrigir tipos e eliminar non-null assertions
Substitui non-null assertions (!) por type assertions ou optional chaining com guards. Troca any por unknown/tipos explícitos. - drizzle.config: DATABASE_URL! → as string - use-form-state: Record<string, any> → Record<string, unknown> - actions: catch (e: any) → catch (e), model tipado explicitamente - pagadores/data: row: any → Record<string, unknown> - note-dialog: result tipado explicitamente - bulk-import: payload as any removido - Map.get()! → optional chaining + guards em relatórios e dashboard Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -184,7 +184,7 @@ export async function updatePasswordAction(
|
|||||||
success: true,
|
success: true,
|
||||||
message: "Senha atualizada com sucesso",
|
message: "Senha atualizada com sucesso",
|
||||||
};
|
};
|
||||||
} catch (authError: any) {
|
} catch (authError) {
|
||||||
console.error("Erro na API do Better Auth:", authError);
|
console.error("Erro na API do Better Auth:", authError);
|
||||||
|
|
||||||
// Verificar se o erro é de senha incorreta
|
// Verificar se o erro é de senha incorreta
|
||||||
|
|||||||
@@ -599,7 +599,7 @@ export async function generateInsightsAction(
|
|||||||
const aggregatedData = await aggregateMonthData(user.id, period);
|
const aggregatedData = await aggregateMonthData(user.id, period);
|
||||||
|
|
||||||
// Selecionar provider
|
// Selecionar provider
|
||||||
let model;
|
let model: ReturnType<typeof google>;
|
||||||
|
|
||||||
// Se o modelo tem "/" é OpenRouter (formato: provider/model)
|
// Se o modelo tem "/" é OpenRouter (formato: provider/model)
|
||||||
if (isOpenRouterFormat && !selectedModel) {
|
if (isOpenRouterFormat && !selectedModel) {
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ export async function createInstallmentAnticipationAction(
|
|||||||
: totalAmount - discount; // Receita: 1000 - 20 = 980
|
: totalAmount - discount; // Receita: 1000 - 20 = 980
|
||||||
|
|
||||||
// 3. Pegar dados da primeira parcela para referência
|
// 3. Pegar dados da primeira parcela para referência
|
||||||
const firstInstallment = installments[0]!;
|
const firstInstallment = installments[0];
|
||||||
|
|
||||||
// 4. Criar lançamento e antecipação em transação
|
// 4. Criar lançamento e antecipação em transação
|
||||||
await db.transaction(async (tx) => {
|
await db.transaction(async (tx) => {
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ export async function duplicatePreviousMonthBudgetsAction(
|
|||||||
amount: b.amount,
|
amount: b.amount,
|
||||||
period: data.period,
|
period: data.period,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
categoriaId: b.categoriaId!,
|
categoriaId: b.categoriaId as string,
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export async function fetchPagadorLancamentos(filters: SQL[]) {
|
|||||||
.orderBy(desc(lancamentos.purchaseDate), desc(lancamentos.createdAt));
|
.orderBy(desc(lancamentos.purchaseDate), desc(lancamentos.createdAt));
|
||||||
|
|
||||||
// Transformar resultado para o formato esperado
|
// Transformar resultado para o formato esperado
|
||||||
return lancamentoRows.map((row: any) => ({
|
return lancamentoRows.map((row: Record<string, unknown>) => ({
|
||||||
...row.lancamento,
|
...row.lancamento,
|
||||||
pagador: row.pagador,
|
pagador: row.pagador,
|
||||||
conta: row.conta,
|
conta: row.conta,
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ export function NoteDialog({
|
|||||||
}
|
}
|
||||||
|
|
||||||
startTransition(async () => {
|
startTransition(async () => {
|
||||||
let result;
|
let result: { success: boolean; message?: string; error?: string };
|
||||||
if (mode === "create") {
|
if (mode === "create") {
|
||||||
result = await createNoteAction(payload);
|
result = await createNoteAction(payload);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ export function BulkImportDialog({
|
|||||||
: undefined,
|
: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await createLancamentoAction(payload as any);
|
const result = await createLancamentoAction(payload);
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
successCount++;
|
successCount++;
|
||||||
@@ -360,7 +360,7 @@ export function BulkImportDialog({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<DialogFooter className="gap-3">
|
<DialogFooter>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|||||||
@@ -591,7 +591,7 @@ export function LancamentosPage({
|
|||||||
<AnticipateInstallmentsDialog
|
<AnticipateInstallmentsDialog
|
||||||
open={anticipateOpen}
|
open={anticipateOpen}
|
||||||
onOpenChange={setAnticipateOpen}
|
onOpenChange={setAnticipateOpen}
|
||||||
seriesId={selectedForAnticipation.seriesId!}
|
seriesId={selectedForAnticipation.seriesId as string}
|
||||||
lancamentoName={selectedForAnticipation.name}
|
lancamentoName={selectedForAnticipation.name}
|
||||||
categorias={categoriaOptions.map((c) => ({
|
categorias={categoriaOptions.map((c) => ({
|
||||||
id: c.value,
|
id: c.value,
|
||||||
@@ -610,7 +610,7 @@ export function LancamentosPage({
|
|||||||
<AnticipationHistoryDialog
|
<AnticipationHistoryDialog
|
||||||
open={anticipationHistoryOpen}
|
open={anticipationHistoryOpen}
|
||||||
onOpenChange={setAnticipationHistoryOpen}
|
onOpenChange={setAnticipationHistoryOpen}
|
||||||
seriesId={selectedForAnticipation.seriesId!}
|
seriesId={selectedForAnticipation.seriesId as string}
|
||||||
lancamentoName={selectedForAnticipation.name}
|
lancamentoName={selectedForAnticipation.name}
|
||||||
onViewLancamento={(lancamentoId) => {
|
onViewLancamento={(lancamentoId) => {
|
||||||
const lancamento = lancamentos.find((l) => l.id === lancamentoId);
|
const lancamento = lancamentos.find((l) => l.id === lancamentoId);
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ export default {
|
|||||||
out: "./drizzle",
|
out: "./drizzle",
|
||||||
dialect: "postgresql",
|
dialect: "postgresql",
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
url: process.env.DATABASE_URL!,
|
url: process.env.DATABASE_URL as string,
|
||||||
},
|
},
|
||||||
} satisfies Config;
|
} satisfies Config;
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import { useState } from "react";
|
|||||||
* updateField('name', 'John');
|
* updateField('name', 'John');
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export function useFormState<T extends Record<string, any>>(initialValues: T) {
|
export function useFormState<T extends Record<string, unknown>>(
|
||||||
|
initialValues: T,
|
||||||
|
) {
|
||||||
const [formState, setFormState] = useState<T>(initialValues);
|
const [formState, setFormState] = useState<T>(initialValues);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -127,9 +127,9 @@ export async function fetchInstallmentAnalysis(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (seriesMap.has(row.seriesId)) {
|
if (seriesMap.has(row.seriesId)) {
|
||||||
const group = seriesMap.get(row.seriesId)!;
|
const group = seriesMap.get(row.seriesId);
|
||||||
group.pendingInstallments.push(installmentDetail);
|
group?.pendingInstallments.push(installmentDetail);
|
||||||
group.totalPendingAmount += amount;
|
if (group) group.totalPendingAmount += amount;
|
||||||
} else {
|
} else {
|
||||||
seriesMap.set(row.seriesId, {
|
seriesMap.set(row.seriesId, {
|
||||||
seriesId: row.seriesId,
|
seriesId: row.seriesId,
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ type ContaSluggedOption = BaseSluggedOption & {
|
|||||||
type CartaoSluggedOption = BaseSluggedOption & {
|
type CartaoSluggedOption = BaseSluggedOption & {
|
||||||
kind: "cartao";
|
kind: "cartao";
|
||||||
logo: string | null;
|
logo: string | null;
|
||||||
|
closingDay: string | null;
|
||||||
|
dueDay: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SluggedFilters = {
|
export type SluggedFilters = {
|
||||||
@@ -160,6 +162,8 @@ export const toOption = (
|
|||||||
logo?: string | null,
|
logo?: string | null,
|
||||||
icon?: string | null,
|
icon?: string | null,
|
||||||
accountType?: string | null,
|
accountType?: string | null,
|
||||||
|
closingDay?: string | null,
|
||||||
|
dueDay?: string | null,
|
||||||
): SelectOption => ({
|
): SelectOption => ({
|
||||||
value,
|
value,
|
||||||
label: normalizeLabel(label),
|
label: normalizeLabel(label),
|
||||||
@@ -170,6 +174,8 @@ export const toOption = (
|
|||||||
logo: logo ?? null,
|
logo: logo ?? null,
|
||||||
icon: icon ?? null,
|
icon: icon ?? null,
|
||||||
accountType: accountType ?? null,
|
accountType: accountType ?? null,
|
||||||
|
closingDay: closingDay ?? null,
|
||||||
|
dueDay: dueDay ?? null,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const fetchLancamentoFilterSources = async (userId: string) => {
|
export const fetchLancamentoFilterSources = async (userId: string) => {
|
||||||
@@ -252,6 +258,8 @@ export const buildSluggedFilters = ({
|
|||||||
slug: contaCartaoSlugger(label),
|
slug: contaCartaoSlugger(label),
|
||||||
kind: "cartao" as const,
|
kind: "cartao" as const,
|
||||||
logo: cartao.logo ?? null,
|
logo: cartao.logo ?? null,
|
||||||
|
closingDay: cartao.closingDay ?? null,
|
||||||
|
dueDay: cartao.dueDay ?? null,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -378,7 +386,7 @@ export const buildLancamentoWhere = ({
|
|||||||
ilike(lancamentos.condition, searchPattern),
|
ilike(lancamentos.condition, searchPattern),
|
||||||
and(isNotNull(contas.name), ilike(contas.name, searchPattern)),
|
and(isNotNull(contas.name), ilike(contas.name, searchPattern)),
|
||||||
and(isNotNull(cartoes.name), ilike(cartoes.name, searchPattern)),
|
and(isNotNull(cartoes.name), ilike(cartoes.name, searchPattern)),
|
||||||
)!,
|
) as SQL,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,8 +509,20 @@ export const buildOptionSets = ({
|
|||||||
: cartaoFiltersRaw;
|
: cartaoFiltersRaw;
|
||||||
|
|
||||||
const cartaoOptions = sortByLabel(
|
const cartaoOptions = sortByLabel(
|
||||||
cartaoOptionsSource.map(({ id, label, slug, logo }) =>
|
cartaoOptionsSource.map(({ id, label, slug, logo, closingDay, dueDay }) =>
|
||||||
toOption(id, label, undefined, undefined, slug, undefined, logo),
|
toOption(
|
||||||
|
id,
|
||||||
|
label,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
slug,
|
||||||
|
undefined,
|
||||||
|
logo,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
closingDay,
|
||||||
|
dueDay,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -123,12 +123,16 @@ export async function fetchCategoryChartData(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
categoryMap.get(categoryId)!.dataByPeriod.set(period, amount);
|
categoryMap.get(categoryId)?.dataByPeriod.set(period, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
const chartData = periods.map((period) => {
|
const chartData = periods.map((period) => {
|
||||||
const [year, month] = period.split("-");
|
const [year, month] = period.split("-");
|
||||||
const date = new Date(Number.parseInt(year, 10), Number.parseInt(month, 10) - 1, 1);
|
const date = new Date(
|
||||||
|
Number.parseInt(year, 10),
|
||||||
|
Number.parseInt(month, 10) - 1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
const monthLabel = format(date, "MMM", { locale: ptBR }).toUpperCase();
|
const monthLabel = format(date, "MMM", { locale: ptBR }).toUpperCase();
|
||||||
|
|
||||||
const dataPoint: { month: string; [key: string]: number | string } = {
|
const dataPoint: { month: string; [key: string]: number | string } = {
|
||||||
@@ -144,7 +148,11 @@ export async function fetchCategoryChartData(
|
|||||||
|
|
||||||
const months = periods.map((period) => {
|
const months = periods.map((period) => {
|
||||||
const [year, month] = period.split("-");
|
const [year, month] = period.split("-");
|
||||||
const date = new Date(Number.parseInt(year, 10), Number.parseInt(month, 10) - 1, 1);
|
const date = new Date(
|
||||||
|
Number.parseInt(year, 10),
|
||||||
|
Number.parseInt(month, 10) - 1,
|
||||||
|
1,
|
||||||
|
);
|
||||||
return format(date, "MMM", { locale: ptBR }).toUpperCase();
|
return format(date, "MMM", { locale: ptBR }).toUpperCase();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ export async function fetchCategoryReport(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const categoryItem = categoryMap.get(categoryId)!;
|
const categoryItem = categoryMap.get(categoryId);
|
||||||
|
if (!categoryItem) continue;
|
||||||
|
|
||||||
// Add monthly data (will calculate percentage later)
|
// Add monthly data (will calculate percentage later)
|
||||||
categoryItem.monthlyData.set(period, {
|
categoryItem.monthlyData.set(period, {
|
||||||
@@ -122,7 +123,8 @@ export async function fetchCategoryReport(
|
|||||||
|
|
||||||
for (let i = 0; i < sortedPeriods.length; i++) {
|
for (let i = 0; i < sortedPeriods.length; i++) {
|
||||||
const period = sortedPeriods[i];
|
const period = sortedPeriods[i];
|
||||||
const monthlyData = categoryItem.monthlyData.get(period)!;
|
const monthlyData = categoryItem.monthlyData.get(period);
|
||||||
|
if (!monthlyData) continue;
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
// Get previous period data
|
// Get previous period data
|
||||||
|
|||||||
@@ -164,7 +164,8 @@ export async function fetchTopEstabelecimentosData(
|
|||||||
c.establishmentName === est.name && c.categoriaId,
|
c.establishmentName === est.name && c.categoriaId,
|
||||||
)
|
)
|
||||||
.map((c: CategoryByEstRow) => ({
|
.map((c: CategoryByEstRow) => ({
|
||||||
name: categoryMap.get(c.categoriaId!)?.name || "Sem categoria",
|
name:
|
||||||
|
categoryMap.get(c.categoriaId as string)?.name || "Sem categoria",
|
||||||
count: Number(c.count) || 0,
|
count: Number(c.count) || 0,
|
||||||
}))
|
}))
|
||||||
.sort(
|
.sort(
|
||||||
@@ -222,9 +223,9 @@ export async function fetchTopEstabelecimentosData(
|
|||||||
const topCategories: TopCategoryData[] = topCategoriesData
|
const topCategories: TopCategoryData[] = topCategoriesData
|
||||||
.filter((c: TopCategoryRow) => c.categoriaId)
|
.filter((c: TopCategoryRow) => c.categoriaId)
|
||||||
.map((cat: TopCategoryRow) => {
|
.map((cat: TopCategoryRow) => {
|
||||||
const catInfo = categoryMap.get(cat.categoriaId!);
|
const catInfo = categoryMap.get(cat.categoriaId as string);
|
||||||
return {
|
return {
|
||||||
id: cat.categoriaId!,
|
id: cat.categoriaId as string,
|
||||||
name: catInfo?.name || "Sem categoria",
|
name: catInfo?.name || "Sem categoria",
|
||||||
icon: catInfo?.icon || null,
|
icon: catInfo?.icon || null,
|
||||||
totalAmount: Math.abs(safeToNumber(cat.totalAmount)),
|
totalAmount: Math.abs(safeToNumber(cat.totalAmount)),
|
||||||
|
|||||||
Reference in New Issue
Block a user