Skip to content

Commit af38b26

Browse files
committedSep 19, 2023
WIP: save
1 parent 107da2f commit af38b26

File tree

14 files changed

+624
-289
lines changed

14 files changed

+624
-289
lines changed
 

‎package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@
2626
}
2727
},
2828
"dependencies": {
29+
"@devoxa/prisma-relay-cursor-connection": "^3.1.0",
2930
"@prisma/client": "^5.2.0",
3031
"@snek-at/function": "*",
3132
"@snek-at/function-cli": "*",
3233
"@snek-at/function-server": "*",
33-
"prisma": "^5.2.0"
34+
"prisma": "^5.2.0",
35+
"slugify": "^1.6.6"
3436
},
3537
"devDependencies": {
3638
"commitizen": "^4.2.5",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the column `userId` on the `Profile` table. All the data in the column will be lost.
5+
- A unique constraint covering the columns `[id]` on the table `Profile` will be added. If there are existing duplicate values, this will fail.
6+
7+
*/
8+
-- DropIndex
9+
DROP INDEX "Profile_userId_key";
10+
11+
-- AlterTable
12+
ALTER TABLE "Post" ALTER COLUMN "id" DROP DEFAULT;
13+
14+
-- AlterTable
15+
ALTER TABLE "Profile" DROP COLUMN "userId",
16+
ALTER COLUMN "id" DROP DEFAULT;
17+
18+
-- CreateIndex
19+
CREATE UNIQUE INDEX "Profile_id_key" ON "Profile"("id");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "Post" ALTER COLUMN "id" SET DEFAULT gen_random_uuid();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
Warnings:
3+
4+
- A unique constraint covering the columns `[slug]` on the table `Post` will be added. If there are existing duplicate values, this will fail.
5+
6+
*/
7+
-- AlterTable
8+
ALTER TABLE "Post" ADD COLUMN "slug" TEXT NOT NULL DEFAULT gen_random_uuid();
9+
10+
-- CreateIndex
11+
CREATE UNIQUE INDEX "Post_slug_key" ON "Post"("slug");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "Post" ALTER COLUMN "slug" DROP DEFAULT;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- CreateEnum
2+
CREATE TYPE "Language" AS ENUM ('EN', 'DE');
3+
4+
-- AlterTable
5+
ALTER TABLE "Post" ADD COLUMN "language" "Language" NOT NULL DEFAULT 'EN';
6+
7+
-- AlterTable
8+
ALTER TABLE "Profile" ADD COLUMN "language" "Language" NOT NULL DEFAULT 'EN';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
Warnings:
3+
4+
- The `privacy` column on the `Post` table would be dropped and recreated. This will lead to data loss if there is data in the column.
5+
6+
*/
7+
-- CreateEnum
8+
CREATE TYPE "Privacy" AS ENUM ('PUBLIC', 'PRIVATE', 'FRIENDS');
9+
10+
-- AlterTable
11+
ALTER TABLE "Post" DROP COLUMN "privacy",
12+
ADD COLUMN "privacy" "Privacy" NOT NULL DEFAULT 'PRIVATE';

‎prisma/schema.prisma

+20-4
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,20 @@ datasource db {
44
url = env("DATABASE_URL")
55
}
66

7+
enum Language {
8+
EN
9+
DE
10+
}
11+
12+
enum Privacy {
13+
PUBLIC
14+
PRIVATE
15+
FRIENDS
16+
}
17+
718
generator client {
8-
provider = "prisma-client-js"
19+
provider = "prisma-client-js"
20+
previewFeatures = ["fullTextSearch"]
921
}
1022

1123
model Activity {
@@ -39,8 +51,7 @@ model ProfileStatistic {
3951
}
4052

4153
model Profile {
42-
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
43-
userId String @unique @db.Uuid
54+
id String @id @unique @db.Uuid
4455
posts Post[] @relation("CreatedByUser")
4556
followers Follow[] @relation("Followed")
4657
following Follow[] @relation("Follower")
@@ -51,6 +62,8 @@ model Profile {
5162
featuredPosts Post[] @relation("FeaturedPosts")
5263
Activity Activity[]
5364
ProfileStatistic ProfileStatistic[]
65+
66+
language Language @default(value: EN)
5467
}
5568

5669
model PostStatistic {
@@ -69,6 +82,7 @@ model PostStatistic {
6982

7083
model Post {
7184
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
85+
slug String @unique
7286
title String
7387
avatarURL String?
7488
summary String?
@@ -80,9 +94,11 @@ model Post {
8094
updatedAt DateTime @updatedAt
8195
featuredBy Profile[] @relation("FeaturedPosts")
8296
83-
privacy String @default("private")
97+
privacy Privacy @default(value: PRIVATE)
8498
Activity Activity[]
8599
PostStatistic PostStatistic[]
100+
101+
language Language @default(value: EN)
86102
}
87103

88104
model Star {

‎src/errors/general.errors.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { ServiceError } from "@snek-at/function";
2+
3+
export class InvalidInputError extends ServiceError {
4+
constructor(message: string) {
5+
super(message, {
6+
code: "INVALID_INPUT",
7+
statusCode: 400,
8+
message,
9+
});
10+
}
11+
}
12+
13+
export class NotFoundError extends ServiceError {
14+
constructor(message: string) {
15+
super(message, {
16+
code: "NOT_FOUND",
17+
statusCode: 404,
18+
message,
19+
});
20+
}
21+
}
22+
23+
export class AuthenticationError extends ServiceError {
24+
constructor(message: string) {
25+
super(message, {
26+
code: "AUTHENTICATION_ERROR",
27+
statusCode: 401,
28+
message,
29+
});
30+
}
31+
}

‎src/repositories/Post.repository.ts

+187-62
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
import * as PQ from "@prisma/client";
22
import { prisma } from "../prisma";
33
import { Profile } from "./Profile.repository";
4+
import slugify from "slugify";
5+
import { NotFoundError } from "../errors/general.errors";
6+
import {
7+
ConnectionArguments,
8+
findManyCursorConnection,
9+
} from "@devoxa/prisma-relay-cursor-connection";
410

5-
export type Privacy = "public" | "private" | "friends";
11+
export type Privacy = PQ.$Enums.Privacy;
12+
export type Language = PQ.$Enums.Language;
613

714
export class Post implements PQ.Post {
815
id: string;
16+
slug: string;
917
title: string;
1018
avatarURL: string | null;
1119
summary: string | null;
@@ -14,6 +22,7 @@ export class Post implements PQ.Post {
1422
createdAt: Date;
1523
updatedAt: Date;
1624
privacy: Privacy;
25+
language: Language;
1726

1827
constructor(data: PQ.Post) {
1928
for (const key in data) {
@@ -34,29 +43,52 @@ export class Post implements PQ.Post {
3443
return data ? new Profile(data.profile) : null;
3544
};
3645

37-
stars = async () => {
38-
const stars = await prisma.post.findUnique({
39-
where: {
40-
id: this.id,
41-
},
42-
select: {
43-
stars: {
44-
select: {
45-
profile: true,
46-
createdAt: true,
47-
},
46+
stars = async (
47+
after: ConnectionArguments["after"],
48+
before: ConnectionArguments["before"],
49+
first: ConnectionArguments["first"],
50+
last: ConnectionArguments["last"],
51+
filters?: { userId?: string }
52+
) => {
53+
try {
54+
return findManyCursorConnection(
55+
async (args: any) => {
56+
const qs = await prisma.star.findMany({
57+
where: {
58+
postId: this.id,
59+
profileId: filters?.userId,
60+
},
61+
62+
include: {
63+
profile: true,
64+
},
65+
...(args as {}),
66+
});
67+
68+
return qs.map((star) => {
69+
return {
70+
profile: () => new Profile(star.profile),
71+
createdAt: star.createdAt,
72+
};
73+
});
4874
},
49-
},
50-
});
51-
52-
return stars
53-
? stars.stars.map((star) => {
54-
return {
55-
profile: () => new Profile(star.profile),
56-
createdAt: star.createdAt,
57-
};
58-
})
59-
: [];
75+
() =>
76+
prisma.star.count({
77+
where: {
78+
postId: this.id,
79+
profileId: filters?.userId,
80+
},
81+
}),
82+
{
83+
after,
84+
before,
85+
first,
86+
last,
87+
}
88+
);
89+
} catch (error) {
90+
throw new NotFoundError("Posts not found");
91+
}
6092
};
6193

6294
async views() {
@@ -83,6 +115,7 @@ export interface PostData {
83115

84116
export interface PostUpdateData {
85117
title?: string;
118+
language?: Language;
86119
avatarURL?: string;
87120
summary?: string;
88121
content?: string;
@@ -93,8 +126,24 @@ export class PostRepository {
93126
constructor(private readonly prismaPost: PQ.PrismaClient["post"]) {}
94127

95128
async create(profileId: string, values: PostData) {
129+
let slug = slugify(values.title, {
130+
lower: true,
131+
});
132+
133+
let i = 1;
134+
135+
while (await this.prismaPost.findUnique({ where: { slug } })) {
136+
slug =
137+
slugify(values.title, {
138+
lower: true,
139+
}) +
140+
"-" +
141+
i++;
142+
}
143+
96144
const post = await this.prismaPost.create({
97145
data: {
146+
slug,
98147
profileId,
99148
...values,
100149
},
@@ -125,39 +174,91 @@ export class PostRepository {
125174
});
126175
}
127176

128-
async find(postId: string) {
177+
async find(postId?: string, slug?: string) {
178+
if (!postId && !slug) {
179+
throw new Error("Either postId or slug must be provided.");
180+
}
181+
129182
const post = await this.prismaPost.findUnique({
130183
where: {
131184
id: postId,
185+
slug,
132186
},
133187
});
134188

135189
return post ? new Post(post) : null;
136190
}
137191

138-
async findAll(filters: {
139-
profileId?: string;
140-
privacy?: Privacy;
141-
limit?: number;
142-
offset?: number;
143-
}) {
192+
async findAll(
193+
after: ConnectionArguments["after"],
194+
before: ConnectionArguments["before"],
195+
first: ConnectionArguments["first"],
196+
last: ConnectionArguments["last"],
197+
filters?: {
198+
profileId?: string;
199+
privacy?: Privacy;
200+
language?: Language;
201+
query?: string;
202+
}
203+
) {
144204
console.log("Find all posts with filters: ", filters);
145205

146-
const posts = await this.prismaPost.findMany({
147-
where: {
148-
profileId: filters.profileId,
149-
privacy: filters.privacy,
150-
},
151-
take: filters.limit,
152-
skip: filters.offset,
153-
});
206+
return findManyCursorConnection(
207+
async (args: any) => {
208+
const qs = await this.prismaPost.findMany({
209+
where: {
210+
profileId: filters?.profileId,
211+
privacy: filters?.privacy,
212+
language: filters?.language,
213+
OR: filters?.query
214+
? [
215+
{ title: { contains: filters.query } },
216+
{ summary: { contains: filters.query } },
217+
{ content: { contains: filters.query } },
218+
]
219+
: undefined,
220+
},
221+
...args,
222+
});
154223

155-
return posts.map((post) => new Post(post));
224+
return qs.map((post) => new Post(post));
225+
},
226+
() =>
227+
this.prismaPost.count({
228+
where: {
229+
profileId: filters?.profileId,
230+
privacy: filters?.privacy,
231+
language: filters?.language,
232+
OR: filters?.query
233+
? [
234+
{ title: { contains: filters.query } },
235+
{ summary: { contains: filters.query } },
236+
{ content: { contains: filters.query } },
237+
]
238+
: undefined,
239+
},
240+
}),
241+
{
242+
after,
243+
before,
244+
first,
245+
last,
246+
}
247+
);
156248
}
157249

158250
async findTrending(
159251
timeFrameInDays: number,
160-
filters: { limit?: number; offset?: number }
252+
filters: {
253+
limit?: number;
254+
offset?: number;
255+
profileId?: string;
256+
language?: Language;
257+
},
258+
after: ConnectionArguments["after"],
259+
before: ConnectionArguments["before"],
260+
first: ConnectionArguments["first"],
261+
last: ConnectionArguments["last"]
161262
) {
162263
// Calculate the date for the beginning of the time frame
163264
const startDate = new Date();
@@ -181,31 +282,55 @@ export class PostRepository {
181282
},
182283
});
183284

184-
const trendingPosts = await this.prismaPost.findMany({
185-
where: {
186-
id: {
187-
in: group.map((post) => post.postId),
188-
},
189-
privacy: "public",
190-
},
191-
take: filters.limit,
192-
skip: filters.offset,
193-
});
285+
console.log("Group: ", group);
286+
287+
return findManyCursorConnection(
288+
async (args: any) => {
289+
const qs = await this.prismaPost.findMany({
290+
where: {
291+
id: {
292+
in: group.map((post) => post.postId),
293+
},
294+
profileId: filters.profileId,
295+
privacy: "PUBLIC",
296+
language: filters.language,
297+
},
298+
...args,
299+
});
194300

195-
console.log("Trending posts: ", trendingPosts);
301+
const sortedTrendingPosts: typeof qs = [];
196302

197-
const sortedTrendingPosts: typeof trendingPosts = [];
303+
for (const { postId } of group) {
304+
// find post by id
305+
const sortedPost = qs.find((post) => post.id === postId);
198306

199-
for (const { postId } of group) {
200-
// find post by id
201-
const sortedPost = trendingPosts.find((post) => post.id === postId);
307+
if (sortedPost) {
308+
sortedTrendingPosts.push(sortedPost);
309+
}
310+
}
202311

203-
if (sortedPost) {
204-
sortedTrendingPosts.push(sortedPost);
205-
}
206-
}
312+
console.log("Sorted trending posts: ", sortedTrendingPosts);
207313

208-
return sortedTrendingPosts.map((post) => new Post(post));
314+
return sortedTrendingPosts.map((post) => new Post(post));
315+
},
316+
() =>
317+
this.prismaPost.count({
318+
where: {
319+
id: {
320+
in: group.map((post) => post.postId),
321+
},
322+
profileId: filters.profileId,
323+
privacy: "PUBLIC",
324+
language: filters.language,
325+
},
326+
}),
327+
{
328+
after,
329+
before,
330+
first,
331+
last,
332+
}
333+
);
209334
}
210335

211336
registerView = async (postId: string) => {
@@ -238,13 +363,13 @@ export class PostRepository {
238363
select: {
239364
profile: {
240365
select: {
241-
userId: true,
366+
id: true,
242367
},
243368
},
244369
},
245370
});
246371

247-
return post?.profile.userId;
372+
return post?.profile.id;
248373
}
249374
}
250375

‎src/repositories/Profile.repository.ts

+217-140
Large diffs are not rendered by default.

‎src/services/post.service.ts

+80-38
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
activityRepository,
99
} from "../repositories/Activity.repository";
1010
import {
11+
Language,
1112
PostData,
1213
PostRepository,
1314
PostUpdateData,
@@ -22,8 +23,10 @@ import {
2223
ProfileRepository,
2324
profileRepository,
2425
} from "../repositories/Profile.repository";
26+
import { AuthenticationError, NotFoundError } from "../errors/general.errors";
27+
import { ConnectionArguments } from "@devoxa/prisma-relay-cursor-connection";
2528

26-
export class Post {
29+
export class PostService {
2730
private repository: {
2831
star: StarRepository;
2932
profile: ProfileRepository;
@@ -43,12 +46,10 @@ export class Post {
4346
create = withContext((context) => async (values: PostData) => {
4447
const userId = context.req.headers["x-forwarded-user"] as string;
4548

46-
const profileId = await this.repository.profile.profileIdByUserId(userId);
47-
48-
const post = await this.repository.post.create(profileId, values);
49+
const post = await this.repository.post.create(userId, values);
4950

5051
await this.repository.activity.createBlogActivity(
51-
profileId,
52+
userId,
5253
post.id,
5354
"create"
5455
);
@@ -80,74 +81,116 @@ export class Post {
8081
await this.repository.post.delete(postId);
8182
});
8283

83-
find = withContext((context) => async (postId: string) => {
84-
const post = await this.repository.post.find(postId);
84+
find = withContext((context) => async (postId?: string, slug?: string) => {
85+
const post = await this.repository.post.find(postId, slug);
8586

8687
const userId = context.req.headers["x-forwarded-user"] as string;
87-
const profileId = await this.repository.profile.profileIdByUserId(userId);
8888

89-
if (post && post.profileId !== profileId) {
90-
await this.repository.post.registerView(postId);
89+
if (post && post.profileId !== userId) {
90+
await this.repository.post.registerView(post.id);
91+
92+
// Return only public posts if user is not the owner of the profile
93+
if (post.privacy !== "PUBLIC") {
94+
throw new NotFoundError("Post not found");
95+
}
9196
}
9297

9398
return post;
9499
});
95100

96101
findAll = withContext(
97102
(context) =>
98-
async (filters?: {
99-
profileId?: string;
100-
privacy?: Privacy;
101-
limit?: number;
102-
offset?: number;
103-
}) => {
104-
const userId = context.req.headers["x-forwarded-user"] as string;
105-
103+
async (
104+
after: ConnectionArguments["after"],
105+
before: ConnectionArguments["before"],
106+
first: ConnectionArguments["first"],
107+
last: ConnectionArguments["last"],
108+
filters?: {
109+
userId?: string;
110+
privacy?: Privacy;
111+
language?: Language;
112+
query?: string;
113+
}
114+
) => {
115+
// Default privacy is public
106116
filters = {
117+
privacy: "PUBLIC",
107118
...filters,
108119
};
109120

110-
try {
111-
const profileId = await this.repository.profile.profileIdByUserId(
112-
userId
121+
const userId = context.req.headers["x-forwarded-user"] as
122+
| string
123+
| undefined;
124+
125+
if (!userId && filters?.privacy !== "PUBLIC") {
126+
throw new AuthenticationError(
127+
"You need to be logged in to view non-public posts"
113128
);
129+
}
114130

115-
if (filters.profileId && filters.profileId !== profileId) {
116-
// Set privacy to public if user is not the owner of the profile
117-
filters.privacy = "public";
131+
filters = {
132+
...filters,
133+
};
134+
135+
try {
136+
if (!userId || (filters.userId && filters.userId !== userId)) {
137+
// Set privacy to public if user is not the owner of the profile or not logged in
138+
filters.privacy = "PUBLIC";
118139
}
119140
} catch (e) {
120141
// Set privacy to public if user is not logged in
121-
filters.privacy = "public";
142+
filters.privacy = "PUBLIC";
122143
}
123144

124-
const posts = await this.repository.post.findAll(filters);
145+
const posts = await this.repository.post.findAll(
146+
after,
147+
before,
148+
first,
149+
last,
150+
filters
151+
);
125152

126153
return posts;
127154
}
128155
);
129156

130-
findTrending = async (filters?: { limit?: number; offset?: number }) => {
131-
const posts = await this.repository.post.findTrending(30, filters || {});
157+
findTrending = async (
158+
after: ConnectionArguments["after"],
159+
before: ConnectionArguments["before"],
160+
first: ConnectionArguments["first"],
161+
last: ConnectionArguments["last"],
162+
filters?: {
163+
limit?: number;
164+
offset?: number;
165+
profileId?: string;
166+
language?: Language;
167+
}
168+
) => {
169+
const posts = await this.repository.post.findTrending(
170+
30,
171+
filters || {},
172+
after,
173+
before,
174+
first,
175+
last
176+
);
132177

133178
return posts;
134179
};
135180

136181
star = withContext((context) => async (postId: string) => {
137182
const userId = context.req.headers["x-forwarded-user"] as string;
138183

139-
const profileId = await this.repository.profile.profileIdByUserId(userId);
140-
141184
const isAlreadyStarred = await this.repository.star.checkStar(
142-
profileId,
185+
userId,
143186
postId
144187
);
145188

146189
if (!isAlreadyStarred) {
147-
const starred = await this.repository.star.star(profileId, postId);
190+
const starred = await this.repository.star.star(userId, postId);
148191

149192
await this.repository.activity.createBlogStarActivity(
150-
profileId,
193+
userId,
151194
postId,
152195
"star"
153196
);
@@ -160,18 +203,17 @@ export class Post {
160203

161204
unstar = withContext((context) => async (postId: string) => {
162205
const userId = context.req.headers["x-forwarded-user"] as string;
163-
const profileId = await this.repository.profile.profileIdByUserId(userId);
164206

165207
const isAlreadyStarred = await this.repository.star.checkStar(
166-
profileId,
208+
userId,
167209
postId
168210
);
169211

170212
if (isAlreadyStarred) {
171-
const starred = await this.repository.star.unstar(profileId, postId);
213+
const starred = await this.repository.star.unstar(userId, postId);
172214

173215
await this.repository.activity.createBlogStarActivity(
174-
profileId,
216+
userId,
175217
postId,
176218
"unstar"
177219
);
@@ -183,4 +225,4 @@ export class Post {
183225
});
184226
}
185227

186-
export const post = new Post();
228+
export const post = new PostService();

‎src/services/profile.service.ts

+31-43
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
ProfileData,
32
ProfileRepository,
43
ProfileUpdateData,
54
profileRepository,
@@ -18,6 +17,7 @@ import {
1817
activityRepository,
1918
} from "../repositories/Activity.repository";
2019
import { withContext } from "@snek-at/function";
20+
import { ConnectionArguments } from "@devoxa/prisma-relay-cursor-connection";
2121

2222
class ProfileService {
2323
private repository: {
@@ -39,104 +39,92 @@ class ProfileService {
3939

4040
const profile = await this.repository.profile.create(userId);
4141

42-
await this.repository.activity.createProfileActivity(profile.id, "create");
42+
await this.repository.activity.createProfileActivity(userId, "create");
4343

4444
return profile;
4545
});
4646

4747
update = withContext((context) => async (values: ProfileUpdateData) => {
4848
const userId = context.req.headers["x-forwarded-user"] as string;
4949

50-
const profileId = await this.repository.profile.profileIdByUserId(userId);
51-
52-
const updatedProfile = await this.repository.profile.update(
53-
profileId,
54-
values
55-
);
50+
const updatedProfile = await this.repository.profile.update(userId, values);
5651

5752
return updatedProfile;
5853
});
5954

6055
delete = withContext((context) => async () => {
6156
const userId = context.req.headers["x-forwarded-user"] as string;
6257

63-
const profileId = await this.repository.profile.profileIdByUserId(userId);
64-
65-
await this.repository.profile.delete(profileId);
58+
await this.repository.profile.delete(userId);
6659

6760
return true;
6861
});
6962

70-
find = withContext((context) => async (profileId?: string) => {
71-
const userId = context.req.headers["x-forwarded-user"] as string;
72-
73-
if (!profileId) {
74-
profileId = await this.repository.profile.profileIdByUserId(userId);
75-
}
63+
find = withContext((context) => async (userId: string) => {
64+
const forwardedUserId = context.req.headers["x-forwarded-user"] as string;
7665

77-
const profile = await this.repository.profile.find(profileId);
66+
const profile = await this.repository.profile.find(userId);
7867

79-
if (profile.userId !== userId) {
80-
await this.repository.profile.registerView(profileId);
68+
if (profile.id !== forwardedUserId) {
69+
await this.repository.profile.registerView(userId);
8170
}
8271

8372
return profile;
8473
});
8574

86-
findAll = async () => {
87-
const profiles = await this.repository.profile.findAll();
88-
89-
return profiles;
75+
findAll = (
76+
after: ConnectionArguments["after"],
77+
before: ConnectionArguments["before"],
78+
first: ConnectionArguments["first"],
79+
last: ConnectionArguments["last"]
80+
) => {
81+
return this.repository.profile.findAll(after, before, first, last);
9082
};
9183

92-
follow = withContext((context) => async (followProfileId: string) => {
93-
const userId = context.req.headers["x-forwarded-user"] as string;
94-
95-
const profileId = await this.repository.profile.profileIdByUserId(userId);
84+
follow = withContext((context) => async (userId: string) => {
85+
const forwardedUserId = context.req.headers["x-forwarded-user"] as string;
9686

9787
const isAlreadyFollowed = await this.repository.follow.checkFollow(
98-
profileId,
99-
followProfileId
88+
forwardedUserId,
89+
userId
10090
);
10191

10292
if (!isAlreadyFollowed) {
10393
const followed = await this.repository.follow.follow(
104-
profileId,
105-
followProfileId
94+
forwardedUserId,
95+
userId
10696
);
10797

10898
await this.repository.activity.createProfileFollowActivity(
109-
profileId,
99+
forwardedUserId,
110100
followed.id,
111101
"follow"
112102
);
113103

114104
return followed;
115105
}
116106

117-
throw new ProfileAlreadyFollowedError(followProfileId);
107+
throw new ProfileAlreadyFollowedError(userId);
118108
});
119109

120-
unfollow = withContext((context) => async (followProfileId: string) => {
121-
const userId = context.req.headers["x-forwarded-user"] as string;
122-
123-
const profileId = await this.repository.profile.profileIdByUserId(userId);
110+
unfollow = withContext((context) => async (userId: string) => {
111+
const forwardedUserId = context.req.headers["x-forwarded-user"] as string;
124112

125113
const isAlreadyFollowed = await this.repository.follow.checkFollow(
126-
profileId,
127-
followProfileId
114+
forwardedUserId,
115+
userId
128116
);
129117

130118
if (isAlreadyFollowed) {
131119
const followed = await this.repository.follow.unfollow(
132-
profileId,
133-
followProfileId
120+
forwardedUserId,
121+
userId
134122
);
135123

136124
return followed;
137125
}
138126

139-
throw new ProfileNotFollowedError(followProfileId);
127+
throw new ProfileNotFollowedError(userId);
140128
});
141129
}
142130

‎src/sfi.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineService, logger } from "@snek-at/function";
22

3-
import { profile } from "./services/profile.service";
43
import { post } from "./services/post.service";
4+
import { profile } from "./services/profile.service";
55

66
export default defineService(
77
{

0 commit comments

Comments
 (0)
Please sign in to comment.