Files
superport/.claude/agents/api-patterns.md
JiWoong Sul 655d473413
Some checks failed
Flutter Test & Quality Check / Test on macos-latest (push) Has been cancelled
Flutter Test & Quality Check / Test on ubuntu-latest (push) Has been cancelled
Flutter Test & Quality Check / Build APK (push) Has been cancelled
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
2025-09-08 17:39:00 +09:00

1.8 KiB

Superport API Patterns v8.0

What This Really Is

Backend API patterns specific to this project. Just code to copy.

Rust Backend Endpoints

// 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

// 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

// 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

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.