npm package: @marcos_feitoza/personal-finance-frontend-core-services
Description: Shared service layer for API communication in Personal Finance frontend packages.
Latest version: 1.7.2

# Frontend Core Services (Flutter)

Shared service layer for API communication in Personal Finance frontend packages.

## Purpose

This package centralizes API client access and shared service logic, keeping feature UI packages focused on presentation and state.

## Conteúdo Principal

- **`services/auth_service.dart`**: Lida com requisições de registro, login e logout para a API de autenticação.
- **`services/api_client.dart`**: Cliente HTTP centralizado que injeta o access token e faz refresh automático em caso de 401.
- **`services/transaction_service.dart`**: Centraliza as chamadas para as APIs de transações, investimentos, trades, dividendos e RRSP.
- **`services/stock_service.dart`**: Interage com o backend para buscar dados de mercado de ações.
- **`services/crypto_service.dart`**: Interage com o backend para buscar dados de mercado de criptomoedas.
- **`services/admin_service.dart`**: Serviços do Admin Console (usuários, segurança, créditos, auditoria e observability centralizada).
- **`providers/auth_provider.dart`**: Um `ChangeNotifier` que gerencia o estado de autenticação do usuário (token, email, status de login) usando `shared_preferences`.
- **`models/`**: Definições de modelos de dados (ex: `PaymentMethod`).

## Updated AI-Related Services

### `services/ai_service.dart`

Provides AI feature calls through `backend-core`:

- `getInsights()`
- `sendChatMessage()`
- `sendFeedback()`
- `simulate()`
- `getMonthlyPlan()`
- `getUsageSummary({month})`

`getUsageSummary()` agora retorna bloco `quota` com:

- `plan` (`free`/`plus`/`pro`)
- `monthly_request_limit` (limite efetivo do plano)
- `plan_limits` (limites base por plano)
- `metered_requests`
- `remaining_requests`

### `services/notification_service.dart`

Backend-backed notification operations (AI notifications, read state, generation trigger):

- `getNotifications({limit, onlyUnread})`
- `getUnreadCount()`
- `getNotificationsSchedule()`
- `markAsRead(id)`
- `markAllAsRead()`
- `triggerAiNotificationsGeneration({trigger})`

### `services/admin_service.dart`

Backend-backed admin operations:

- user lifecycle: role/plan/status
- security: revoke sessions / force password change / reset MFA placeholder
- AI credits: balance, ledger, manual adjustment, promo grant, monthly top-up
- audit: list admin audit logs
- AI observability (admin): summary filtered by user/window

### `models/app_notification.dart`

Data model for app notifications consumed by feature UI packages.

## API Gateway Strategy

All service calls target `BASE_API_URL` and go through `ApiClient` with JWT injection/refresh behavior.

Default base URL:

`http://personal-finance.casa/api`

Status (2026-02-15):

- `AuthService`, `TransactionService`, `UserService`, `MetadataService`, `AiService`, `NotificationService`, `StockService`, `CryptoService` e `LoggingService` usam `BASE_API_URL`.
- Não há mais base URL hardcoded nesses services.

Market/Crypto routing toggle (`dart-define`):

- `USE_CORE_MARKET_PROXY=true` (default): routes through `backend-core`
  - `/api/core-market-data/*`
  - `/api/core-crypto/*`
- `USE_CORE_MARKET_PROXY=false`: fallback to legacy direct routes
  - `/api/market-data/*`
  - `/api/crypto/*`

Production recommendation:

- Keep `USE_CORE_MARKET_PROXY=true` and disable direct ingress routing for market/crypto services.

## Why This Matters

- avoids direct feature package coupling to backend endpoints
- makes migration from local storage to backend-backed notifications transparent for UI
- keeps AI integration reusable across dashboard/profile/future modules
- keeps admin-only operational data centralized in admin flows

## Observability Ownership

- User-facing `AiService` mantém funcionalidades de produto (insights/chat/plan/usage).
- Observability operacional foi centralizada no Admin Console via `AdminService`.

## Plan-Aware UX (Backend Contracts)

Com o backend atualizado para planos:

- `/api/users/me` inclui `plan`
- rotas de investimentos podem retornar `403` com `code=plan_upgrade_required` para usuários `free`

Recomendação de UX:

- interceptar `plan_upgrade_required`
- mostrar dialog de upgrade (em vez de erro técnico)
- redirecionar para página de planos (quando disponível)

## Local Dependency Usage

```yaml
personal_finance_frontend_core_services:
  path: ../personal-finance-frontend-core-services
```

### Exemplo de Uso no Frontend

```dart
// No widget principal ou na árvore de widgets
ChangeNotifierProvider(
  create: (_) => AuthProvider(),
  child: MyApp(),
);

// Para acessar o token de autenticação e o email do usuário
final authProvider = Provider.of<AuthProvider>(context);
final token = authProvider.token;
final userEmail = authProvider.userEmail;

// Para usar um serviço de API
final transactionService = TransactionService();
final trades = await transactionService.getTrades(token: token);
```

## Features

-   **Gerenciamento de Autenticação**: Provedor de autenticação (`AuthProvider`) que lida com o ciclo de vida do token JWT e armazena o email do usuário.
-   **Interação com API do Backend**: Serviços dedicados para todas as operações com o backend.
-   **Tipagem Segura**: Utiliza modelos de dados para garantir que as interações com a API sejam tipadas e robustas.
-   **Logging Centralizado**: Não tem um `AppLogger` próprio, mas depende do `AppLogger` definido em `personal-finance-frontend-core-ui` para logs em tempo de execução.

## Autenticação: access + refresh token

O `AuthService` implementa:

- `POST /api/auth/token` (login) — salva `access_token` e `refresh_token`
- `POST /api/auth/refresh` — renova e rotaciona tokens
- `POST /api/auth/logout` — revoga refresh token (best-effort)

Tokens são persistidos no `SharedPreferences`:

- `access_token`
- `refresh_token`

## Refresh automático em caso de 401

O `ApiClient` é o caminho recomendado para chamadas HTTP, pois ele:

1. injeta `Authorization: Bearer <access_token>` automaticamente
2. se receber **401**, tenta `AuthService.refreshAccessToken()` uma vez e reexecuta a request
3. possui um lock simples para evitar múltiplos refresh em paralelo

Por isso, serviços do pacote (`TransactionService`, `UserService`, `CryptoService`, `StockService`, `LoggingService`) passaram a usar o `ApiClient`.