4.8 KiB
🔄 Backend Integration Guide - PraFrota Frontend
🎯 Overview
This document outlines how the PraFrota Angular frontend integrates with the BFF Tenant API backend, following the established architectural patterns and best practices.
🏗️ Architecture Alignment
Multi-tenant Architecture
The frontend must always include the following headers in all API requests:
headers: {
'tenant-uuid': string; // UUID of the current tenant
'tenant-user-auth': string; // JWT token for user authentication
}
CQRS Pattern Integration
Our frontend services are structured to align with the backend's CQRS pattern:
@Injectable({
providedIn: 'root'
})
export class VehicleService {
constructor(private http: HttpClient) {}
// Query Operations (Read)
getVehicles(filters: VehicleFilters): Observable<ResponsePaginated<Vehicle>> {
return this.http.get<ResponsePaginated<Vehicle>>('/api/vehicle', { params: filters });
}
// Command Operations (Write)
createVehicle(vehicle: CreateVehicleDto): Observable<Response<Vehicle>> {
return this.http.post<Response<Vehicle>>('/api/vehicle', vehicle);
}
}
📦 Domain Integration
BaseDomainComponent Pattern
Our BaseDomainComponent is designed to work seamlessly with the backend's domain structure:
@Component({
selector: 'app-vehicle',
standalone: true,
imports: [CommonModule, TabSystemComponent],
templateUrl: './vehicle.component.html'
})
export class VehicleComponent extends BaseDomainComponent<Vehicle> {
constructor(
service: VehicleService,
titleService: TitleService,
headerActionsService: HeaderActionsService,
cdr: ChangeDetectorRef
) {
super(titleService, headerActionsService, cdr, new VehicleServiceAdapter(service));
}
protected override getDomainConfig(): DomainConfig {
return {
domain: 'vehicle',
title: 'Veículos',
entityName: 'veículo',
subTabs: ['dados', 'documentos'],
columns: [
{ field: "id", header: "Id", sortable: true, filterable: true },
{ field: "plate", header: "Placa", sortable: true, filterable: true },
// ... other columns
]
};
}
}
🔄 Response Handling
Standard Response Types
The frontend expects and handles these standard response types from the backend:
// Single Entity Response
interface Response<T> {
data: T;
}
// Paginated Response
interface ResponsePaginated<T> {
data: T[];
totalCount: number;
pageCount: number;
currentPage: number;
}
Error Handling
All services should implement consistent error handling:
@Injectable({
providedIn: 'root'
})
export class ErrorHandlingService {
handleError(error: HttpErrorResponse): Observable<never> {
// Handle tenant-specific errors
if (error.status === 401) {
// Handle authentication errors
}
if (error.status === 403) {
// Handle authorization errors
}
// ... other error handling
return throwError(() => error);
}
}
📊 Data Table Integration
Our data table component is optimized for the backend's pagination and filtering:
@Component({
selector: 'app-data-table',
standalone: true,
template: `...`
})
export class DataTableComponent<T> {
@Input() data: T[] = [];
@Input() totalCount: number = 0;
@Input() currentPage: number = 1;
@Input() pageSize: number = 10;
// ... implementation
}
🔐 Authentication Flow
The frontend implements a complete authentication flow that aligns with the backend's requirements:
- Login: Obtain JWT token and tenant information
- Token Storage: Secure storage of tokens
- Request Interception: Automatic header injection
- Token Refresh: Automatic token refresh mechanism
📝 Best Practices
-
Service Layer:
- Always use
providedIn: 'root' - Implement proper error handling
- Use TypeScript interfaces for DTOs
- Always use
-
Component Layer:
- Extend
BaseDomainComponentfor domain components - Use
TabSystemComponentfor complex forms - Implement proper loading states
- Extend
-
State Management:
- Use services for state management
- Implement proper caching strategies
- Handle offline scenarios
-
Error Handling:
- Implement global error handling
- Show user-friendly error messages
- Log errors appropriately
🔄 API Integration Checklist
When integrating with a new backend endpoint:
- Define proper TypeScript interfaces
- Implement service with proper error handling
- Add proper loading states
- Implement caching if needed
- Add proper validation
- Test error scenarios
- Document the integration
📚 Additional Resources
- Backend Swagger:
https://prafrota-be-bff-tenant-api.grupopra.tech/swagger - Backend Documentation:
/docs/mcp/ - Frontend Architecture:
/docs/ARCHITECTURE.md