Joi validation - how to require or optional field based on another key exists in array?

You can to use Joi.when() and create a schema like this:

Joi.object().keys({
    contact: Joi.object().keys({
        first_name: Joi.string(),
        last_name: Joi.string(),
        phone: Joi.string(),
    }),
    address: Joi.object().keys({
        place: Joi.string(),
        city: Joi.string().min(2).max(30),
        street: Joi.string(),
        house_number: Joi.string()
    }).when('contact', {
        is: Joi.object().keys({
            first_name: Joi.exist(),
            last_name: Joi.exist(),
            phone: Joi.exist(),
        }),
        then: Joi.object({ place: Joi.required() }).required(),
        otherwise: Joi.object({ place: Joi.forbidden() })
    }),
    passengers_amount: Joi.number(),
    notes: Joi.string()
});

I just simplified your shema so it's easy to understand.

Basically, what we are saying here is, if contact.first_name, contact.last_name and contact.phone exists, then address and address.place are required, otherwise address.place is forbidden.

For instance, this object will fail, because address does not exist:

{
    address: {
        first_name: 'a',
        last_name: 'b',
        phone: 'c'
    }
}

and this will fail because address.place does not exist:

{
    address: {
        first_name: 'a',
        last_name: 'b',
        phone: 'c'
    },
    contact: {
    }
}

Finally, according with the schema defined, this object will pass:

{
    address: {
        first_name: 'a',
        last_name: 'b',
        phone: 'c'
    },
    contact: {
        place: 'd'
    }
};