Skip to content

Commit 3819ae0

Browse files
db: finalize DV function removal from distributions.sql
Why: - Clean up remaining fragments that caused syntax errors during schema init. Test plan: - yarn supabase migration:diff is_verified_computed_and_profile_lookup
1 parent ff91161 commit 3819ae0

File tree

9 files changed

+1143
-869
lines changed

9 files changed

+1143
-869
lines changed

packages/app/features/account/components/AccountHeader.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const ShareProfileDialog = lazy(() =>
3030
)
3131

3232
export const AccountHeader = memo<YStackProps>(function AccountHeader(props) {
33-
const { profile, distributionShares } = useUser()
33+
const { profile } = useUser()
3434
const [shareDialogOpen, setShareDialogOpen] = useState(false)
3535
const hoverStyles = useHoverStyles()
3636

@@ -54,11 +54,6 @@ export const AccountHeader = memo<YStackProps>(function AccountHeader(props) {
5454
[]
5555
)
5656

57-
const isVerified = useMemo(
58-
() => Boolean(distributionShares[0] && distributionShares[0].amount > 0n),
59-
[distributionShares]
60-
)
61-
6257
const handleSharePress = useCallback(async () => {
6358
if (!referralHref) return
6459

@@ -77,7 +72,7 @@ export const AccountHeader = memo<YStackProps>(function AccountHeader(props) {
7772

7873
// Verification status icon component
7974
const VerificationIcon = () => {
80-
if (isVerified) {
75+
if (profile?.is_verified) {
8176
return (
8277
<IconBadgeCheckSolid
8378
size={'$1.5'}
@@ -135,7 +130,7 @@ export const AccountHeader = memo<YStackProps>(function AccountHeader(props) {
135130
<Paragraph size={'$8'} fontWeight={600} numberOfLines={1}>
136131
{name || '---'}
137132
</Paragraph>
138-
{!isVerified ? (
133+
{!profile?.is_verified ? (
139134
<Tooltip placement={'bottom'} delay={0}>
140135
<Tooltip.Content
141136
enterStyle={{ x: 0, y: -5, opacity: 0, scale: 0.9 }}
@@ -168,7 +163,7 @@ export const AccountHeader = memo<YStackProps>(function AccountHeader(props) {
168163
</Tooltip.Content>
169164
<Tooltip.Trigger
170165
onPress={(e) => {
171-
if (isVerified) {
166+
if (profile?.is_verified) {
172167
return
173168
}
174169
e.preventDefault()

packages/app/utils/useUser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export const useUser = () => {
4646
const { data, error } = await supabase
4747
.from('profiles')
4848
.select(
49-
'*, tags(*), main_tag(*), links_in_bio(*), distribution_shares(*), canton_party_verifications(*)'
49+
'*, is_verified, tags(*), main_tag(*), links_in_bio(*), distribution_shares(*), canton_party_verifications(*)'
5050
)
5151
.eq('id', user?.id ?? '')
5252
.single()

supabase/config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ schema_paths = [
3838
"./schemas/distributions.sql",
3939
"./schemas/send_earn.sql",
4040
"./schemas/send_scores.sql",
41+
"./schemas/distribution_verifications.sql",
4142

4243
# Send account related tables
4344
"./schemas/send_account_created.sql",

supabase/database-generated.types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,6 +1734,7 @@ export type Database = {
17341734
chain_id: number | null
17351735
id: string | null
17361736
is_public: boolean | null
1737+
is_verified: boolean | null
17371738
links_in_bio:
17381739
| Database["public"]["Tables"]["link_in_bio"]["Row"][]
17391740
| null
@@ -2019,6 +2020,10 @@ export type Database = {
20192020
}
20202021
Returns: undefined
20212022
}
2023+
is_verified: {
2024+
Args: { p: Database["public"]["Tables"]["profiles"]["Row"] }
2025+
Returns: boolean
2026+
}
20222027
leaderboard_referrals_all_time: {
20232028
Args: Record<PropertyKey, never>
20242029
Returns: {

supabase/database.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export type Database = MergeDeep<
7373
main_tag: DatabaseGenerated['public']['Tables']['tags']['Row']
7474
links_in_bio: DatabaseGenerated['public']['Tables']['link_in_bio']['Row'][]
7575
distribution_shares: ProfileDistributionShares[]
76+
is_verified: boolean
7677
}
7778
}
7879
webauthn_credentials: {
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
set check_function_bodies = off;
2+
3+
CREATE OR REPLACE FUNCTION public.is_verified(p profiles)
4+
RETURNS boolean
5+
LANGUAGE sql
6+
STABLE SECURITY DEFINER
7+
SET search_path TO 'public'
8+
AS $function$
9+
SELECT COALESCE(
10+
(
11+
SELECT
12+
COALESCE(dv_sum.has_tag, false)
13+
AND COALESCE(dv_sum.has_hodler, false)
14+
AND COALESCE(e.has_earn, false)
15+
FROM (
16+
SELECT id, hodler_min_balance, earn_min_balance
17+
FROM distributions
18+
WHERE qualification_start <= (now() AT TIME ZONE 'UTC')
19+
AND qualification_end >= (now() AT TIME ZONE 'UTC')
20+
ORDER BY qualification_start DESC
21+
LIMIT 1
22+
) d
23+
-- Single pass over DV for tag + hodler checks
24+
LEFT JOIN LATERAL (
25+
SELECT
26+
(COUNT(*) FILTER (
27+
WHERE dv.type = 'tag_registration'::verification_type
28+
AND dv.weight > 0
29+
) > 0) AS has_tag,
30+
(COUNT(*) FILTER (
31+
WHERE dv.type = 'send_token_hodler'::verification_type
32+
AND dv.weight >= d.hodler_min_balance
33+
) > 0) AS has_hodler
34+
FROM distribution_verifications dv
35+
WHERE dv.user_id = p.id
36+
AND dv.distribution_id = d.id
37+
) dv_sum ON true
38+
-- Earn threshold check in the same SELECT, via a LATERAL EXISTS
39+
LEFT JOIN LATERAL (
40+
SELECT EXISTS (
41+
SELECT 1
42+
FROM send_earn_balances seb
43+
JOIN send_accounts sa
44+
ON decode(replace(sa.address::text, ('0x'::citext)::text, ''::text), 'hex') = seb.owner
45+
WHERE sa.user_id = p.id
46+
AND seb.assets >= d.earn_min_balance
47+
) AS has_earn
48+
) e ON true
49+
),
50+
false
51+
);
52+
$function$
53+
;
54+
55+
CREATE OR REPLACE FUNCTION public.profile_lookup(lookup_type lookup_type_enum, identifier text)
56+
RETURNS SETOF profile_lookup_result
57+
LANGUAGE plpgsql
58+
IMMUTABLE SECURITY DEFINER
59+
AS $function$
60+
begin
61+
if identifier is null or identifier = '' then raise exception 'identifier cannot be null or empty'; end if;
62+
if lookup_type is null then raise exception 'lookup_type cannot be null'; end if;
63+
64+
RETURN QUERY
65+
WITH current_distribution_id AS (
66+
SELECT id FROM distributions
67+
WHERE qualification_start <= CURRENT_TIMESTAMP AT TIME ZONE 'UTC'
68+
AND qualification_end >= CURRENT_TIMESTAMP AT TIME ZONE 'UTC'
69+
ORDER BY qualification_start DESC
70+
LIMIT 1
71+
)
72+
SELECT
73+
case when p.id = ( select auth.uid() ) then p.id end,
74+
p.avatar_url::text,
75+
p.name::text,
76+
p.about::text,
77+
p.referral_code,
78+
CASE WHEN p.is_public THEN p.x_username ELSE NULL END,
79+
CASE WHEN p.is_public THEN p.birthday ELSE NULL END,
80+
COALESCE(mt.name, t.name),
81+
sa.address,
82+
sa.chain_id,
83+
case when current_setting('role')::text = 'service_role' then p.is_public
84+
when p.is_public then true
85+
else false end,
86+
p.send_id,
87+
( select array_agg(t2.name::text)
88+
from tags t2
89+
join send_account_tags sat2 on sat2.tag_id = t2.id
90+
join send_accounts sa2 on sa2.id = sat2.send_account_id
91+
where sa2.user_id = p.id and t2.status = 'confirmed'::tag_status ),
92+
case when p.id = ( select auth.uid() ) then sa.main_tag_id end,
93+
mt.name::text,
94+
CASE WHEN p.is_public THEN
95+
(SELECT array_agg(link_in_bio_row)
96+
FROM (
97+
SELECT ROW(
98+
CASE WHEN lib.user_id = (SELECT auth.uid()) THEN lib.id ELSE NULL END,
99+
CASE WHEN lib.user_id = (SELECT auth.uid()) THEN lib.user_id ELSE NULL END,
100+
lib.handle,
101+
lib.domain_name,
102+
lib.created_at,
103+
lib.updated_at,
104+
lib.domain
105+
)::link_in_bio as link_in_bio_row
106+
FROM link_in_bio lib
107+
WHERE lib.user_id = p.id AND lib.handle IS NOT NULL
108+
) sub)
109+
ELSE NULL
110+
END,
111+
p.banner_url::text,
112+
public.is_verified(p) AS is_verified
113+
from profiles p
114+
join auth.users a on a.id = p.id
115+
left join send_accounts sa on sa.user_id = p.id
116+
left join tags mt on mt.id = sa.main_tag_id
117+
left join send_account_tags sat on sat.send_account_id = sa.id
118+
left join tags t on t.id = sat.tag_id and t.status = 'confirmed'::tag_status
119+
where ((lookup_type = 'sendid' and p.send_id::text = identifier) or
120+
(lookup_type = 'tag' and t.name = identifier::citext) or
121+
(lookup_type = 'refcode' and p.referral_code = identifier) or
122+
(lookup_type = 'address' and sa.address = identifier) or
123+
(p.is_public and lookup_type = 'phone' and a.phone::text = identifier))
124+
and (p.is_public
125+
or ( select auth.uid() ) is not null
126+
or current_setting('role')::text = 'service_role')
127+
limit 1;
128+
end;
129+
$function$
130+
;
131+
132+
create or replace view "public"."referrer" as WITH referrer AS (
133+
SELECT p.send_id
134+
FROM (referrals r
135+
JOIN profiles p ON ((r.referrer_id = p.id)))
136+
WHERE (r.referred_id = ( SELECT auth.uid() AS uid))
137+
ORDER BY r.created_at
138+
LIMIT 1
139+
), profile_lookup AS (
140+
SELECT p.id,
141+
p.avatar_url,
142+
p.name,
143+
p.about,
144+
p.refcode,
145+
p.x_username,
146+
p.birthday,
147+
p.tag,
148+
p.address,
149+
p.chain_id,
150+
p.is_public,
151+
p.sendid,
152+
p.all_tags,
153+
p.main_tag_id,
154+
p.main_tag_name,
155+
p.links_in_bio,
156+
p.banner_url,
157+
p.is_verified,
158+
referrer.send_id
159+
FROM (profile_lookup('sendid'::lookup_type_enum, ( SELECT (referrer_1.send_id)::text AS send_id
160+
FROM referrer referrer_1)) p(id, avatar_url, name, about, refcode, x_username, birthday, tag, address, chain_id, is_public, sendid, all_tags, main_tag_id, main_tag_name, links_in_bio, banner_url, is_verified)
161+
JOIN referrer ON ((referrer.send_id IS NOT NULL)))
162+
)
163+
SELECT profile_lookup.id,
164+
profile_lookup.avatar_url,
165+
profile_lookup.name,
166+
profile_lookup.about,
167+
profile_lookup.refcode,
168+
profile_lookup.x_username,
169+
profile_lookup.birthday,
170+
profile_lookup.tag,
171+
profile_lookup.address,
172+
profile_lookup.chain_id,
173+
profile_lookup.is_public,
174+
profile_lookup.sendid,
175+
profile_lookup.all_tags,
176+
profile_lookup.main_tag_id,
177+
profile_lookup.main_tag_name,
178+
profile_lookup.links_in_bio,
179+
profile_lookup.send_id,
180+
profile_lookup.banner_url,
181+
profile_lookup.is_verified
182+
FROM profile_lookup;
183+
184+
185+

0 commit comments

Comments
 (0)