30 KiB
Model Context Protocol (MCP) - Angular Workspace
📋 Visão Geral do Projeto
Este é um workspace Angular multi-projeto com foco em gerenciamento de frota de veículos (PraFrota), incluindo sistema de escala e aplicações IDT. O projeto utiliza Angular 19.2.x com arquitetura modular baseada em domínios.
🏗️ Estrutura do Workspace
angular-workspace/
├── projects/
│ ├── idt_app/ # Aplicação principal PraFrota
│ ├── idt_pattern/ # Biblioteca de padrões
│ ├── libs/ # Bibliotecas compartilhadas
│ ├── cliente/ # Aplicação cliente
│ └── escala/ # Sistema de escala
├── environments/ # Configurações de ambiente
├── proxy.conf.json # Configuração de proxy
└── mercado-live-routes-data.json # Dados de rotas
Projetos Principais
- idt_app: Aplicação principal para gerenciamento de frota
- escala: Sistema de gerenciamento de escalas
- cliente: Aplicação voltada para clientes
- libs: Bibliotecas compartilhadas entre projetos
📊 Dashboard Tab System ⭐ NOVO
Visão Geral
Sistema de dashboard automático integrado ao BaseDomainComponent que adiciona uma aba de dashboard antes da aba de lista em qualquer domínio.
Características
- Aba Dashboard: Aparece automaticamente ANTES da "Lista de [Domínio]"
- KPIs Automáticos: Total, Ativos, Recentes (últimos 7 dias)
- KPIs Customizados: Definidos por domínio
- Design Responsivo: Desktop e mobile
- Dark Mode: Suporte completo
- Configuração Simples: Apenas uma flag
showDashboardTab: true
Implementação
// Em qualquer domínio (ex: vehicles.component.ts)
protected override getDomainConfig(): DomainConfig {
return {
domain: 'vehicle',
title: 'Veículos',
entityName: 'veículo',
subTabs: ['dados', 'documentos'],
showDashboardTab: true, // ✅ Habilita dashboard
dashboardConfig: { // ✅ Configuração opcional
customKPIs: [
{
id: 'active-vehicles',
label: 'Veículos Ativos',
value: '150',
icon: 'fas fa-car',
color: 'success',
trend: 'up',
change: '+5%'
}
]
},
columns: [...]
};
}
Componentes Envolvidos
BaseDomainComponent: Lógica de criação das abasDomainDashboardComponent: Componente visual do dashboardTabSystemComponent: Renderização das abas
Documentação
🎯 Domínios de Negócio
IDT App - Estrutura de Domínios
projects/idt_app/src/app/domain/
├── vehicles/ # Gerenciamento de veículos
├── drivers/ # Gerenciamento de motoristas
├── routes/ # Gerenciamento de rotas
├── finances/ # Gestão financeira
└── session/ # Controle de sessão
Shared Resources
projects/idt_app/src/app/shared/
├── components/ # Componentes reutilizáveis
│ └── tab-system/ # Sistema de abas para edição
├── services/ # Serviços compartilhados
└── interfaces/ # Interfaces TypeScript
🔧 Configurações Técnicas
Scripts NPM Principais
ng serve: Desenvolvimento geralESCALA_development: Desenvolvimento do sistema de escalaserve:prafrota: Desenvolvimento da aplicação PraFrotabuild:prafrota: Build de produção da aplicação PraFrotabuild:prafrota --watch: Build contínuo para desenvolvimento PWAhttp-server dist/idt_app -p 8080 --ssl: Servir PWA com HTTPS local
Dependências Principais
- Angular: 19.2.13 (Core framework)
- Angular Material: 19.2.9 (UI Components)
- Leaflet: Mapas interativos
- NgxMask: Máscaras de input
- RxJS: Programação reativa
- TypeScript: 5.5.4
🌐 Integração de APIs
Backend Principal - PraFrota
- URL Base:
https://prafrota-be-bff-tenant-api.grupopra.tech - Versão: v1
- Autenticação: Bearer Token (JWT)
APIs Externas Integradas
ViaCEP (Consulta CEP)
- URL:
https://viacep.com.br/ws/{CEP}/json/ - Proxy: Configurado via
proxy.conf.json - Service:
CepService
Mercado Livre Routes
- Endpoints: Multiple APIs consolidados
- Paginação: Client-side para múltiplas APIs
- Tipos: FirstMile, LineHaul, LastMile
📊 Padrões de Dados
Interfaces de Rotas Mercado Livre
// Union type para diferentes tipos de rota
type MercadoLiveRouteRaw = FirstMileRoute | LineHaulRoute | LastMileRoute;
// Interface unificada para exibição
interface MercadoLiveRoute {
id: string;
routeType: 'first_mile' | 'line_haul' | 'last_mile';
vehicleType?: string;
locationName?: string;
driverName?: string;
departureDate?: Date;
status: string;
// ... outros campos unificados
}
Mapeamento de Dados
Padrão de mapeamento type-safe para consolidação de APIs:
class RouteMapper {
static mapRoutesToInterface(routes: MercadoLiveRouteRaw[]): MercadoLiveRoute[]
static mapFirstMileRoute(route: FirstMileRoute): MercadoLiveRoute
static mapLineHaulRoute(route: LineHaulRoute): MercadoLiveRoute
static mapLastMileRoute(route: LastMileRoute): MercadoLiveRoute
}
🔍 Serviços Principais
Logger Service
Sistema de logging estruturado com buffer e formatação:
interface LoggerService {
debug(message: string, ...args: any[]): void;
info(message: string, ...args: any[]): void;
warn(message: string, ...args: any[]): void;
error(message: string, ...args: any[]): void;
}
CEP Service
Consulta de endereços via ViaCEP:
@Injectable()
export class CepService {
consultarCep(cep: string): Observable<CepResponse>
}
Route Services
Gerenciamento de rotas com paginação local:
@Injectable()
export class MercadoLiveService {
loadRoutes(page: number, pageSize: number): Observable<PaginatedResponse>
}
🎨 Padrões de Componentes
Standalone Components
Todos os componentes utilizam o padrão standalone:
@Component({
selector: 'app-component',
standalone: true,
imports: [CommonModule, ReactiveFormsModule, MaterialModules],
templateUrl: './component.html'
})
🎯 TEMPLATE HTML OBRIGATÓRIO - BaseDomainComponent
TODOS os componentes que estendem BaseDomainComponent DEVEM usar exatamente este template HTML:
<div class="domain-container">
<div class="main-content">
<app-tab-system
#tabSystem
[config]="tabConfig"
[events]="tabEvents"
[showDebugInfo]="false"
(tabSelected)="onTabSelected($event)"
(tabClosed)="onTabClosed($event)"
(tabAdded)="onTabAdded($event)"
(tableEvent)="onTableEvent($event)">
</app-tab-system>
</div>
</div>
Componentes que seguem este padrão:
- VehiclesComponent ✅
- DriversComponent ✅
- RoutesComponent ✅
- FinancialCategoriesComponent ✅
- AccountPayableComponent ✅
🎯 PADRÃO OBRIGATÓRIO - Services com ApiClientService
NUNCA usar HttpClient diretamente! Todos os services DEVEM usar ApiClientService:
import { Injectable } from '@angular/core';
import { Observable, map } from 'rxjs';
import { ApiClientService } from '../../shared/services/api/api-client.service';
import { DomainService } from '../../shared/components/base-domain/base-domain.component';
@Injectable({
providedIn: 'root'
})
export class ExampleService implements DomainService<Entity> {
constructor(
private apiClient: ApiClientService // ✅ CORRETO
// private http: HttpClient // ❌ ERRADO
) {}
getEntities(page: number, pageSize: number, filters: any): Observable<any> {
return this.apiClient.get<any>(`entities?page=${page}&limit=${pageSize}`);
}
create(data: any): Observable<Entity> {
return this.apiClient.post<Entity>('entities', data);
}
update(id: any, data: any): Observable<Entity> {
return this.apiClient.patch<Entity>(`entities/${id}`, data);
}
getById(id: string): Observable<Entity> {
return this.apiClient.get<Entity>(`entities/${id}`);
}
delete(id: string): Observable<void> {
return this.apiClient.delete<void>(`entities/${id}`);
}
}
Services que seguem este padrão:
- VehiclesService ✅
- DriversService ✅
- RoutesService ✅
- FinancialCategoriesService ✅
- AccountPayableService ✅
🚫 PADRÕES DE NOMENCLATURA OBRIGATÓRIOS
NUNCA criar métodos com sufixos específicos! Todos os services DEVEM seguir a nomenclatura padrão:
✅ MÉTODOS CORRETOS:
// Métodos da interface DomainService (OBRIGATÓRIOS)
getEntities(page: number, pageSize: number, filters: any)
create(data: any): Observable<Entity>
update(id: any, data: any): Observable<Entity>
// Métodos específicos padrão (OBRIGATÓRIOS)
getById(id: string): Observable<Entity>
delete(id: string): Observable<void>
get[Domain]s(page, limit, filters): Observable<PaginatedResponse<Entity>>
❌ MÉTODOS INCORRETOS (NUNCA usar):
// ❌ ERRADO - Com sufixos específicos
createRoute() // Usar apenas: create()
updateRoute() // Usar apenas: update()
deleteRoute() // Usar apenas: delete()
getRoute() // Usar apenas: getById()
// ❌ ERRADO - Nomenclatura não padronizada
addEntity(), editEntity(), removeEntity(), findById()
📋 VERIFICAÇÃO DE CONFORMIDADE:
| Service | create | update | delete | getById | get[Domain]s |
|---|---|---|---|---|---|
| VehiclesService | ✅ | ✅ | ✅ | ✅ | getVehicles ✅ |
| DriversService | ✅ | ✅ | ✅ | ✅ | getDrivers ✅ |
| RoutesService | ✅ | ✅ | ✅ | ✅ | getRoutes ✅ |
| FinancialCategoriesService | ✅ | ✅ | ✅ | ✅ | getCategories ✅ |
| AccountPayableService | ✅ | ✅ | ✅ | ✅ | getAccounts ✅ |
Reactive Forms
Formulários construídos com FormBuilder:
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
field: ['', [Validators.required]]
});
}
Data Tables
Componentes de tabela com paginação, filtros e ordenação usando Angular Material.
Tab System - Sistema de Abas para Edição
Sistema avançado de abas para edição de registros com limite configurável e gestão de estado:
Configuração Básica
// Configuração do sistema de abas
const tabConfig: TabSystemConfig = {
maxTabs: 3, // Limite máximo de abas
allowDuplicates: false, // Previne duplicatas
autoSave: false, // Auto-save desabilitado
confirmClose: true // Confirmação para fechar
};
// Eventos do sistema
const tabEvents = {
onMaxTabsReached: () => {
console.warn('Limite máximo de abas atingido!');
},
onUnsavedChanges: (tabs: TabItem[]) => {
console.warn('Mudanças não salvas:', tabs);
}
};
Uso no Template
<app-tab-system
[config]="tabConfig"
[events]="tabEvents"
[showDebugInfo]="true"
(tabSelected)="onTabSelected($event)"
(tabClosed)="onTabClosed($event)"
(tabAdded)="onTabAdded($event)">
</app-tab-system>
Adicionar Aba Programaticamente
async addNewTab(item: any) {
const tabItem: TabItem = {
id: item.id,
title: item.name,
type: 'driver', // 'product' | 'vehicle' | 'driver' | 'route'
data: item,
isLoading: true,
isModified: false
};
const success = await this.tabSystem.addTab(tabItem);
if (success) {
// Carregar dados detalhados
this.loadItemDetails(item.id);
}
}
Aplicação no Domínio de Motoristas
Exemplo prático implementado em drivers-tabs-demo.component.ts:
@Component({
selector: 'app-drivers-tabs-demo',
standalone: true,
imports: [/* Material modules */, TabSystemComponent]
})
export class DriversTabsDemoComponent {
@ViewChild('tabSystem') tabSystem!: TabSystemComponent;
// Configuração específica para motoristas
tabConfig: TabSystemConfig = {
maxTabs: 4,
allowDuplicates: false,
autoSave: false,
confirmClose: true
};
async addDriverTab(driver: Driver): Promise<void> {
const tabItem: TabItem = {
id: driver.id,
title: driver.name,
type: 'driver',
data: driver,
isLoading: true,
isModified: false
};
const success = await this.tabSystem.addTab(tabItem);
if (success) {
// Simular carregamento de detalhes
setTimeout(() => {
this.loadDriverDetails(driver.id);
}, 1500);
}
}
private loadDriverDetails(driverId: string): void {
// Encontrar a aba e atualizar com dados detalhados
const tabs = this.tabSystem.getTabs();
const tabIndex = tabs.findIndex(tab =>
tab.id === driverId && tab.type === 'driver'
);
if (tabIndex !== -1) {
const detailedData = {
documents: { cnh: '123456789', cnh_expiry: new Date() },
performance_score: 85,
status: 'ATIVO'
};
this.tabSystem.tabSystemService.updateTab(tabIndex, detailedData);
this.tabSystem.tabSystemService.setTabLoading(tabIndex, false);
}
}
}
Funcionalidades do Sistema de Abas
- Limite Configurável: Máximo de abas simultâneas
- Prevenção de Duplicatas: Não permite abrir o mesmo item duas vezes
- Estados de Loading: Indicadores visuais durante carregamento
- Indicadores de Modificação: Marcação (*) para itens não salvos
- Ícones por Tipo: product, vehicle, driver, route
- Botões de Fechar: Com tooltips e confirmação
- Responsividade: Adaptação para dispositivos móveis
- Otimização Mobile: Títulos compactos para telas ≤ 768px
- Debug Mode: Informações de desenvolvimento
- Eventos: Sistema completo de callbacks
Otimização Mobile dos Títulos das Tabs
Sistema automático de formatação de títulos para dispositivos móveis:
// Comportamento automático baseado no tamanho da tela
// Mobile (≤ 768px):
"Motorista: João Silva" → "João Silva"
"Veículo: Toyota Corolla" → "Toyota Corolla"
"Novo Motorista" → "Novo Motorista" (inalterado)
// Desktop (> 768px):
"Motorista: João Silva" → "Motorista: João Silva" (completo)
Implementação:
- Detecção: Automática via
@HostListener('window:resize') - Lógica: Remove domínio apenas se contém ":" e não inicia com "Novo"
- Responsivo: Atualização instantânea ao redimensionar
- Universal: Funciona para todos os domínios (motoristas, veículos, etc.)
📊 Data-Table - Otimização Mobile
Melhorias de Responsividade
Header da Tabela (Mobile ≤ 768px)
Layout reorganizado em duas linhas:
┌─────────────────────────────────────┐
│ [🔍 Busca Global - 80%] [Filtros-20%]│ ← Linha 1
│ [Requisições] [Col] [Grup] [5▼] [Exp] │ ← Linha 2
└─────────────────────────────────────┘
Funcionalidades:
- Busca Global: 80% da largura para máximo aproveitamento
- Botões Compactos: Textos reduzidos ("Col", "Grup", "Exp")
- Layout Edge-to-Edge: Sem bordas laterais para ganho de espaço
- Filtros Expansíveis: Sistema toggle para filtros por coluna
Paginação Otimizada
Mobile:
┌─────────────────────────────────────┐
│ 1-5 de 5 [◀] [1] [2] [3] [▶] │ ← Linha única
└─────────────────────────────────────┘
Melhorias implementadas:
- Texto Compacto: "1-5 de 5" ao invés de "Exibindo 1 a 5 de 5 registros"
- Altura Reduzida: padding otimizado (0.375rem mobile vs 0.75rem desktop)
- Layout Horizontal: Forçado em linha única para mobile
- Alinhamento Inteligente: Texto à esquerda, controles à direita
- Navegação Compacta: Botões menores com espaçamento otimizado
CSS Budget Management
Sistema de compressão avançada para manter funcionalidades dentro do limite:
// Seção ultra-comprimida para mobile
@media (max-width: 768px) {
.data-table-container,.table-menu{border-left:none!important;border-right:none!important;border-radius:0!important;margin:0!important}
.pagination{padding:.375rem .5rem!important;flex-direction:row!important;justify-content:space-between!important}
// ... regras comprimidas
}
Estratégias aplicadas:
- Compressão Manual: Remoção de espaços e comentários
- Seletores Combinados: Agrupamento de regras similares
- Important Flags: Uso estratégico para sobrescrever padrões
- Propriedades Mínimas: Apenas essenciais para mobile
📄 Paginação Multi-API
Padrão para Consolidação de APIs
loadRoutes(page: number, pageSize: number) {
// 1. Buscar dados de múltiplas APIs
const requests = [
this.api.getFirstMile(1, 1000),
this.api.getLineHaul(1, 1000),
this.api.getLastMile(1, 1000)
];
// 2. Consolidar dados
forkJoin(requests).subscribe(results => {
const allRoutes = results.flat();
const mappedRoutes = this.mapRoutesToInterface(allRoutes);
// 3. Aplicar paginação local
const startIndex = (page - 1) * pageSize;
const endIndex = startIndex + pageSize;
const paginatedRoutes = mappedRoutes.slice(startIndex, endIndex);
this.routes = paginatedRoutes;
this.totalCount = mappedRoutes.length;
});
}
🗂️ Estrutura de Arquivos
Convenções de Nomenclatura
- Arquivos:
kebab-case(ex:vehicle-form.component.ts) - Classes:
PascalCase(ex:VehicleFormComponent) - Propriedades:
camelCase(ex:vehicleName) - Constantes:
SCREAMING_SNAKE_CASE(ex:API_BASE_URL)
Organização por Feature
domain/vehicles/
├── components/
│ ├── vehicle-form/
│ ├── vehicle-list/
│ └── vehicle-map/
├── services/
│ └── vehicle.service.ts
├── interfaces/
│ └── vehicle.interface.ts
└── vehicle.routes.ts
⚙️ Configurações de Desenvolvimento
Proxy Configuration
{
"/api/ws/*": {
"target": "https://viacep.com.br",
"secure": true,
"changeOrigin": true,
"logLevel": "debug"
}
}
Environment Configuration
- Development: Local development settings
- Production: Production optimizations
- Debug Remote: Remote debugging configuration
🔐 Autenticação e Segurança
Headers Obrigatórios
Content-Type: application/json
Authorization: Bearer <token>
X-Tenant-ID: <tenant-id>
X-Client-Version: 1.0.0
Gestão de Tokens
- JWT: Bearer tokens para autenticação
- Refresh: Renovação automática de tokens
- Tenant: Multi-tenancy via headers
📱 Recursos de UI/UX
Angular Material
Componentes Material Design integrados:
- Tables com paginação otimizada para mobile
- Forms com validação responsiva
- Navigation com sidenav adaptativo
- Cards e layouts responsivos
Sistema de Abas Avançado
- Tab System: Gerenciamento inteligente de abas de edição
- Mobile First: Títulos otimizados automaticamente para mobile
- Estado Persistente: Controle de modificações não salvas
- Limite Inteligente: Máximo configurável de abas simultâneas
Data-Table Responsiva
- Header Adaptativo: Layout reorganizado em mobile (duas linhas)
- Paginação Compacta: Texto reduzido e controles otimizados
- Edge-to-Edge: Aproveitamento máximo da tela em mobile
- Filtros Inteligentes: Sistema expansível para dispositivos móveis
PWA (Progressive Web App) ✅ NOVO
Implementação completa de Progressive Web App com funcionalidades nativas:
Funcionalidades Principais
- Instalação Nativa: Prompt automático para instalar como app
- Updates Automáticos: Notificações de novas versões disponíveis
- Offline Ready: Service Worker configurado para cache
- Notificações Visuais: Interface responsiva para interações PWA
- Debug Tools: Painel de desenvolvimento para testes
- Cross-Platform: Suporte completo para desktop e mobile
Estrutura de Implementação
Serviços PWA:
// PWAService - Gerenciamento principal
@Injectable({ providedIn: 'root' })
export class PWAService {
// Observables para estado PWA
public installPromptAvailable$: Observable<boolean>
public updateAvailable$: Observable<boolean>
// Métodos principais
public async activateUpdate(): Promise<void>
public async showInstallPrompt(): Promise<boolean>
public async checkForUpdate(): Promise<boolean>
// Verificações de estado
public isInstalledPWA(): boolean
public isPWASupported(): boolean
}
Componente de Notificações:
// PWANotificationsComponent - Interface visual
@Component({
selector: 'app-pwa-notifications',
standalone: true
})
export class PWANotificationsComponent {
showUpdateNotification = false;
showInstallNotification = false;
showDebugInfo = false; // ✅ Desabilitado para produção (padrão)
}
Configuração e Setup
1. Service Worker Configuration (ngsw-config.json):
{
"index": "/index.html",
"assetGroups": [
{
"name": "app",
"installMode": "prefetch",
"resources": {
"files": ["/favicon.ico", "/index.html", "/manifest.webmanifest", "/*.css", "/*.js"]
}
},
{
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": ["/**/*.(svg|cur|jpg|jpeg|png|apng|webp|avif|gif|otf|ttf|woff|woff2)"]
}
}
]
}
2. Manifest PWA (manifest.webmanifest):
{
"name": "IDT App - Gestão Inteligente",
"short_name": "IDT App",
"display": "standalone",
"orientation": "portrait-primary",
"theme_color": "#FFC82E",
"background_color": "#FFFFFF",
"categories": ["business", "productivity", "utilities"],
"icons": [/* Ícones de 72x72 até 512x512 */]
}
3. Build Configuration (angular.json):
{
"configurations": {
"production": {
"serviceWorker": "projects/idt_app/ngsw-config.json",
"budgets": [{"type": "initial", "maximumWarning": "4mb", "maximumError": "5mb"}]
}
}
}
Fluxos de Funcionamento
Fluxo de Atualização:
- Service Worker detecta nova versão disponível
- PWAService emite evento via Observable
- PWANotificationsComponent exibe notificação
- Usuário clica "Atualizar agora"
- Service Worker ativa nova versão e recarrega app
Fluxo de Instalação:
- Browser dispara evento
beforeinstallprompt - PWAService intercepta e armazena evento
- Exibe notificação de instalação
- Usuário clica "Instalar"
- Mostra dialog nativo do browser
- Detecta instalação via
appinstalled
Interface Responsiva
Desktop - Notificações no canto superior direito:
.pwa-notification {
position: fixed;
top: 80px;
right: 20px;
max-width: 400px;
}
Mobile - Bottom sheet acima do footer menu:
@media (max-width: 768px) {
.pwa-notification {
bottom: 80px; /* Acima do mobile footer */
left: 10px;
right: 10px;
max-width: none;
}
}
Suporte por Plataforma
Desktop (Chrome, Edge, Firefox):
- ✅ Prompt de instalação automático
- ✅ Ícone na barra de tarefas
- ✅ Janela standalone
- ✅ Notificações de update
Mobile (Android):
- ✅ Add to Home Screen
- ✅ Splash screen personalizada
- ✅ Tema da status bar (#FFC82E)
- ✅ Orientação portrait
iOS (Safari):
- ✅ Add to Home Screen (manual)
- ✅ Meta tags específicas
- ⚠️ Limitações do Safari PWA
Debug e Teste
Debug Panel (desabilitado por padrão, comentado para reativação):
// 🔧 DEBUG PWA - Painel de desenvolvimento
// showDebugInfo = true; // ✅ Habilitar para desenvolvimento/testes
showDebugInfo = false; // ✅ Desabilitado para produção (padrão)
Informações exibidas:
- PWA Suportado: ✅/❌
- PWA Instalado: ✅/❌
- Pode Instalar: ✅/❌
- Update Disponível: ✅/❌
Console Logs informativos:
console.log('🚀 IDT App inicializado');
console.log('📱 PWA Suportado:', this.isPWASupported());
console.log('🏠 PWA Instalado:', this.isInstalledPWA());
console.log('🔄 Nova versão disponível!');
console.log('📲 Prompt de instalação PWA disponível');
Comandos de Teste
Desenvolvimento PWA:
# Build de produção (necessário para Service Worker)
npm run build:prafrota
# Servir com HTTPS (necessário para PWA)
npx http-server dist/idt_app -p 8080 --ssl
# Acessar: https://localhost:8080
Testar Updates:
# 1. Build inicial
npm run build:prafrota
# 2. Alterar código (ex: adicionar console.log)
# 3. Build novamente
npm run build:prafrota
# 4. Service Worker detectará automaticamente a mudança
DevTools - Verificações:
- Application > Manifest: Validar configurações PWA
- Application > Service Workers: Status do SW
- Lighthouse: Audit PWA score (esperado: 90-100/100)
- Network > Offline: Testar funcionamento offline
Métricas de Performance
Bundle Impact:
PWA Service: ~3kB gzipped
PWA Component: ~2kB gzipped
Service Worker: ~15kB (Angular SW)
Total Impact: ~20kB
Lighthouse PWA Criteria:
- ✅ Manifest válido
- ✅ Service Worker registrado
- ✅ Ícones adequados (72px-512px)
- ✅ HTTPS em produção
- ✅ Viewport responsivo
- ✅ Splash screen configurada
- ✅ Theme color definido
Futuras Melhorias
Push Notifications:
- Integração com Firebase Cloud Messaging
- Notificações de sistema
- Badge counts no ícone
Offline Advanced:
- Cache de dados críticos de API
- Background sync
- Indicador de status de conectividade
App Shortcuts:
- Quick actions no ícone do app
- Jump lists personalizadas
- Context menus
Otimizações Mobile Gerais
- Breakpoint: ≤ 768px para mobile
- Touch-Friendly: Controles adequados para toque
- Edge-to-Edge: Layouts que aproveitam toda a tela
- Responsive Typography: Textos adaptados para cada dispositivo
- PWA Mobile: Interface nativa com splash screen e tema personalizado
- Navigation: Bottom sheets e drawers adaptivos
- Performance: Lazy loading e otimizações específicas para mobile
🔒 Prevenção de Zoom Mobile ✅ NOVO
Implementação completa para experiência nativa sem zoom indesejado:
Funcionalidades Implementadas
- Double-tap Prevention: Bloqueia zoom por dois toques
- Pinch Prevention: Desabilita zoom por dois dedos
- Keyboard Zoom Prevention: Previne Ctrl+/- no desktop
- Pull-to-refresh Control: Gerencia refresh contextual
- iOS Optimization: Font-size 16px para prevenir auto-zoom
Configuração Técnica
1. Meta Viewport (index.html):
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<meta name="format-detection" content="telephone=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-touch-fullscreen" content="yes">
2. CSS Prevention (app.scss):
html, body {
touch-action: manipulation; /* Previne pinch/double-tap */
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
/* Permite seleção em inputs */
input, textarea, select, [contenteditable] {
user-select: text;
font-size: 16px !important; /* Previne auto-zoom iOS */
}
3. JavaScript Service (MobileBehaviorService):
@Injectable({ providedIn: 'root' })
export class MobileBehaviorService {
// Prevenção automática de zoom
// Otimização de touch
// Controle de pull-to-refresh
// Detecção de dispositivo mobile
}
Comportamentos Controlados
Zoom Prevention:
- ❌ Double-tap zoom
- ❌ Pinch zoom (dois dedos)
- ❌ Ctrl+scroll zoom
- ❌ Keyboard zoom (Ctrl +/-)
Preservado:
- ✅ Scroll vertical/horizontal
- ✅ Seleção de texto em inputs
- ✅ Navegação por touch
- ✅ Swipe gestures em carousels
Mobile Experience:
- ✅ Experiência nativa sem zoom
- ✅ Touch-action otimizado
- ✅ 300ms delay removido
- ✅ Safe areas respeitadas
- ✅ PWA standalone optimized
🧪 Testes e Qualidade
Estrutura de Testes
- Unit Tests: Jasmine + Karma
- E2E Tests: Protractor/Cypress (configuração futura)
- Linting: ESLint + Angular ESLint
Code Quality
- TypeScript: Tipagem estrita
- Interfaces: Contratos bem definidos
- Services: Injeção de dependência
- Observables: Programação reativa com RxJS
🚀 Deploy e Build
Scripts de Build
- Development:
ng serve - Production:
ng build --configuration=production - Specific Projects: Scripts individuais por projeto
Otimizações
- Tree Shaking: Remoção de código não utilizado
- Lazy Loading: Carregamento sob demanda
- Service Workers: PWA capabilities
📚 Documentação Adicional
Links Úteis
Documentação PWA
- PWA_IMPLEMENTATION.md: Guia técnico completo da implementação PWA (400+ linhas)
- PWA_QUICK_START.md: Guia rápido para desenvolvimento e troubleshooting PWA
- Service Worker: Configuração avançada em
ngsw-config.json - Manifest: Especificações PWA em
manifest.webmanifest
Padrões de Arquitetura ✅ NOVO
- PATTERNS_INDEX.md: Índice centralizado de todos os padrões documentados
- APP_COMPONENT_PATTERN.md: Padrão de integração PWA/Mobile no app.component.ts
- MOBILE_ZOOM_PREVENTION.md: Implementação completa de prevenção de zoom mobile
- Tab System: Sistema avançado de abas para edição com gestão de estado
- Data Table: Componentes responsivos com otimizações mobile
Patterns e Best Practices
- DDD: Domain Driven Design
- SOLID: Princípios de desenvolvimento
- Reactive Programming: RxJS patterns
- Component Communication: Input/Output, Services, State Management
- PWA Best Practices: Offline-first, installable, reliable
Este documento serve como referência central para o desenvolvimento e manutenção do projeto Angular workspace. Mantenha-o atualizado conforme as mudanças na arquitetura e funcionalidades.
Última atualização: Janeiro 2025 - Adicionada implementação completa PWA com notificações automáticas, prompts de instalação e documentação técnica detalhada.