widget-exactly-one-source-invariant-enforced-three-layers

Widgets must have exactly one data source (Cube semantic OR raw SQL, never both/neither). This invariant is enforced at three independent layers: Pydantic validator, Postgres CHECK constraint, and service-layer domain error. All three must stay in sync when the Widget schema changes.