Skip to content

Instantly share code, notes, and snippets.

@grippado
Created August 12, 2025 15:35
Show Gist options
  • Select an option

  • Save grippado/3c1d1e8e899e842822a70cb3c6228f97 to your computer and use it in GitHub Desktop.

Select an option

Save grippado/3c1d1e8e899e842822a70cb3c6228f97 to your computer and use it in GitHub Desktop.

🔍 ANÁLISE GERAL

Pontos Positivos

  • Arquitetura sólida: Uso correto de componentes standalone (Angular 17+)
  • Acessibilidade excelente: Implementação robusta de ARIA, roles e navegação por teclado
  • Testes bem estruturados: Cobertura de testes unitários abrangente
  • Gerenciamento de estado: Uso apropriado de RxJS e BehaviorSubject
  • TypeScript bem tipado: Interfaces bem definidas

🚨 INCONSISTÊNCIAS E PROBLEMAS CRÍTICOS

1. Validação de Formulário Inconsistente

// PROBLEMA: Validação dupla e contraditória
// No FormBuilder: minLength(1)
Validators.minLength(1)

// No onSubmit: minLength(3) 
if (!trimmedTitle || trimmedTitle.length < 3) {
  return;
}

Impacto: Usuário pode inserir texto de 1-2 caracteres, mas o submit falha silenciosamente.

Solução:

// Unificar para minLength(3)
this.form = this.formBuilder.group({
  title: ['', [
    Validators.required, 
    Validators.minLength(3), // ← Corrigir aqui
    Validators.maxLength(200)
  ]]
});

2. Erro na Mensagem de Validação

<!-- ERRO: Mensagem incorreta -->
<span class="visually-hidden" *ngIf="titleControl?.errors?.['minlength']">
  O título deve ter pelo menos 1 caracteres.
</span>

Problema: Diz "1 caracteres" mas a regra real é 3.

3. URLs Hardcoded no ApiService

// PROBLEMA: URL não configurável
private baseUrl = 'http://localhost:8001';

Impacto: Dificulta deploy em diferentes ambientes.

Solução: Usar environment variables.

4. Problemas de Responsividade

Layout Fixo:

// PROBLEMA: Valores fixos sem responsividade
.form-input {
  width: 300px; // ← Valor fixo
}

.app-container {
  height: 100vh; // ← Problemático em mobile
  overflow: hidden;
}

Sem Media Queries:

  • Nenhum breakpoint para mobile/tablet
  • Formulário pode quebrar em telas pequenas

5. Gerenciamento de Estado Complexo Desnecessário

TodoService.addTodo() Overcomplexo:

// PROBLEMA: Lógica muito complexa para uma operação simples
switchMap((response: any) => {
  const created = response && typeof response === 'object' && 'data' in response
    ? (response as any).data
    : response;
  // ... lógica confusa

Problema: Tenta lidar com múltiplos formatos de resposta da API, mas isso deveria ser padronizado.

6. Inconsistências de Estilo CSS

Mistura de Unidades:

// Inconsistente: rem vs px
padding: 0.5rem;    // rem
width: 300px;       // px  
margin-left: 10px;  // px

Variáveis CSS não Utilizadas:

// Definidas mas não usadas consistentemente
body {
  font-family: var(--font-family-primary); // ← var() não definida
  // Deveria ser: $font-family-primary
}

7. Loading State Inadequado

// PROBLEMA: Loading é resetado antes da operação completar
this.isSubmitting = true;
this.addTodo.emit({ title: trimmedTitle });
this.resetForm(); // ← Reseta loading imediatamente

8. Tratamento de Erro Inconsistente

  • ApiService: Só loga no console
  • AppComponent: Anuncia para leitores de tela, mas não mostra visualmente
  • TodoService: Não trata erros de sincronização de estado

🚀 MELHORIAS SUGERIDAS

1. Configuração de Ambiente

// environment.ts
export const environment = {
  production: false,
  apiUrl: 'http://localhost:8001'
};

// api.service.ts
constructor(@Inject('API_URL') private baseUrl: string) {}

2. Responsividade Mobile-First

// _mixins.scss
@mixin mobile {
  @media (max-width: 768px) { @content; }
}

.form-input {
  width: 100%;
  max-width: 400px;
  
  @include mobile {
    max-width: 100%;
  }
}

3. Estado de Loading Global

// loading.service.ts
@Injectable()
export class LoadingService {
  private loadingSubject = new BehaviorSubject<boolean>(false);
  public loading$ = this.loadingSubject.asObservable();
}

4. Tratamento de Erro Unificado

// error-handler.service.ts
@Injectable()
export class ErrorHandlerService {
  handleError(error: any, userMessage: string) {
    // Log técnico
    console.error(error);
    
    // Notificação para usuário
    this.notificationService.showError(userMessage);
    
    // Tracking de erros
    this.analyticsService.trackError(error);
  }
}

5. Validador Customizado

// validators/custom-validators.ts
export function trimmedMinLength(length: number): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    const trimmed = control.value?.trim();
    return trimmed && trimmed.length >= length ? null : 
           { trimmedMinLength: { required: length, actual: trimmed?.length || 0 } };
  };
}

6. Design System Consistente

// _tokens.scss
$spacing-xs: 0.25rem;
$spacing-sm: 0.5rem;
$spacing-md: 1rem;
$spacing-lg: 1.5rem;
$spacing-xl: 2rem;

// Usar apenas estes valores

📊 PRIORIZAÇÃO DAS MELHORIAS

🔴 Crítico (Corrigir Imediatamente)

  1. Validação de formulário inconsistente
  2. Mensagem de erro incorreta
  3. Layout quebrado em mobile

🟡 Importante (Próxima Sprint)

  1. URLs hardcoded
  2. Tratamento de erro inadequado
  3. Estado de loading confuso

🟢 Melhoria (Backlog)

  1. Design system unificado
  2. Performance otimizations
  3. Testes de integração

🎯 CONCLUSÃO

O código da Débora demonstra competência técnica sólida com excelente foco em acessibilidade e arquitetura Angular moderna. No entanto, há inconsistências críticas principalmente na validação de formulários e responsividade que afetam a experiência do usuário.

Pontuação: 7.5/10

  • Arquitetura: 9/10
  • Acessibilidade: 10/10
  • Testes: 8/10
  • Responsividade: 4/10
  • Validação: 5/10
  • Tratamento de Erros: 6/10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment