This query checks if active version questions are bound to enumerators that are missing. The is_enumerator_missing column will be true if the enumerator does not exist in the questions table.
selectv.idas versions_id,v.lifecycle_stageas versions_lifecycle_stage,q.idas questions_id,q.nameas question_name,q.question_type,q.enumerator_id,casewheneq.idisnullthen true else false endas is_enumerator_missingfrom questions as qinner join versions_questions as vqonvq.questions_id=q.idinner join versions as vonvq.versions_id=v.idleft join questions as eqonq.enumerator_id=eq.idwhereq.enumerator_idis not nullandeq.idisnullandv.lifecycle_stage='active'order byv.iddesc
Check Programs for Missing Questions
This query flattens out the program block_definitions json. The debug_notes column will provide a message describing problems that were found.
The query debug_notes currently checks if
questionDefinition points to a question that doesn't exist
questionDefinition enumerator points to a question that doesn't exist
hidePredicate points to a question that doesn't exist
with program_definitions as
(
select
v.id as versions_id,
v.lifecycle_stage as versions_lifecycle_stage,
p.id as programs_id,
p.name as programs_name,
cast(jsonb_array_elements(p.block_definitions)->>'id' as bigint) as block_definitions_id,
jsonb_array_elements(p.block_definitions)->>'name' as block_definitions_name,
cast(jsonb_array_elements(p.block_definitions)->>'repeaterId' as bigint) as block_definitions_repeaterId,
cast(jsonb_array_elements(p.block_definitions)->'hidePredicate'->'rootNode'->'node'->'questionId' as bigint) as hidePredicate_questionId,
cast(jsonb_array_elements(jsonb_array_elements(p.block_definitions)->'questionDefinitions')->>'id' as bigint) as questionDefinitions_id,
cast(jsonb_array_elements(jsonb_array_elements(p.block_definitions)->'questionDefinitions')->>'optional' as bool) as questionDefinitions_optional
--jsonb_array_elements(p.block_definitions)->'optionalPredicate' as optionalPredicate,
from programs as p
inner join versions_programs as vp
on p.id = vp.programs_id
inner join versions as v
on v.id = vp.versions_id
),
program_questions_expanded as
(
select
pd.versions_id,
pd.versions_lifecycle_stage,
pd.programs_id,
pd.programs_name,
-- Block Definition Questions
pd.block_definitions_id,
pd.block_definitions_name,
pd.block_definitions_repeaterId,
pd.questionDefinitions_id,
pd.questionDefinitions_optional,
qd.id as questions_id,
qd.name as questions_name,
qd.question_type,
case when pd.questionDefinitions_id is not null and qd.id is null
then concat('No question found for id "', pd.questionDefinitions_id, '". ')
else null
end as questionDefinitions_debug_notes,
-- Enumerator
qd.enumerator_id,
qe.name as enumerator_questions_name,
case when qd.enumerator_id is not null and qe.id is null
then concat('No question found for enumerator id "', qd.enumerator_id, '". ')
else null
end as questionDefinitions_enumerator_debug_notes,
-- HidePredicate
pd.hidePredicate_questionId,
qh.name as hidePredicate_name,
qh.question_type as hidePredicate_question_type,
case when pd.hidePredicate_questionId is not null and qh.id is null
then concat('No question found for hidePredicate question id "', pd.hidePredicate_questionId, '". ')
else null
end as hidePredicate_debug_notes
from program_definitions as pd
left join questions as qd
on qd.id = pd.questiondefinitions_id
left join questions as qe
on qe.id = qd.enumerator_id
left join questions as qh
on qh.id = pd.hidepredicate_questionid
)
select
versions_id,
versions_lifecycle_stage,
programs_id,
programs_name,
block_definitions_id,
block_definitions_name,
block_definitions_repeaterId,
questionDefinitions_id,
questionDefinitions_optional,
questions_id,
questions_name,
question_type,
enumerator_id,
enumerator_questions_name,
hidePredicate_questionId,
hidePredicate_name,
hidePredicate_question_type,
nullif(concat(
questionDefinitions_debug_notes,
questionDefinitions_enumerator_debug_notes,
hidePredicate_debug_notes
), '') as debug_notes
from program_questions_expanded
where versions_lifecycle_stage = 'active'
--and programs_name = 'Utility Discount Program - Extended'
order by versions_id desc, programs_name, block_definitions_id