Implementation Log: US-11 Consistent Mutation Responses
Feature: US-11 Consistent Mutation Responses
Summary
US-11 aligned the GraphQL mutation boundary with the existing application-level validation model. startUpload, startUploadBatch, and completeUpload now accept omitted or null input values at the schema boundary so routine validation failures can be returned in payload userErrors instead of surfacing as GraphQL transport errors. The change preserves the existing success payload shapes and keeps the byte-count contract explicit via the ByteCount scalar.
Implementation Details
- Relaxed the mutation argument and input-field nullability in the GraphQL schema so the resolvers and application services can return friendly user errors for missing input instead of failing during GraphQL argument coercion.
-- Kept the
ByteCountschema type forstartUpload.fileSizeBytesto preserve the public contract. -- Changed the scalar input coercion path soByteCountnow passes string and integer values through to resolver-level validation instead of rejecting malformed byte-count strings at the transport boundary. - Reused the existing resolver and service validation paths instead of duplicating business rules in the HTTP or GraphQL handler layers.
- Added focused GraphQL handler coverage for invalid
startUploadinput, omittedstartUploadBatchinput, and omittedcompleteUploadinput to prove the payload-level error contract across every mutation. - Updated the public API reference to explain that these mutation inputs remain business-required even though the schema is intentionally permissive to support payload-level validation, and completed the missing
startUploadBatchcontract section with per-file semantics and error codes.
Files Changed
src/GraphQL/Schema/schema.graphql- made mutation arguments and their input fields nullable so invalid requests reach payload-level validation.src/GraphQL/SchemaFactory.php- relaxedByteCountinput coercion while preserving strict output serialization.tests/Unit/Http/GraphQLHandlerTest.php- added invalid-input coverage for all three mutations through the local GraphQL handler.docs/api/01-agree-api-schema.md- documented the intentionally permissive mutation input boundary, updated the published mutation signatures, and added the missingstartUploadBatchreference section.mkdocs.yml- added the US-11 implementation log to the documentation navigation.
Validation
- Editor diagnostics on
tests/Unit/Http/GraphQLHandlerTest.phpandsrc/GraphQL/SchemaFactory.php- no errors. php -d opcache.jit=0 vendor/bin/phpunit --configuration phpunit.xml --filter 'itReturnsPayloadLevelUserErrorsWhenStartUploadInputFailsValidation|itReturnsPayloadLevelUserErrorsWhenStartUploadBatchOmitsInput|itReturnsPayloadLevelUserErrorsWhenCompleteUploadOmitsInput' tests/Unit/Http/GraphQLHandlerTest.php- assertions passed; PHPUnit reported only the existing missing code coverage driver warning.php -d opcache.jit=0 vendor/bin/phpunit --configuration phpunit.xml tests/Unit/Http/GraphQLHandlerTest.php- passed with 25 tests and 184 assertions; PHPUnit reported only the existing missing code coverage driver warning.php -d opcache.jit=0 vendor/bin/phpunit --configuration phpunit.xml --testsuite=unit- passed with 227 tests and 1046 assertions; PHPUnit reported only the existing missing code coverage driver warning.php -d opcache.jit=0 vendor/bin/phpstan analyse -c phpstan.neon --no-progress- passed with no errors.
Delivery Chunks
- Mutation schema boundary - relaxed mutation input coercion so routine validation no longer escapes as transport-level GraphQL errors.
- Scalar contract preservation - kept
ByteCountas the public type while moving malformed-value handling into the payload validation path. - Contract verification - added end-to-end GraphQL handler coverage for invalid input across every mutation.