web: migrate health notifications to js_interop; add browser hook
- Replace dart:js with package:js in health_check_service_web.dart\n- Implement showHealthCheckNotification in web/index.html\n- Pin js dependency to ^0.6.7 for flutter_secure_storage_web compatibility auth: harden AuthInterceptor + tests - Allow overrideAuthRepository injection for testing\n- Normalize imports to package: paths\n- Add unit test covering token attach, 401→refresh→retry, and failure path\n- Add integration test skeleton gated by env vars ui/data: map User.companyName to list column - Add companyName to domain User\n- Map UserDto.company?.name\n- Render companyName in user_list cleanup: remove legacy equipment table + unused code; minor warnings - Remove _buildFlexibleTable and unused helpers\n- Remove unused zipcode details and cache retry constant\n- Fix null-aware and non-null assertions\n- Address child-last warnings in administrator dialog docs: update AGENTS.md session context
This commit is contained in:
85
.claude/agents/api-patterns.md
Normal file
85
.claude/agents/api-patterns.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Superport API Patterns v8.0
|
||||
|
||||
## What This Really Is
|
||||
Backend API patterns specific to this project. Just code to copy.
|
||||
|
||||
## Rust Backend Endpoints
|
||||
```rust
|
||||
// GET endpoint pattern
|
||||
#[get("/equipment")]
|
||||
async fn get_equipment(db: web::Data<DbPool>) -> Result<HttpResponse> {
|
||||
let items = Equipment::find_all(&db).await?;
|
||||
Ok(HttpResponse::Ok().json(items))
|
||||
}
|
||||
|
||||
// POST with validation
|
||||
#[post("/equipment")]
|
||||
async fn create_equipment(
|
||||
req: web::Json<CreateEquipmentRequest>,
|
||||
db: web::Data<DbPool>,
|
||||
) -> Result<HttpResponse> {
|
||||
req.validate()?; // Always validate
|
||||
let item = Equipment::create(&db, req.into_inner()).await?;
|
||||
Ok(HttpResponse::Created().json(item))
|
||||
}
|
||||
```
|
||||
|
||||
## Frontend API Calls
|
||||
```dart
|
||||
// Always use this pattern
|
||||
class EquipmentApi {
|
||||
Future<ApiResponse<List<EquipmentDto>>> getEquipments() async {
|
||||
final response = await dio.get('/equipment');
|
||||
return ApiResponse.fromJson(
|
||||
response.data,
|
||||
(json) => (json as List).map((e) => EquipmentDto.fromJson(e)).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## DTO Field Mapping
|
||||
```dart
|
||||
// Backend fields MUST match exactly
|
||||
@JsonSerializable()
|
||||
class EquipmentDto {
|
||||
@JsonKey(name: 'companies_id') // NOT company_id
|
||||
final int? companiesId;
|
||||
|
||||
@JsonKey(name: 'warehouses_id') // NOT warehouse_id
|
||||
final int? warehousesId;
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
```dart
|
||||
try {
|
||||
final result = await api.getEquipments();
|
||||
// Success path
|
||||
} on DioError catch (e) {
|
||||
if (e.response?.statusCode == 404) {
|
||||
// Handle not found
|
||||
} else {
|
||||
// Generic error
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Common Endpoints in Project
|
||||
```
|
||||
GET /equipment
|
||||
POST /equipment
|
||||
PUT /equipment/:id
|
||||
DELETE /equipment/:id
|
||||
|
||||
GET /equipment-history
|
||||
POST /equipment-history
|
||||
|
||||
GET /companies
|
||||
GET /warehouses
|
||||
GET /models
|
||||
GET /vendors
|
||||
```
|
||||
|
||||
---
|
||||
*Backend owns logic. Frontend just calls.*
|
||||
Reference in New Issue
Block a user