Just in case it is useful for someone in the future, I ended up implementing:
- Start Date (normal Contentful date field, required)
- End Date (date field with an App extension)
For custom entry validation, I leveraged two additional fields:
- Field Validation (JSON field, disabled from editing and response)
- Validation (Boolean field with an App extension, required, disabled in response)
The End Date UI extension checks the Start Date and if it is greater than the End Date, it sets a property in the Field Validation JSON field for the field ID to false.
The Validation UI extension checks the JSON field for any property/field that is false and if any are, it sets its own value to null, and since it is a required field, it prevents the entry from being saved. This extension does not render an input, just a message indicating the validation status, and if invalid it lists the invalid fields.
Date validation: https://github.com/blakestein/contentful-date-validation
Entry validation: https://github.com/blakestein/contentful-entry-validation