El enfoque de Zod como fuente única para validaciones y constraints es sólido, pero cuidado: no todas las reglas de negocio son expresables en un schema de Zod. Las que dependen de estado (ej. 'un pedido no puede modificarse si ya está enviado') requieren lógica en el servicio o en triggers. Si intentas forzarlas en Zod acabarás con validaciones incompletas o duplicadas de forma caótica.
Además, generar constraints desde Zod solo cubre checks simples (tipos, rangos, regex). Las reglas que involucran múltiples tablas o agregados (ej. stock disponible) no las puedes poner en un CHECK, necesitas transacciones y bloqueos en el servicio. Ahí es donde el ORM como cajón de sastre se queda corto y acabas metiendo lógica en la BD de todas formas, pero sin control.
Mi recomendación: Zod para validación de entrada y constraints básicas, triggers solo para auditoría, y toda la lógica de negocio con estado en la capa de servicio. Si el rendimiento duele, usa SELECT ... FOR UPDATE o caché distribuida, pero no sacrifiques la mantenibilidad.