18 Commits

Author SHA1 Message Date
Felipe Coutinho
18893bfe02 docs: atualiza árvore de diretórios em README e CLAUDE com estrutura pós-refatoração
- Adiciona subpastas novas em shared/components/ (brand, widgets, feedback)
- Documenta o padrão interno de feature: actions.ts, queries.ts, actions/,
  components/, hooks/, lib/
- Atualiza shared/lib/ com pastas que já existiam mas faltavam listar
  (import, notifications, storage, version)
- Atualiza shared/utils/ com fetch-json.ts (movido do shared/lib) e id.ts
- Inclui lib/ no checklist de criação de nova feature

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 18:49:44 +00:00
Felipe Coutinho
7fdf9e2876 chore: prepara versão 2.5.4
Bump de patch refletindo a refatoração estrutural do commit anterior.
Sem mudanças funcionais — usuário não percebe nenhuma diferença.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 18:43:01 +00:00
Felipe Coutinho
7d0781b035 refactor: faxina arquitetural — código morto, identificadores em inglês e estrutura padronizada
Refatoração estrutural sem mudanças funcionais. Saldo líquido: −428 linhas.

Removido:
- 14 funções/constantes mortas verificadas via grep no repo todo: validateCategoriaOwnership,
  getInstallmentAnticipationsAction, getAnticipationDetailsAction, formatDecimalForDb,
  currencyFormatterNoCents, optionalDecimalSchema, formatMonthLabel,
  getGoalProgressStatusColorClass, MONTH_PERIOD_PARAM, calculateRemainingInstallments,
  e 5 funções fetch* não usadas em inbox/queries.ts.
- 1 tipo morto (ImportRow) + 2 órfãos consequentes (InstallmentAnticipationWithRelations,
  GoalProgressStatus convertido em interno).
- ~30 export keywords desnecessários (símbolos usados apenas no próprio arquivo).
- Re-exports mortos em barrels: EstablishmentLogoPicker, CategoryReportSkeleton,
  WidgetSkeleton, toNameKey.
- Arquivo features/reports/types.ts (barrel inteiro era órfão).

Padronizado (PT-BR→EN em identificadores expostos):
- 4 constantes globais (LANCAMENTOS_* → TRANSACTIONS_*).
- 12 tipos/interfaces (Lancamento*/Pagador*/Estabelecimento* → equivalentes EN).
- 13 funções/components exportados (fetchPagador*, EstabelecimentoInput, PagadorInfoCard, etc.).
- 5 props cross-file (preLancamentosCount → inboxPendingCount, pagadorAvatarUrl → payerAvatarUrl, etc.).
- Mantidas em PT-BR conforme exceção do CLAUDE.md: variáveis locais (pagador, categoria,
  lancamento), accessor key pagadorName (persistida em preferências), strings de UI.

Reorganizado:
- transactions/: 14 helpers soltos na raiz movidos para lib/; barrel actions.ts reduzido
  de 76 linhas de wrappers para 14 linhas de re-exports puros; anticipation-actions.ts
  movido para actions/anticipation.ts.
- dashboard/: 8 helpers soltos consolidados em dashboard/lib/.
- reports/: 5 query files na raiz consolidados em reports/lib/.
- payers/: detail-actions.ts (21KB) e detail-queries.ts movidos para payers/lib/.
- shared/components/: 9 dos 16 componentes soltos agrupados em brand/, widgets/, feedback/.
- shared/lib/fetch-json.ts movido para shared/utils/fetch-json.ts.

Validação: pnpm exec tsc --noEmit (0 erros), biome check (0 issues), knip (sem unused).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 18:42:54 +00:00
Felipe Coutinho
b9b843b9db Revise README for .env setup and remove acknowledgments
Updated instructions for creating a .env file and removed acknowledgments section.
2026-05-05 14:51:36 -03:00
Felipe Coutinho
01215b3124 chore: prepara versao 2.5.3 2026-05-05 17:17:33 +00:00
Felipe Coutinho
d70223e7b3 chore: renova massa de dados mock 2026-05-05 17:17:26 +00:00
Felipe Coutinho
6ea064e1bd style: ajusta espacamento de telas do dashboard 2026-05-05 17:17:19 +00:00
Felipe Coutinho
9c0669a152 feat: padroniza contas e cartoes inativos 2026-05-05 17:17:13 +00:00
Felipe Coutinho
b2d4b29cb5 feat: aprimora detalhes de lancamentos 2026-05-05 17:17:06 +00:00
Felipe Coutinho
1df2ba787d chore: bump versão para 2.5.2 e atualizar changelog
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 15:42:51 +00:00
Felipe Coutinho
e5d9b66cca feat(dashboard): complementar texto de recorrências com "mensais"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 15:42:48 +00:00
Felipe Coutinho
37edb1b76d feat(notes): substituir ícone de tarefa pendente por RiSubtractLine em contextos read-only
No card e no modal de detalhes de anotações, onde não há interação
de marcação, tarefas não concluídas exibem RiSubtractLine em vez
do quadrado com borda. Locais interativos mantêm o comportamento atual.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 15:42:44 +00:00
Felipe Coutinho
6288f5f8d4 feat(budgets, cards): progress bar em cor destructive quando limite excedido
Adiciona prop indicatorClassName ao componente Progress. Orçamentos
estourados e cartões com 100% do limite utilizado exibem a barra
com indicador e fundo na cor destructive.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 15:42:39 +00:00
Felipe Coutinho
57ac326c2a feat(transactions): filtro de contas por tipo dinheiro e sinal + em transferências recebidas
Ao selecionar "Dinheiro" como forma de pagamento, exibe apenas contas
do tipo "Dinheiro". Transferências recebidas (amount > 0) passam a
exibir sinal + mantendo a cor azul.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 15:42:35 +00:00
Felipe Coutinho
dccc18b1c1 fix(transfers): corrigir forma de pagamento de pix para transferência bancária
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 15:42:31 +00:00
Felipe Coutinho
0cb01a1d4c feat(accounts): adicionar tipos de conta dinheiro e outros com ícones no seletor
Adiciona "Dinheiro" (issue #50) e "Outros" à lista de tipos de conta.
Implementa AccountTypeSelectContent com ícones distintos por tipo via
getAccountTypeIcon em shared/utils/icons.tsx.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 15:42:27 +00:00
Felipe Coutinho
51652da4f8 fix(invoices): exibir ícone de anexo na fatura do cartão (2.5.1)
fetchCardTransactions não preenchia hasAttachments, então o ícone não
aparecia em /cards/[cardId]/invoice. Agora delega para
fetchTransactionsWithRelations, que já calcula o flag via EXISTS.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 01:44:08 +00:00
Felipe Coutinho
7a74f9405e fix(lint): corrigir formatação do snapshot de migration e imports
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 22:28:27 +00:00
260 changed files with 5033 additions and 4888 deletions

View File

@@ -5,6 +5,75 @@ Todas as mudanças notáveis deste projeto serão documentadas neste arquivo.
O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/), O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/),
e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR/). e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR/).
## [2.5.4] - 2026-05-06
Esta versão é uma faxina arquitetural de larga escala sem nenhuma mudança visível ao usuário. Removido código morto, padronizamos identificadores em inglês conforme a convenção do projeto, simplificamos o barrel de Server Actions e consolidamos os arquivos de helpers/queries soltos nas raízes das features dentro de pastas `lib/`. O resultado é uma estrutura previsível e consistente entre features (`actions.ts`, `queries.ts`, `actions/`, `components/`, `hooks/`, `lib/`) e um saldo líquido de 428 linhas de código com zero impacto em comportamento, performance ou banco de dados.
### Alterado
- Padronização da estrutura de `transactions/`: 14 helpers soltos na raiz movidos para `lib/`; barrel `actions.ts` reduzido de 76 linhas de wrappers redundantes para 14 linhas de re-exports puros; `anticipation-actions.ts` movido para `actions/anticipation.ts`.
- Reorganização de `dashboard/`: 8 helpers soltos consolidados em `dashboard/lib/`; orquestradores (`fetch-dashboard-data.ts`, `page-data-queries.ts`) permanecem na raiz como entry points.
- Reorganização de `reports/`: 5 query files na raiz consolidados em `reports/lib/`.
- Reorganização de `payers/`: god file `detail-actions.ts` (21KB) e `detail-queries.ts` movidos para `payers/lib/`.
- `shared/components/`: 9 dos 16 componentes soltos agrupados em 3 novas subpastas temáticas (`brand/`, `widgets/`, `feedback/`).
- `shared/lib/fetch-json.ts` movido para `shared/utils/fetch-json.ts` (categorização correta — utilitário genérico de transporte HTTP).
- Padronização EN dos identificadores remanescentes: 4 constantes globais (`LANCAMENTOS_*``TRANSACTIONS_*`), 12 tipos/interfaces (`Lancamento*`/`Pagador*`/`Estabelecimento*` → equivalentes em EN), 13 funções/components exportados (`fetchPagador*`, `EstabelecimentoInput`, `PagadorInfoCard`, etc.), 5 props cross-file (`preLancamentosCount``inboxPendingCount`, etc.).
- Server Actions de `insights/` simplificadas: barrel reduzido para re-exports puros.
- Mantidas intencionalmente em PT-BR conforme exceção do `CLAUDE.md`: variáveis locais (`pagador`, `categoria`, `lancamento`), accessor key `pagadorName` (persistida em preferências do usuário), strings de UI.
### Removido
- 14 funções/constantes mortas verificadas via `grep` em todo o repo: `validateCategoriaOwnership`, `getInstallmentAnticipationsAction`, `getAnticipationDetailsAction`, `formatDecimalForDb`, `currencyFormatterNoCents`, `optionalDecimalSchema`, `formatMonthLabel`, `getGoalProgressStatusColorClass`, `MONTH_PERIOD_PARAM`, `calculateRemainingInstallments`, e 5 funções `fetch*` não usadas em `inbox/queries.ts`.
- 1 tipo morto: `ImportRow` em `transactions/actions/import-action.ts`.
- 2 tipos órfãos consequentes: `InstallmentAnticipationWithRelations`, `GoalProgressStatus` (este último convertido em interno).
- ~30 `export` keywords desnecessários (símbolos usados apenas no próprio arquivo) — visibilidade reduzida sem mudar comportamento.
- Re-exports mortos em barrels: `EstablishmentLogoPicker` em `entity-avatar/index.ts`, `CategoryReportSkeleton` e `WidgetSkeleton` em `skeletons/index.ts`, `toNameKey` em `establishment-logo-queries.ts`.
- Arquivo `features/reports/types.ts` (barrel inteiro era órfão — todos os 5 tipos eram importados direto de `@/shared/lib/types/reports`).
## [2.5.3] - 2026-05-05
Esta versão foca em polimento do diálogo de detalhes do lançamento, refresh visual da linha do tempo de parcelas e limpeza terminológica em torno de contas/cartões inativos. O diálogo de detalhes ganhou logo da conta/cartão, ícone colorido por categoria e avatar do responsável; a barra de progresso de parcelas foi redesenhada num layout horizontal compacto; e o widget "Minhas Contas" do dashboard passou a ocultar automaticamente contas marcadas como inativas. Internamente, o termo "arquivadas" foi padronizado como "inativas" nas tabs de contas e cartões, surgiram constantes compartilhadas para formas de pagamento liquidáveis e um helper `isAccountInactive`, e o seed de mock data ganhou cobertura mais realista (novas pessoas, contas, cartões e assinaturas recorrentes).
### Adicionado
- Logo da conta/cartão, ícone colorido por categoria e avatar do responsável no diálogo de detalhes do lançamento.
- Constantes `SETTLEABLE_PAYMENT_METHODS` e `CREDIT_CARD_PAYMENT_METHOD` em `features/transactions/constants.ts`.
- Helper `isAccountInactive(status)` em `shared/lib/accounts/constants.ts`, reaproveitado em `account-card.tsx` e `my-accounts-widget.tsx`.
### Alterado
- Widget "Minhas Contas" do dashboard agora oculta contas inativas (filtra antes de aplicar a regra de "não consideradas") e ajusta o empty state quando o usuário só tem contas inativas.
- Linha do tempo de parcelas (`InstallmentTimeline`) redesenhada: layout horizontal com barra de progresso, datas de compra e quitação alinhadas nas pontas e contador "N restante(s)" / "Última parcela" abaixo.
- Diálogo de detalhes do lançamento: badge de status "Pendente" virou "Em aberto" com variante `info`, "Resumo" virou "Total" e ID do lançamento passou a exibir o UUID completo em fonte monoespaçada (sem truncar).
- Tabs em contas e cartões: "Arquivadas/Arquivados" renomeadas para "Inativas/Inativos".
- Legenda do calendário envolvida em `Card` para destacar visualmente do conteúdo da página.
- Páginas `cards`, `categories`, `inbox`, `notes`, `payers` perderam `items-start` no `<main>` (alinhamento natural à largura total); `calendar` ajustou gap de 3 para 4.
- Tabela de lançamentos: extraído IIFE de payment-method dos botões de liquidação com as novas constantes compartilhadas; bloco logo+label da coluna Conta/Cartão deduplicado via reuso de variável JSX; removido `capitalize` redundante do label "Venc.".
- Mock data renovado em `scripts/mock-data.ts`: novas pessoas (Mario), novas contas (Itaú Personnalité, Banco Inter), novo cartão Inter Black, e cobertura mais ampla de assinaturas recorrentes (Vivo, Sabesp, Disney+, HBO Max, Amazon Prime, OpenAI, Apple iCloud, Notion, YouTube Premium).
### Removido
- Comentário narrativo `{/* Opções de Antecipação */}` em `transactions-columns.tsx`.
- Helper local `shortTransactionId` em `transaction-details-dialog.tsx` (substituído pela exibição do UUID completo).
## [2.5.2] - 2026-05-04
Esta versão traz melhorias visuais e de usabilidade em contas, lançamentos, orçamentos, cartões e anotações: novos tipos de conta, ícones no seletor, feedback visual de limite excedido nas progress bars e refinamentos nos ícones de tarefas em anotações.
### Adicionado
- Novos tipos de conta `"Dinheiro"` e `"Outros"` na lista padrão do diálogo de contas (issue #50).
- Ícones por tipo de conta no seletor (Conta Corrente, Poupança, Carteira Digital, Investimento, Pré-Pago, Dinheiro, Outros).
- Filtro automático: ao selecionar `"Dinheiro"` como forma de pagamento em lançamentos, o select de conta exibe apenas contas do tipo `"Dinheiro"`.
- Sinal `+` no valor de transferências recebidas na tabela de lançamentos (mantém cor azul).
### Alterado
- Forma de pagamento de novas transferências entre contas alterada de `"Pix"` para `"Transferência bancária"`.
- Progress bar de orçamentos excedidos agora exibe indicador e fundo na cor `destructive`.
- Progress bar de cartões com 100% do limite utilizado agora exibe indicador e fundo na cor `destructive`.
- Ícone de tarefa não concluída no card e no modal de detalhes de anotações substituído por `RiSubtractLine` (locais sem interação de marcação).
## [2.5.1] - 2026-05-04
Versão de correção pontual focada na exibição do indicador de anexo nas tabelas de lançamentos da fatura do cartão. Em `/cards/[cardId]/invoice`, lançamentos com anexos não mostravam o ícone porque o fetcher dedicado da fatura não calculava o flag `hasAttachments`. A primeira tentativa de adicionar o EXISTS via `extras` na query relacional gerou SQL inválido (Drizzle re-aliasava `transactionAttachments.transactionId` para o alias da tabela externa). A correção definitiva troca o fetcher pela função compartilhada `fetchTransactionsWithRelations` de `features/transactions`, que já implementa o EXISTS corretamente via `select`.
### Corrigido
- Ícone de anexo voltou a aparecer na tabela de lançamentos da fatura do cartão (`/cards/[cardId]/invoice`). `fetchCardTransactions` em `features/invoices/queries.ts` agora delega para `fetchTransactionsWithRelations`, garantindo que o flag `hasAttachments` seja preenchido com a mesma EXISTS subquery usada no restante do app.
## [2.5.0] - 2026-05-01 ## [2.5.0] - 2026-05-01
Esta versão melhora o fechamento de faturas, a correção de lançamentos já registrados e a conferência de saldos contra o extrato do banco. O novo **ajuste de fatura** fecha a conta entre o total calculado pelo sistema e o valor real cobrado pelo banco, sem exigir que o usuário reabra lançamentos individuais. A mesma ideia foi estendida para **contas correntes**: na página do extrato, ao lado de "Saldo ao final do período", o usuário informa o saldo real e o sistema cria (ou atualiza) um lançamento de ajuste no período visualizado. Também entra o fluxo de **reembolso** para despesas à vista: pelo menu de ações do lançamento, o usuário informa a data do reembolso e o sistema cria uma receita espelhada no extrato ou na fatura correta. O widget de boletos do dashboard ganhou paridade com o widget de faturas — confirmação de pagamento agora pede conta de origem e data antes de quitar o boleto. Por fim, o **limite do cartão** passou a ser obrigatório e o sistema bloqueia despesas em cartão que ultrapassem o limite disponível, retornando uma mensagem com o valor exato disponível. As operações mantêm rastro no lançamento gerado e respeitam a proteção de faturas já pagas. Esta versão melhora o fechamento de faturas, a correção de lançamentos já registrados e a conferência de saldos contra o extrato do banco. O novo **ajuste de fatura** fecha a conta entre o total calculado pelo sistema e o valor real cobrado pelo banco, sem exigir que o usuário reabra lançamentos individuais. A mesma ideia foi estendida para **contas correntes**: na página do extrato, ao lado de "Saldo ao final do período", o usuário informa o saldo real e o sistema cria (ou atualiza) um lançamento de ajuste no período visualizado. Também entra o fluxo de **reembolso** para despesas à vista: pelo menu de ações do lançamento, o usuário informa a data do reembolso e o sistema cria uma receita espelhada no extrato ou na fatura correta. O widget de boletos do dashboard ganhou paridade com o widget de faturas — confirmação de pagamento agora pede conta de origem e data antes de quitar o boleto. Por fim, o **limite do cartão** passou a ser obrigatório e o sistema bloqueia despesas em cartão que ultrapassem o limite disponível, retornando uma mensagem com o valor exato disponível. As operações mantêm rastro no lançamento gerado e respeitam a proteção de faturas já pagas.

View File

@@ -97,7 +97,7 @@ src/
│ ├── api/ │ ├── api/
│ ├── globals.css │ ├── globals.css
│ └── layout.tsx │ └── layout.tsx
├── features/ ├── features/ # cada feature segue: actions.ts, queries.ts, actions/, components/, hooks/, lib/
│ ├── auth/ │ ├── auth/
│ ├── landing/ │ ├── landing/
│ ├── dashboard/ │ ├── dashboard/
@@ -117,9 +117,12 @@ src/
│ └── settings/ │ └── settings/
├── shared/ ├── shared/
│ ├── components/ │ ├── components/
│ │ ├── ui/ │ │ ├── ui/ # shadcn/ui primitives
│ │ ├── navigation/ │ │ ├── navigation/ # navbar, sidebar, breadcrumbs
│ │ ├── providers/ │ │ ├── providers/ # React context providers
│ │ ├── brand/ # logos do app (logo, logo-icon, logo-text)
│ │ ├── widgets/ # widget-card, widget-empty-state, expandable-widget-card
│ │ ├── feedback/ # empty-state, status-dot, payment-success
│ │ ├── month-picker/ │ │ ├── month-picker/
│ │ ├── logo-picker/ │ │ ├── logo-picker/
│ │ ├── calculator/ │ │ ├── calculator/
@@ -134,34 +137,56 @@ src/
│ │ ├── calculator/ │ │ ├── calculator/
│ │ ├── categories/ │ │ ├── categories/
│ │ ├── email/ │ │ ├── email/
│ │ ├── import/
│ │ ├── installments/ │ │ ├── installments/
│ │ ├── invoices/ │ │ ├── invoices/
│ │ ├── logo/ │ │ ├── logo/
│ │ ├── notifications/
│ │ ├── payers/ │ │ ├── payers/
│ │ ├── schemas/ │ │ ├── schemas/
│ │ ├── storage/
│ │ ├── transfers/ │ │ ├── transfers/
│ │ ├── types/ │ │ ├── types/
│ │ ├── version/
│ │ └── db.ts │ │ └── db.ts
│ └── utils/ │ └── utils/
│ ├── period/ │ ├── period/
│ ├── calculator.ts
│ ├── calendar.ts
│ ├── category-colors.ts
│ ├── currency.ts │ ├── currency.ts
│ ├── date.ts │ ├── date.ts
│ ├── export-branding.ts
│ ├── fetch-json.ts
│ ├── financial-dates.ts │ ├── financial-dates.ts
│ ├── percentage.ts │ ├── icons.tsx
│ ├── category-colors.ts │ ├── id.ts
│ ├── calendar.ts │ ├── initials.ts
│ ├── math.ts │ ├── math.ts
│ ├── number.ts │ ├── number.ts
│ ├── percentage.ts
│ ├── string.ts │ ├── string.ts
── initials.ts ── ui.ts
│ ├── icons.tsx
│ ├── export-branding.ts
│ ├── ui.ts
│ └── calculator.ts
└── db/ └── db/
└── schema.ts └── schema.ts
``` ```
### Estrutura interna padrão de uma feature
Toda feature em `src/features/<nome>/` segue:
```text
<feature>/
├── actions.ts # entry point de Server Actions (barrel quando há actions/)
├── queries.ts # entry point de leitura do banco
├── actions/ # (opcional) Server Actions divididas por domínio quando o volume cresce
├── components/ # componentes de UI da feature
├── hooks/ # React hooks específicos da feature
└── lib/ # helpers, types, sub-queries e constantes internas
```
`actions.ts` e `queries.ts` são as portas de entrada da feature. Tudo que é helper interno fica em `lib/`. Componentes e hooks ficam nas pastas com nome óbvio.
--- ---
## Import Patterns ## Import Patterns
@@ -299,9 +324,11 @@ export async function fetchData(userId: string, period: string) {
2. Criar a feature em `src/features/<feature>/` 2. Criar a feature em `src/features/<feature>/`
3. Separar: 3. Separar:
- `components/` - `components/`
- `queries.ts` - `queries.ts` (entry point de leitura)
- `actions.ts` - `actions.ts` (entry point de Server Actions; vira barrel quando crescer e migrar para `actions/`)
- `types.ts` ou `schemas.ts` quando fizer sentido - `lib/` para helpers internos, sub-queries por tópico, types e constantes da feature
- `types.ts` ou `schemas.ts` quando fizer sentido (alternativa a `lib/`)
- `hooks/` quando houver hooks específicos da feature
4. Extrair para `src/shared/` tudo que for reutilizavel 4. Extrair para `src/shared/` tudo que for reutilizavel
5. Atualizar navegacao e `revalidateForEntity()` se a feature tiver CRUD 5. Atualizar navegacao e `revalidateForEntity()` se a feature tiver CRUD
6. Rodar: 6. Rodar:

View File

@@ -8,7 +8,7 @@
> **⚠️ Não há versão online hospedada.** Você precisa clonar o repositório e rodar localmente ou no seu próprio servidor. > **⚠️ Não há versão online hospedada.** Você precisa clonar o repositório e rodar localmente ou no seu próprio servidor.
[![Version](https://img.shields.io/badge/version-2.5.0-blue?style=flat-square)](CHANGELOG.md) [![Version](https://img.shields.io/badge/version-2.5.4-blue?style=flat-square)](CHANGELOG.md)
[![Next.js](https://img.shields.io/badge/Next.js-black?style=flat-square&logo=next.js)](https://nextjs.org/) [![Next.js](https://img.shields.io/badge/Next.js-black?style=flat-square&logo=next.js)](https://nextjs.org/)
[![TypeScript](https://img.shields.io/badge/TypeScript-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-blue?style=flat-square&logo=postgresql)](https://www.postgresql.org/) [![PostgreSQL](https://img.shields.io/badge/PostgreSQL-blue?style=flat-square&logo=postgresql)](https://www.postgresql.org/)
@@ -127,21 +127,20 @@ Só quer rodar o OpenMonetis. **Não precisa clonar o repositório nem instalar
# 1. Baixe o compose # 1. Baixe o compose
curl -fsSL https://raw.githubusercontent.com/felipegcoutinho/openmonetis/main/docker-compose.yml -o docker-compose.yml curl -fsSL https://raw.githubusercontent.com/felipegcoutinho/openmonetis/main/docker-compose.yml -o docker-compose.yml
# 2. Suba tudo # 2. Crie um .en na mesma pasta.
# .env mínimo recomendado para produção
BETTER_AUTH_SECRET=gere-um-valor-com-openssl-rand-base64-32
BETTER_AUTH_URL=http://seu-dominio.com
# 3. Suba tudo
docker compose up -d docker compose up -d
``` ```
Acesse em: `http://localhost:3000` Acesse em: `http://localhost:3000`
O banco sobe com credenciais padrão. Para personalizar (senha, Google OAuth, e-mail, IA...), crie um `.env` na mesma pasta **antes** de subir: O banco sobe com credenciais padrão. Para personalizar (senha, Google OAuth, e-mail, IA...), crie um `.env` na mesma pasta **antes** de subir.
```bash Mais sobre .env em [Variáveis de Ambiente](#-variáveis-de-ambiente).
# .env mínimo recomendado para produção
BETTER_AUTH_SECRET=gere-um-valor-com-openssl-rand-base64-32
BETTER_AUTH_URL=https://seu-dominio.com
```
Veja todas as variáveis disponíveis em [Variáveis de Ambiente](#-variáveis-de-ambiente).
**Banco remoto (Supabase, Neon, Railway...):** defina `DATABASE_URL` no `.env` e suba só o app: **Banco remoto (Supabase, Neon, Railway...):** defina `DATABASE_URL` no `.env` e suba só o app:
@@ -508,7 +507,18 @@ openmonetis/
│ │ └── auth/ # Formulários de autenticação │ │ └── auth/ # Formulários de autenticação
│ │ │ │
│ ├── shared/ # Código reutilizado entre features │ ├── shared/ # Código reutilizado entre features
│ │ ├── components/ # UI compartilhada (shadcn/ui, navigation, skeletons...) │ │ ├── components/ # UI compartilhada
│ │ │ ├── ui/ # shadcn/ui primitives
│ │ │ ├── navigation/ # navbar, sidebar, breadcrumbs
│ │ │ ├── brand/ # logos do app
│ │ │ ├── widgets/ # widget-card e variantes
│ │ │ ├── feedback/ # empty-state, status-dot, payment-success
│ │ │ ├── entity-avatar/ # avatares de categoria/estabelecimento
│ │ │ ├── month-picker/ # seletor de período
│ │ │ ├── logo-picker/ # seletor de logos
│ │ │ ├── calculator/ # calculadora de cálculos rápidos
│ │ │ ├── skeletons/ # loading skeletons
│ │ │ └── providers/ # React context providers
│ │ ├── hooks/ # React hooks globais │ │ ├── hooks/ # React hooks globais
│ │ ├── lib/ # Helpers de domínio (auth, db, payers, schemas, email...) │ │ ├── lib/ # Helpers de domínio (auth, db, payers, schemas, email...)
│ │ └── utils/ # Utilitários (currency, date, period, math, string...) │ │ └── utils/ # Utilitários (currency, date, period, math, string...)
@@ -524,6 +534,22 @@ openmonetis/
└── proxy.ts # Middleware (auth + multi-domínio) └── proxy.ts # Middleware (auth + multi-domínio)
``` ```
### Estrutura interna de uma feature
Toda feature em `src/features/<nome>/` segue o mesmo padrão:
```
<feature>/
├── actions.ts # Server Actions (entry point — barrel re-export quando há actions/)
├── queries.ts # Funções de leitura do banco (entry point)
├── actions/ # (opcional) Server Actions divididas por domínio quando o volume cresce
├── components/ # Componentes de UI da feature
├── hooks/ # React hooks específicos da feature
└── lib/ # Helpers, types, sub-queries e constantes
```
A regra é: `actions.ts` e `queries.ts` são as portas de entrada da feature. Tudo que é helper interno fica em `lib/`. Componentes e hooks ficam nas pastas com nome óbvio.
--- ---
## 🤝 Contribuindo ## 🤝 Contribuindo
@@ -563,12 +589,6 @@ Para o texto legal completo, consulte o arquivo [LICENSE](LICENSE) ou visite [cr
--- ---
## 🙏 Agradecimentos
[Next.js](https://nextjs.org/) · [Better Auth](https://better-auth.com/) · [Drizzle ORM](https://orm.drizzle.team/) · [shadcn/ui](https://ui.shadcn.com/) · [Biome](https://biomejs.dev/) · [Vercel](https://vercel.com/)
---
**Desenvolvido por:** Felipe Coutinho — [@felipegcoutinho](https://github.com/felipegcoutinho) **Desenvolvido por:** Felipe Coutinho — [@felipegcoutinho](https://github.com/felipegcoutinho)
<div align="center"> <div align="center">

View File

@@ -1,5 +1,5 @@
{ {
"$schema": "https://biomejs.dev/schemas/2.4.13/schema.json", "$schema": "https://biomejs.dev/schemas/2.4.14/schema.json",
"vcs": { "vcs": {
"enabled": true, "enabled": true,
"clientKind": "git", "clientKind": "git",

File diff suppressed because it is too large Load Diff

View File

@@ -1,209 +1,209 @@
{ {
"version": "7", "version": "7",
"dialect": "postgresql", "dialect": "postgresql",
"entries": [ "entries": [
{ {
"idx": 0, "idx": 0,
"version": "7", "version": "7",
"when": 1762993507299, "when": 1762993507299,
"tag": "0000_flashy_manta", "tag": "0000_flashy_manta",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 1, "idx": 1,
"version": "7", "version": "7",
"when": 1765199006435, "when": 1765199006435,
"tag": "0001_young_mister_fear", "tag": "0001_young_mister_fear",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 2, "idx": 2,
"version": "7", "version": "7",
"when": 1765200545692, "when": 1765200545692,
"tag": "0002_slimy_flatman", "tag": "0002_slimy_flatman",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 3, "idx": 3,
"version": "7", "version": "7",
"when": 1767102605526, "when": 1767102605526,
"tag": "0003_green_korg", "tag": "0003_green_korg",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 4, "idx": 4,
"version": "7", "version": "7",
"when": 1767104066872, "when": 1767104066872,
"tag": "0004_acoustic_mach_iv", "tag": "0004_acoustic_mach_iv",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 5, "idx": 5,
"version": "7", "version": "7",
"when": 1767106121811, "when": 1767106121811,
"tag": "0005_adorable_bruce_banner", "tag": "0005_adorable_bruce_banner",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 6, "idx": 6,
"version": "7", "version": "7",
"when": 1767107487318, "when": 1767107487318,
"tag": "0006_youthful_mister_fear", "tag": "0006_youthful_mister_fear",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 7, "idx": 7,
"version": "7", "version": "7",
"when": 1767118780033, "when": 1767118780033,
"tag": "0007_sturdy_kate_bishop", "tag": "0007_sturdy_kate_bishop",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 8, "idx": 8,
"version": "7", "version": "7",
"when": 1767125796314, "when": 1767125796314,
"tag": "0008_fat_stick", "tag": "0008_fat_stick",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 9, "idx": 9,
"version": "7", "version": "7",
"when": 1768925100873, "when": 1768925100873,
"tag": "0009_add_dashboard_widgets", "tag": "0009_add_dashboard_widgets",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 10, "idx": 10,
"version": "7", "version": "7",
"when": 1769369834242, "when": 1769369834242,
"tag": "0010_lame_psynapse", "tag": "0010_lame_psynapse",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 11, "idx": 11,
"version": "7", "version": "7",
"when": 1769447087678, "when": 1769447087678,
"tag": "0011_remove_unused_inbox_columns", "tag": "0011_remove_unused_inbox_columns",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 12, "idx": 12,
"version": "7", "version": "7",
"when": 1769533200000, "when": 1769533200000,
"tag": "0012_rename_tables_to_portuguese", "tag": "0012_rename_tables_to_portuguese",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 13, "idx": 13,
"version": "7", "version": "7",
"when": 1769523352777, "when": 1769523352777,
"tag": "0013_fancy_rick_jones", "tag": "0013_fancy_rick_jones",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 14, "idx": 14,
"version": "7", "version": "7",
"when": 1769619226903, "when": 1769619226903,
"tag": "0014_yielding_jack_flag", "tag": "0014_yielding_jack_flag",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 15, "idx": 15,
"version": "7", "version": "7",
"when": 1770332054481, "when": 1770332054481,
"tag": "0015_concerned_kat_farrell", "tag": "0015_concerned_kat_farrell",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 16, "idx": 16,
"version": "7", "version": "7",
"when": 1771166328908, "when": 1771166328908,
"tag": "0016_complete_randall", "tag": "0016_complete_randall",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 17, "idx": 17,
"version": "7", "version": "7",
"when": 1772400510326, "when": 1772400510326,
"tag": "0017_previous_warstar", "tag": "0017_previous_warstar",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 18, "idx": 18,
"version": "7", "version": "7",
"when": 1773020417482, "when": 1773020417482,
"tag": "0018_rainy_epoch", "tag": "0018_rainy_epoch",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 19, "idx": 19,
"version": "7", "version": "7",
"when": 1773699152928, "when": 1773699152928,
"tag": "0019_ordinary_wild_pack", "tag": "0019_ordinary_wild_pack",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 20, "idx": 20,
"version": "7", "version": "7",
"when": 1773841892114, "when": 1773841892114,
"tag": "0020_add-budget-invoice-unique-constraints", "tag": "0020_add-budget-invoice-unique-constraints",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 21, "idx": 21,
"version": "7", "version": "7",
"when": 1774033320053, "when": 1774033320053,
"tag": "0021_careful_malcolm_colcord", "tag": "0021_careful_malcolm_colcord",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 22, "idx": 22,
"version": "7", "version": "7",
"when": 1748000000000, "when": 1748000000000,
"tag": "0022_import-category-mappings", "tag": "0022_import-category-mappings",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 23, "idx": 23,
"version": "7", "version": "7",
"when": 1774529878374, "when": 1774529878374,
"tag": "0023_sturdy_wolfpack", "tag": "0023_sturdy_wolfpack",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 24, "idx": 24,
"version": "7", "version": "7",
"when": 1774891206703, "when": 1774891206703,
"tag": "0024_petite_lucky_pierre", "tag": "0024_petite_lucky_pierre",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 25, "idx": 25,
"version": "7", "version": "7",
"when": 1776351838548, "when": 1776351838548,
"tag": "0025_burly_colonel_america", "tag": "0025_burly_colonel_america",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 26, "idx": 26,
"version": "7", "version": "7",
"when": 1777042423451, "when": 1777042423451,
"tag": "0026_bored_eternity", "tag": "0026_bored_eternity",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 28, "idx": 28,
"version": "7", "version": "7",
"when": 1777153372633, "when": 1777153372633,
"tag": "0028_fancy_reaper", "tag": "0028_fancy_reaper",
"breakpoints": true "breakpoints": true
}, },
{ {
"idx": 29, "idx": 29,
"version": "7", "version": "7",
"when": 1777648189399, "when": 1777648189399,
"tag": "0029_friendly_spitfire", "tag": "0029_friendly_spitfire",
"breakpoints": true "breakpoints": true
} }
] ]
} }

View File

@@ -12,8 +12,10 @@
], ],
// PostCSS is inferred from the config file, but the project only depends on // PostCSS is inferred from the config file, but the project only depends on
// the Tailwind PostCSS plugin directly. // the Tailwind PostCSS plugin directly.
// `server-only` is provided implicitly by Next.js — no install needed.
"ignoreDependencies": [ "ignoreDependencies": [
"postcss" "postcss",
"server-only"
], ],
"next": true, "next": true,
"postcss": true, "postcss": true,

View File

@@ -21,6 +21,7 @@ const nextConfig: NextConfig = {
experimental: { experimental: {
prefetchInlining: true, prefetchInlining: true,
turbopackFileSystemCacheForDev: true, turbopackFileSystemCacheForDev: true,
optimizePackageImports: ["@remixicon/react"],
}, },
// Headers for Safari compatibility // Headers for Safari compatibility

View File

@@ -1,6 +1,6 @@
{ {
"name": "openmonetis", "name": "openmonetis",
"version": "2.5.0", "version": "2.5.4",
"private": true, "private": true,
"packageManager": "pnpm@10.33.0", "packageManager": "pnpm@10.33.0",
"scripts": { "scripts": {
@@ -33,9 +33,9 @@
"dependencies": { "dependencies": {
"@ai-sdk/anthropic": "^3.0.74", "@ai-sdk/anthropic": "^3.0.74",
"@ai-sdk/google": "^3.0.67", "@ai-sdk/google": "^3.0.67",
"@ai-sdk/openai": "^3.0.57", "@ai-sdk/openai": "^3.0.60",
"@aws-sdk/client-s3": "^3.1040.0", "@aws-sdk/client-s3": "^3.1042.0",
"@aws-sdk/s3-request-presigner": "^3.1040.0", "@aws-sdk/s3-request-presigner": "^3.1042.0",
"@better-auth/passkey": "^1.6.9", "@better-auth/passkey": "^1.6.9",
"@dnd-kit/core": "^6.3.1", "@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0", "@dnd-kit/sortable": "^10.0.0",
@@ -63,10 +63,10 @@
"@radix-ui/react-toggle-group": "1.1.11", "@radix-ui/react-toggle-group": "1.1.11",
"@radix-ui/react-tooltip": "1.2.8", "@radix-ui/react-tooltip": "1.2.8",
"@remixicon/react": "4.9.0", "@remixicon/react": "4.9.0",
"@tanstack/react-query": "^5.100.7", "@tanstack/react-query": "^5.100.9",
"@tanstack/react-table": "8.21.3", "@tanstack/react-table": "8.21.3",
"@tanstack/react-virtual": "^3.13.24", "@tanstack/react-virtual": "^3.13.24",
"ai": "^6.0.173", "ai": "^6.0.175",
"better-auth": "1.6.9", "better-auth": "1.6.9",
"canvas-confetti": "^1.9.4", "canvas-confetti": "^1.9.4",
"class-variance-authority": "0.7.1", "class-variance-authority": "0.7.1",
@@ -89,7 +89,7 @@
"sonner": "2.0.7", "sonner": "2.0.7",
"tailwind-merge": "3.5.0", "tailwind-merge": "3.5.0",
"vaul": "1.1.2", "vaul": "1.1.2",
"zod": "4.4.1" "zod": "4.4.3"
}, },
"pnpm": { "pnpm": {
"overrides": { "overrides": {
@@ -97,7 +97,7 @@
} }
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "2.4.13", "@biomejs/biome": "2.4.14",
"@tailwindcss/postcss": "4.2.4", "@tailwindcss/postcss": "4.2.4",
"@types/canvas-confetti": "^1.9.0", "@types/canvas-confetti": "^1.9.0",
"@types/node": "25.6.0", "@types/node": "25.6.0",
@@ -106,7 +106,7 @@
"@types/react-dom": "19.2.3", "@types/react-dom": "19.2.3",
"dotenv": "^17.4.2", "dotenv": "^17.4.2",
"drizzle-kit": "0.31.10", "drizzle-kit": "0.31.10",
"knip": "^6.10.0", "knip": "^6.11.0",
"tailwindcss": "4.2.4", "tailwindcss": "4.2.4",
"tsx": "4.21.0", "tsx": "4.21.0",
"typescript": "6.0.3" "typescript": "6.0.3"

447
pnpm-lock.yaml generated
View File

@@ -13,22 +13,22 @@ importers:
dependencies: dependencies:
'@ai-sdk/anthropic': '@ai-sdk/anthropic':
specifier: ^3.0.74 specifier: ^3.0.74
version: 3.0.74(zod@4.4.1) version: 3.0.74(zod@4.4.3)
'@ai-sdk/google': '@ai-sdk/google':
specifier: ^3.0.67 specifier: ^3.0.67
version: 3.0.67(zod@4.4.1) version: 3.0.67(zod@4.4.3)
'@ai-sdk/openai': '@ai-sdk/openai':
specifier: ^3.0.57 specifier: ^3.0.60
version: 3.0.57(zod@4.4.1) version: 3.0.60(zod@4.4.3)
'@aws-sdk/client-s3': '@aws-sdk/client-s3':
specifier: ^3.1040.0 specifier: ^3.1042.0
version: 3.1040.0 version: 3.1042.0
'@aws-sdk/s3-request-presigner': '@aws-sdk/s3-request-presigner':
specifier: ^3.1040.0 specifier: ^3.1042.0
version: 3.1040.0 version: 3.1042.0
'@better-auth/passkey': '@better-auth/passkey':
specifier: ^1.6.9 specifier: ^1.6.9
version: 1.6.9(22762a9b26d2e46f2ba0c21d31406330) version: 1.6.9(60d949d2bbdb8e45901f3be9be360abb)
'@dnd-kit/core': '@dnd-kit/core':
specifier: ^6.3.1 specifier: ^6.3.1
version: 6.3.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5) version: 6.3.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
@@ -40,7 +40,7 @@ importers:
version: 3.2.2(react@19.2.5) version: 3.2.2(react@19.2.5)
'@openrouter/ai-sdk-provider': '@openrouter/ai-sdk-provider':
specifier: ^2.9.0 specifier: ^2.9.0
version: 2.9.0(ai@6.0.173(zod@4.4.1))(zod@4.4.1) version: 2.9.0(ai@6.0.175(zod@4.4.3))(zod@4.4.3)
'@radix-ui/react-alert-dialog': '@radix-ui/react-alert-dialog':
specifier: 1.1.15 specifier: 1.1.15
version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
@@ -108,8 +108,8 @@ importers:
specifier: 4.9.0 specifier: 4.9.0
version: 4.9.0(react@19.2.5) version: 4.9.0(react@19.2.5)
'@tanstack/react-query': '@tanstack/react-query':
specifier: ^5.100.7 specifier: ^5.100.9
version: 5.100.7(react@19.2.5) version: 5.100.9(react@19.2.5)
'@tanstack/react-table': '@tanstack/react-table':
specifier: 8.21.3 specifier: 8.21.3
version: 8.21.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5) version: 8.21.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
@@ -117,8 +117,8 @@ importers:
specifier: ^3.13.24 specifier: ^3.13.24
version: 3.13.24(react-dom@19.2.5(react@19.2.5))(react@19.2.5) version: 3.13.24(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
ai: ai:
specifier: ^6.0.173 specifier: ^6.0.175
version: 6.0.173(zod@4.4.1) version: 6.0.175(zod@4.4.3)
better-auth: better-auth:
specifier: 1.6.9 specifier: 1.6.9
version: 1.6.9(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)))(mongodb@7.1.0)(mysql2@3.15.3)(next@16.2.4(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(pg@8.20.0)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) version: 1.6.9(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)))(mongodb@7.1.0)(mysql2@3.15.3)(next@16.2.4(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(pg@8.20.0)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
@@ -186,12 +186,12 @@ importers:
specifier: 1.1.2 specifier: 1.1.2
version: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) version: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
zod: zod:
specifier: 4.4.1 specifier: 4.4.3
version: 4.4.1 version: 4.4.3
devDependencies: devDependencies:
'@biomejs/biome': '@biomejs/biome':
specifier: 2.4.13 specifier: 2.4.14
version: 2.4.13 version: 2.4.14
'@tailwindcss/postcss': '@tailwindcss/postcss':
specifier: 4.2.4 specifier: 4.2.4
version: 4.2.4 version: 4.2.4
@@ -217,8 +217,8 @@ importers:
specifier: 0.31.10 specifier: 0.31.10
version: 0.31.10 version: 0.31.10
knip: knip:
specifier: ^6.10.0 specifier: ^6.11.0
version: 6.10.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) version: 6.11.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
tailwindcss: tailwindcss:
specifier: 4.2.4 specifier: 4.2.4
version: 4.2.4 version: 4.2.4
@@ -237,8 +237,8 @@ packages:
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
'@ai-sdk/gateway@3.0.108': '@ai-sdk/gateway@3.0.110':
resolution: {integrity: sha512-hOtwiM6E/m1PgqHnx0/grvh0P/kjENHsN222OL5iYPQwfWmcX+26oFXM7HGL/UzonB+RORMkYAbskgAiANVwCQ==} resolution: {integrity: sha512-sbv8+1L9/BRKydn8dMNwoMQKupA4iLJ9N+yvxgW6wMQ/94UepDf3FeYWMj/dLdzolAHZ6izRUP4s5WqQkmJ2Zg==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
@@ -249,8 +249,8 @@ packages:
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
'@ai-sdk/openai@3.0.57': '@ai-sdk/openai@3.0.60':
resolution: {integrity: sha512-2kfzDQYYz0m/yRF4bre9s2j8wNiPdhfHzYZc3dxAOMlprvGmRZOvoZBx8chlJIFwL7xR2EFkvLagBvo2llCXPw==} resolution: {integrity: sha512-vZKqbDSCF1T65gDMG2ILJ2NAEpG45U2VtvEve1Fv/WRLu2i5TPUqxjlGKm+5a7Dd57Yr6CGePxrJhsQJC8LJ3A==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
@@ -292,48 +292,48 @@ packages:
'@aws-crypto/util@5.2.0': '@aws-crypto/util@5.2.0':
resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==}
'@aws-sdk/client-s3@3.1040.0': '@aws-sdk/client-s3@3.1042.0':
resolution: {integrity: sha512-Ldfby1xDrlZwNY2NxP9pwdVrf8sqHbGBKP1UkoG/oWcePGlGhjY8iVwy8hRy9f1EQfHVFWIFunwHaPQxhYTnWQ==} resolution: {integrity: sha512-z3Ibstr7ckDT10dz/nkk4+93LitrrO49Oq563/JoFHt30ZNodPBCfSxysKcelLyi/lNVF1MZrhZZfikUAG3iNQ==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/core@3.974.7': '@aws-sdk/core@3.974.8':
resolution: {integrity: sha512-YhRC90ofz5oolTJZlA8voU/oUrCB2azi8Usx51k8hhB5LpWbYQMMXKUqSqkoL0Cru+RQJgWTHpAfEDDIwfUhJw==} resolution: {integrity: sha512-njR2qoG6ZuB0kvAS2FyICsFZJ6gmCcf2X/7JcD14sUvGDm26wiZ5BrA6LOiUxKFEF+IVe7kdroxyE00YlkiYsw==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/crc64-nvme@3.972.7': '@aws-sdk/crc64-nvme@3.972.7':
resolution: {integrity: sha512-QUagVVBbC8gODCF6e1aV0mE2TXWB9Opz4k8EJFdNrujUVQm5R4AjJa1mpOqzwOuROBzqJU9zawzig7M96L8Ejg==} resolution: {integrity: sha512-QUagVVBbC8gODCF6e1aV0mE2TXWB9Opz4k8EJFdNrujUVQm5R4AjJa1mpOqzwOuROBzqJU9zawzig7M96L8Ejg==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-env@3.972.33': '@aws-sdk/credential-provider-env@3.972.34':
resolution: {integrity: sha512-bJV7eViSJV6GSuuN+VIdNVPdwPsNSf75BiC2v5alPrjR/OCcqgKwSZInKbDFz9mNeizldsyf67jt6YSIiv53Cw==} resolution: {integrity: sha512-XT0jtf8Fw9JE6ppsQeoNnZRiG+jqRixMT1v1ZR17G60UvVdsQmTG8nbEyHuEPfMxDXEhfdARaM/XiEhca4lGHQ==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-http@3.972.35': '@aws-sdk/credential-provider-http@3.972.36':
resolution: {integrity: sha512-x/BQGEIdq0oI+4WxLjKmnQvT7CnF9r8ezdGt7wXwxb7ckHXQz0Zmgxt8v3Ne0JaT3R5YefmuybHX6E8EnsDXyA==} resolution: {integrity: sha512-DPoGWfy7J7RKxvbf5kOKIGQkD2ek3dbKgzKIGrnLuvZBz5myU+Im/H6pmc14QcnFbqHMqxvtWSgRDSJW3qXLQg==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-ini@3.972.37': '@aws-sdk/credential-provider-ini@3.972.38':
resolution: {integrity: sha512-eUTpmWfd/BKsq9medhCRcu+GRAhFP2Zrn7/2jKDHHOOjCkhrMoTp/t4cEthqFoG7gE0VGp5wUxrXTdvBCmSmJg==} resolution: {integrity: sha512-oDzUBu2MGJFgoar05sPMCwSrhw44ASyccrHzj66vO69OZqi7I6hZZxXfuPLC8OCzW7C+sU+bI73XHij41yekgQ==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-login@3.972.37': '@aws-sdk/credential-provider-login@3.972.38':
resolution: {integrity: sha512-Ty68y8ISSC+g5Q3D0K8uAaoINwvfaOslnNpsF/LgVUxyosYXHawcK2yV4HLXDVugiTTYLQfJfcw0ce5meAGkKw==} resolution: {integrity: sha512-g1NosS8qe4OF++G2UFCM5ovSkgipC7YYor5KCWatG0UoMSO5YFj9C8muePlyVmOBV/WTI16Jo3/s1NUo/o1Bww==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-node@3.972.38': '@aws-sdk/credential-provider-node@3.972.39':
resolution: {integrity: sha512-BQ9XYnBDVxR2HuV5huXYQYF/PZMTsY+EnwfGnCU2cA8Zw63XpkOtPY8WqiMIZMQCrKPQQEiFURS/o9CIolRLqg==} resolution: {integrity: sha512-HEswDQyxUtadoZ/bJsPPENHg7R0Lzym5LuMksJeHvqhCOpP+rtkDLKI4/ZChH4w3cf5kG8n6bZuI8PzajoiqMg==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-process@3.972.33': '@aws-sdk/credential-provider-process@3.972.34':
resolution: {integrity: sha512-yfjGksI9WQbdMObb0VeLXqzTLI+a0qXLJT9gCDiv0+X/xjPpI3mTz6a5FibrhpuEKIe0gSgvs3MaoFZy5cx4WA==} resolution: {integrity: sha512-T3IFs4EVmVi1dVN5RciFnklCANSzvrQd/VuHY9ThHSQmYkTogjcGkoJEr+oNUPQZnso52183088NqysMPji1/Q==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-sso@3.972.37': '@aws-sdk/credential-provider-sso@3.972.38':
resolution: {integrity: sha512-fpwE+20ntpp3i9Xb9vUuQfXLDKYHH+5I2V+ZG96SX1nBzrruhy10RXDgmN7t1etOz3c55stlA3TeQASUA451NQ==} resolution: {integrity: sha512-5ZxG+t0+3Q3QPh8KEjX6syskhgNf7I0MN7oGioTf6Lm1NTjfP7sIcYGNsthXC2qR8vcD3edNZwCr2ovfSSWuRA==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/credential-provider-web-identity@3.972.37': '@aws-sdk/credential-provider-web-identity@3.972.38':
resolution: {integrity: sha512-aryawqyebf+3WhAFNHfF62rekFpYtVcVN7dQ89qnAWsa4n5hJst8qBG6gXC24WHtW7Nnhkf9ScYnjwo0Brn3bw==} resolution: {integrity: sha512-lYHFF30DGI20jZcYX8cm6Ns0V7f1dDN6g/MBDLTyD/5iw+bXs3yBr2iAiHDkx4RFU5JgsnZvCHYKiRVPRdmOgw==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-bucket-endpoint@3.972.10': '@aws-sdk/middleware-bucket-endpoint@3.972.10':
@@ -344,8 +344,8 @@ packages:
resolution: {integrity: sha512-2Yn0f1Qiq/DjxYR3wfI3LokXnjOhFM7Ssn4LTdFDIxRMCE6I32MAsVnhPX1cUZsuVA9tiZtwwhlSLAtFGxAZlQ==} resolution: {integrity: sha512-2Yn0f1Qiq/DjxYR3wfI3LokXnjOhFM7Ssn4LTdFDIxRMCE6I32MAsVnhPX1cUZsuVA9tiZtwwhlSLAtFGxAZlQ==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-flexible-checksums@3.974.15': '@aws-sdk/middleware-flexible-checksums@3.974.16':
resolution: {integrity: sha512-j4Zp7rA1HfhDTteICnx/tPax4N/v5wmytgguXExUGyEwQ8Ug4EBA4kjp9puFAN1UZoBVpxoiXMiuTFvjaHjeEw==} resolution: {integrity: sha512-6ru8doI0/XzszqLIPXf0E/V7HhAw1Pu94010XCKYtBUfD0LxF0BuOzrUf8OQGR6j2o6wgKTHUniOmndQycHwCA==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-host-header@3.972.10': '@aws-sdk/middleware-host-header@3.972.10':
@@ -364,36 +364,36 @@ packages:
resolution: {integrity: sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==} resolution: {integrity: sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-sdk-s3@3.972.36': '@aws-sdk/middleware-sdk-s3@3.972.37':
resolution: {integrity: sha512-YhPix+0x/MdQrb1Ug1GDKeS5fqylIy+naz800asX8II4jqfTk2KY2KhmmYCwZcky8YWtRQQwWCGdoqeAnip8Uw==} resolution: {integrity: sha512-Km7M+i8DrLArVzrid1gfxeGhYHBd3uxvE77g0s5a52zPSVosxzQBnJ0gwWb6NIp/DOk8gsBMhi7V+cpJG0ndTA==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-ssec@3.972.10': '@aws-sdk/middleware-ssec@3.972.10':
resolution: {integrity: sha512-Gli9A0u8EVVb+5bFDGS/QbSVg28w/wpEidg1ggVcSj65BDTdGR6punsOcVjqdiu1i42WHWo51MCvARPIIz9juw==} resolution: {integrity: sha512-Gli9A0u8EVVb+5bFDGS/QbSVg28w/wpEidg1ggVcSj65BDTdGR6punsOcVjqdiu1i42WHWo51MCvARPIIz9juw==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/middleware-user-agent@3.972.37': '@aws-sdk/middleware-user-agent@3.972.38':
resolution: {integrity: sha512-N1oNpdiLoVAWYD3WFBnUi3LlfoDA06ZHo4ozyjbsJNLvILzvt//0CnR8N+CZ0NWeYgVB/5V59ivixHCWCx2ALw==} resolution: {integrity: sha512-iz+B29TXcAZsJpwB+AwG/TTGA5l/VnmMZ2UxtiySOZjI6gCdmviXPwdgzcmuazMy16rXoPY4mYCGe7zdNKfx5A==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/nested-clients@3.997.5': '@aws-sdk/nested-clients@3.997.6':
resolution: {integrity: sha512-jGFr6DxtcMTmzOkG/a0jCZYv4BBDmeNYVeO+/memSoDkYCJu4Y58xviYmzwJfYyIVSts+X/BVjJm1uGBnwHEMg==} resolution: {integrity: sha512-WBDnqatJl+kGObpfmfSxqnXeYTu3Me8wx8WCtvoxX3pfWrrTv8I4WTMSSs7PZqcRcVh8WeUKMgGFjMG+52SR1w==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/region-config-resolver@3.972.13': '@aws-sdk/region-config-resolver@3.972.13':
resolution: {integrity: sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==} resolution: {integrity: sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/s3-request-presigner@3.1040.0': '@aws-sdk/s3-request-presigner@3.1042.0':
resolution: {integrity: sha512-AmesZGG/B5sDIiWahyY11fOkXSsuHc7LciE88YFURehMVSdEORo2Vzz1d2kBgmJG9oar5Vmmwf9X/w7mqb7ytg==} resolution: {integrity: sha512-yWgXWDg4W0Vk1xlY4M7puM07ce6PPBS4tBytNOpu57k+wY0puXgxkGN0+k/dUAA4sR4Th6+wDps50gBBLj48Ew==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/signature-v4-multi-region@3.996.24': '@aws-sdk/signature-v4-multi-region@3.996.25':
resolution: {integrity: sha512-amP7tLikppN940wbBFISYqiuzVmpzMS9U3mcgtmVLjX4fdWI/SNCvrXv6ZxfVzTT4cT0rPKOLhFah2xLwzREWw==} resolution: {integrity: sha512-+CMIt3e1VzlklAECmG+DtP1sV8iKq25FuA0OKpnJ4KA0kxUtd7CgClY7/RU6VzJBQwbN4EJ9Ue6plvqx1qGadw==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/token-providers@3.1039.0': '@aws-sdk/token-providers@3.1041.0':
resolution: {integrity: sha512-NMSFL2HwkAOoCeLCQiqoOq5pT3vVbSjww2QZTuYgYknVwhhv125PSDzZIcL5EYnlxuPWjEOdauZK+FspkZDVdw==} resolution: {integrity: sha512-Th7kPI6YPtvJUcdznooXJMy+9rQWjmEF81LxaJssngBzuysK4a/x+l8kjm1zb7nYsUPbndnBdUnwng/3PLvtGw==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@aws-sdk/types@3.973.8': '@aws-sdk/types@3.973.8':
@@ -419,8 +419,8 @@ packages:
'@aws-sdk/util-user-agent-browser@3.972.10': '@aws-sdk/util-user-agent-browser@3.972.10':
resolution: {integrity: sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==} resolution: {integrity: sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==}
'@aws-sdk/util-user-agent-node@3.973.23': '@aws-sdk/util-user-agent-node@3.973.24':
resolution: {integrity: sha512-gGwq8L2Euw0aNG6Ey4EktiAo3fSCVoDy1CaBIthd+oeaKHPXUrNaApMewQ6La5Hv0lcznOtECZaNvYyc5LXXfA==} resolution: {integrity: sha512-ZWwlkjcIp7cEL8ZfTpTAPNkwx25p7xol0xlKoWVVf22+nsjwmLcHYtTPjIV1cSpmB/b6DaK4cb1fSkvCXHgRdw==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
peerDependencies: peerDependencies:
aws-crt: '>=1.0.0' aws-crt: '>=1.0.0'
@@ -541,59 +541,59 @@ packages:
'@better-fetch/fetch@1.1.21': '@better-fetch/fetch@1.1.21':
resolution: {integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==} resolution: {integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==}
'@biomejs/biome@2.4.13': '@biomejs/biome@2.4.14':
resolution: {integrity: sha512-gLXOwkOBBg0tr7bDsqlkIh4uFeKuMjxvqsrb1Tukww1iDmHcfr4Uu8MoQxp0Rcte+69+osRNWXwHsu/zxT6XqA==} resolution: {integrity: sha512-TmAvxOEgrpLypzVGJ8FulIZnlyA9TxrO1hyqYrCz9r+bwma9xXxuLA5IuYnj55XQneFx460KjRbx6SWGLkg3bQ==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
hasBin: true hasBin: true
'@biomejs/cli-darwin-arm64@2.4.13': '@biomejs/cli-darwin-arm64@2.4.14':
resolution: {integrity: sha512-2KImO1jhNFBa2oWConyr0x6flxbQpGKv6902uGXpYM62Xyem8U80j441SyUJ8KyngsmKbQjeIv1q2CQfDkNnYg==} resolution: {integrity: sha512-XvgoE9XOawUOQPdmvs4J7wPhi/DLwSCGks3AlPJDmh34O0awRTqCED1HRcRDdpf1Zrp4us4MGOOdIxNpbqNF5Q==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@biomejs/cli-darwin-x64@2.4.13': '@biomejs/cli-darwin-x64@2.4.14':
resolution: {integrity: sha512-BKrJklbaFN4p1Ts4kPBczo+PkbsHQg57kmJ+vON9u2t6uN5okYHaSr7h/MutPCWQgg2lglaWoSmm+zhYW+oOkg==} resolution: {integrity: sha512-jE7hKBCFhOx3uUh+ZkWBfOHxAcILPfhFplNkuID/eZeSTLHzfZzoZxW8fbqY9xXRnPi7jGNAf1iPVR+0yWsM/Q==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@biomejs/cli-linux-arm64-musl@2.4.13': '@biomejs/cli-linux-arm64-musl@2.4.14':
resolution: {integrity: sha512-U5MsuBQW25dXaYtqWWSPM3P96H6Y+fHuja3TQpMNnylocHW0tEbtFTDlUj6oM+YJLntvEkQy4grBvQNUD4+RCg==} resolution: {integrity: sha512-/z+6gqAqqUQTHazwStxSXKHg9b8UvqBmDFRp+c4wYbq2KXhELQDon9EoC9RpmQ8JWkqQx/lIUy/cs+MhzDZp6A==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [musl] libc: [musl]
'@biomejs/cli-linux-arm64@2.4.13': '@biomejs/cli-linux-arm64@2.4.14':
resolution: {integrity: sha512-NzkUDSqfvMBrPplKgVr3aXLHZ2NEELvvF4vZxXulEylKWIGqlvNEcwUcj9OLrn75TD3lJ/GIqCVlBwd1MZCuYQ==} resolution: {integrity: sha512-2TELhZnW5RSLL063l9rc5xLpA0ZIw0Ccwy/0q384rvNAgFw3yI76bd59547yxowdQr5MNPET/xDLrLuvgSeeWQ==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@biomejs/cli-linux-x64-musl@2.4.13': '@biomejs/cli-linux-x64-musl@2.4.14':
resolution: {integrity: sha512-Z601MienRgTBDza/+u2CH3RSrWoXo9rtr8NK6A4KJzqGgfxx+H3VlyLgTJ4sRo40T3pIsqpTmiOQEvYzQvBRvQ==} resolution: {integrity: sha512-R6BWgJdQOwW9ulJatuTVrQkjnODjqHZkKNOqb1sz++3Noe5LYd0i3PchnOBUCYAPHoPWHhjJqbdZlHEu0hpjdA==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [musl] libc: [musl]
'@biomejs/cli-linux-x64@2.4.13': '@biomejs/cli-linux-x64@2.4.14':
resolution: {integrity: sha512-Az3ZZedYRBo9EQzNnD9SxFcR1G5QsGo6VEc2hIyVPZ1rdKwee/7E9oeBBZFpE8Z44ekxsDQBqbiWGW5ShOhUSQ==} resolution: {integrity: sha512-zHrlQZDBDUz4OLAraYpWKcnLS6HOewBFWYOzY91d1ZjdqZwibOyb6BEu6WuWLugyo0P3riCmsbV9UqV1cSXwQg==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
libc: [glibc] libc: [glibc]
'@biomejs/cli-win32-arm64@2.4.13': '@biomejs/cli-win32-arm64@2.4.14':
resolution: {integrity: sha512-Px9PS2B5/Q183bUwy/5VHqp3J2lzdOCeVGzMpphYfl8oSa7VDCqenBdqWpy6DCy/en4Rbf/Y1RieZF6dJPcc9A==} resolution: {integrity: sha512-M3EH5hqOI/F/FUA2u4xcLoUgmxd218mvuj/6JL7Hv2toQvr2/AdOvKSpGkoRuWFCtQPVa+ZqkEV3Q5xBA9+XSA==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@biomejs/cli-win32-x64@2.4.13': '@biomejs/cli-win32-x64@2.4.14':
resolution: {integrity: sha512-tTcMkXyBrmHi9BfrD2VNHs/5rYIUKETqsBlYOvSAABwBkJhSDVb5e7wPukftsQbO3WzQkXe6kaztC6WtUOXSoQ==} resolution: {integrity: sha512-WL0EG5qE+EAKomGXbf2g6VnSKJhTL3tXC0QRzWRwA5VpjxNYa6H4P7ZWfymbGE4IhZZQi1KXQ2R0YjwInmz2fA==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@@ -2602,6 +2602,7 @@ packages:
'@smithy/util-retry@4.3.6': '@smithy/util-retry@4.3.6':
resolution: {integrity: sha512-p6/FO1n2KxMeQyna067i0uJ6TSbb165ZhnRtCpWh4Foxqbfc6oW+XITaL8QkFJj3KFnDe2URt4gOhgU06EP9ew==} resolution: {integrity: sha512-p6/FO1n2KxMeQyna067i0uJ6TSbb165ZhnRtCpWh4Foxqbfc6oW+XITaL8QkFJj3KFnDe2URt4gOhgU06EP9ew==}
engines: {node: '>=18.0.0'} engines: {node: '>=18.0.0'}
deprecated: '@smithy/util-retry v4.3.6 contains a bug in Adaptive Retry, see https://github.com/smithy-lang/smithy-typescript/issues/1993. Upgrade to 4.3.7+'
'@smithy/util-stream@4.5.25': '@smithy/util-stream@4.5.25':
resolution: {integrity: sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==} resolution: {integrity: sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==}
@@ -2735,11 +2736,11 @@ packages:
'@tailwindcss/postcss@4.2.4': '@tailwindcss/postcss@4.2.4':
resolution: {integrity: sha512-wgAVj6nUWAolAu8YFvzT2cTBIElWHkjZwFYovF+xsqKsW2ADxM/X2opxj5NsF/qVccAOjRNe8X2IdPzMsWyHTg==} resolution: {integrity: sha512-wgAVj6nUWAolAu8YFvzT2cTBIElWHkjZwFYovF+xsqKsW2ADxM/X2opxj5NsF/qVccAOjRNe8X2IdPzMsWyHTg==}
'@tanstack/query-core@5.100.7': '@tanstack/query-core@5.100.9':
resolution: {integrity: sha512-5R7i6ENJLhVeeJrrUz7jKBXUXv/BJrxf9FQJSkR13bPrb3zOcE8A0Z0PxYCcsKPOsiIlTibrBL/zZbtUO1TFyQ==} resolution: {integrity: sha512-SJSFw1S8+kQ0+knv/XGfrbocWoAlT7vDKsSImtLx3ZPQmEcR46hkDjLSvynSy25N8Ms4tIEini1FuBd5k7IscQ==}
'@tanstack/react-query@5.100.7': '@tanstack/react-query@5.100.9':
resolution: {integrity: sha512-LoISYWz8dOOuQbeIctF8K6yi42TWtR1WPGpwGuRUpF3u79JVVIg/PVR0MQdIA0VSHqD/ydf/b7PhKTkg3I4fLQ==} resolution: {integrity: sha512-Oa44XkaI3kCNN6ME0KByU3xT3SEUNOMfZpHxL6+wFoTm+OeUFYHKdeYVe0aOXlRDm/f15sgLwEt2HDorIdW8+A==}
peerDependencies: peerDependencies:
react: ^18 || ^19 react: ^18 || ^19
@@ -2835,8 +2836,8 @@ packages:
resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==}
engines: {node: '>= 20'} engines: {node: '>= 20'}
ai@6.0.173: ai@6.0.175:
resolution: {integrity: sha512-X2noFb82kouYQ4nlKGm1cR1Wvlp4Xit7fjJzwXv/msKQmtqkQn9NiXH6kCX4Gl4G+9DRWsJHIKANtWk8Ix1nTw==} resolution: {integrity: sha512-6fFFHzbh6FIZnYc31V6osOxq25ABJYCShfG0O6ajHiA4FB/DgnPi1mP8cO5aAU3HNSbQHiMazdlh9bIsp97mVA==}
engines: {node: '>=18'} engines: {node: '>=18'}
peerDependencies: peerDependencies:
zod: ^3.25.76 || ^4.1.8 zod: ^3.25.76 || ^4.1.8
@@ -3487,8 +3488,8 @@ packages:
jszip@3.10.1: jszip@3.10.1:
resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
knip@6.10.0: knip@6.11.0:
resolution: {integrity: sha512-u9EaTj17MYkTw2aojWSwMoRQ6pI/ZtjDexuhqkQ8uQuvMFJXeeHu6MhKDdSppijGaiNGtDSMFYs+w5iZLrb2Cg==} resolution: {integrity: sha512-84PTlN8Q5smLpTbzs8smTVh8PMbTDXtw0tFksXq/m6auGFC/KSzJykKFmnYh3As38kiWDkoDBvdTTyKk5M1TAQ==}
engines: {node: ^20.19.0 || >=22.12.0} engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true hasBin: true
@@ -4320,42 +4321,42 @@ packages:
resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
zod@4.4.1: zod@4.4.3:
resolution: {integrity: sha512-a6ENMBBGZBsnlSebQ/eKCguSBeGKSf4O7BPnqVPmYGtpBYI7VSqoVqw+QcB7kPRjbqPwhYTpFbVj/RqNz/CT0Q==} resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
snapshots: snapshots:
'@ai-sdk/anthropic@3.0.74(zod@4.4.1)': '@ai-sdk/anthropic@3.0.74(zod@4.4.3)':
dependencies: dependencies:
'@ai-sdk/provider': 3.0.10 '@ai-sdk/provider': 3.0.10
'@ai-sdk/provider-utils': 4.0.26(zod@4.4.1) '@ai-sdk/provider-utils': 4.0.26(zod@4.4.3)
zod: 4.4.1 zod: 4.4.3
'@ai-sdk/gateway@3.0.108(zod@4.4.1)': '@ai-sdk/gateway@3.0.110(zod@4.4.3)':
dependencies: dependencies:
'@ai-sdk/provider': 3.0.10 '@ai-sdk/provider': 3.0.10
'@ai-sdk/provider-utils': 4.0.26(zod@4.4.1) '@ai-sdk/provider-utils': 4.0.26(zod@4.4.3)
'@vercel/oidc': 3.2.0 '@vercel/oidc': 3.2.0
zod: 4.4.1 zod: 4.4.3
'@ai-sdk/google@3.0.67(zod@4.4.1)': '@ai-sdk/google@3.0.67(zod@4.4.3)':
dependencies: dependencies:
'@ai-sdk/provider': 3.0.10 '@ai-sdk/provider': 3.0.10
'@ai-sdk/provider-utils': 4.0.26(zod@4.4.1) '@ai-sdk/provider-utils': 4.0.26(zod@4.4.3)
zod: 4.4.1 zod: 4.4.3
'@ai-sdk/openai@3.0.57(zod@4.4.1)': '@ai-sdk/openai@3.0.60(zod@4.4.3)':
dependencies: dependencies:
'@ai-sdk/provider': 3.0.10 '@ai-sdk/provider': 3.0.10
'@ai-sdk/provider-utils': 4.0.26(zod@4.4.1) '@ai-sdk/provider-utils': 4.0.26(zod@4.4.3)
zod: 4.4.1 zod: 4.4.3
'@ai-sdk/provider-utils@4.0.26(zod@4.4.1)': '@ai-sdk/provider-utils@4.0.26(zod@4.4.3)':
dependencies: dependencies:
'@ai-sdk/provider': 3.0.10 '@ai-sdk/provider': 3.0.10
'@standard-schema/spec': 1.1.0 '@standard-schema/spec': 1.1.0
eventsource-parser: 3.0.8 eventsource-parser: 3.0.8
zod: 4.4.1 zod: 4.4.3
'@ai-sdk/provider@3.0.10': '@ai-sdk/provider@3.0.10':
dependencies: dependencies:
@@ -4410,29 +4411,29 @@ snapshots:
'@smithy/util-utf8': 2.3.0 '@smithy/util-utf8': 2.3.0
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/client-s3@3.1040.0': '@aws-sdk/client-s3@3.1042.0':
dependencies: dependencies:
'@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha1-browser': 5.2.0
'@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0
'@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/sha256-js': 5.2.0
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/credential-provider-node': 3.972.38 '@aws-sdk/credential-provider-node': 3.972.39
'@aws-sdk/middleware-bucket-endpoint': 3.972.10 '@aws-sdk/middleware-bucket-endpoint': 3.972.10
'@aws-sdk/middleware-expect-continue': 3.972.10 '@aws-sdk/middleware-expect-continue': 3.972.10
'@aws-sdk/middleware-flexible-checksums': 3.974.15 '@aws-sdk/middleware-flexible-checksums': 3.974.16
'@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-host-header': 3.972.10
'@aws-sdk/middleware-location-constraint': 3.972.10 '@aws-sdk/middleware-location-constraint': 3.972.10
'@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10
'@aws-sdk/middleware-recursion-detection': 3.972.11 '@aws-sdk/middleware-recursion-detection': 3.972.11
'@aws-sdk/middleware-sdk-s3': 3.972.36 '@aws-sdk/middleware-sdk-s3': 3.972.37
'@aws-sdk/middleware-ssec': 3.972.10 '@aws-sdk/middleware-ssec': 3.972.10
'@aws-sdk/middleware-user-agent': 3.972.37 '@aws-sdk/middleware-user-agent': 3.972.38
'@aws-sdk/region-config-resolver': 3.972.13 '@aws-sdk/region-config-resolver': 3.972.13
'@aws-sdk/signature-v4-multi-region': 3.996.24 '@aws-sdk/signature-v4-multi-region': 3.996.25
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-endpoints': 3.996.8
'@aws-sdk/util-user-agent-browser': 3.972.10 '@aws-sdk/util-user-agent-browser': 3.972.10
'@aws-sdk/util-user-agent-node': 3.973.23 '@aws-sdk/util-user-agent-node': 3.973.24
'@smithy/config-resolver': 4.4.17 '@smithy/config-resolver': 4.4.17
'@smithy/core': 3.23.17 '@smithy/core': 3.23.17
'@smithy/eventstream-serde-browser': 4.2.14 '@smithy/eventstream-serde-browser': 4.2.14
@@ -4470,7 +4471,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- aws-crt - aws-crt
'@aws-sdk/core@3.974.7': '@aws-sdk/core@3.974.8':
dependencies: dependencies:
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@aws-sdk/xml-builder': 3.972.22 '@aws-sdk/xml-builder': 3.972.22
@@ -4492,17 +4493,17 @@ snapshots:
'@smithy/types': 4.14.1 '@smithy/types': 4.14.1
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/credential-provider-env@3.972.33': '@aws-sdk/credential-provider-env@3.972.34':
dependencies: dependencies:
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/property-provider': 4.2.14 '@smithy/property-provider': 4.2.14
'@smithy/types': 4.14.1 '@smithy/types': 4.14.1
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/credential-provider-http@3.972.35': '@aws-sdk/credential-provider-http@3.972.36':
dependencies: dependencies:
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/fetch-http-handler': 5.3.17 '@smithy/fetch-http-handler': 5.3.17
'@smithy/node-http-handler': 4.6.1 '@smithy/node-http-handler': 4.6.1
@@ -4513,16 +4514,16 @@ snapshots:
'@smithy/util-stream': 4.5.25 '@smithy/util-stream': 4.5.25
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/credential-provider-ini@3.972.37': '@aws-sdk/credential-provider-ini@3.972.38':
dependencies: dependencies:
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/credential-provider-env': 3.972.33 '@aws-sdk/credential-provider-env': 3.972.34
'@aws-sdk/credential-provider-http': 3.972.35 '@aws-sdk/credential-provider-http': 3.972.36
'@aws-sdk/credential-provider-login': 3.972.37 '@aws-sdk/credential-provider-login': 3.972.38
'@aws-sdk/credential-provider-process': 3.972.33 '@aws-sdk/credential-provider-process': 3.972.34
'@aws-sdk/credential-provider-sso': 3.972.37 '@aws-sdk/credential-provider-sso': 3.972.38
'@aws-sdk/credential-provider-web-identity': 3.972.37 '@aws-sdk/credential-provider-web-identity': 3.972.38
'@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/nested-clients': 3.997.6
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/credential-provider-imds': 4.2.14 '@smithy/credential-provider-imds': 4.2.14
'@smithy/property-provider': 4.2.14 '@smithy/property-provider': 4.2.14
@@ -4532,10 +4533,10 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- aws-crt - aws-crt
'@aws-sdk/credential-provider-login@3.972.37': '@aws-sdk/credential-provider-login@3.972.38':
dependencies: dependencies:
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/nested-clients': 3.997.6
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/property-provider': 4.2.14 '@smithy/property-provider': 4.2.14
'@smithy/protocol-http': 5.3.14 '@smithy/protocol-http': 5.3.14
@@ -4545,14 +4546,14 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- aws-crt - aws-crt
'@aws-sdk/credential-provider-node@3.972.38': '@aws-sdk/credential-provider-node@3.972.39':
dependencies: dependencies:
'@aws-sdk/credential-provider-env': 3.972.33 '@aws-sdk/credential-provider-env': 3.972.34
'@aws-sdk/credential-provider-http': 3.972.35 '@aws-sdk/credential-provider-http': 3.972.36
'@aws-sdk/credential-provider-ini': 3.972.37 '@aws-sdk/credential-provider-ini': 3.972.38
'@aws-sdk/credential-provider-process': 3.972.33 '@aws-sdk/credential-provider-process': 3.972.34
'@aws-sdk/credential-provider-sso': 3.972.37 '@aws-sdk/credential-provider-sso': 3.972.38
'@aws-sdk/credential-provider-web-identity': 3.972.37 '@aws-sdk/credential-provider-web-identity': 3.972.38
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/credential-provider-imds': 4.2.14 '@smithy/credential-provider-imds': 4.2.14
'@smithy/property-provider': 4.2.14 '@smithy/property-provider': 4.2.14
@@ -4562,20 +4563,20 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- aws-crt - aws-crt
'@aws-sdk/credential-provider-process@3.972.33': '@aws-sdk/credential-provider-process@3.972.34':
dependencies: dependencies:
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/property-provider': 4.2.14 '@smithy/property-provider': 4.2.14
'@smithy/shared-ini-file-loader': 4.4.9 '@smithy/shared-ini-file-loader': 4.4.9
'@smithy/types': 4.14.1 '@smithy/types': 4.14.1
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/credential-provider-sso@3.972.37': '@aws-sdk/credential-provider-sso@3.972.38':
dependencies: dependencies:
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/nested-clients': 3.997.6
'@aws-sdk/token-providers': 3.1039.0 '@aws-sdk/token-providers': 3.1041.0
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/property-provider': 4.2.14 '@smithy/property-provider': 4.2.14
'@smithy/shared-ini-file-loader': 4.4.9 '@smithy/shared-ini-file-loader': 4.4.9
@@ -4584,10 +4585,10 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- aws-crt - aws-crt
'@aws-sdk/credential-provider-web-identity@3.972.37': '@aws-sdk/credential-provider-web-identity@3.972.38':
dependencies: dependencies:
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/nested-clients': 3.997.6
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/property-provider': 4.2.14 '@smithy/property-provider': 4.2.14
'@smithy/shared-ini-file-loader': 4.4.9 '@smithy/shared-ini-file-loader': 4.4.9
@@ -4613,12 +4614,12 @@ snapshots:
'@smithy/types': 4.14.1 '@smithy/types': 4.14.1
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/middleware-flexible-checksums@3.974.15': '@aws-sdk/middleware-flexible-checksums@3.974.16':
dependencies: dependencies:
'@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32': 5.2.0
'@aws-crypto/crc32c': 5.2.0 '@aws-crypto/crc32c': 5.2.0
'@aws-crypto/util': 5.2.0 '@aws-crypto/util': 5.2.0
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/crc64-nvme': 3.972.7 '@aws-sdk/crc64-nvme': 3.972.7
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/is-array-buffer': 4.2.2 '@smithy/is-array-buffer': 4.2.2
@@ -4657,9 +4658,9 @@ snapshots:
'@smithy/types': 4.14.1 '@smithy/types': 4.14.1
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/middleware-sdk-s3@3.972.36': '@aws-sdk/middleware-sdk-s3@3.972.37':
dependencies: dependencies:
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@aws-sdk/util-arn-parser': 3.972.3 '@aws-sdk/util-arn-parser': 3.972.3
'@smithy/core': 3.23.17 '@smithy/core': 3.23.17
@@ -4680,9 +4681,9 @@ snapshots:
'@smithy/types': 4.14.1 '@smithy/types': 4.14.1
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/middleware-user-agent@3.972.37': '@aws-sdk/middleware-user-agent@3.972.38':
dependencies: dependencies:
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-endpoints': 3.996.8
'@smithy/core': 3.23.17 '@smithy/core': 3.23.17
@@ -4691,21 +4692,21 @@ snapshots:
'@smithy/util-retry': 4.3.6 '@smithy/util-retry': 4.3.6
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/nested-clients@3.997.5': '@aws-sdk/nested-clients@3.997.6':
dependencies: dependencies:
'@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0
'@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/sha256-js': 5.2.0
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/middleware-host-header': 3.972.10 '@aws-sdk/middleware-host-header': 3.972.10
'@aws-sdk/middleware-logger': 3.972.10 '@aws-sdk/middleware-logger': 3.972.10
'@aws-sdk/middleware-recursion-detection': 3.972.11 '@aws-sdk/middleware-recursion-detection': 3.972.11
'@aws-sdk/middleware-user-agent': 3.972.37 '@aws-sdk/middleware-user-agent': 3.972.38
'@aws-sdk/region-config-resolver': 3.972.13 '@aws-sdk/region-config-resolver': 3.972.13
'@aws-sdk/signature-v4-multi-region': 3.996.24 '@aws-sdk/signature-v4-multi-region': 3.996.25
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@aws-sdk/util-endpoints': 3.996.8 '@aws-sdk/util-endpoints': 3.996.8
'@aws-sdk/util-user-agent-browser': 3.972.10 '@aws-sdk/util-user-agent-browser': 3.972.10
'@aws-sdk/util-user-agent-node': 3.973.23 '@aws-sdk/util-user-agent-node': 3.973.24
'@smithy/config-resolver': 4.4.17 '@smithy/config-resolver': 4.4.17
'@smithy/core': 3.23.17 '@smithy/core': 3.23.17
'@smithy/fetch-http-handler': 5.3.17 '@smithy/fetch-http-handler': 5.3.17
@@ -4743,9 +4744,9 @@ snapshots:
'@smithy/types': 4.14.1 '@smithy/types': 4.14.1
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/s3-request-presigner@3.1040.0': '@aws-sdk/s3-request-presigner@3.1042.0':
dependencies: dependencies:
'@aws-sdk/signature-v4-multi-region': 3.996.24 '@aws-sdk/signature-v4-multi-region': 3.996.25
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@aws-sdk/util-format-url': 3.972.10 '@aws-sdk/util-format-url': 3.972.10
'@smithy/middleware-endpoint': 4.4.32 '@smithy/middleware-endpoint': 4.4.32
@@ -4754,19 +4755,19 @@ snapshots:
'@smithy/types': 4.14.1 '@smithy/types': 4.14.1
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/signature-v4-multi-region@3.996.24': '@aws-sdk/signature-v4-multi-region@3.996.25':
dependencies: dependencies:
'@aws-sdk/middleware-sdk-s3': 3.972.36 '@aws-sdk/middleware-sdk-s3': 3.972.37
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/protocol-http': 5.3.14 '@smithy/protocol-http': 5.3.14
'@smithy/signature-v4': 5.3.14 '@smithy/signature-v4': 5.3.14
'@smithy/types': 4.14.1 '@smithy/types': 4.14.1
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/token-providers@3.1039.0': '@aws-sdk/token-providers@3.1041.0':
dependencies: dependencies:
'@aws-sdk/core': 3.974.7 '@aws-sdk/core': 3.974.8
'@aws-sdk/nested-clients': 3.997.5 '@aws-sdk/nested-clients': 3.997.6
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/property-provider': 4.2.14 '@smithy/property-provider': 4.2.14
'@smithy/shared-ini-file-loader': 4.4.9 '@smithy/shared-ini-file-loader': 4.4.9
@@ -4810,9 +4811,9 @@ snapshots:
bowser: 2.14.1 bowser: 2.14.1
tslib: 2.8.1 tslib: 2.8.1
'@aws-sdk/util-user-agent-node@3.973.23': '@aws-sdk/util-user-agent-node@3.973.24':
dependencies: dependencies:
'@aws-sdk/middleware-user-agent': 3.972.37 '@aws-sdk/middleware-user-agent': 3.972.38
'@aws-sdk/types': 3.973.8 '@aws-sdk/types': 3.973.8
'@smithy/node-config-provider': 4.3.14 '@smithy/node-config-provider': 4.3.14
'@smithy/types': 4.14.1 '@smithy/types': 4.14.1
@@ -4842,69 +4843,69 @@ snapshots:
'@babel/helper-validator-identifier': 7.28.5 '@babel/helper-validator-identifier': 7.28.5
optional: true optional: true
'@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1)': '@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1)':
dependencies: dependencies:
'@better-auth/utils': 0.4.0 '@better-auth/utils': 0.4.0
'@better-fetch/fetch': 1.1.21 '@better-fetch/fetch': 1.1.21
'@opentelemetry/semantic-conventions': 1.40.0 '@opentelemetry/semantic-conventions': 1.40.0
'@standard-schema/spec': 1.1.0 '@standard-schema/spec': 1.1.0
better-call: 1.3.5(zod@4.4.1) better-call: 1.3.5(zod@4.4.3)
jose: 6.2.1 jose: 6.2.1
kysely: 0.28.14 kysely: 0.28.14
nanostores: 1.1.1 nanostores: 1.1.1
zod: 4.4.1 zod: 4.4.3
optionalDependencies: optionalDependencies:
'@opentelemetry/api': 1.9.0 '@opentelemetry/api': 1.9.0
'@better-auth/drizzle-adapter@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)))': '@better-auth/drizzle-adapter@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)))':
dependencies: dependencies:
'@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1) '@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1)
'@better-auth/utils': 0.4.0 '@better-auth/utils': 0.4.0
optionalDependencies: optionalDependencies:
drizzle-orm: 0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)) drizzle-orm: 0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))
'@better-auth/kysely-adapter@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(kysely@0.28.14)': '@better-auth/kysely-adapter@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(kysely@0.28.14)':
dependencies: dependencies:
'@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1) '@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1)
'@better-auth/utils': 0.4.0 '@better-auth/utils': 0.4.0
optionalDependencies: optionalDependencies:
kysely: 0.28.14 kysely: 0.28.14
'@better-auth/memory-adapter@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)': '@better-auth/memory-adapter@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)':
dependencies: dependencies:
'@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1) '@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1)
'@better-auth/utils': 0.4.0 '@better-auth/utils': 0.4.0
'@better-auth/mongo-adapter@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(mongodb@7.1.0)': '@better-auth/mongo-adapter@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(mongodb@7.1.0)':
dependencies: dependencies:
'@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1) '@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1)
'@better-auth/utils': 0.4.0 '@better-auth/utils': 0.4.0
optionalDependencies: optionalDependencies:
mongodb: 7.1.0 mongodb: 7.1.0
'@better-auth/passkey@1.6.9(22762a9b26d2e46f2ba0c21d31406330)': '@better-auth/passkey@1.6.9(60d949d2bbdb8e45901f3be9be360abb)':
dependencies: dependencies:
'@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1) '@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1)
'@better-auth/utils': 0.4.0 '@better-auth/utils': 0.4.0
'@better-fetch/fetch': 1.1.21 '@better-fetch/fetch': 1.1.21
'@simplewebauthn/browser': 13.2.2 '@simplewebauthn/browser': 13.2.2
'@simplewebauthn/server': 13.2.3 '@simplewebauthn/server': 13.2.3
better-auth: 1.6.9(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)))(mongodb@7.1.0)(mysql2@3.15.3)(next@16.2.4(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(pg@8.20.0)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) better-auth: 1.6.9(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)))(mongodb@7.1.0)(mysql2@3.15.3)(next@16.2.4(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(pg@8.20.0)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
better-call: 1.3.5(zod@4.4.1) better-call: 1.3.5(zod@4.4.3)
nanostores: 1.1.1 nanostores: 1.1.1
zod: 4.4.1 zod: 4.4.3
'@better-auth/prisma-adapter@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))': '@better-auth/prisma-adapter@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))':
dependencies: dependencies:
'@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1) '@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1)
'@better-auth/utils': 0.4.0 '@better-auth/utils': 0.4.0
optionalDependencies: optionalDependencies:
'@prisma/client': 7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3) '@prisma/client': 7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3)
prisma: 7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) prisma: 7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)
'@better-auth/telemetry@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)': '@better-auth/telemetry@1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)':
dependencies: dependencies:
'@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1) '@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1)
'@better-auth/utils': 0.4.0 '@better-auth/utils': 0.4.0
'@better-fetch/fetch': 1.1.21 '@better-fetch/fetch': 1.1.21
@@ -4914,39 +4915,39 @@ snapshots:
'@better-fetch/fetch@1.1.21': {} '@better-fetch/fetch@1.1.21': {}
'@biomejs/biome@2.4.13': '@biomejs/biome@2.4.14':
optionalDependencies: optionalDependencies:
'@biomejs/cli-darwin-arm64': 2.4.13 '@biomejs/cli-darwin-arm64': 2.4.14
'@biomejs/cli-darwin-x64': 2.4.13 '@biomejs/cli-darwin-x64': 2.4.14
'@biomejs/cli-linux-arm64': 2.4.13 '@biomejs/cli-linux-arm64': 2.4.14
'@biomejs/cli-linux-arm64-musl': 2.4.13 '@biomejs/cli-linux-arm64-musl': 2.4.14
'@biomejs/cli-linux-x64': 2.4.13 '@biomejs/cli-linux-x64': 2.4.14
'@biomejs/cli-linux-x64-musl': 2.4.13 '@biomejs/cli-linux-x64-musl': 2.4.14
'@biomejs/cli-win32-arm64': 2.4.13 '@biomejs/cli-win32-arm64': 2.4.14
'@biomejs/cli-win32-x64': 2.4.13 '@biomejs/cli-win32-x64': 2.4.14
'@biomejs/cli-darwin-arm64@2.4.13': '@biomejs/cli-darwin-arm64@2.4.14':
optional: true optional: true
'@biomejs/cli-darwin-x64@2.4.13': '@biomejs/cli-darwin-x64@2.4.14':
optional: true optional: true
'@biomejs/cli-linux-arm64-musl@2.4.13': '@biomejs/cli-linux-arm64-musl@2.4.14':
optional: true optional: true
'@biomejs/cli-linux-arm64@2.4.13': '@biomejs/cli-linux-arm64@2.4.14':
optional: true optional: true
'@biomejs/cli-linux-x64-musl@2.4.13': '@biomejs/cli-linux-x64-musl@2.4.14':
optional: true optional: true
'@biomejs/cli-linux-x64@2.4.13': '@biomejs/cli-linux-x64@2.4.14':
optional: true optional: true
'@biomejs/cli-win32-arm64@2.4.13': '@biomejs/cli-win32-arm64@2.4.14':
optional: true optional: true
'@biomejs/cli-win32-x64@2.4.13': '@biomejs/cli-win32-x64@2.4.14':
optional: true optional: true
'@chevrotain/cst-dts-gen@10.5.0': '@chevrotain/cst-dts-gen@10.5.0':
@@ -5522,10 +5523,10 @@ snapshots:
'@nodable/entities@2.1.0': {} '@nodable/entities@2.1.0': {}
'@openrouter/ai-sdk-provider@2.9.0(ai@6.0.173(zod@4.4.1))(zod@4.4.1)': '@openrouter/ai-sdk-provider@2.9.0(ai@6.0.175(zod@4.4.3))(zod@4.4.3)':
dependencies: dependencies:
ai: 6.0.173(zod@4.4.1) ai: 6.0.175(zod@4.4.3)
zod: 4.4.1 zod: 4.4.3
'@opentelemetry/api@1.9.0': {} '@opentelemetry/api@1.9.0': {}
@@ -6889,11 +6890,11 @@ snapshots:
postcss: 8.5.8 postcss: 8.5.8
tailwindcss: 4.2.4 tailwindcss: 4.2.4
'@tanstack/query-core@5.100.7': {} '@tanstack/query-core@5.100.9': {}
'@tanstack/react-query@5.100.7(react@19.2.5)': '@tanstack/react-query@5.100.9(react@19.2.5)':
dependencies: dependencies:
'@tanstack/query-core': 5.100.7 '@tanstack/query-core': 5.100.9
react: 19.2.5 react: 19.2.5
'@tanstack/react-table@8.21.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@tanstack/react-table@8.21.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
@@ -6983,13 +6984,13 @@ snapshots:
'@vercel/oidc@3.2.0': {} '@vercel/oidc@3.2.0': {}
ai@6.0.173(zod@4.4.1): ai@6.0.175(zod@4.4.3):
dependencies: dependencies:
'@ai-sdk/gateway': 3.0.108(zod@4.4.1) '@ai-sdk/gateway': 3.0.110(zod@4.4.3)
'@ai-sdk/provider': 3.0.10 '@ai-sdk/provider': 3.0.10
'@ai-sdk/provider-utils': 4.0.26(zod@4.4.1) '@ai-sdk/provider-utils': 4.0.26(zod@4.4.3)
'@opentelemetry/api': 1.9.0 '@opentelemetry/api': 1.9.0
zod: 4.4.1 zod: 4.4.3
archiver-utils@2.1.0: archiver-utils@2.1.0:
dependencies: dependencies:
@@ -7058,23 +7059,23 @@ snapshots:
better-auth@1.6.9(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)))(mongodb@7.1.0)(mysql2@3.15.3)(next@16.2.4(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(pg@8.20.0)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5): better-auth@1.6.9(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(drizzle-kit@0.31.10)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)))(mongodb@7.1.0)(mysql2@3.15.3)(next@16.2.4(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(pg@8.20.0)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5):
dependencies: dependencies:
'@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1) '@better-auth/core': 1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1)
'@better-auth/drizzle-adapter': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))) '@better-auth/drizzle-adapter': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(drizzle-orm@0.45.2(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(@types/pg@8.20.0)(kysely@0.28.14)(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)))
'@better-auth/kysely-adapter': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(kysely@0.28.14) '@better-auth/kysely-adapter': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(kysely@0.28.14)
'@better-auth/memory-adapter': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0) '@better-auth/memory-adapter': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)
'@better-auth/mongo-adapter': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(mongodb@7.1.0) '@better-auth/mongo-adapter': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(mongodb@7.1.0)
'@better-auth/prisma-adapter': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3)) '@better-auth/prisma-adapter': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(@prisma/client@7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3))(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))
'@better-auth/telemetry': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.1))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21) '@better-auth/telemetry': 1.6.9(@better-auth/core@1.6.9(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(@opentelemetry/api@1.9.0)(better-call@1.3.5(zod@4.4.3))(jose@6.2.1)(kysely@0.28.14)(nanostores@1.1.1))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)
'@better-auth/utils': 0.4.0 '@better-auth/utils': 0.4.0
'@better-fetch/fetch': 1.1.21 '@better-fetch/fetch': 1.1.21
'@noble/ciphers': 2.1.1 '@noble/ciphers': 2.1.1
'@noble/hashes': 2.0.1 '@noble/hashes': 2.0.1
better-call: 1.3.5(zod@4.4.1) better-call: 1.3.5(zod@4.4.3)
defu: 6.1.7 defu: 6.1.7
jose: 6.2.1 jose: 6.2.1
kysely: 0.28.14 kysely: 0.28.14
nanostores: 1.1.1 nanostores: 1.1.1
zod: 4.4.1 zod: 4.4.3
optionalDependencies: optionalDependencies:
'@prisma/client': 7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3) '@prisma/client': 7.4.2(prisma@7.4.2(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3))(typescript@6.0.3)
drizzle-kit: 0.31.10 drizzle-kit: 0.31.10
@@ -7090,14 +7091,14 @@ snapshots:
- '@cloudflare/workers-types' - '@cloudflare/workers-types'
- '@opentelemetry/api' - '@opentelemetry/api'
better-call@1.3.5(zod@4.4.1): better-call@1.3.5(zod@4.4.3):
dependencies: dependencies:
'@better-auth/utils': 0.4.0 '@better-auth/utils': 0.4.0
'@better-fetch/fetch': 1.1.21 '@better-fetch/fetch': 1.1.21
rou3: 0.7.12 rou3: 0.7.12
set-cookie-parser: 3.0.1 set-cookie-parser: 3.0.1
optionalDependencies: optionalDependencies:
zod: 4.4.1 zod: 4.4.3
big-integer@1.6.52: {} big-integer@1.6.52: {}
@@ -7657,7 +7658,7 @@ snapshots:
readable-stream: 2.3.8 readable-stream: 2.3.8
setimmediate: 1.0.5 setimmediate: 1.0.5
knip@6.10.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): knip@6.11.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0):
dependencies: dependencies:
fdir: 6.5.0(picomatch@4.0.4) fdir: 6.5.0(picomatch@4.0.4)
formatly: 0.3.0 formatly: 0.3.0
@@ -7672,7 +7673,7 @@ snapshots:
tinyglobby: 0.2.16 tinyglobby: 0.2.16
unbash: 3.0.0 unbash: 3.0.0
yaml: 2.8.3 yaml: 2.8.3
zod: 4.4.1 zod: 4.4.3
transitivePeerDependencies: transitivePeerDependencies:
- '@emnapi/core' - '@emnapi/core'
- '@emnapi/runtime' - '@emnapi/runtime'
@@ -8513,4 +8514,4 @@ snapshots:
compress-commons: 4.1.2 compress-commons: 4.1.2
readable-stream: 3.6.2 readable-stream: 3.6.2
zod@4.4.1: {} zod@4.4.3: {}

BIN
public/logos/dinheiro.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
import { Logo } from "@/shared/components/logo"; import { Logo } from "@/shared/components/brand/logo";
export default function AuthLayout({ export default function AuthLayout({
children, children,

View File

@@ -7,8 +7,8 @@ import { AdjustBalanceDialog } from "@/features/accounts/components/adjust-balan
import type { Account } from "@/features/accounts/components/types"; import type { Account } from "@/features/accounts/components/types";
import { import {
fetchAccountData, fetchAccountData,
fetchAccountLancamentosPage,
fetchAccountSummary, fetchAccountSummary,
fetchAccountTransactionsPage,
} from "@/features/accounts/statement-queries"; } from "@/features/accounts/statement-queries";
import { fetchUserPreferences } from "@/features/settings/queries"; import { fetchUserPreferences } from "@/features/settings/queries";
import { TransactionsPage as LancamentosSection } from "@/features/transactions/components/page/transactions-page"; import { TransactionsPage as LancamentosSection } from "@/features/transactions/components/page/transactions-page";
@@ -22,7 +22,7 @@ import {
mapTransactionsData, mapTransactionsData,
type ResolvedSearchParams, type ResolvedSearchParams,
resolveTransactionPagination, resolveTransactionPagination,
} from "@/features/transactions/page-helpers"; } from "@/features/transactions/lib/page-helpers";
import { import {
fetchRecentEstablishments, fetchRecentEstablishments,
fetchTransactionFilterSources, fetchTransactionFilterSources,
@@ -89,7 +89,7 @@ export default async function Page({ params, searchParams }: PageProps) {
accountId: account.id, accountId: account.id,
}); });
const transactionsPage = await fetchAccountLancamentosPage( const transactionsPage = await fetchAccountTransactionsPage(
filters, filters,
pagination, pagination,
); );

View File

@@ -19,7 +19,6 @@ export default function RootLayout({
subtitle="Gerencie os anexos das suas transações" subtitle="Gerencie os anexos das suas transações"
/> />
<MonthNavigation /> <MonthNavigation />
{children} {children}
</section> </section>
); );

View File

@@ -25,9 +25,7 @@ export default async function Page({ searchParams }: PageProps) {
const userId = await getUserId(); const userId = await getUserId();
const resolvedSearchParams = searchParams ? await searchParams : undefined; const resolvedSearchParams = searchParams ? await searchParams : undefined;
const periodoParam = getSingleParam(resolvedSearchParams, "periodo"); const periodoParam = getSingleParam(resolvedSearchParams, "periodo");
const { period: selectedPeriod } = parsePeriodParam(periodoParam); const { period: selectedPeriod } = parsePeriodParam(periodoParam);
const { budgets, categoriesOptions } = await fetchBudgetsForUser( const { budgets, categoriesOptions } = await fetchBudgetsForUser(
userId, userId,
selectedPeriod, selectedPeriod,

View File

@@ -4,7 +4,7 @@ import { fetchCalendarData } from "@/features/calendar/queries";
import { import {
getSingleParam, getSingleParam,
type ResolvedSearchParams, type ResolvedSearchParams,
} from "@/features/transactions/page-helpers"; } from "@/features/transactions/lib/page-helpers";
import MonthNavigation from "@/shared/components/month-picker/month-navigation"; import MonthNavigation from "@/shared/components/month-picker/month-navigation";
import { getUserId } from "@/shared/lib/auth/server"; import { getUserId } from "@/shared/lib/auth/server";
import type { CalendarPeriod } from "@/shared/lib/types/calendar"; import type { CalendarPeriod } from "@/shared/lib/types/calendar";
@@ -36,7 +36,7 @@ export default async function Page({ searchParams }: PageProps) {
}; };
return ( return (
<main className="flex flex-col gap-3"> <main className="flex flex-col gap-4">
<MonthNavigation /> <MonthNavigation />
<MonthlyCalendar <MonthlyCalendar
period={calendarPeriod} period={calendarPeriod}

View File

@@ -21,7 +21,7 @@ import {
getSingleParam, getSingleParam,
mapTransactionsData, mapTransactionsData,
type ResolvedSearchParams, type ResolvedSearchParams,
} from "@/features/transactions/page-helpers"; } from "@/features/transactions/lib/page-helpers";
import { import {
fetchRecentEstablishments, fetchRecentEstablishments,
fetchTransactionFilterSources, fetchTransactionFilterSources,

View File

@@ -10,7 +10,7 @@ export default async function Page() {
await fetchAllCardsForUser(userId); await fetchAllCardsForUser(userId);
return ( return (
<main className="flex flex-col items-start gap-6"> <main className="flex flex-col gap-6">
<CardsPage <CardsPage
cards={activeCards} cards={activeCards}
archivedCards={archivedCards} archivedCards={archivedCards}

View File

@@ -7,7 +7,7 @@ import { TransactionsPage } from "@/features/transactions/components/page/transa
import { import {
buildOptionSets, buildOptionSets,
buildSluggedFilters, buildSluggedFilters,
} from "@/features/transactions/page-helpers"; } from "@/features/transactions/lib/page-helpers";
import { import {
fetchRecentEstablishments, fetchRecentEstablishments,
fetchTransactionFilterSources, fetchTransactionFilterSources,

View File

@@ -9,7 +9,7 @@ export default async function Page() {
const categories = await fetchCategoriesForUser(userId); const categories = await fetchCategoriesForUser(userId);
return ( return (
<main className="flex flex-col items-start gap-6"> <main className="flex flex-col gap-6">
<CategoriesPage categories={categories} /> <CategoriesPage categories={categories} />
</main> </main>
); );

View File

@@ -2,9 +2,9 @@ import { connection } from "next/server";
import { DashboardGridEditable } from "@/features/dashboard/components/dashboard-grid-editable"; import { DashboardGridEditable } from "@/features/dashboard/components/dashboard-grid-editable";
import { DashboardMetricsCards } from "@/features/dashboard/components/dashboard-metrics-cards"; import { DashboardMetricsCards } from "@/features/dashboard/components/dashboard-metrics-cards";
import { DashboardWelcome } from "@/features/dashboard/components/dashboard-welcome"; import { DashboardWelcome } from "@/features/dashboard/components/dashboard-welcome";
import { extractDashboardLogoNames } from "@/features/dashboard/extract-logo-names"; import { extractDashboardLogoNames } from "@/features/dashboard/lib/extract-logo-names";
import { fetchDashboardPageData } from "@/features/dashboard/page-data-queries"; import { fetchDashboardPageData } from "@/features/dashboard/page-data-queries";
import { getSingleParam } from "@/features/transactions/page-helpers"; import { getSingleParam } from "@/features/transactions/lib/page-helpers";
import { LogoPrefetchProvider } from "@/shared/components/entity-avatar"; import { LogoPrefetchProvider } from "@/shared/components/entity-avatar";
import MonthNavigation from "@/shared/components/month-picker/month-navigation"; import MonthNavigation from "@/shared/components/month-picker/month-navigation";
import { getUser } from "@/shared/lib/auth/server"; import { getUser } from "@/shared/lib/auth/server";

View File

@@ -56,7 +56,7 @@ export default async function Page({ searchParams }: PageProps) {
const normalizedSourceApps = Array.isArray(sourceApps) ? sourceApps : []; const normalizedSourceApps = Array.isArray(sourceApps) ? sourceApps : [];
return ( return (
<main className="flex flex-col items-start gap-6"> <main className="flex flex-col gap-6">
<InboxPage <InboxPage
activeStatus={activeStatus} activeStatus={activeStatus}
activeApp={activeApp} activeApp={activeApp}

View File

@@ -1,5 +1,5 @@
import { connection } from "next/server"; import { connection } from "next/server";
import { fetchDashboardNavbarData } from "@/features/dashboard/navbar-queries"; import { fetchDashboardNavbarData } from "@/features/dashboard/lib/navbar-queries";
import { AppNavbar } from "@/shared/components/navigation/navbar/app-navbar"; import { AppNavbar } from "@/shared/components/navigation/navbar/app-navbar";
import { LogoDevProvider } from "@/shared/components/providers/logo-dev-provider"; import { LogoDevProvider } from "@/shared/components/providers/logo-dev-provider";
import { PrivacyProvider } from "@/shared/components/providers/privacy-provider"; import { PrivacyProvider } from "@/shared/components/providers/privacy-provider";
@@ -21,8 +21,8 @@ export default async function DashboardLayout({
<PrivacyProvider> <PrivacyProvider>
<AppNavbar <AppNavbar
user={{ ...session.user, image: session.user.image ?? null }} user={{ ...session.user, image: session.user.image ?? null }}
pagadorAvatarUrl={navbarData.pagadorAvatarUrl} payerAvatarUrl={navbarData.payerAvatarUrl}
preLancamentosCount={navbarData.preLancamentosCount} inboxPendingCount={navbarData.inboxPendingCount}
notificationsSnapshot={navbarData.notificationsSnapshot} notificationsSnapshot={navbarData.notificationsSnapshot}
/> />
<div className="relative flex flex-1 flex-col pt-16"> <div className="relative flex flex-1 flex-col pt-16">

View File

@@ -9,7 +9,7 @@ export default async function Page() {
const { activeNotes, archivedNotes } = await fetchAllNotesForUser(userId); const { activeNotes, archivedNotes } = await fetchAllNotesForUser(userId);
return ( return (
<main className="flex flex-col items-start gap-6"> <main className="flex flex-col gap-6">
<NotesPage notes={activeNotes} archivedNotes={archivedNotes} /> <NotesPage notes={activeNotes} archivedNotes={archivedNotes} />
</main> </main>
); );

View File

@@ -4,7 +4,7 @@ import { Skeleton } from "@/shared/components/ui/skeleton";
* Loading state para a página de detalhes do pagador. * Loading state para a página de detalhes do pagador.
* Layout: navegação mensal + tabs com card compartilhado do pagador. * Layout: navegação mensal + tabs com card compartilhado do pagador.
*/ */
export default function PagadorDetailsLoading() { export default function PayerDetailsLoading() {
return ( return (
<main className="flex flex-col gap-6"> <main className="flex flex-col gap-6">
<div className="h-[60px] animate-pulse rounded-md bg-foreground/10" /> <div className="h-[60px] animate-pulse rounded-md bg-foreground/10" />

View File

@@ -8,7 +8,7 @@ import { connection } from "next/server";
import { PayerCardUsageCard } from "@/features/payers/components/details/payer-card-usage-card"; import { PayerCardUsageCard } from "@/features/payers/components/details/payer-card-usage-card";
import { PayerHeaderCard } from "@/features/payers/components/details/payer-header-card"; import { PayerHeaderCard } from "@/features/payers/components/details/payer-header-card";
import { PayerHistoryCard } from "@/features/payers/components/details/payer-history-card"; import { PayerHistoryCard } from "@/features/payers/components/details/payer-history-card";
import { PagadorInfoCard } from "@/features/payers/components/details/payer-info-card"; import { PayerInfoCard } from "@/features/payers/components/details/payer-info-card";
import { PayerLeaveShareCard } from "@/features/payers/components/details/payer-leave-share-card"; import { PayerLeaveShareCard } from "@/features/payers/components/details/payer-leave-share-card";
import { PayerMonthlySummaryCard } from "@/features/payers/components/details/payer-monthly-summary-card"; import { PayerMonthlySummaryCard } from "@/features/payers/components/details/payer-monthly-summary-card";
import { import {
@@ -16,12 +16,12 @@ import {
PayerPaymentStatusCard, PayerPaymentStatusCard,
} from "@/features/payers/components/details/payer-payment-method-cards"; } from "@/features/payers/components/details/payer-payment-method-cards";
import { PayerSharingCard } from "@/features/payers/components/details/payer-sharing-card"; import { PayerSharingCard } from "@/features/payers/components/details/payer-sharing-card";
import { buildReadOnlyOptionSets } from "@/features/payers/lib/build-readonly-option-sets";
import { import {
fetchCurrentUserShare, fetchCurrentUserShare,
fetchPagadorLancamentos,
fetchPayerShares, fetchPayerShares,
} from "@/features/payers/detail-queries"; fetchPayerTransactions,
import { buildReadOnlyOptionSets } from "@/features/payers/lib/build-readonly-option-sets"; } from "@/features/payers/lib/detail-queries";
import { fetchUserPreferences } from "@/features/settings/queries"; import { fetchUserPreferences } from "@/features/settings/queries";
import { TransactionsPage as LancamentosSection } from "@/features/transactions/components/page/transactions-page"; import { TransactionsPage as LancamentosSection } from "@/features/transactions/components/page/transactions-page";
import { import {
@@ -36,13 +36,12 @@ import {
type SluggedFilters, type SluggedFilters,
type SlugMaps, type SlugMaps,
type TransactionSearchFilters, type TransactionSearchFilters,
} from "@/features/transactions/page-helpers"; } from "@/features/transactions/lib/page-helpers";
import { import {
fetchRecentEstablishments, fetchRecentEstablishments,
fetchTransactionFilterSources, fetchTransactionFilterSources,
} from "@/features/transactions/queries"; } from "@/features/transactions/queries";
import { LogoPrefetchProvider } from "@/shared/components/entity-avatar"; import { LogoPrefetchProvider } from "@/shared/components/entity-avatar";
import { ExpandableWidgetCard } from "@/shared/components/expandable-widget-card";
import MonthNavigation from "@/shared/components/month-picker/month-navigation"; import MonthNavigation from "@/shared/components/month-picker/month-navigation";
import { import {
Tabs, Tabs,
@@ -50,16 +49,17 @@ import {
TabsList, TabsList,
TabsTrigger, TabsTrigger,
} from "@/shared/components/ui/tabs"; } from "@/shared/components/ui/tabs";
import { ExpandableWidgetCard } from "@/shared/components/widgets/expandable-widget-card";
import { getUserId } from "@/shared/lib/auth/server"; import { getUserId } from "@/shared/lib/auth/server";
import { prefetchLogoMappings } from "@/shared/lib/logo/prefetch-server"; import { prefetchLogoMappings } from "@/shared/lib/logo/prefetch-server";
import { getPayerAccess } from "@/shared/lib/payers/access"; import { getPayerAccess } from "@/shared/lib/payers/access";
import { import {
fetchPagadorBoletoItems, fetchPayerBoletoItems,
fetchPagadorBoletoStats, fetchPayerBoletoStats,
fetchPagadorCardUsage, fetchPayerCardUsage,
fetchPagadorPaymentStatus,
fetchPayerHistory, fetchPayerHistory,
fetchPayerMonthlyBreakdown, fetchPayerMonthlyBreakdown,
fetchPayerPaymentStatus,
type PayerCardUsageItem, type PayerCardUsageItem,
} from "@/shared/lib/payers/details"; } from "@/shared/lib/payers/details";
import { parsePeriodParam } from "@/shared/utils/period"; import { parsePeriodParam } from "@/shared/utils/period";
@@ -182,7 +182,7 @@ export default async function Page({ params, searchParams }: PageProps) {
estabelecimentos, estabelecimentos,
userPreferences, userPreferences,
] = await Promise.all([ ] = await Promise.all([
fetchPagadorLancamentos(filters), fetchPayerTransactions(filters),
fetchPayerMonthlyBreakdown({ fetchPayerMonthlyBreakdown({
userId: dataOwnerId, userId: dataOwnerId,
payerId: pagador.id, payerId: pagador.id,
@@ -193,22 +193,22 @@ export default async function Page({ params, searchParams }: PageProps) {
payerId: pagador.id, payerId: pagador.id,
period: selectedPeriod, period: selectedPeriod,
}), }),
fetchPagadorCardUsage({ fetchPayerCardUsage({
userId: dataOwnerId, userId: dataOwnerId,
payerId: pagador.id, payerId: pagador.id,
period: selectedPeriod, period: selectedPeriod,
}), }),
fetchPagadorBoletoStats({ fetchPayerBoletoStats({
userId: dataOwnerId, userId: dataOwnerId,
payerId: pagador.id, payerId: pagador.id,
period: selectedPeriod, period: selectedPeriod,
}), }),
fetchPagadorBoletoItems({ fetchPayerBoletoItems({
userId: dataOwnerId, userId: dataOwnerId,
payerId: pagador.id, payerId: pagador.id,
period: selectedPeriod, period: selectedPeriod,
}), }),
fetchPagadorPaymentStatus({ fetchPayerPaymentStatus({
userId: dataOwnerId, userId: dataOwnerId,
payerId: pagador.id, payerId: pagador.id,
period: selectedPeriod, period: selectedPeriod,
@@ -333,7 +333,7 @@ export default async function Page({ params, searchParams }: PageProps) {
/> />
<TabsContent value="profile" className="space-y-4"> <TabsContent value="profile" className="space-y-4">
<PagadorInfoCard payer={payerData} /> <PayerInfoCard payer={payerData} />
{canEdit && payerData.shareCode ? ( {canEdit && payerData.shareCode ? (
<PayerSharingCard <PayerSharingCard
payerId={pagador.id} payerId={pagador.id}

View File

@@ -4,7 +4,7 @@ import { Skeleton } from "@/shared/components/ui/skeleton";
* Loading state para a página de pessoas * Loading state para a página de pessoas
* Layout: Header + Input de compartilhamento + Grid de cards * Layout: Header + Input de compartilhamento + Grid de cards
*/ */
export default function PagadoresLoading() { export default function PayersLoading() {
return ( return (
<main className="flex flex-col items-start gap-6"> <main className="flex flex-col items-start gap-6">
<div className="w-full space-y-6"> <div className="w-full space-y-6">

View File

@@ -9,7 +9,7 @@ export default async function Page() {
const { payers, avatarOptions } = await fetchPayersForUser(userId); const { payers, avatarOptions } = await fetchPayersForUser(userId);
return ( return (
<main className="flex flex-col items-start gap-6"> <main className="flex flex-col gap-6">
<PayersPage payers={payers} avatarOptions={avatarOptions} /> <PayersPage payers={payers} avatarOptions={avatarOptions} />
</main> </main>
); );

View File

@@ -1,11 +1,11 @@
import { RiBankCard2Line } from "@remixicon/react"; import { RiBankCard2Line } from "@remixicon/react";
import { connection } from "next/server"; import { connection } from "next/server";
import { fetchCartoesReportData } from "@/features/reports/cards-report-queries";
import { CardCategoryBreakdown } from "@/features/reports/components/cards/card-category-breakdown"; import { CardCategoryBreakdown } from "@/features/reports/components/cards/card-category-breakdown";
import { CardInvoiceStatus } from "@/features/reports/components/cards/card-invoice-status"; import { CardInvoiceStatus } from "@/features/reports/components/cards/card-invoice-status";
import { CardTopExpenses } from "@/features/reports/components/cards/card-top-expenses"; import { CardTopExpenses } from "@/features/reports/components/cards/card-top-expenses";
import { CardUsageChart } from "@/features/reports/components/cards/card-usage-chart"; import { CardUsageChart } from "@/features/reports/components/cards/card-usage-chart";
import { CardsOverview } from "@/features/reports/components/cards/cards-overview"; import { CardsOverview } from "@/features/reports/components/cards/cards-overview";
import { fetchCartoesReportData } from "@/features/reports/lib/cards-report-queries";
import MonthNavigation from "@/shared/components/month-picker/month-navigation"; import MonthNavigation from "@/shared/components/month-picker/month-navigation";
import { Card } from "@/shared/components/ui/card"; import { Card } from "@/shared/components/ui/card";
import { getUser } from "@/shared/lib/auth/server"; import { getUser } from "@/shared/lib/auth/server";

View File

@@ -1,15 +1,15 @@
import { redirect } from "next/navigation"; import { redirect } from "next/navigation";
import { connection } from "next/server"; import { connection } from "next/server";
import type { Category } from "@/db/schema"; import type { Category } from "@/db/schema";
import { fetchCategoryChartData } from "@/features/reports/category-chart-queries";
import { fetchCategoryReport } from "@/features/reports/category-report-queries";
import { fetchUserCategories } from "@/features/reports/category-trends-queries";
import { CategoryReportPage } from "@/features/reports/components/category-report-page"; import { CategoryReportPage } from "@/features/reports/components/category-report-page";
import type { import type {
CategoryOption, CategoryOption,
FilterState, FilterState,
} from "@/features/reports/components/types"; } from "@/features/reports/components/types";
import { validateDateRange } from "@/features/reports/utils"; import { fetchCategoryChartData } from "@/features/reports/lib/category-chart-queries";
import { fetchCategoryReport } from "@/features/reports/lib/category-report-queries";
import { fetchUserCategories } from "@/features/reports/lib/category-trends-queries";
import { validateDateRange } from "@/features/reports/lib/utils";
import { getUserId } from "@/shared/lib/auth/server"; import { getUserId } from "@/shared/lib/auth/server";
import type { CategoryReportFilters } from "@/shared/lib/types/reports"; import type { CategoryReportFilters } from "@/shared/lib/types/reports";
import { addMonthsToPeriod, getCurrentPeriod } from "@/shared/utils/period"; import { addMonthsToPeriod, getCurrentPeriod } from "@/shared/utils/period";

View File

@@ -34,7 +34,7 @@ const validatePeriodFilter = (value: string | null): PeriodFilter => {
return "6"; return "6";
}; };
export default async function TopEstabelecimentosPage({ export default async function TopEstablishmentsPage({
searchParams, searchParams,
}: PageProps) { }: PageProps) {
await connection(); await connection();

View File

@@ -3,7 +3,7 @@ import { ImportPage } from "@/features/transactions/components/import/import-pag
import { import {
buildOptionSets, buildOptionSets,
buildSluggedFilters, buildSluggedFilters,
} from "@/features/transactions/page-helpers"; } from "@/features/transactions/lib/page-helpers";
import { fetchTransactionFilterSources } from "@/features/transactions/queries"; import { fetchTransactionFilterSources } from "@/features/transactions/queries";
import { getUserId } from "@/shared/lib/auth/server"; import { getUserId } from "@/shared/lib/auth/server";

View File

@@ -8,7 +8,7 @@ import { Skeleton } from "@/shared/components/ui/skeleton";
* Loading state para a página de lançamentos * Loading state para a página de lançamentos
* Mantém o mesmo layout da página final * Mantém o mesmo layout da página final
*/ */
export default function LancamentosLoading() { export default function TransactionsLoading() {
return ( return (
<main className="flex flex-col gap-6"> <main className="flex flex-col gap-6">
{/* Month Picker placeholder */} {/* Month Picker placeholder */}

View File

@@ -11,7 +11,7 @@ import {
mapTransactionsData, mapTransactionsData,
type ResolvedSearchParams, type ResolvedSearchParams,
resolveTransactionPagination, resolveTransactionPagination,
} from "@/features/transactions/page-helpers"; } from "@/features/transactions/lib/page-helpers";
import { import {
fetchRecentEstablishments, fetchRecentEstablishments,
fetchTransactionFilterSources, fetchTransactionFilterSources,

View File

@@ -24,7 +24,7 @@ import {
import { landingImages } from "@/features/landing/images"; import { landingImages } from "@/features/landing/images";
import { fetchGitHubStats } from "@/features/landing/queries"; import { fetchGitHubStats } from "@/features/landing/queries";
import { AnimatedThemeToggler } from "@/shared/components/animated-theme-toggler"; import { AnimatedThemeToggler } from "@/shared/components/animated-theme-toggler";
import { Logo } from "@/shared/components/logo"; import { Logo } from "@/shared/components/brand/logo";
import { NavbarShell } from "@/shared/components/navigation/navbar/navbar-shell"; import { NavbarShell } from "@/shared/components/navigation/navbar/navbar-shell";
import { Badge } from "@/shared/components/ui/badge"; import { Badge } from "@/shared/components/ui/badge";
import { Button } from "@/shared/components/ui/button"; import { Button } from "@/shared/components/ui/button";

View File

@@ -1,5 +1,5 @@
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { fetchTransactionAttachments } from "@/features/transactions/attachment-queries"; import { fetchTransactionAttachments } from "@/features/transactions/lib/attachment-queries";
import { getOptionalUserSession } from "@/shared/lib/auth/server"; import { getOptionalUserSession } from "@/shared/lib/auth/server";
const PRIVATE_RESPONSE_HEADERS = { const PRIVATE_RESPONSE_HEADERS = {

View File

@@ -1,5 +1,5 @@
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import { fetchInstallmentAnticipations } from "@/features/transactions/anticipation-queries"; import { fetchInstallmentAnticipations } from "@/features/transactions/lib/anticipation-queries";
import { getOptionalUserSession } from "@/shared/lib/auth/server"; import { getOptionalUserSession } from "@/shared/lib/auth/server";
const PRIVATE_RESPONSE_HEADERS = { const PRIVATE_RESPONSE_HEADERS = {

View File

@@ -15,6 +15,7 @@ import {
TooltipContent, TooltipContent,
TooltipTrigger, TooltipTrigger,
} from "@/shared/components/ui/tooltip"; } from "@/shared/components/ui/tooltip";
import { isAccountInactive } from "@/shared/lib/accounts/constants";
import { cn } from "@/shared/utils/ui"; import { cn } from "@/shared/utils/ui";
interface AccountCardProps { interface AccountCardProps {
@@ -46,7 +47,7 @@ export function AccountCard({
onTransfer, onTransfer,
className, className,
}: AccountCardProps) { }: AccountCardProps) {
const isInactive = status?.toLowerCase() === "inativa"; const isInactive = isAccountInactive(status);
const balanceColor = const balanceColor =
balance > 0 balance > 0
@@ -145,6 +146,7 @@ export function AccountCard({
<span className="text-xs text-muted-foreground">Saldo</span> <span className="text-xs text-muted-foreground">Saldo</span>
<MoneyValues <MoneyValues
amount={balance} amount={balance}
showPositiveSign
className={cn("text-2xl font-semibold", balanceColor)} className={cn("text-2xl font-semibold", balanceColor)}
/> />
</div> </div>

View File

@@ -37,7 +37,9 @@ const DEFAULT_ACCOUNT_TYPES = [
"Conta Poupança", "Conta Poupança",
"Carteira Digital", "Carteira Digital",
"Conta Investimento", "Conta Investimento",
"Dinheiro",
"Pré-Pago | VR/VA", "Pré-Pago | VR/VA",
"Outros",
] as const; ] as const;
const DEFAULT_ACCOUNT_STATUS = ["Ativa", "Inativa"] as const; const DEFAULT_ACCOUNT_STATUS = ["Ativa", "Inativa"] as const;

View File

@@ -12,7 +12,10 @@ import {
SelectValue, SelectValue,
} from "@/shared/components/ui/select"; } from "@/shared/components/ui/select";
import { Textarea } from "@/shared/components/ui/textarea"; import { Textarea } from "@/shared/components/ui/textarea";
import { StatusSelectContent } from "./account-select-items"; import {
AccountTypeSelectContent,
StatusSelectContent,
} from "./account-select-items";
import type { AccountFormValues } from "./types"; import type { AccountFormValues } from "./types";
@@ -54,12 +57,16 @@ export function AccountFormFields({
onValueChange={(value) => onChange("accountType", value)} onValueChange={(value) => onChange("accountType", value)}
> >
<SelectTrigger id="account-type" className="w-full"> <SelectTrigger id="account-type" className="w-full">
<SelectValue placeholder="Selecione o tipo" /> <SelectValue placeholder="Selecione o tipo">
{values.accountType && (
<AccountTypeSelectContent label={values.accountType} />
)}
</SelectValue>
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent>
{accountTypes.map((type) => ( {accountTypes.map((type) => (
<SelectItem key={type} value={type}> <SelectItem key={type} value={type}>
{type} <AccountTypeSelectContent label={type} />
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>

View File

@@ -1,6 +1,18 @@
"use client"; "use client";
import StatusDot from "@/shared/components/status-dot"; import StatusDot from "@/shared/components/feedback/status-dot";
import { getAccountTypeIcon } from "@/shared/utils/icons";
export function AccountTypeSelectContent({ label }: { label: string }) {
const icon = getAccountTypeIcon(label);
return (
<span className="flex items-center gap-2">
{icon}
<span>{label}</span>
</span>
);
}
export function StatusSelectContent({ label }: { label: string }) { export function StatusSelectContent({ label }: { label: string }) {
const isActive = label === "Ativa"; const isActive = label === "Ativa";

View File

@@ -8,7 +8,7 @@ import { toast } from "sonner";
import { deleteAccountAction } from "@/features/accounts/actions"; import { deleteAccountAction } from "@/features/accounts/actions";
import { AccountCard } from "@/features/accounts/components/account-card"; import { AccountCard } from "@/features/accounts/components/account-card";
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog"; import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
import { EmptyState } from "@/shared/components/empty-state"; import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Button } from "@/shared/components/ui/button"; import { Button } from "@/shared/components/ui/button";
import { Card } from "@/shared/components/ui/card"; import { Card } from "@/shared/components/ui/card";
import { import {
@@ -186,14 +186,14 @@ export function AccountsPage({
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full"> <Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
<TabsList> <TabsList>
<TabsTrigger value="ativos">Ativas</TabsTrigger> <TabsTrigger value="ativos">Ativas</TabsTrigger>
<TabsTrigger value="arquivados">Arquivadas</TabsTrigger> <TabsTrigger value="inativas">Inativas</TabsTrigger>
</TabsList> </TabsList>
<TabsContent value="ativos" className="mt-4"> <TabsContent value="ativos" className="mt-4">
{renderAccountList(orderedAccounts, false)} {renderAccountList(orderedAccounts, false)}
</TabsContent> </TabsContent>
<TabsContent value="arquivados" className="mt-4"> <TabsContent value="inativas" className="mt-4">
{renderAccountList(orderedArchivedAccounts, true)} {renderAccountList(orderedArchivedAccounts, true)}
</TabsContent> </TabsContent>
</Tabs> </Tabs>

View File

@@ -99,13 +99,13 @@ async function fetchAccountsByStatus(
return { accounts, logoOptions }; return { accounts, logoOptions };
} }
export async function fetchAccountsForUser( async function fetchAccountsForUser(
userId: string, userId: string,
): Promise<{ accounts: AccountData[]; logoOptions: string[] }> { ): Promise<{ accounts: AccountData[]; logoOptions: string[] }> {
return fetchAccountsByStatus(userId, false); return fetchAccountsByStatus(userId, false);
} }
export async function fetchInactiveForUser( async function fetchInactiveForUser(
userId: string, userId: string,
): Promise<{ accounts: AccountData[]; logoOptions: string[] }> { ): Promise<{ accounts: AccountData[]; logoOptions: string[] }> {
return fetchAccountsByStatus(userId, true); return fetchAccountsByStatus(userId, true);

View File

@@ -154,7 +154,7 @@ export async function fetchAccountSummary(
}; };
} }
export async function fetchAccountLancamentos( export async function fetchAccountTransactions(
filters: SQL[], filters: SQL[],
settledOnly = true, settledOnly = true,
) { ) {
@@ -167,7 +167,7 @@ export async function fetchAccountLancamentos(
}); });
} }
export async function fetchAccountLancamentosPage( export async function fetchAccountTransactionsPage(
filters: SQL[], filters: SQL[],
{ {
page, page,

View File

@@ -18,7 +18,7 @@ import { fetchTransactionDialogOptionsAction } from "@/features/transactions/act
import { TransactionDetailsDialog } from "@/features/transactions/components/dialogs/transaction-details-dialog"; import { TransactionDetailsDialog } from "@/features/transactions/components/dialogs/transaction-details-dialog";
import { TransactionDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog"; import { TransactionDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog";
import type { TransactionItem } from "@/features/transactions/components/types"; import type { TransactionItem } from "@/features/transactions/components/types";
import { EmptyState } from "@/shared/components/empty-state"; import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Card, CardContent } from "@/shared/components/ui/card"; import { Card, CardContent } from "@/shared/components/ui/card";
import { cn } from "@/shared/utils/ui"; import { cn } from "@/shared/utils/ui";

View File

@@ -2,11 +2,11 @@
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { fetchJson } from "@/shared/lib/fetch-json"; import { fetchJson } from "@/shared/utils/fetch-json";
const ATTACHMENT_URL_STALE_TIME = 4 * 60 * 1000; const ATTACHMENT_URL_STALE_TIME = 4 * 60 * 1000;
export const attachmentUrlQueryKey = (attachmentId: string) => const attachmentUrlQueryKey = (attachmentId: string) =>
["attachments", "url", attachmentId] as const; ["attachments", "url", attachmentId] as const;
export function useAttachmentUrlQuery(attachmentId: string, enabled: boolean) { export function useAttachmentUrlQuery(attachmentId: string, enabled: boolean) {

View File

@@ -3,7 +3,7 @@ import {
RiBarChart2Line, RiBarChart2Line,
RiShieldCheckLine, RiShieldCheckLine,
} from "@remixicon/react"; } from "@remixicon/react";
import { Logo } from "@/shared/components/logo"; import { Logo } from "@/shared/components/brand/logo";
import { DotPattern } from "@/shared/components/ui/dot-pattern"; import { DotPattern } from "@/shared/components/ui/dot-pattern";
import { AuthSidebarInvoicesMock } from "./auth-sidebar-invoices-mock"; import { AuthSidebarInvoicesMock } from "./auth-sidebar-invoices-mock";

View File

@@ -90,6 +90,7 @@ export function BudgetCard({ budget, onEdit, onRemove }: BudgetCardProps) {
<Progress <Progress
value={usagePercent} value={usagePercent}
className={cn("h-2.5", exceeded && "bg-destructive/20!")} className={cn("h-2.5", exceeded && "bg-destructive/20!")}
indicatorClassName={cn(exceeded && "bg-destructive")}
aria-label={`${usagePercent.toFixed(1)}% do orçamento utilizado`} aria-label={`${usagePercent.toFixed(1)}% do orçamento utilizado`}
/> />
<span className="text-xs text-muted-foreground"> <span className="text-xs text-muted-foreground">

View File

@@ -8,7 +8,7 @@ import {
duplicatePreviousMonthBudgetsAction, duplicatePreviousMonthBudgetsAction,
} from "@/features/budgets/actions"; } from "@/features/budgets/actions";
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog"; import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
import { EmptyState } from "@/shared/components/empty-state"; import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Button } from "@/shared/components/ui/button"; import { Button } from "@/shared/components/ui/button";
import { Card } from "@/shared/components/ui/card"; import { Card } from "@/shared/components/ui/card";
import { BudgetCard } from "./budget-card"; import { BudgetCard } from "./budget-card";

View File

@@ -26,7 +26,7 @@ type BudgetData = {
} | null; } | null;
}; };
export type CategoryOption = { type CategoryOption = {
id: string; id: string;
name: string; name: string;
icon: string | null; icon: string | null;

View File

@@ -1,6 +1,7 @@
"use client"; "use client";
import { EVENT_TYPE_STYLES } from "@/features/calendar/components/day-cell"; import { EVENT_TYPE_STYLES } from "@/features/calendar/components/day-cell";
import { Card } from "@/shared/components/ui/card";
import { cn } from "@/shared/utils/ui"; import { cn } from "@/shared/utils/ui";
const LEGEND_ITEMS = [ const LEGEND_ITEMS = [
@@ -12,22 +13,24 @@ const LEGEND_ITEMS = [
export function CalendarLegend() { export function CalendarLegend() {
return ( return (
<ul className="flex items-center justify-start gap-2 px-1"> <Card className="px-4 py-2">
{LEGEND_ITEMS.map((item) => ( <ul className="flex flex-row items-center gap-2">
<li {LEGEND_ITEMS.map((item) => (
key={item.label} <li
className={cn( key={item.label}
"flex items-center gap-1 rounded-md px-2 py-1 text-xs font-medium", className={cn(
item.wrapper, "flex items-center gap-1 rounded-md px-2 py-1 text-xs font-medium",
)} item.wrapper,
> )}
<span >
className={cn("size-1.5 shrink-0 rounded-full", item.dot)} <span
aria-hidden className={cn("size-1.5 shrink-0 rounded-full", item.dot)}
/> aria-hidden
{item.label} />
</li> {item.label}
))} </li>
</ul> ))}
</ul>
</Card>
); );
} }

View File

@@ -4,7 +4,7 @@ import {
buildOptionSets, buildOptionSets,
buildSluggedFilters, buildSluggedFilters,
mapTransactionsData, mapTransactionsData,
} from "@/features/transactions/page-helpers"; } from "@/features/transactions/lib/page-helpers";
import { import {
fetchRecentEstablishments, fetchRecentEstablishments,
fetchTransactionFilterSources, fetchTransactionFilterSources,

View File

@@ -69,6 +69,7 @@ export function CardItem({
const usagePercent = const usagePercent =
limit > 0 ? Math.min(Math.max((used / limit) * 100, 0), 100) : 0; limit > 0 ? Math.min(Math.max((used / limit) * 100, 0), 100) : 0;
const exceeded = usagePercent >= 100;
const logoPath = resolveLogoSrc(logo); const logoPath = resolveLogoSrc(logo);
const brandAsset = resolveCardBrandAsset(brand); const brandAsset = resolveCardBrandAsset(brand);
@@ -194,7 +195,8 @@ export function CardItem({
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<Progress <Progress
value={usagePercent} value={usagePercent}
className="h-2.5" className={cn("h-2.5", exceeded && "bg-destructive/20!")}
indicatorClassName={cn(exceeded && "bg-destructive")}
aria-label={`${usagePercent.toFixed(0)}% do limite utilizado`} aria-label={`${usagePercent.toFixed(0)}% do limite utilizado`}
/> />
<span className="text-xs text-muted-foreground"> <span className="text-xs text-muted-foreground">

View File

@@ -2,7 +2,7 @@
import { RiBankLine } from "@remixicon/react"; import { RiBankLine } from "@remixicon/react";
import Image from "next/image"; import Image from "next/image";
import StatusDot from "@/shared/components/status-dot"; import StatusDot from "@/shared/components/feedback/status-dot";
import { resolveCardBrandLogoSrc } from "@/shared/lib/cards/brand-assets"; import { resolveCardBrandLogoSrc } from "@/shared/lib/cards/brand-assets";
import { resolveLogoSrc } from "@/shared/lib/logo"; import { resolveLogoSrc } from "@/shared/lib/logo";

View File

@@ -6,7 +6,7 @@ import { useMemo, useState } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
import { deleteCardAction } from "@/features/cards/actions"; import { deleteCardAction } from "@/features/cards/actions";
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog"; import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
import { EmptyState } from "@/shared/components/empty-state"; import { EmptyState } from "@/shared/components/feedback/empty-state";
import { Button } from "@/shared/components/ui/button"; import { Button } from "@/shared/components/ui/button";
import { Card as UiCard } from "@/shared/components/ui/card"; import { Card as UiCard } from "@/shared/components/ui/card";
import { import {
@@ -174,14 +174,14 @@ export function CardsPage({
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full"> <Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
<TabsList> <TabsList>
<TabsTrigger value="ativos">Ativos</TabsTrigger> <TabsTrigger value="ativos">Ativos</TabsTrigger>
<TabsTrigger value="arquivados">Arquivados</TabsTrigger> <TabsTrigger value="inativos">Inativos</TabsTrigger>
</TabsList> </TabsList>
<TabsContent value="ativos" className="mt-4"> <TabsContent value="ativos" className="mt-4">
{renderCardList(orderedCards, false)} {renderCardList(orderedCards, false)}
</TabsContent> </TabsContent>
<TabsContent value="arquivados" className="mt-4"> <TabsContent value="inativos" className="mt-4">
{renderCardList(orderedArchivedCards, true)} {renderCardList(orderedArchivedCards, true)}
</TabsContent> </TabsContent>
</Tabs> </Tabs>

View File

@@ -19,7 +19,7 @@ type CardData = {
accountName: string; accountName: string;
}; };
export type AccountSimple = { type AccountSimple = {
id: string; id: string;
name: string; name: string;
logo: string | null; logo: string | null;
@@ -121,7 +121,7 @@ async function fetchCardsByStatus(
return { cards: cardList, accounts, logoOptions }; return { cards: cardList, accounts, logoOptions };
} }
export async function fetchCardsForUser(userId: string): Promise<{ async function fetchCardsForUser(userId: string): Promise<{
cards: CardData[]; cards: CardData[];
accounts: AccountSimple[]; accounts: AccountSimple[];
logoOptions: string[]; logoOptions: string[];
@@ -129,7 +129,7 @@ export async function fetchCardsForUser(userId: string): Promise<{
return fetchCardsByStatus(userId, false); return fetchCardsByStatus(userId, false);
} }
export async function fetchInactiveForUser(userId: string): Promise<{ async function fetchInactiveForUser(userId: string): Promise<{
cards: CardData[]; cards: CardData[];
accounts: AccountSimple[]; accounts: AccountSimple[];
logoOptions: string[]; logoOptions: string[];

View File

@@ -1,6 +1,6 @@
"use client"; "use client";
import StatusDot from "@/shared/components/status-dot"; import StatusDot from "@/shared/components/feedback/status-dot";
export function TypeSelectContent({ label }: { label: string }) { export function TypeSelectContent({ label }: { label: string }) {
const isReceita = label === "Receita"; const isReceita = label === "Receita";

View File

@@ -3,7 +3,7 @@ import { type Category, categories } from "@/db/schema";
import type { CategoryType } from "@/shared/lib/categories/constants"; import type { CategoryType } from "@/shared/lib/categories/constants";
import { db } from "@/shared/lib/db"; import { db } from "@/shared/lib/db";
export type CategoryData = { type CategoryData = {
id: string; id: string;
name: string; name: string;
type: CategoryType; type: CategoryType;

View File

@@ -8,7 +8,7 @@ import {
} from "@/shared/utils/financial-dates"; } from "@/shared/utils/financial-dates";
export type BillDialogState = PaymentDialogState; export type BillDialogState = PaymentDialogState;
export type BillStatusDateItem = Pick< type BillStatusDateItem = Pick<
DashboardBill, DashboardBill,
"dueDate" | "boletoPaymentDate" | "isSettled" "dueDate" | "boletoPaymentDate" | "isSettled"
>; >;

View File

@@ -1,6 +1,6 @@
import { and, desc, eq, isNull, ne, or, sql } from "drizzle-orm"; import { and, desc, eq, isNull, ne, or, sql } from "drizzle-orm";
import { categories, financialAccounts, transactions } from "@/db/schema"; import { categories, financialAccounts, transactions } from "@/db/schema";
import { mapTransactionsData } from "@/features/transactions/page-helpers"; import { mapTransactionsData } from "@/features/transactions/lib/page-helpers";
import { import {
ACCOUNT_AUTO_INVOICE_NOTE_PREFIX, ACCOUNT_AUTO_INVOICE_NOTE_PREFIX,
INITIAL_BALANCE_NOTE, INITIAL_BALANCE_NOTE,
@@ -17,7 +17,7 @@ import { getPreviousPeriod } from "@/shared/utils/period";
type MappedLancamentos = ReturnType<typeof mapTransactionsData>; type MappedLancamentos = ReturnType<typeof mapTransactionsData>;
export type CategoryDetailData = { type CategoryDetailData = {
category: { category: {
id: string; id: string;
name: string; name: string;

View File

@@ -11,14 +11,14 @@ import {
formatPeriodMonthShort, formatPeriodMonthShort,
} from "@/shared/utils/period"; } from "@/shared/utils/period";
export type CategoryOption = { type CategoryOption = {
id: string; id: string;
name: string; name: string;
icon: string | null; icon: string | null;
type: "receita" | "despesa"; type: "receita" | "despesa";
}; };
export type CategoryHistoryItem = { type CategoryHistoryItem = {
id: string; id: string;
name: string; name: string;
icon: string | null; icon: string | null;

View File

@@ -22,7 +22,7 @@ import {
excludeInitialBalanceWhenConfigured, excludeInitialBalanceWhenConfigured,
excludeRefundEntries, excludeRefundEntries,
excludeTransactionsFromExcludedAccounts, excludeTransactionsFromExcludedAccounts,
} from "@/features/dashboard/transaction-filters"; } from "@/features/dashboard/lib/transaction-filters";
import { db } from "@/shared/lib/db"; import { db } from "@/shared/lib/db";
import { getAdminPayerId } from "@/shared/lib/payers/get-admin-id"; import { getAdminPayerId } from "@/shared/lib/payers/get-admin-id";
import { safeToNumber as toNumber } from "@/shared/utils/number"; import { safeToNumber as toNumber } from "@/shared/utils/number";

View File

@@ -1,10 +1,10 @@
export type CategoryOption = { type CategoryOption = {
id: string; id: string;
name: string; name: string;
type: string; type: string;
}; };
export type CategoryTransaction = { type CategoryTransaction = {
id: string; id: string;
name: string; name: string;
amount: number; amount: number;

View File

@@ -14,7 +14,7 @@ import {
TooltipContent, TooltipContent,
TooltipTrigger, TooltipTrigger,
} from "@/shared/components/ui/tooltip"; } from "@/shared/components/ui/tooltip";
import { getCurrentPeriod, formatPeriodForUrl } from "@/shared/utils/period"; import { formatPeriodForUrl, getCurrentPeriod } from "@/shared/utils/period";
import { cn } from "@/shared/utils/ui"; import { cn } from "@/shared/utils/ui";
type BillListItemProps = { type BillListItemProps = {
@@ -44,7 +44,7 @@ export function BillListItem({ bill, period, onPay }: BillListItemProps) {
return ( return (
<li className="flex items-center justify-between transition-all duration-300 py-1.5"> <li className="flex items-center justify-between transition-all duration-300 py-1.5">
<div className="flex min-w-0 flex-1 items-center gap-2 py-1"> <div className="flex min-w-0 flex-1 items-center gap-2 py-0.5">
<EstablishmentLogo name={bill.name} size={37} /> <EstablishmentLogo name={bill.name} size={37} />
<div className="min-w-0"> <div className="min-w-0">

View File

@@ -14,8 +14,8 @@ import type {
} from "@/features/dashboard/bills/bills-queries"; } from "@/features/dashboard/bills/bills-queries";
import { AccountCardSelectContent } from "@/features/transactions/components/select-items"; import { AccountCardSelectContent } from "@/features/transactions/components/select-items";
import { EstablishmentLogo } from "@/shared/components/entity-avatar"; import { EstablishmentLogo } from "@/shared/components/entity-avatar";
import { PaymentSuccess } from "@/shared/components/feedback/payment-success";
import MoneyValues from "@/shared/components/money-values"; import MoneyValues from "@/shared/components/money-values";
import { PaymentSuccess } from "@/shared/components/payment-success";
import { Badge } from "@/shared/components/ui/badge"; import { Badge } from "@/shared/components/ui/badge";
import { Button } from "@/shared/components/ui/button"; import { Button } from "@/shared/components/ui/button";
import { Card } from "@/shared/components/ui/card"; import { Card } from "@/shared/components/ui/card";

View File

@@ -1,6 +1,6 @@
import { RiBarcodeFill } from "@remixicon/react"; import { RiBarcodeFill } from "@remixicon/react";
import type { DashboardBill } from "@/features/dashboard/bills/bills-queries"; import type { DashboardBill } from "@/features/dashboard/bills/bills-queries";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { BillListItem } from "./bill-list-item"; import { BillListItem } from "./bill-list-item";
type BillsListProps = { type BillsListProps = {

View File

@@ -13,7 +13,7 @@ import {
TabsList, TabsList,
TabsTrigger, TabsTrigger,
} from "@/shared/components/ui/tabs"; } from "@/shared/components/ui/tabs";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { formatPeriodForUrl } from "@/shared/utils/period"; import { formatPeriodForUrl } from "@/shared/utils/period";
import { CategoryBreakdownChart } from "./category-breakdown-chart"; import { CategoryBreakdownChart } from "./category-breakdown-chart";
import { CategoryBreakdownList } from "./category-breakdown-list"; import { CategoryBreakdownList } from "./category-breakdown-list";

View File

@@ -40,8 +40,8 @@ import {
} from "@/features/dashboard/widget-registry/widget-config"; } from "@/features/dashboard/widget-registry/widget-config";
import { NoteDialog } from "@/features/notes/components/note-dialog"; import { NoteDialog } from "@/features/notes/components/note-dialog";
import { TransactionDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog"; import { TransactionDialog } from "@/features/transactions/components/dialogs/transaction-dialog/transaction-dialog";
import { ExpandableWidgetCard } from "@/shared/components/expandable-widget-card";
import { Button } from "@/shared/components/ui/button"; import { Button } from "@/shared/components/ui/button";
import { ExpandableWidgetCard } from "@/shared/components/widgets/expandable-widget-card";
type DashboardGridEditableProps = { type DashboardGridEditableProps = {
data: DashboardData; data: DashboardData;

View File

@@ -1,6 +1,6 @@
import { RiFundsLine } from "@remixicon/react"; import { RiFundsLine } from "@remixicon/react";
import type { GoalProgressItem } from "@/features/dashboard/goals-progress/goals-progress-queries"; import type { GoalProgressItem } from "@/features/dashboard/goals-progress/goals-progress-queries";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { GoalProgressItem as GoalProgressListItem } from "./goals-progress-item"; import { GoalProgressItem as GoalProgressListItem } from "./goals-progress-item";
type GoalsProgressListProps = { type GoalsProgressListProps = {

View File

@@ -1,6 +1,6 @@
import { RiNumbersLine } from "@remixicon/react"; import { RiNumbersLine } from "@remixicon/react";
import type { InstallmentExpense } from "@/features/dashboard/expenses/installment-expenses-queries"; import type { InstallmentExpense } from "@/features/dashboard/expenses/installment-expenses-queries";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { InstallmentExpenseListItem } from "./installment-expense-list-item"; import { InstallmentExpenseListItem } from "./installment-expense-list-item";
type InstallmentExpensesListProps = { type InstallmentExpensesListProps = {

View File

@@ -14,8 +14,8 @@ import type {
InvoicePaymentAccountOption, InvoicePaymentAccountOption,
} from "@/features/dashboard/invoices/invoices-queries"; } from "@/features/dashboard/invoices/invoices-queries";
import { AccountCardSelectContent } from "@/features/transactions/components/select-items"; import { AccountCardSelectContent } from "@/features/transactions/components/select-items";
import { PaymentSuccess } from "@/shared/components/feedback/payment-success";
import MoneyValues from "@/shared/components/money-values"; import MoneyValues from "@/shared/components/money-values";
import { PaymentSuccess } from "@/shared/components/payment-success";
import { Badge } from "@/shared/components/ui/badge"; import { Badge } from "@/shared/components/ui/badge";
import { Button } from "@/shared/components/ui/button"; import { Button } from "@/shared/components/ui/button";
import { Card } from "@/shared/components/ui/card"; import { Card } from "@/shared/components/ui/card";

View File

@@ -1,6 +1,6 @@
import { RiBillLine } from "@remixicon/react"; import { RiBillLine } from "@remixicon/react";
import type { DashboardInvoice } from "@/features/dashboard/invoices/invoices-queries"; import type { DashboardInvoice } from "@/features/dashboard/invoices/invoices-queries";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { InvoiceListItem } from "./invoice-list-item"; import { InvoiceListItem } from "./invoice-list-item";
type InvoicesListProps = { type InvoicesListProps = {

View File

@@ -1,6 +1,6 @@
import { RiTodoLine } from "@remixicon/react"; import { RiTodoLine } from "@remixicon/react";
import type { Note } from "@/features/notes/components/types"; import type { Note } from "@/features/notes/components/types";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { NoteListItem } from "./note-list-item"; import { NoteListItem } from "./note-list-item";
type NotesListProps = { type NotesListProps = {

View File

@@ -1,5 +1,5 @@
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { import {
PaymentBreakdownListItem, PaymentBreakdownListItem,
type PaymentBreakdownListItemData, type PaymentBreakdownListItemData,

View File

@@ -1,5 +1,5 @@
import StatusDot from "@/shared/components/feedback/status-dot";
import MoneyValues from "@/shared/components/money-values"; import MoneyValues from "@/shared/components/money-values";
import StatusDot from "@/shared/components/status-dot";
import { Progress } from "@/shared/components/ui/progress"; import { Progress } from "@/shared/components/ui/progress";
type PaymentStatusCategorySectionProps = { type PaymentStatusCategorySectionProps = {

View File

@@ -1,7 +1,7 @@
import { RiWallet3Line } from "@remixicon/react"; import { RiWallet3Line } from "@remixicon/react";
import type { PaymentStatusData } from "@/features/dashboard/payments/payment-status-queries"; import type { PaymentStatusData } from "@/features/dashboard/payments/payment-status-queries";
import { CardContent } from "@/shared/components/ui/card"; import { CardContent } from "@/shared/components/ui/card";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { PaymentStatusCategorySection } from "./payment-status-category-section"; import { PaymentStatusCategorySection } from "./payment-status-category-section";
type PaymentStatusWidgetViewProps = { type PaymentStatusWidgetViewProps = {

View File

@@ -6,7 +6,7 @@ import {
import { formatPercentage } from "@/shared/utils/percentage"; import { formatPercentage } from "@/shared/utils/percentage";
import { cn } from "@/shared/utils/ui"; import { cn } from "@/shared/utils/ui";
export type PercentageChangeTrend = "up" | "down" | "flat"; type PercentageChangeTrend = "up" | "down" | "flat";
type PercentageChangeIndicatorProps = { type PercentageChangeIndicatorProps = {
value?: number | null; value?: number | null;

View File

@@ -14,7 +14,7 @@ import {
TooltipContent, TooltipContent,
TooltipTrigger, TooltipTrigger,
} from "@/shared/components/ui/tooltip"; } from "@/shared/components/ui/tooltip";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { formatDateOnly } from "@/shared/utils/date"; import { formatDateOnly } from "@/shared/utils/date";
import { formatBytes } from "@/shared/utils/number"; import { formatBytes } from "@/shared/utils/number";

View File

@@ -26,7 +26,7 @@ import {
PopoverContent, PopoverContent,
PopoverTrigger, PopoverTrigger,
} from "@/shared/components/ui/popover"; } from "@/shared/components/ui/popover";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { CATEGORY_COLORS } from "@/shared/utils/category-colors"; import { CATEGORY_COLORS } from "@/shared/utils/category-colors";
import { formatCurrency, formatCurrencyCompact } from "@/shared/utils/currency"; import { formatCurrency, formatCurrencyCompact } from "@/shared/utils/currency";
import { getIconComponent } from "@/shared/utils/icons"; import { getIconComponent } from "@/shared/utils/icons";

View File

@@ -5,7 +5,7 @@ import type { DashboardCategoryBreakdownItem } from "@/features/dashboard/catego
import { PercentageChangeIndicator } from "@/features/dashboard/components/percentage-change-indicator"; import { PercentageChangeIndicator } from "@/features/dashboard/components/percentage-change-indicator";
import { CategoryIconBadge } from "@/shared/components/entity-avatar"; import { CategoryIconBadge } from "@/shared/components/entity-avatar";
import MoneyValues from "@/shared/components/money-values"; import MoneyValues from "@/shared/components/money-values";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { formatPercentage } from "@/shared/utils/percentage"; import { formatPercentage } from "@/shared/utils/percentage";
type CategoryTrendsWidgetProps = { type CategoryTrendsWidgetProps = {

View File

@@ -9,7 +9,7 @@ import Image from "next/image";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useMemo, useState } from "react"; import { useMemo, useState } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
import type { DashboardInboxSnapshot } from "@/features/dashboard/inbox-snapshot-queries"; import type { DashboardInboxSnapshot } from "@/features/dashboard/lib/inbox-snapshot-queries";
import type { DashboardWidgetQuickActionOptions } from "@/features/dashboard/widget-registry/widget-config"; import type { DashboardWidgetQuickActionOptions } from "@/features/dashboard/widget-registry/widget-config";
import { import {
discardInboxItemAction, discardInboxItemAction,
@@ -19,7 +19,7 @@ import { TransactionDialog } from "@/features/transactions/components/dialogs/tr
import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog"; import { ConfirmActionDialog } from "@/shared/components/confirm-action-dialog";
import MoneyValues from "@/shared/components/money-values"; import MoneyValues from "@/shared/components/money-values";
import { Button } from "@/shared/components/ui/button"; import { Button } from "@/shared/components/ui/button";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { resolveLogoSrc } from "@/shared/lib/logo"; import { resolveLogoSrc } from "@/shared/lib/logo";
const DEFAULT_INBOX_APP_LOGO = "/avatars/default_icon.png"; const DEFAULT_INBOX_APP_LOGO = "/avatars/default_icon.png";

View File

@@ -9,7 +9,7 @@ import {
ChartContainer, ChartContainer,
ChartTooltip, ChartTooltip,
} from "@/shared/components/ui/chart"; } from "@/shared/components/ui/chart";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { formatCurrency } from "@/shared/utils/currency"; import { formatCurrency } from "@/shared/utils/currency";
type IncomeExpenseBalanceWidgetProps = { type IncomeExpenseBalanceWidgetProps = {

View File

@@ -10,7 +10,7 @@ import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { useTransition } from "react"; import { useTransition } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
import type { DashboardAccount } from "@/features/dashboard/accounts-queries"; import type { DashboardAccount } from "@/features/dashboard/lib/accounts-queries";
import { updateMyAccountsWidgetPreference } from "@/features/dashboard/widget-registry/widget-actions"; import { updateMyAccountsWidgetPreference } from "@/features/dashboard/widget-registry/widget-actions";
import MoneyValues from "@/shared/components/money-values"; import MoneyValues from "@/shared/components/money-values";
import { Badge } from "@/shared/components/ui/badge"; import { Badge } from "@/shared/components/ui/badge";
@@ -21,7 +21,8 @@ import {
TooltipContent, TooltipContent,
TooltipTrigger, TooltipTrigger,
} from "@/shared/components/ui/tooltip"; } from "@/shared/components/ui/tooltip";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { isAccountInactive } from "@/shared/lib/accounts/constants";
import { resolveLogoSrc } from "@/shared/lib/logo"; import { resolveLogoSrc } from "@/shared/lib/logo";
import { formatPeriodForUrl } from "@/shared/utils/period"; import { formatPeriodForUrl } from "@/shared/utils/period";
@@ -42,12 +43,15 @@ export function MyAccountsWidget({
}: MyAccountsWidgetProps) { }: MyAccountsWidgetProps) {
const [isPending, startTransition] = useTransition(); const [isPending, startTransition] = useTransition();
const excludedAccountsCount = accounts.filter( const activeAccounts = accounts.filter(
(account) => !isAccountInactive(account.status),
);
const excludedAccountsCount = activeAccounts.filter(
(account) => account.excludeFromBalance, (account) => account.excludeFromBalance,
).length; ).length;
const visibleAccounts = showExcludedAccounts const visibleAccounts = showExcludedAccounts
? accounts ? activeAccounts
: accounts.filter((account) => !account.excludeFromBalance); : activeAccounts.filter((account) => !account.excludeFromBalance);
const displayedAccounts = visibleAccounts.slice(0, 5); const displayedAccounts = visibleAccounts.slice(0, 5);
const remainingCount = visibleAccounts.length - displayedAccounts.length; const remainingCount = visibleAccounts.length - displayedAccounts.length;
const hiddenExcludedAccountsCount = showExcludedAccounts const hiddenExcludedAccountsCount = showExcludedAccounts
@@ -117,7 +121,7 @@ export function MyAccountsWidget({
) : null} ) : null}
<div> <div>
{accounts.length === 0 ? ( {activeAccounts.length === 0 ? (
<div className="-mt-10"> <div className="-mt-10">
<WidgetEmptyState <WidgetEmptyState
icon={ icon={

View File

@@ -7,14 +7,14 @@ import {
} from "@remixicon/react"; } from "@remixicon/react";
import Link from "next/link"; import Link from "next/link";
import { PercentageChangeIndicator } from "@/features/dashboard/components/percentage-change-indicator"; import { PercentageChangeIndicator } from "@/features/dashboard/components/percentage-change-indicator";
import type { DashboardPagador } from "@/features/dashboard/payers-queries"; import type { DashboardPagador } from "@/features/dashboard/lib/payers-queries";
import MoneyValues from "@/shared/components/money-values"; import MoneyValues from "@/shared/components/money-values";
import { import {
Avatar, Avatar,
AvatarFallback, AvatarFallback,
AvatarImage, AvatarImage,
} from "@/shared/components/ui/avatar"; } from "@/shared/components/ui/avatar";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { getAvatarSrc } from "@/shared/lib/payers/utils"; import { getAvatarSrc } from "@/shared/lib/payers/utils";
import { buildInitials } from "@/shared/utils/initials"; import { buildInitials } from "@/shared/utils/initials";

View File

@@ -12,7 +12,7 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from "@/shared/components/ui/select"; } from "@/shared/components/ui/select";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { CATEGORY_TYPE_LABEL } from "@/shared/lib/categories/constants"; import { CATEGORY_TYPE_LABEL } from "@/shared/lib/categories/constants";
import { formatTransactionDate } from "@/shared/utils/date"; import { formatTransactionDate } from "@/shared/utils/date";

View File

@@ -2,7 +2,7 @@ import { RiRefreshLine } from "@remixicon/react";
import type { RecurringExpensesData } from "@/features/dashboard/expenses/recurring-expenses-queries"; import type { RecurringExpensesData } from "@/features/dashboard/expenses/recurring-expenses-queries";
import { EstablishmentLogo } from "@/shared/components/entity-avatar"; import { EstablishmentLogo } from "@/shared/components/entity-avatar";
import MoneyValues from "@/shared/components/money-values"; import MoneyValues from "@/shared/components/money-values";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
type RecurringExpensesWidgetProps = { type RecurringExpensesWidgetProps = {
data: RecurringExpensesData; data: RecurringExpensesData;
@@ -13,7 +13,7 @@ const formatOccurrences = (value: number | null) => {
return "Recorrência contínua"; return "Recorrência contínua";
} }
return `${value} recorrências`; return `${value} recorrências mensais`;
}; };
export function RecurringExpensesWidget({ export function RecurringExpensesWidget({

View File

@@ -3,7 +3,7 @@
import { RiArrowUpDoubleLine, RiStore2Line } from "@remixicon/react"; import { RiArrowUpDoubleLine, RiStore2Line } from "@remixicon/react";
import { useState } from "react"; import { useState } from "react";
import type { TopExpensesData } from "@/features/dashboard/expenses/top-expenses-queries"; import type { TopExpensesData } from "@/features/dashboard/expenses/top-expenses-queries";
import type { TopEstablishmentsData } from "@/features/dashboard/top-establishments-queries"; import type { TopEstablishmentsData } from "@/features/dashboard/lib/top-establishments-queries";
import { import {
Tabs, Tabs,
TabsContent, TabsContent,

View File

@@ -1,8 +1,8 @@
import { RiStore2Line } from "@remixicon/react"; import { RiStore2Line } from "@remixicon/react";
import type { TopEstablishmentsData } from "@/features/dashboard/top-establishments-queries"; import type { TopEstablishmentsData } from "@/features/dashboard/lib/top-establishments-queries";
import { EstablishmentLogo } from "@/shared/components/entity-avatar"; import { EstablishmentLogo } from "@/shared/components/entity-avatar";
import MoneyValues from "@/shared/components/money-values"; import MoneyValues from "@/shared/components/money-values";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
type TopEstablishmentsWidgetProps = { type TopEstablishmentsWidgetProps = {
data: TopEstablishmentsData; data: TopEstablishmentsData;

View File

@@ -9,7 +9,7 @@ import type {
import { EstablishmentLogo } from "@/shared/components/entity-avatar"; import { EstablishmentLogo } from "@/shared/components/entity-avatar";
import MoneyValues from "@/shared/components/money-values"; import MoneyValues from "@/shared/components/money-values";
import { Switch } from "@/shared/components/ui/switch"; import { Switch } from "@/shared/components/ui/switch";
import { WidgetEmptyState } from "@/shared/components/widget-empty-state"; import { WidgetEmptyState } from "@/shared/components/widgets/widget-empty-state";
import { formatTransactionDate } from "@/shared/utils/date"; import { formatTransactionDate } from "@/shared/utils/date";
type TopExpensesWidgetProps = { type TopExpensesWidgetProps = {

View File

@@ -31,7 +31,7 @@ function calculateDueDate(period: string, dueDay: string | null): Date | null {
} }
} }
export type InstallmentDetail = { type InstallmentDetail = {
id: string; id: string;
currentInstallment: number; currentInstallment: number;
amount: number; amount: number;

View File

@@ -4,7 +4,7 @@ import {
formatLastInstallmentDate, formatLastInstallmentDate,
} from "@/shared/lib/installments/utils"; } from "@/shared/lib/installments/utils";
export type InstallmentExpenseDisplay = { type InstallmentExpenseDisplay = {
compactLabel: string | null; compactLabel: string | null;
isLast: boolean; isLast: boolean;
remainingInstallments: number; remainingInstallments: number;
@@ -13,7 +13,7 @@ export type InstallmentExpenseDisplay = {
progress: number; progress: number;
}; };
export const buildInstallmentCompactLabel = ( const buildInstallmentCompactLabel = (
currentInstallment: number | null, currentInstallment: number | null,
installmentCount: number | null, installmentCount: number | null,
) => { ) => {
@@ -24,7 +24,7 @@ export const buildInstallmentCompactLabel = (
return null; return null;
}; };
export const isInstallmentLast = ( const isInstallmentLast = (
currentInstallment: number | null, currentInstallment: number | null,
installmentCount: number | null, installmentCount: number | null,
) => { ) => {
@@ -35,7 +35,7 @@ export const isInstallmentLast = (
return currentInstallment === installmentCount && installmentCount > 1; return currentInstallment === installmentCount && installmentCount > 1;
}; };
export const calculateInstallmentRemainingCount = ( const calculateInstallmentRemainingCount = (
currentInstallment: number | null, currentInstallment: number | null,
installmentCount: number | null, installmentCount: number | null,
) => { ) => {
@@ -46,7 +46,7 @@ export const calculateInstallmentRemainingCount = (
return Math.max(0, installmentCount - currentInstallment); return Math.max(0, installmentCount - currentInstallment);
}; };
export const calculateInstallmentRemainingAmount = ( const calculateInstallmentRemainingAmount = (
amount: number, amount: number,
currentInstallment: number | null, currentInstallment: number | null,
installmentCount: number | null, installmentCount: number | null,
@@ -54,7 +54,7 @@ export const calculateInstallmentRemainingAmount = (
amount * amount *
calculateInstallmentRemainingCount(currentInstallment, installmentCount); calculateInstallmentRemainingCount(currentInstallment, installmentCount);
export const formatInstallmentEndDate = ( const formatInstallmentEndDate = (
period: string, period: string,
currentInstallment: number | null, currentInstallment: number | null,
installmentCount: number | null, installmentCount: number | null,
@@ -72,7 +72,7 @@ export const formatInstallmentEndDate = (
return formatLastInstallmentDate(lastDate); return formatLastInstallmentDate(lastDate);
}; };
export const buildInstallmentProgress = ( const buildInstallmentProgress = (
currentInstallment: number | null, currentInstallment: number | null,
installmentCount: number | null, installmentCount: number | null,
) => { ) => {

View File

@@ -1,4 +1,4 @@
export type RecurringExpense = { type RecurringExpense = {
id: string; id: string;
name: string; name: string;
amount: number; amount: number;

View File

@@ -1,13 +1,13 @@
import { cacheLife, cacheTag } from "next/cache"; import { cacheLife, cacheTag } from "next/cache";
import { fetchAttachmentsForPeriod } from "@/features/attachments/queries"; import { fetchAttachmentsForPeriod } from "@/features/attachments/queries";
import { fetchDashboardAccounts } from "./accounts-queries";
import { fetchDashboardCategoryOverview } from "./categories/category-overview-queries"; import { fetchDashboardCategoryOverview } from "./categories/category-overview-queries";
import { fetchDashboardInboxSnapshot } from "./inbox-snapshot-queries";
import { fetchDashboardInvoices } from "./invoices/invoices-queries"; import { fetchDashboardInvoices } from "./invoices/invoices-queries";
import { fetchDashboardAccounts } from "./lib/accounts-queries";
import { fetchDashboardInboxSnapshot } from "./lib/inbox-snapshot-queries";
import { fetchDashboardPayers } from "./lib/payers-queries";
import { fetchDashboardNotes } from "./notes/notes-queries"; import { fetchDashboardNotes } from "./notes/notes-queries";
import { fetchDashboardCurrentPeriodOverview } from "./overview/current-period-overview-queries"; import { fetchDashboardCurrentPeriodOverview } from "./overview/current-period-overview-queries";
import { fetchDashboardPeriodOverview } from "./overview/period-overview-queries"; import { fetchDashboardPeriodOverview } from "./overview/period-overview-queries";
import { fetchDashboardPayers } from "./payers-queries";
async function fetchDashboardDataInternal(userId: string, period: string) { async function fetchDashboardDataInternal(userId: string, period: string) {
const [ const [

View File

@@ -5,7 +5,6 @@ import type {
import type { import type {
GoalProgressCategory, GoalProgressCategory,
GoalProgressItem, GoalProgressItem,
GoalProgressStatus,
} from "@/features/dashboard/goals-progress/goals-progress-queries"; } from "@/features/dashboard/goals-progress/goals-progress-queries";
import { formatPercentage } from "@/shared/utils/percentage"; import { formatPercentage } from "@/shared/utils/percentage";
@@ -18,9 +17,6 @@ export const formatGoalProgressPercentage = (value: number, withSign = false) =>
signDisplay: withSign ? "always" : "auto", signDisplay: withSign ? "always" : "auto",
}); });
export const getGoalProgressStatusColorClass = (status: GoalProgressStatus) =>
status === "exceeded" ? "text-destructive" : "";
export const mapGoalProgressCategoriesToBudgetCategories = ( export const mapGoalProgressCategoriesToBudgetCategories = (
categories: GoalProgressCategory[], categories: GoalProgressCategory[],
): BudgetCategory[] => ): BudgetCategory[] =>

View File

@@ -1,4 +1,4 @@
export type GoalProgressStatus = "on-track" | "critical" | "exceeded"; type GoalProgressStatus = "on-track" | "critical" | "exceeded";
export type GoalProgressItem = { export type GoalProgressItem = {
id: string; id: string;

View File

@@ -55,7 +55,7 @@ type RawInvoiceBreakdownRow = {
amount: number | string | null; amount: number | string | null;
}; };
export type InvoicePagadorBreakdown = { type InvoicePagadorBreakdown = {
payerId: string | null; payerId: string | null;
pagadorName: string; pagadorName: string;
pagadorAvatar: string | null; pagadorAvatar: string | null;

View File

@@ -1,4 +1,4 @@
import type { DashboardData } from "./fetch-dashboard-data"; import type { DashboardData } from "../fetch-dashboard-data";
/** /**
* Coleta todos os nomes de estabelecimentos exibidos nos widgets do * Coleta todos os nomes de estabelecimentos exibidos nos widgets do

View File

@@ -3,7 +3,7 @@ import { cacheLife, cacheTag } from "next/cache";
import { cards, financialAccounts, inboxItems } from "@/db/schema"; import { cards, financialAccounts, inboxItems } from "@/db/schema";
import { db } from "@/shared/lib/db"; import { db } from "@/shared/lib/db";
export type DashboardInboxItem = { type DashboardInboxItem = {
id: string; id: string;
sourceAppName: string | null; sourceAppName: string | null;
parsedName: string | null; parsedName: string | null;

Some files were not shown because too many files have changed in this diff Show More