Skip to content

Commit 716c75d

Browse files
authored
Fix/profile v4 (#194)
* fix(profile): add reposted_by * fix(profile): remove migrations * fix(profile): add username to reposted by
1 parent 30d894e commit 716c75d

File tree

4 files changed

+214
-0
lines changed

4 files changed

+214
-0
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm';
2+
3+
export class AddReposterUsername1765636698571 implements MigrationInterface {
4+
name = 'AddReposterUsername1765636698571';
5+
6+
public async up(query_runner: QueryRunner): Promise<void> {
7+
await query_runner.query(
8+
`DELETE FROM "typeorm_metadata" WHERE "type" = $1 AND "name" = $2 AND "schema" = $3`,
9+
['VIEW', 'user_posts_view', 'public']
10+
);
11+
await query_runner.query(`DROP VIEW "user_posts_view"`);
12+
await query_runner.query(`CREATE VIEW "user_posts_view" AS
13+
SELECT
14+
t.tweet_id::text AS id,
15+
t.user_id AS profile_user_id,
16+
t.user_id AS tweet_author_id,
17+
t.tweet_id,
18+
NULL::uuid AS repost_id,
19+
t.type::text AS post_type,
20+
t.created_at AS post_date,
21+
t.type::text AS type,
22+
t.content,
23+
t.images,
24+
t.videos,
25+
t.num_likes,
26+
t.num_reposts,
27+
t.num_views,
28+
t.num_quotes,
29+
t.num_replies,
30+
t.num_bookmarks,
31+
t.mentions,
32+
t.created_at,
33+
t.updated_at,
34+
u.username,
35+
u.name,
36+
u.followers,
37+
u.following,
38+
u.avatar_url,
39+
u.cover_url,
40+
u.verified,
41+
u.bio,
42+
NULL::text AS reposted_by_name,
43+
NULL::text AS reposted_by_username,
44+
COALESCE(tq.original_tweet_id, trep.original_tweet_id) AS parent_id,
45+
trep.conversation_id AS conversation_id
46+
FROM tweets t
47+
INNER JOIN "user" u ON t.user_id = u.id
48+
LEFT JOIN tweet_quotes tq ON t.tweet_id = tq.quote_tweet_id
49+
LEFT JOIN tweet_replies trep ON t.tweet_id = trep.reply_tweet_id
50+
51+
UNION ALL
52+
53+
SELECT
54+
(tr.tweet_id::text || '_' || tr.user_id::text) AS id,
55+
tr.user_id AS profile_user_id,
56+
t.user_id AS tweet_author_id,
57+
tr.tweet_id,
58+
tr.tweet_id AS repost_id,
59+
t.type::text AS post_type,
60+
tr.created_at AS post_date,
61+
'repost' AS type,
62+
t.content,
63+
t.images,
64+
t.videos,
65+
t.num_likes,
66+
t.num_reposts,
67+
t.num_views,
68+
t.num_quotes,
69+
t.num_replies,
70+
t.num_bookmarks,
71+
t.mentions,
72+
t.created_at,
73+
t.updated_at,
74+
u.username,
75+
u.name,
76+
u.followers,
77+
u.following,
78+
u.avatar_url,
79+
u.cover_url,
80+
u.verified,
81+
u.bio,
82+
reposter.name AS reposted_by_name,
83+
reposter.username AS reposted_by_username,
84+
COALESCE(tq.original_tweet_id, trep.original_tweet_id) AS parent_id,
85+
trep.conversation_id AS conversation_id
86+
87+
FROM tweet_reposts tr
88+
INNER JOIN tweets t ON tr.tweet_id = t.tweet_id
89+
INNER JOIN "user" u ON t.user_id = u.id
90+
INNER JOIN "user" reposter ON tr.user_id = reposter.id
91+
LEFT JOIN tweet_quotes tq ON t.tweet_id = tq.quote_tweet_id
92+
LEFT JOIN tweet_replies trep ON t.tweet_id = trep.reply_tweet_id
93+
`);
94+
await query_runner.query(
95+
`INSERT INTO "typeorm_metadata"("database", "schema", "table", "type", "name", "value") VALUES (DEFAULT, $1, DEFAULT, $2, $3, $4)`,
96+
[
97+
'public',
98+
'VIEW',
99+
'user_posts_view',
100+
'SELECT \n t.tweet_id::text AS id,\n t.user_id AS profile_user_id,\n t.user_id AS tweet_author_id,\n t.tweet_id,\n NULL::uuid AS repost_id,\n t.type::text AS post_type,\n t.created_at AS post_date,\n t.type::text AS type,\n t.content,\n t.images,\n t.videos,\n t.num_likes,\n t.num_reposts,\n t.num_views,\n t.num_quotes,\n t.num_replies,\n t.num_bookmarks,\n t.mentions,\n t.created_at,\n t.updated_at,\n u.username,\n u.name,\n u.followers,\n u.following,\n u.avatar_url,\n u.cover_url,\n u.verified,\n u.bio,\n NULL::text AS reposted_by_name,\n NULL::text AS reposted_by_username,\n COALESCE(tq.original_tweet_id, trep.original_tweet_id) AS parent_id,\n trep.conversation_id AS conversation_id\n FROM tweets t\n INNER JOIN "user" u ON t.user_id = u.id\n LEFT JOIN tweet_quotes tq ON t.tweet_id = tq.quote_tweet_id\n LEFT JOIN tweet_replies trep ON t.tweet_id = trep.reply_tweet_id\n \n UNION ALL\n \n SELECT \n (tr.tweet_id::text || \'_\' || tr.user_id::text) AS id,\n tr.user_id AS profile_user_id,\n t.user_id AS tweet_author_id,\n tr.tweet_id,\n tr.tweet_id AS repost_id,\n t.type::text AS post_type,\n tr.created_at AS post_date,\n \'repost\' AS type,\n t.content,\n t.images,\n t.videos,\n t.num_likes,\n t.num_reposts,\n t.num_views,\n t.num_quotes,\n t.num_replies,\n t.num_bookmarks,\n t.mentions,\n t.created_at,\n t.updated_at,\n u.username,\n u.name,\n u.followers,\n u.following,\n u.avatar_url,\n u.cover_url,\n u.verified,\n u.bio,\n reposter.name AS reposted_by_name,\n reposter.username AS reposted_by_username,\n COALESCE(tq.original_tweet_id, trep.original_tweet_id) AS parent_id,\n trep.conversation_id AS conversation_id\n\n FROM tweet_reposts tr\n INNER JOIN tweets t ON tr.tweet_id = t.tweet_id\n INNER JOIN "user" u ON t.user_id = u.id\n INNER JOIN "user" reposter ON tr.user_id = reposter.id\n LEFT JOIN tweet_quotes tq ON t.tweet_id = tq.quote_tweet_id\n LEFT JOIN tweet_replies trep ON t.tweet_id = trep.reply_tweet_id',
101+
]
102+
);
103+
}
104+
105+
public async down(query_runner: QueryRunner): Promise<void> {
106+
await query_runner.query(
107+
`DELETE FROM "typeorm_metadata" WHERE "type" = $1 AND "name" = $2 AND "schema" = $3`,
108+
['VIEW', 'user_posts_view', 'public']
109+
);
110+
await query_runner.query(`DROP VIEW "user_posts_view"`);
111+
await query_runner.query(`CREATE VIEW "user_posts_view" AS SELECT
112+
t.tweet_id::text AS id,
113+
t.user_id AS profile_user_id,
114+
t.user_id AS tweet_author_id,
115+
t.tweet_id,
116+
NULL::uuid AS repost_id,
117+
'tweet' AS post_type,
118+
t.created_at AS post_date,
119+
t.type::text AS type,
120+
t.content,
121+
t.images,
122+
t.videos,
123+
t.num_likes,
124+
t.num_reposts,
125+
t.num_views,
126+
t.num_quotes,
127+
t.num_replies,
128+
t.num_bookmarks,
129+
t.mentions,
130+
t.created_at,
131+
t.updated_at,
132+
u.username,
133+
u.name,
134+
u.followers,
135+
u.following,
136+
u.avatar_url,
137+
u.cover_url,
138+
u.verified,
139+
u.bio,
140+
NULL::text AS reposted_by_name,
141+
COALESCE(tq.original_tweet_id, trep.original_tweet_id) AS parent_id,
142+
trep.conversation_id AS conversation_id
143+
FROM tweets t
144+
INNER JOIN "user" u ON t.user_id = u.id
145+
LEFT JOIN tweet_quotes tq ON t.tweet_id = tq.quote_tweet_id
146+
LEFT JOIN tweet_replies trep ON t.tweet_id = trep.reply_tweet_id
147+
148+
UNION ALL
149+
150+
SELECT
151+
(tr.tweet_id::text || '_' || tr.user_id::text) AS id,
152+
tr.user_id AS profile_user_id,
153+
t.user_id AS tweet_author_id,
154+
tr.tweet_id,
155+
tr.tweet_id AS repost_id,
156+
t.type::text AS post_type,
157+
tr.created_at AS post_date,
158+
'repost' AS type,
159+
t.content,
160+
t.images,
161+
t.videos,
162+
t.num_likes,
163+
t.num_reposts,
164+
t.num_views,
165+
t.num_quotes,
166+
t.num_replies,
167+
t.num_bookmarks,
168+
t.mentions,
169+
t.created_at,
170+
t.updated_at,
171+
u.username,
172+
u.name,
173+
u.followers,
174+
u.following,
175+
u.avatar_url,
176+
u.cover_url,
177+
u.verified,
178+
u.bio,
179+
reposter.name AS reposted_by_name,
180+
COALESCE(tq.original_tweet_id, trep.original_tweet_id) AS parent_id,
181+
trep.conversation_id AS conversation_id
182+
183+
FROM tweet_reposts tr
184+
INNER JOIN tweets t ON tr.tweet_id = t.tweet_id
185+
INNER JOIN "user" u ON t.user_id = u.id
186+
INNER JOIN "user" reposter ON tr.user_id = reposter.id
187+
LEFT JOIN tweet_quotes tq ON t.tweet_id = tq.quote_tweet_id
188+
LEFT JOIN tweet_replies trep ON t.tweet_id = trep.reply_tweet_id`);
189+
await query_runner.query(
190+
`INSERT INTO "typeorm_metadata"("database", "schema", "table", "type", "name", "value") VALUES (DEFAULT, $1, DEFAULT, $2, $3, $4)`,
191+
[
192+
'public',
193+
'VIEW',
194+
'user_posts_view',
195+
'SELECT \n t.tweet_id::text AS id,\n t.user_id AS profile_user_id,\n t.user_id AS tweet_author_id,\n t.tweet_id,\n NULL::uuid AS repost_id,\n \'tweet\' AS post_type,\n t.created_at AS post_date,\n t.type::text AS type,\n t.content,\n t.images,\n t.videos,\n t.num_likes,\n t.num_reposts,\n t.num_views,\n t.num_quotes,\n t.num_replies,\n t.num_bookmarks,\n t.mentions,\n t.created_at,\n t.updated_at,\n u.username,\n u.name,\n u.followers,\n u.following,\n u.avatar_url,\n u.cover_url,\n u.verified,\n u.bio,\n NULL::text AS reposted_by_name,\n COALESCE(tq.original_tweet_id, trep.original_tweet_id) AS parent_id,\n trep.conversation_id AS conversation_id\n FROM tweets t\n INNER JOIN "user" u ON t.user_id = u.id\n LEFT JOIN tweet_quotes tq ON t.tweet_id = tq.quote_tweet_id\n LEFT JOIN tweet_replies trep ON t.tweet_id = trep.reply_tweet_id\n \n UNION ALL\n \n SELECT \n (tr.tweet_id::text || \'_\' || tr.user_id::text) AS id,\n tr.user_id AS profile_user_id,\n t.user_id AS tweet_author_id,\n tr.tweet_id,\n tr.tweet_id AS repost_id,\n t.type::text AS post_type,\n tr.created_at AS post_date,\n \'repost\' AS type,\n t.content,\n t.images,\n t.videos,\n t.num_likes,\n t.num_reposts,\n t.num_views,\n t.num_quotes,\n t.num_replies,\n t.num_bookmarks,\n t.mentions,\n t.created_at,\n t.updated_at,\n u.username,\n u.name,\n u.followers,\n u.following,\n u.avatar_url,\n u.cover_url,\n u.verified,\n u.bio,\n reposter.name AS reposted_by_name,\n COALESCE(tq.original_tweet_id, trep.original_tweet_id) AS parent_id,\n trep.conversation_id AS conversation_id\n\n FROM tweet_reposts tr\n INNER JOIN tweets t ON tr.tweet_id = t.tweet_id\n INNER JOIN "user" u ON t.user_id = u.id\n INNER JOIN "user" reposter ON tr.user_id = reposter.id\n LEFT JOIN tweet_quotes tq ON t.tweet_id = tq.quote_tweet_id\n LEFT JOIN tweet_replies trep ON t.tweet_id = trep.reply_tweet_id',
196+
]
197+
);
198+
}
199+
}

src/tweets/dto/reposted-by-user.dto.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ export class RepostedByUserDTO {
1919
})
2020
name: string;
2121

22+
@ApiProperty({
23+
description: 'Username',
24+
example: 'John123',
25+
})
26+
username: string;
27+
2228
@ApiProperty({
2329
description: 'When the tweet was reposted (ISO 8601 timestamp)',
2430
example: '2025-10-31T12:00:00.000Z',

src/tweets/entities/user-posts-view.entity.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import { UserFollows } from '../../user/entities/user-follows.entity';
3838
u.verified,
3939
u.bio,
4040
NULL::text AS reposted_by_name,
41+
NULL::text AS reposted_by_username,
4142
COALESCE(tq.original_tweet_id, trep.original_tweet_id) AS parent_id,
4243
trep.conversation_id AS conversation_id
4344
FROM tweets t
@@ -77,6 +78,7 @@ import { UserFollows } from '../../user/entities/user-follows.entity';
7778
u.verified,
7879
u.bio,
7980
reposter.name AS reposted_by_name,
81+
reposter.username AS reposted_by_username,
8082
COALESCE(tq.original_tweet_id, trep.original_tweet_id) AS parent_id,
8183
trep.conversation_id AS conversation_id
8284
@@ -176,6 +178,9 @@ export class UserPostsView {
176178
@ViewColumn()
177179
reposted_by_name: string | null;
178180

181+
@ViewColumn()
182+
reposted_by_username: string | null;
183+
179184
@ViewColumn()
180185
parent_id: string | null;
181186

src/tweets/tweets.repository.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ export class TweetsRepository extends Repository<Tweet> {
169169
'ranked.created_at AS created_at',
170170
'ranked.updated_at AS updated_at',
171171
'ranked.reposted_by_name AS reposted_by_name',
172+
'ranked.reposted_by_username AS reposted_by_usernname',
172173
'ranked.parent_id AS parent_id',
173174
'ranked.conversation_id AS conversation_id',
174175
'ranked.group_id AS group_id',
@@ -269,6 +270,8 @@ export class TweetsRepository extends Repository<Tweet> {
269270

270271
query = this.attachRepostInfo(query, 'tweet');
271272

273+
query = this.attachRepliedTweetQuery(query, user_id);
274+
272275
query = this.attachUserInteractionBooleanFlags(
273276
query,
274277
current_user_id,
@@ -600,6 +603,7 @@ export class TweetsRepository extends Repository<Tweet> {
600603
'repost_id', ${table_alias}.repost_id,
601604
'id', ${table_alias}.profile_user_id,
602605
'name', ${table_alias}.reposted_by_name,
606+
'username', ${table_alias}.reposted_by_username,
603607
'reposted_at', ${table_alias}.post_date
604608
) ELSE NULL END AS reposted_by`);
605609
return query;

0 commit comments

Comments
 (0)