Skip to content

Commit ee2ad5d

Browse files
Merge pull request #339 from cardanoapi/feat/dbsync/proposal-apis
Update details query in proposal
2 parents 45013b4 + 458fb76 commit ee2ad5d

File tree

1 file changed

+226
-18
lines changed

1 file changed

+226
-18
lines changed

dbsync-api/src/repository/proposal.ts

Lines changed: 226 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,84 @@ export const fetchProposals = async (
1212
includeVoteCount?: boolean
1313
) => {
1414
const result = (await prisma.$queryRaw`
15-
WITH LatestDrepDistr AS (
15+
WITH LatestDrepDistr AS (
16+
SELECT
17+
*,
18+
ROW_NUMBER() OVER (PARTITION BY hash_id ORDER BY epoch_no DESC) AS rn
19+
FROM
20+
drep_distr
21+
),
22+
CommitteeData AS (
23+
SELECT DISTINCT ON (ch.raw)
24+
encode(ch.raw, 'hex') AS hash,
25+
cm.expiration_epoch,
26+
ch.has_script
27+
FROM
28+
committee_member cm
29+
JOIN committee_hash ch ON cm.committee_hash_id = ch.id
30+
ORDER BY
31+
ch.raw, cm.expiration_epoch DESC
32+
),
33+
ParsedDescription AS (
34+
SELECT
35+
gov_action_proposal.id,
36+
description->'tag' AS tag,
37+
description->'contents'->1 AS members_to_be_removed,
38+
description->'contents'->2 AS members,
39+
description->'contents'->3 AS threshold
40+
FROM
41+
gov_action_proposal
42+
WHERE
43+
gov_action_proposal.type = 'NewCommittee'
44+
),
45+
MembersToBeRemoved AS (
1646
SELECT
17-
*,
18-
ROW_NUMBER() OVER (PARTITION BY hash_id ORDER BY epoch_no DESC) AS rn
47+
id,
48+
json_agg(VALUE->>'keyHash') AS members_to_be_removed
1949
FROM
20-
drep_distr
21-
),
50+
ParsedDescription pd,
51+
json_array_elements(members_to_be_removed::json) AS value
52+
GROUP BY
53+
id
54+
),
55+
ProcessedCurrentMembers AS (
56+
SELECT
57+
pd.id,
58+
json_agg(
59+
json_build_object(
60+
'hash', regexp_replace(kv.key, '^keyHash-', ''),
61+
'newExpirationEpoch', kv.value::int
62+
)
63+
) AS current_members
64+
FROM
65+
ParsedDescription pd,
66+
jsonb_each_text(pd.members) AS kv(key, value)
67+
GROUP BY
68+
pd.id
69+
),
70+
EnrichedCurrentMembers AS (
71+
SELECT
72+
pcm.id,
73+
json_agg(
74+
json_build_object(
75+
'hash', cm.hash,
76+
'expirationEpoch', cm.expiration_epoch,
77+
'hasScript', cm.has_script,
78+
'newExpirationEpoch', (member->>'newExpirationEpoch')::int
79+
)
80+
) AS enriched_members
81+
FROM
82+
ProcessedCurrentMembers pcm
83+
LEFT JOIN json_array_elements(pcm.current_members) AS member ON true
84+
LEFT JOIN CommitteeData cm
85+
ON (CASE
86+
WHEN (member->>'hash') ~ '^[0-9a-fA-F]+$'
87+
THEN encode(decode(member->>'hash', 'hex'), 'hex')
88+
ELSE NULL
89+
END) = cm.hash
90+
GROUP BY
91+
pcm.id
92+
),
2293
EpochUtils AS (
2394
SELECT
2495
(Max(end_time) - Min(end_time)) /(Max(NO) - Min(NO)) AS epoch_duration,
@@ -54,18 +125,51 @@ SELECT
54125
'index', gov_action_proposal.index,
55126
'type', gov_action_proposal.type::text,
56127
'details', CASE
57-
when gov_action_proposal.type = 'TreasuryWithdrawals' then
58-
json_build_object('Reward Address', stake_address.view, 'Amount', treasury_withdrawal.amount)
59-
when gov_action_proposal.type::text = 'InfoAction' then
60-
json_build_object()
61-
when gov_action_proposal.type::text = 'HardForkInitiation' then
62-
json_build_object(
63-
'major', (gov_action_proposal.description->'contents'->1->>'major')::int,
64-
'minor', (gov_action_proposal.description->'contents'->1->>'minor')::int
65-
)
66-
ELSE
67-
null
68-
END,
128+
when gov_action_proposal.type = 'TreasuryWithdrawals' then
129+
json_build_object('Reward Address', stake_address.view, 'Amount', treasury_withdrawal.amount)
130+
when gov_action_proposal.type::text = 'InfoAction' then
131+
json_build_object('data', gov_action_proposal.description)
132+
when gov_action_proposal.type::text = 'HardForkInitiation' then
133+
json_build_object(
134+
'major', (gov_action_proposal.description->'contents'->1->>'major')::int,
135+
'minor', (gov_action_proposal.description->'contents'->1->>'minor')::int
136+
)
137+
WHEN gov_action_proposal.type::text = 'NoConfidence' THEN
138+
json_build_object('data', gov_action_proposal.description->'contents')
139+
WHEN gov_action_proposal.type::text = 'ParameterChange' THEN
140+
json_build_object('data', gov_action_proposal.description->'contents')
141+
WHEN gov_action_proposal.type::text = 'NewConstitution' THEN
142+
json_build_object(
143+
'anchor', gov_action_proposal.description->'contents'->1->'anchor',
144+
'script', gov_action_proposal.description->'contents'->1->'script'
145+
)
146+
WHEN gov_action_proposal.type::text = 'NewCommittee' THEN
147+
(
148+
SELECT
149+
json_build_object(
150+
'tag', pd.tag,
151+
'members', em.enriched_members,
152+
'membersToBeRemoved', mtr.members_to_be_removed,
153+
'threshold',
154+
CASE
155+
WHEN (pd.threshold->>'numerator') IS NOT NULL
156+
AND (pd.threshold->>'denominator') IS NOT NULL
157+
THEN (pd.threshold->>'numerator')::float / (pd.threshold->>'denominator')::float
158+
ELSE NULL
159+
END
160+
)
161+
FROM
162+
ParsedDescription pd
163+
JOIN
164+
MembersToBeRemoved mtr ON pd.id = mtr.id
165+
JOIN
166+
EnrichedCurrentMembers em ON pd.id = em.id
167+
WHERE
168+
pd.id = gov_action_proposal.id
169+
)
170+
ELSE
171+
null
172+
END,
69173
'status', CASE
70174
when gov_action_proposal.enacted_epoch is not NULL then json_build_object('enactedEpoch', gov_action_proposal.enacted_epoch)
71175
when gov_action_proposal.ratified_epoch is not NULL then json_build_object('ratifiedEpoch', gov_action_proposal.ratified_epoch)
@@ -885,6 +989,77 @@ export const fetchProposalById = async (proposalId: string, proposaIndex: number
885989
FROM
886990
drep_distr
887991
),
992+
CommitteeData AS (
993+
SELECT DISTINCT ON (ch.raw)
994+
encode(ch.raw, 'hex') AS hash,
995+
cm.expiration_epoch,
996+
ch.has_script
997+
FROM
998+
committee_member cm
999+
JOIN committee_hash ch ON cm.committee_hash_id = ch.id
1000+
ORDER BY
1001+
ch.raw, cm.expiration_epoch DESC
1002+
),
1003+
ParsedDescription AS (
1004+
SELECT
1005+
gov_action_proposal.id,
1006+
description->'tag' AS tag,
1007+
description->'contents'->1 AS members_to_be_removed,
1008+
description->'contents'->2 AS members,
1009+
description->'contents'->3 AS threshold
1010+
FROM
1011+
gov_action_proposal
1012+
WHERE
1013+
gov_action_proposal.type = 'NewCommittee'
1014+
),
1015+
MembersToBeRemoved AS (
1016+
SELECT
1017+
id,
1018+
json_agg(VALUE->>'keyHash') AS members_to_be_removed
1019+
FROM
1020+
ParsedDescription pd,
1021+
json_array_elements(members_to_be_removed::json) AS value
1022+
GROUP BY
1023+
id
1024+
),
1025+
ProcessedCurrentMembers AS (
1026+
SELECT
1027+
pd.id,
1028+
json_agg(
1029+
json_build_object(
1030+
'hash', regexp_replace(kv.key, '^keyHash-', ''),
1031+
'newExpirationEpoch', kv.value::int
1032+
)
1033+
) AS current_members
1034+
FROM
1035+
ParsedDescription pd,
1036+
jsonb_each_text(pd.members) AS kv(key, value)
1037+
GROUP BY
1038+
pd.id
1039+
),
1040+
EnrichedCurrentMembers AS (
1041+
SELECT
1042+
pcm.id,
1043+
json_agg(
1044+
json_build_object(
1045+
'hash', cm.hash,
1046+
'expirationEpoch', cm.expiration_epoch,
1047+
'hasScript', cm.has_script,
1048+
'newExpirationEpoch', (member->>'newExpirationEpoch')::int
1049+
)
1050+
) AS enriched_members
1051+
FROM
1052+
ProcessedCurrentMembers pcm
1053+
LEFT JOIN json_array_elements(pcm.current_members) AS member ON true
1054+
LEFT JOIN CommitteeData cm
1055+
ON (CASE
1056+
WHEN (member->>'hash') ~ '^[0-9a-fA-F]+$'
1057+
THEN encode(decode(member->>'hash', 'hex'), 'hex')
1058+
ELSE NULL
1059+
END) = cm.hash
1060+
GROUP BY
1061+
pcm.id
1062+
),
8881063
EpochUtils AS (
8891064
SELECT
8901065
(Max(end_time) - Min(end_time)) /(Max(NO) - Min(NO)) AS epoch_duration,
@@ -923,12 +1098,45 @@ export const fetchProposalById = async (proposalId: string, proposaIndex: number
9231098
when gov_action_proposal.type = 'TreasuryWithdrawals' then
9241099
json_build_object('Reward Address', stake_address.view, 'Amount', treasury_withdrawal.amount)
9251100
when gov_action_proposal.type::text = 'InfoAction' then
926-
json_build_object()
1101+
json_build_object('data', gov_action_proposal.description)
9271102
when gov_action_proposal.type::text = 'HardForkInitiation' then
9281103
json_build_object(
9291104
'major', (gov_action_proposal.description->'contents'->1->>'major')::int,
9301105
'minor', (gov_action_proposal.description->'contents'->1->>'minor')::int
9311106
)
1107+
WHEN gov_action_proposal.type::text = 'NoConfidence' THEN
1108+
json_build_object('data', gov_action_proposal.description->'contents')
1109+
WHEN gov_action_proposal.type::text = 'ParameterChange' THEN
1110+
json_build_object('data', gov_action_proposal.description->'contents')
1111+
WHEN gov_action_proposal.type::text = 'NewConstitution' THEN
1112+
json_build_object(
1113+
'anchor', gov_action_proposal.description->'contents'->1->'anchor',
1114+
'script', gov_action_proposal.description->'contents'->1->'script'
1115+
)
1116+
WHEN gov_action_proposal.type::text = 'NewCommittee' THEN
1117+
(
1118+
SELECT
1119+
json_build_object(
1120+
'tag', pd.tag,
1121+
'members', em.enriched_members,
1122+
'membersToBeRemoved', mtr.members_to_be_removed,
1123+
'threshold',
1124+
CASE
1125+
WHEN (pd.threshold->>'numerator') IS NOT NULL
1126+
AND (pd.threshold->>'denominator') IS NOT NULL
1127+
THEN (pd.threshold->>'numerator')::float / (pd.threshold->>'denominator')::float
1128+
ELSE NULL
1129+
END
1130+
)
1131+
FROM
1132+
ParsedDescription pd
1133+
JOIN
1134+
MembersToBeRemoved mtr ON pd.id = mtr.id
1135+
JOIN
1136+
EnrichedCurrentMembers em ON pd.id = em.id
1137+
WHERE
1138+
pd.id = gov_action_proposal.id
1139+
)
9321140
ELSE
9331141
null
9341142
END,

0 commit comments

Comments
 (0)