Skip to content

Commit 9a926df

Browse files
authored
Add is hidden (#752)
1 parent 86a360d commit 9a926df

6 files changed

Lines changed: 190 additions & 19 deletions

File tree

api/dbv1/full_comments.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type FullComment struct {
3131
IsCurrentUserReacted bool `json:"is_current_user_reacted"`
3232
IsArtistReacted bool `json:"is_artist_reacted"`
3333
IsDelete bool `json:"-"`
34+
IsMembersOnly bool `json:"is_members_only"`
3435
IsTombstone bool `json:"is_tombstone"`
3536
ReactCount int `json:"react_count"`
3637
CreatedAt time.Time `json:"created_at"`
@@ -108,6 +109,7 @@ func (q *Queries) FullCommentsKeyed(ctx context.Context, arg GetCommentsParams)
108109
) AS is_artist_reacted,
109110
110111
comments.is_delete,
112+
comments.is_members_only,
111113
112114
coalesce((
113115
SELECT is_muted

api/dbv1/models.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1_fan_club_feed.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ func fanClubRedactCommentMessageMap(m map[string]any) {
193193
}
194194

195195
func fanClubCommentForFeedJSON(co dbv1.FullComment, reveal bool) (any, error) {
196-
if reveal {
196+
if reveal || !co.IsMembersOnly {
197197
return co, nil
198198
}
199199
b, err := json.Marshal(co)

api/v1_fan_club_feed_test.go

Lines changed: 172 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,13 @@ func TestFanClubFeed_IncludesTextPostWhenCommentRowPresent(t *testing.T) {
220220
app := emptyTestApp(t)
221221

222222
commentRow := map[string]any{
223-
"comment_id": 910,
224-
"user_id": 2,
225-
"entity_id": 1,
226-
"entity_type": "FanClub",
227-
"text": "hello fan club",
228-
"created_at": "2020-06-01 00:00:00",
223+
"comment_id": 910,
224+
"user_id": 2,
225+
"entity_id": 1,
226+
"entity_type": "FanClub",
227+
"text": "hello fan club",
228+
"is_members_only": true,
229+
"created_at": "2020-06-01 00:00:00",
229230
}
230231

231232
database.Seed(app.pool.Replicas[0], database.FixtureMap{
@@ -318,12 +319,13 @@ func TestFanClubFeed_FanWithoutBalanceGetsFeedWithRedactedText(t *testing.T) {
318319
},
319320
"comments": []map[string]any{
320321
{
321-
"comment_id": 920,
322-
"user_id": 2,
323-
"entity_id": 1,
324-
"entity_type": "FanClub",
325-
"text": "secret post",
326-
"created_at": "2020-06-01 00:00:00",
322+
"comment_id": 920,
323+
"user_id": 2,
324+
"entity_id": 1,
325+
"entity_type": "FanClub",
326+
"text": "secret post",
327+
"is_members_only": true,
328+
"created_at": "2020-06-01 00:00:00",
327329
},
328330
},
329331
})
@@ -342,6 +344,157 @@ func TestFanClubFeed_FanWithoutBalanceGetsFeedWithRedactedText(t *testing.T) {
342344
})
343345
}
344346

347+
func TestFanClubFeed_PublicPostVisibleToNonHolder(t *testing.T) {
348+
app := emptyTestApp(t)
349+
database.Seed(app.pool.Replicas[0], database.FixtureMap{
350+
"users": testFanClubFeedBaseUsers(),
351+
"artist_coins": {
352+
{
353+
"user_id": 1,
354+
"mint": testFanClubFeedMint,
355+
"decimals": 6,
356+
"ticker": "FCT",
357+
},
358+
},
359+
"sol_user_balances": {
360+
{
361+
"user_id": 2,
362+
"mint": testFanClubFeedMint,
363+
"balance": int64(1), // not enough to reveal members-only
364+
},
365+
},
366+
"comments": []map[string]any{
367+
{
368+
"comment_id": 940,
369+
"user_id": 1,
370+
"entity_id": 1,
371+
"entity_type": "FanClub",
372+
"text": "public announcement",
373+
"is_members_only": false,
374+
"created_at": "2020-06-01 00:00:00",
375+
},
376+
},
377+
})
378+
379+
path := testFanClubFeedURL(2, "sort_method=newest")
380+
status, body := testGetWithWallet(t, app, path, "0xc3d1d41e6872ffbd15c473d14fc3a9250be5b5e0")
381+
require.Equal(t, 200, status, string(body))
382+
383+
enc940, err := trashid.EncodeHashId(940)
384+
require.NoError(t, err)
385+
386+
// Non-holder can still see the message because is_members_only=false
387+
jsonAssert(t, body, map[string]any{
388+
"data.#": 1,
389+
"data.0.item_type": "text_post",
390+
"data.0.comment.message": "public announcement",
391+
"data.0.comment.id": enc940,
392+
"data.0.comment.is_members_only": false,
393+
})
394+
}
395+
396+
func TestFanClubFeed_MembersOnlyPostRedactedForNonHolder(t *testing.T) {
397+
app := emptyTestApp(t)
398+
database.Seed(app.pool.Replicas[0], database.FixtureMap{
399+
"users": testFanClubFeedBaseUsers(),
400+
"artist_coins": {
401+
{
402+
"user_id": 1,
403+
"mint": testFanClubFeedMint,
404+
"decimals": 6,
405+
"ticker": "FCT",
406+
},
407+
},
408+
"sol_user_balances": {
409+
{
410+
"user_id": 2,
411+
"mint": testFanClubFeedMint,
412+
"balance": int64(1), // not enough
413+
},
414+
},
415+
"comments": []map[string]any{
416+
{
417+
"comment_id": 941,
418+
"user_id": 1,
419+
"entity_id": 1,
420+
"entity_type": "FanClub",
421+
"text": "secret vip post",
422+
"is_members_only": true,
423+
"created_at": "2020-06-01 00:00:00",
424+
},
425+
},
426+
})
427+
428+
path := testFanClubFeedURL(2, "sort_method=newest")
429+
status, body := testGetWithWallet(t, app, path, "0xc3d1d41e6872ffbd15c473d14fc3a9250be5b5e0")
430+
require.Equal(t, 200, status, string(body))
431+
432+
// Non-holder cannot see the message because is_members_only=true
433+
jsonAssert(t, body, map[string]any{
434+
"data.#": 1,
435+
"data.0.item_type": "text_post",
436+
"data.0.comment.message": nil,
437+
"data.0.comment.is_members_only": true,
438+
})
439+
}
440+
441+
func TestFanClubFeed_MixedPublicAndMembersOnlyPosts(t *testing.T) {
442+
app := emptyTestApp(t)
443+
database.Seed(app.pool.Replicas[0], database.FixtureMap{
444+
"users": testFanClubFeedBaseUsers(),
445+
"artist_coins": {
446+
{
447+
"user_id": 1,
448+
"mint": testFanClubFeedMint,
449+
"decimals": 6,
450+
"ticker": "FCT",
451+
},
452+
},
453+
"sol_user_balances": {
454+
{
455+
"user_id": 2,
456+
"mint": testFanClubFeedMint,
457+
"balance": int64(1), // not enough
458+
},
459+
},
460+
"comments": []map[string]any{
461+
{
462+
"comment_id": 950,
463+
"user_id": 1,
464+
"entity_id": 1,
465+
"entity_type": "FanClub",
466+
"text": "public post",
467+
"is_members_only": false,
468+
"created_at": "2020-06-02 00:00:00",
469+
},
470+
{
471+
"comment_id": 951,
472+
"user_id": 1,
473+
"entity_id": 1,
474+
"entity_type": "FanClub",
475+
"text": "secret post",
476+
"is_members_only": true,
477+
"created_at": "2020-06-01 00:00:00",
478+
},
479+
},
480+
})
481+
482+
path := testFanClubFeedURL(2, "sort_method=newest")
483+
status, body := testGetWithWallet(t, app, path, "0xc3d1d41e6872ffbd15c473d14fc3a9250be5b5e0")
484+
require.Equal(t, 200, status, string(body))
485+
486+
// Both posts appear, but only the public one has a visible message
487+
jsonAssert(t, body, map[string]any{
488+
"data.#": 2,
489+
"data.0.item_type": "text_post",
490+
"data.0.comment.message": "public post",
491+
"data.0.comment.is_members_only": false,
492+
"data.1.item_type": "text_post",
493+
"data.1.comment.message": nil,
494+
"data.1.comment.is_members_only": true,
495+
})
496+
}
497+
345498
func TestFanClubFeed_ExternalSolanaWalletRevealsTextPost(t *testing.T) {
346499
app := emptyTestApp(t)
347500
pub, priv, err := ed25519.GenerateKey(nil)
@@ -370,12 +523,13 @@ func TestFanClubFeed_ExternalSolanaWalletRevealsTextPost(t *testing.T) {
370523
},
371524
"comments": []map[string]any{
372525
{
373-
"comment_id": 930,
374-
"user_id": 2,
375-
"entity_id": 1,
376-
"entity_type": "FanClub",
377-
"text": "holders only",
378-
"created_at": "2020-06-01 00:00:00",
526+
"comment_id": 930,
527+
"user_id": 2,
528+
"entity_id": 1,
529+
"entity_type": "FanClub",
530+
"text": "holders only",
531+
"is_members_only": true,
532+
"created_at": "2020-06-01 00:00:00",
379533
},
380534
},
381535
})
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-- Add is_members_only flag to fan club text posts.
2+
-- Default false so track comments (the vast majority) are unaffected.
3+
-- Fan club post creation explicitly sets this to true when the artist
4+
-- has the "Members Only" toggle enabled.
5+
6+
ALTER TABLE public.comments
7+
ADD COLUMN IF NOT EXISTS is_members_only boolean NOT NULL DEFAULT false;
8+
9+
-- Back-fill existing fan club text posts as members-only (preserving
10+
-- current behaviour where all fan club posts were gated).
11+
UPDATE public.comments
12+
SET is_members_only = true
13+
WHERE entity_type = 'FanClub';

sql/01_schema.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6777,6 +6777,7 @@ CREATE TABLE public.comments (
67776777
is_delete boolean DEFAULT false,
67786778
is_visible boolean DEFAULT true,
67796779
is_edited boolean DEFAULT false,
6780+
is_members_only boolean DEFAULT false NOT NULL,
67806781
txhash text NOT NULL,
67816782
blockhash text NOT NULL,
67826783
blocknumber integer

0 commit comments

Comments
 (0)