Phase A: generierter Dart-Client + DI-Foundation für Rust-Backend

OpenAPI-Generator-Setup:
- tool/generate_api_client.sh: Direkter Aufruf der openapi-generator-cli.jar
  (Java-CLI statt Dart-build_runner-Integration — vermeidet die
  analyzer-/source_gen-Version-Hölle mit json_serializable)
- tool/fetch_openapi_generator.sh: lädt die JAR (29 MB) nach (gitignored)
- openapi/holzleitner.json: Snapshot der Backend-Spec für reproduzierbare
  Generation
- packages/holzleitner_api/: generiertes Dart-Sub-Package (built_value +
  dio), per path-dep im Haupt-pubspec eingehängt

Netzwerk-Layer (lib/data/network/):
- BackendConfig: API- und Keycloak-Endpoints für Local-Dev (localhost
  wegen Keycloak-iss-Claim).
- AuthTokenProvider-Schnittstelle.
- DevPasswordGrantTokenProvider: Phase-A-Provider via Keycloak
  password-grant, Token-Caching mit Expiry-Check (Phase B ersetzt das
  durch flutter_appauth PKCE).
- HolzleitnerAuthInterceptor: dynamischer Bearer-Inject pro Request.
- HolzleitnerApiFactory: baut die generierte HolzleitnerApi-Klasse
  mit unserem Interceptor statt der vier Default-Auth-Interceptors.
- network_locator.registerNetworking(): get_it-Setup, in main() vor
  runApp() aufgerufen.

Clean-Arch-Scaffolding (lib/data/, lib/domain/):
- Verzeichnisstruktur für Phase C+D angelegt (mapper/, repository/,
  entity/, repository/) — befüllt sich in den Folge-Phasen.

Smoke-Test:
- tool/smoke_test_api.dart ruft /health (ungeschützt) und /me/cars
  (mit Bearer) via generiertem Client — grün gegen lokales Backend.
This commit is contained in:
Dennis Nemec
2026-05-14 22:44:51 +02:00
parent 456fb59668
commit 8cf4045e44
222 changed files with 19350 additions and 0 deletions

View File

@ -0,0 +1,103 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
import 'dart:async';
import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:dio/dio.dart';
import 'package:holzleitner_api/src/api_util.dart';
import 'package:holzleitner_api/src/model/account.dart';
class AccountsApi {
final Dio _dio;
final Serializers _serializers;
const AccountsApi(this._dio, this._serializers);
/// Liest den Account zu einer Personalnummer.
///
///
/// Parameters:
/// * [personalnummer] - Personalnummer des Accounts
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [Account] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<Account>> getAccount({
required int personalnummer,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/accounts/{personalnummer}'.replaceAll('{' r'personalnummer' '}', encodeQueryParameter(_serializers, personalnummer, const FullType(int)).toString());
final _options = Options(
method: r'GET',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
validateStatus: validateStatus,
);
final _response = await _dio.request<Object>(
_path,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
Account? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(Account),
) as Account;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<Account>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
}

View File

@ -0,0 +1,315 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
import 'dart:async';
import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:dio/dio.dart';
import 'package:holzleitner_api/src/api_util.dart';
import 'package:holzleitner_api/src/model/car_response.dart';
import 'package:holzleitner_api/src/model/cars_list.dart';
import 'package:holzleitner_api/src/model/create_car_request.dart';
import 'package:holzleitner_api/src/model/update_car_request.dart';
class CarsApi {
final Dio _dio;
final Serializers _serializers;
const CarsApi(this._dio, this._serializers);
/// Legt ein neues Fahrzeug für den angemeldeten Fahrer an.
///
///
/// Parameters:
/// * [createCarRequest]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [CarResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<CarResponse>> createMyCar({
required CreateCarRequest createCarRequest,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/me/cars';
final _options = Options(
method: r'POST',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
contentType: 'application/json',
validateStatus: validateStatus,
);
dynamic _bodyData;
try {
const _type = FullType(CreateCarRequest);
_bodyData = _serializers.serialize(createCarRequest, specifiedType: _type);
} catch(error, stackTrace) {
throw DioException(
requestOptions: _options.compose(
_dio.options,
_path,
),
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
final _response = await _dio.request<Object>(
_path,
data: _bodyData,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
CarResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(CarResponse),
) as CarResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<CarResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
/// Listet die Fahrzeuge des angemeldeten Fahrers.
///
///
/// Parameters:
/// * [includeInactive] - Wenn true, werden inaktive Fahrzeuge mitgeliefert (default: false)
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [CarsList] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<CarsList>> listMyCars({
bool? includeInactive,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/me/cars';
final _options = Options(
method: r'GET',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
validateStatus: validateStatus,
);
final _queryParameters = <String, dynamic>{
if (includeInactive != null) r'includeInactive': encodeQueryParameter(_serializers, includeInactive, const FullType(bool)),
};
final _response = await _dio.request<Object>(
_path,
options: _options,
queryParameters: _queryParameters,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
CarsList? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(CarsList),
) as CarsList;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<CarsList>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
/// Aktualisiert ein Fahrzeug (Kennzeichen ändern / deaktivieren).
///
///
/// Parameters:
/// * [carId]
/// * [updateCarRequest]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [CarResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<CarResponse>> updateMyCar({
required String carId,
required UpdateCarRequest updateCarRequest,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/me/cars/{car_id}'.replaceAll('{' r'car_id' '}', encodeQueryParameter(_serializers, carId, const FullType(String)).toString());
final _options = Options(
method: r'PATCH',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
contentType: 'application/json',
validateStatus: validateStatus,
);
dynamic _bodyData;
try {
const _type = FullType(UpdateCarRequest);
_bodyData = _serializers.serialize(updateCarRequest, specifiedType: _type);
} catch(error, stackTrace) {
throw DioException(
requestOptions: _options.compose(
_dio.options,
_path,
),
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
final _response = await _dio.request<Object>(
_path,
data: _bodyData,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
CarResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(CarResponse),
) as CarResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<CarResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
}

View File

@ -0,0 +1,601 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
import 'dart:async';
import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:dio/dio.dart';
import 'package:holzleitner_api/src/api_util.dart';
import 'package:holzleitner_api/src/model/assign_car_request.dart';
import 'package:holzleitner_api/src/model/cancel_delivery_request.dart';
import 'package:holzleitner_api/src/model/create_delivery_note_request.dart';
import 'package:holzleitner_api/src/model/delivery_note_response.dart';
import 'package:holzleitner_api/src/model/delivery_response.dart';
import 'package:holzleitner_api/src/model/hold_delivery_request.dart';
class DeliveriesApi {
final Dio _dio;
final Serializers _serializers;
const DeliveriesApi(this._dio, this._serializers);
/// Setzt das &#x60;assigned_car_id&#x60; einer Lieferung. &#x60;carId: null&#x60; löst die Zuordnung wieder. Der Use Case stellt sicher, dass das Fahrzeug zum angemeldeten Account gehört.
///
///
/// Parameters:
/// * [deliveryId]
/// * [assignCarRequest]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [DeliveryResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<DeliveryResponse>> assignCar({
required String deliveryId,
required AssignCarRequest assignCarRequest,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/deliveries/{delivery_id}/assigned-car'.replaceAll('{' r'delivery_id' '}', encodeQueryParameter(_serializers, deliveryId, const FullType(String)).toString());
final _options = Options(
method: r'PUT',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
contentType: 'application/json',
validateStatus: validateStatus,
);
dynamic _bodyData;
try {
const _type = FullType(AssignCarRequest);
_bodyData = _serializers.serialize(assignCarRequest, specifiedType: _type);
} catch(error, stackTrace) {
throw DioException(
requestOptions: _options.compose(
_dio.options,
_path,
),
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
final _response = await _dio.request<Object>(
_path,
data: _bodyData,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
DeliveryResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(DeliveryResponse),
) as DeliveryResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<DeliveryResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
/// Setzt die Lieferung auf &#x60;canceled&#x60; — endgültig. Erlaubt aus &#x60;active&#x60; und &#x60;held&#x60;.
///
///
/// Parameters:
/// * [deliveryId]
/// * [cancelDeliveryRequest]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [DeliveryResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<DeliveryResponse>> cancel({
required String deliveryId,
required CancelDeliveryRequest cancelDeliveryRequest,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/deliveries/{delivery_id}/cancel'.replaceAll('{' r'delivery_id' '}', encodeQueryParameter(_serializers, deliveryId, const FullType(String)).toString());
final _options = Options(
method: r'POST',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
contentType: 'application/json',
validateStatus: validateStatus,
);
dynamic _bodyData;
try {
const _type = FullType(CancelDeliveryRequest);
_bodyData = _serializers.serialize(cancelDeliveryRequest, specifiedType: _type);
} catch(error, stackTrace) {
throw DioException(
requestOptions: _options.compose(
_dio.options,
_path,
),
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
final _response = await _dio.request<Object>(
_path,
data: _bodyData,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
DeliveryResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(DeliveryResponse),
) as DeliveryResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<DeliveryResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
/// Schließt die Lieferung ab — &#x60;state &#x3D; completed&#x60;. Nur aus &#x60;active&#x60;.
///
///
/// Parameters:
/// * [deliveryId]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [DeliveryResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<DeliveryResponse>> complete({
required String deliveryId,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/deliveries/{delivery_id}/complete'.replaceAll('{' r'delivery_id' '}', encodeQueryParameter(_serializers, deliveryId, const FullType(String)).toString());
final _options = Options(
method: r'POST',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
validateStatus: validateStatus,
);
final _response = await _dio.request<Object>(
_path,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
DeliveryResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(DeliveryResponse),
) as DeliveryResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<DeliveryResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
/// Legt eine neue Notiz an einer Lieferung an. Mindestens eines von &#x60;text&#x60; und &#x60;imageAttachment&#x60; muss inhaltlich gefüllt sein (Leerstrings werden serverseitig getrimmt und als leer behandelt).
///
///
/// Parameters:
/// * [deliveryId]
/// * [createDeliveryNoteRequest]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [DeliveryNoteResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<DeliveryNoteResponse>> createNote({
required String deliveryId,
required CreateDeliveryNoteRequest createDeliveryNoteRequest,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/deliveries/{delivery_id}/notes'.replaceAll('{' r'delivery_id' '}', encodeQueryParameter(_serializers, deliveryId, const FullType(String)).toString());
final _options = Options(
method: r'POST',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
contentType: 'application/json',
validateStatus: validateStatus,
);
dynamic _bodyData;
try {
const _type = FullType(CreateDeliveryNoteRequest);
_bodyData = _serializers.serialize(createDeliveryNoteRequest, specifiedType: _type);
} catch(error, stackTrace) {
throw DioException(
requestOptions: _options.compose(
_dio.options,
_path,
),
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
final _response = await _dio.request<Object>(
_path,
data: _bodyData,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
DeliveryNoteResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(DeliveryNoteResponse),
) as DeliveryNoteResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<DeliveryNoteResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
/// Setzt die Lieferung auf &#x60;held&#x60;. Nur aus &#x60;active&#x60; zulässig.
///
///
/// Parameters:
/// * [deliveryId]
/// * [holdDeliveryRequest]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [DeliveryResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<DeliveryResponse>> hold({
required String deliveryId,
required HoldDeliveryRequest holdDeliveryRequest,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/deliveries/{delivery_id}/hold'.replaceAll('{' r'delivery_id' '}', encodeQueryParameter(_serializers, deliveryId, const FullType(String)).toString());
final _options = Options(
method: r'POST',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
contentType: 'application/json',
validateStatus: validateStatus,
);
dynamic _bodyData;
try {
const _type = FullType(HoldDeliveryRequest);
_bodyData = _serializers.serialize(holdDeliveryRequest, specifiedType: _type);
} catch(error, stackTrace) {
throw DioException(
requestOptions: _options.compose(
_dio.options,
_path,
),
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
final _response = await _dio.request<Object>(
_path,
data: _bodyData,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
DeliveryResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(DeliveryResponse),
) as DeliveryResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<DeliveryResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
/// Setzt die Lieferung zurück auf &#x60;active&#x60;. Nur aus &#x60;held&#x60; zulässig.
///
///
/// Parameters:
/// * [deliveryId]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [DeliveryResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<DeliveryResponse>> resume({
required String deliveryId,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/deliveries/{delivery_id}/resume'.replaceAll('{' r'delivery_id' '}', encodeQueryParameter(_serializers, deliveryId, const FullType(String)).toString());
final _options = Options(
method: r'POST',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
validateStatus: validateStatus,
);
final _response = await _dio.request<Object>(
_path,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
DeliveryResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(DeliveryResponse),
) as DeliveryResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<DeliveryResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
}

View File

@ -0,0 +1,90 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
import 'dart:async';
import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:dio/dio.dart';
class HealthApi {
final Dio _dio;
final Serializers _serializers;
const HealthApi(this._dio, this._serializers);
/// Health-Endpoint für Load-Balancer und Container-Probes. Bewusst kein Auth — eine &#x60;200 ok&#x60;-Antwort darf nicht von der Auth abhängen.
///
///
/// Parameters:
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [String] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<String>> health({
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/health';
final _options = Options(
method: r'GET',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[],
...?extra,
},
validateStatus: validateStatus,
);
final _response = await _dio.request<Object>(
_path,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
String? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : rawResponse as String;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<String>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
}

View File

@ -0,0 +1,123 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
import 'dart:async';
import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:dio/dio.dart';
import 'package:holzleitner_api/src/model/apply_scans_request.dart';
import 'package:holzleitner_api/src/model/apply_scans_response.dart';
class ScansApi {
final Dio _dio;
final Serializers _serializers;
const ScansApi(this._dio, this._serializers);
/// Wendet eine Liste von Scan-Events idempotent an.
/// Pro Event ein eigenes Resultat. Status &#x60;applied&#x60; schreibt einen frischen Audit-Eintrag, &#x60;duplicate&#x60; liefert den aktuellen Stand am Server, &#x60;rejected&#x60; enthält die Begründung. Reihenfolge der &#x60;results&#x60; entspricht der Reihenfolge der &#x60;scans&#x60; im Request.
///
/// Parameters:
/// * [applyScansRequest]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [ApplyScansResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<ApplyScansResponse>> applyScans({
required ApplyScansRequest applyScansRequest,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/scans';
final _options = Options(
method: r'POST',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
contentType: 'application/json',
validateStatus: validateStatus,
);
dynamic _bodyData;
try {
const _type = FullType(ApplyScansRequest);
_bodyData = _serializers.serialize(applyScansRequest, specifiedType: _type);
} catch(error, stackTrace) {
throw DioException(
requestOptions: _options.compose(
_dio.options,
_path,
),
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
final _response = await _dio.request<Object>(
_path,
data: _bodyData,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
ApplyScansResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(ApplyScansResponse),
) as ApplyScansResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<ApplyScansResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
}

View File

@ -0,0 +1,123 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
import 'dart:async';
import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:dio/dio.dart';
import 'package:holzleitner_api/src/model/sync_tour_request.dart';
import 'package:holzleitner_api/src/model/sync_tour_response.dart';
class SyncApi {
final Dio _dio;
final Serializers _serializers;
const SyncApi(this._dio, this._serializers);
/// Sync-Endpoint für das ERP: legt eine Tagestour samt Lieferungen und Positionen idempotent an. Identität pro Tour &#x60;(driver_personalnummer, tour_date)&#x60;, pro Lieferung &#x60;(belegart_id, belegnummer)&#x60;.
///
///
/// Parameters:
/// * [syncTourRequest]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [SyncTourResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<SyncTourResponse>> syncTour({
required SyncTourRequest syncTourRequest,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/sync/tour';
final _options = Options(
method: r'POST',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
contentType: 'application/json',
validateStatus: validateStatus,
);
dynamic _bodyData;
try {
const _type = FullType(SyncTourRequest);
_bodyData = _serializers.serialize(syncTourRequest, specifiedType: _type);
} catch(error, stackTrace) {
throw DioException(
requestOptions: _options.compose(
_dio.options,
_path,
),
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
final _response = await _dio.request<Object>(
_path,
data: _bodyData,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
SyncTourResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(SyncTourResponse),
) as SyncTourResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<SyncTourResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
}

View File

@ -0,0 +1,288 @@
//
// AUTO-GENERATED FILE, DO NOT MODIFY!
//
import 'dart:async';
import 'package:built_value/json_object.dart';
import 'package:built_value/serializer.dart';
import 'package:dio/dio.dart';
import 'package:holzleitner_api/src/api_util.dart';
import 'package:holzleitner_api/src/model/set_delivery_order_request.dart';
import 'package:holzleitner_api/src/model/set_delivery_order_response.dart';
import 'package:holzleitner_api/src/model/tour_details.dart';
import 'package:holzleitner_api/src/model/tour_summary_list.dart';
class ToursApi {
final Dio _dio;
final Serializers _serializers;
const ToursApi(this._dio, this._serializers);
/// Lädt eine Tour mit allen Lieferungen, Positionen und referenzierten Stammdaten — die App nutzt das als einzigen großen Read.
///
///
/// Parameters:
/// * [tourId] - Eindeutige Tour-Id (UUID)
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [TourDetails] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<TourDetails>> getTour({
required String tourId,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/tours/{tour_id}'.replaceAll('{' r'tour_id' '}', encodeQueryParameter(_serializers, tourId, const FullType(String)).toString());
final _options = Options(
method: r'GET',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
validateStatus: validateStatus,
);
final _response = await _dio.request<Object>(
_path,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
TourDetails? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(TourDetails),
) as TourDetails;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<TourDetails>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
/// Listet heutige Touren des angemeldeten Fahrers (Filter aus dem JWT).
///
///
/// Parameters:
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [TourSummaryList] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<TourSummaryList>> listMyToursToday({
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/me/tours/today';
final _options = Options(
method: r'GET',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
validateStatus: validateStatus,
);
final _response = await _dio.request<Object>(
_path,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
TourSummaryList? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(TourSummaryList),
) as TourSummaryList;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<TourSummaryList>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
/// Schreibt die Sortier-Reihenfolge aller Lieferungen einer Tour neu. Der Client schickt die **vollständige** neue Reihenfolge; fehlende oder fremde Lieferungs-Ids werden mit &#x60;400 validation&#x60; abgelehnt.
///
///
/// Parameters:
/// * [tourId]
/// * [setDeliveryOrderRequest]
/// * [cancelToken] - A [CancelToken] that can be used to cancel the operation
/// * [headers] - Can be used to add additional headers to the request
/// * [extras] - Can be used to add flags to the request
/// * [validateStatus] - A [ValidateStatus] callback that can be used to determine request success based on the HTTP status of the response
/// * [onSendProgress] - A [ProgressCallback] that can be used to get the send progress
/// * [onReceiveProgress] - A [ProgressCallback] that can be used to get the receive progress
///
/// Returns a [Future] containing a [Response] with a [SetDeliveryOrderResponse] as data
/// Throws [DioException] if API call or serialization fails
Future<Response<SetDeliveryOrderResponse>> setDeliveryOrder({
required String tourId,
required SetDeliveryOrderRequest setDeliveryOrderRequest,
CancelToken? cancelToken,
Map<String, dynamic>? headers,
Map<String, dynamic>? extra,
ValidateStatus? validateStatus,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
final _path = r'/tours/{tour_id}/delivery-order'.replaceAll('{' r'tour_id' '}', encodeQueryParameter(_serializers, tourId, const FullType(String)).toString());
final _options = Options(
method: r'PUT',
headers: <String, dynamic>{
...?headers,
},
extra: <String, dynamic>{
'secure': <Map<String, String>>[
{
'type': 'http',
'scheme': 'bearer',
'name': 'bearer_auth',
},
],
...?extra,
},
contentType: 'application/json',
validateStatus: validateStatus,
);
dynamic _bodyData;
try {
const _type = FullType(SetDeliveryOrderRequest);
_bodyData = _serializers.serialize(setDeliveryOrderRequest, specifiedType: _type);
} catch(error, stackTrace) {
throw DioException(
requestOptions: _options.compose(
_dio.options,
_path,
),
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
final _response = await _dio.request<Object>(
_path,
data: _bodyData,
options: _options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress,
);
SetDeliveryOrderResponse? _responseData;
try {
final rawResponse = _response.data;
_responseData = rawResponse == null ? null : _serializers.deserialize(
rawResponse,
specifiedType: const FullType(SetDeliveryOrderResponse),
) as SetDeliveryOrderResponse;
} catch (error, stackTrace) {
throw DioException(
requestOptions: _response.requestOptions,
response: _response,
type: DioExceptionType.unknown,
error: error,
stackTrace: stackTrace,
);
}
return Response<SetDeliveryOrderResponse>(
data: _responseData,
headers: _response.headers,
isRedirect: _response.isRedirect,
requestOptions: _response.requestOptions,
redirects: _response.redirects,
statusCode: _response.statusCode,
statusMessage: _response.statusMessage,
extra: _response.extra,
);
}
}