Skip to content

Commit

Permalink
update tags for account, challenge, post
Browse files Browse the repository at this point in the history
  • Loading branch information
orlein committed Nov 28, 2024
1 parent 2f7c59f commit e15a8ff
Show file tree
Hide file tree
Showing 18 changed files with 159 additions and 135 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@oz-adv/backend",
"version": "0.0.2 (2024-11-28.001)",
"version": "0.0.2 (2024-11-28.002)",
"description": "Backend for the Oz-Adv project",
"type": "module",
"scripts": {
Expand Down
9 changes: 6 additions & 3 deletions src/account/account-api-live.mts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ export const AccountApiLive = HttpApiBuilder.group(Api, 'account', (handlers) =>
.handle('signUp', ({ payload }) =>
accountService.signUp(payload).pipe(withSystemActor),
)
.handle('findById', ({ path }) => accountService.findAccountById(path.id))
.handle('findById', ({ path }) =>
accountService.findAccountById(path.accountId),
)
.handle('findTags', ({ path }) => accountService.findTags(path.accountId))
.handle('updateById', ({ path, payload }) =>
accountService
.updateAccountById(path.id, payload)
.pipe(policyUse(accountPolicy.canUpdate(path.id))),
.updateAccountById(path.accountId, payload)
.pipe(policyUse(accountPolicy.canUpdate(path.accountId))),
)
.handle('signIn', ({ payload }) =>
accountService.signIn(payload).pipe(withSystemActor),
Expand Down
29 changes: 25 additions & 4 deletions src/account/account-api.mts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ import {
import { Account, AccountId } from './account-schema.mjs';
import { SignIn } from './sign-in-schema.mjs';
import { SignUp } from './sign-up-schema.mjs';
import { Tag } from '@/tag/tag-schema.mjs';

export class AccountApi extends HttpApiGroup.make('account')
.add(
HttpApiEndpoint.get('findById', '/:id')
HttpApiEndpoint.get('findById', '/:accountId')
.setPath(
Schema.Struct({
id: AccountId,
accountId: AccountId,
}),
)
.addSuccess(Account.json)
Expand All @@ -39,10 +40,30 @@ export class AccountApi extends HttpApiGroup.make('account')
),
)
.add(
HttpApiEndpoint.patch('updateById', '/:id')
HttpApiEndpoint.get('findTags', '/:accountId/tags')
.setPath(
Schema.Struct({
id: AccountId,
accountId: AccountId,
}),
)
.addError(AccountNotFound)
.addSuccess(Schema.Array(Tag.json))
.annotateContext(
OpenApi.annotations({
title: '계정 태그 조회',
description:
'계정의 태그를 조회합니다. 계정이 존재하지 않는 경우 404를 반환합니다. 다른 사람의 계정을 조회할 수 있습니다. 로그인하지 않아도 사용할 수 있습니다.',
override: {
summary: '(사용가능) 계정 태그 조회',
},
}),
),
)
.add(
HttpApiEndpoint.patch('updateById', '/:accountId')
.setPath(
Schema.Struct({
accountId: AccountId,
}),
)
.middleware(Authentication)
Expand Down
23 changes: 20 additions & 3 deletions src/account/account-repo.mts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Email } from '@/misc/email-schema.mjs';
import { makeTestLayer } from '@/misc/test-layer.mjs';
import { SqlLive } from '@/sql/sql-live.mjs';
import { Tag } from '@/tag/tag-schema.mjs';
import { Model, SqlClient, SqlSchema } from '@effect/sql';
import { Context, Effect, Layer, Option, pipe } from 'effect';
import { Account, AccountId } from './account-schema.mjs';
import { makeTestLayer } from '@/misc/test-layer.mjs';
import { Email } from '@/misc/email-schema.mjs';
import { AccountNotFound } from './account-error.mjs';
import { Account, AccountId } from './account-schema.mjs';

const make = Effect.gen(function* () {
const sql = yield* SqlClient.SqlClient;
Expand All @@ -21,6 +22,21 @@ const make = Effect.gen(function* () {
execute: (key) => sql`select * from account where email = ${key}`,
})(email).pipe(Effect.orDie, Effect.withSpan('AccountRepo.findByEmail'));

const findTags = (accountId: AccountId) =>
SqlSchema.findAll({
Request: AccountId,
Result: Tag,
execute: (req) => sql`
SELECT DISTINCT t.*
FROM tag t
left join tag_target tt on tt.tag_id = t.id
left join challenge_participant cp on tt.challenge_id = cp.challenge_id
LEFT JOIN post p ON tt.post_id = p.id
LEFT JOIN challenge c ON tt.challenge_id = c.id
WHERE p.account_id = ${req}
OR c.account_id = ${req};`,
})(accountId).pipe(Effect.orDie, Effect.withSpan('AccountRepo.findTags'));

const updateById = (
existing: Account,
target: Partial<typeof Account.jsonUpdate.Type>,
Expand Down Expand Up @@ -52,6 +68,7 @@ const make = Effect.gen(function* () {
return {
...repo,
findByEmail,
findTags,
updateById,
with: with_,
} as const;
Expand Down
6 changes: 6 additions & 0 deletions src/account/account-service.mts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ const make = Effect.gen(function* () {
}),
);

const findTags = (accountId: AccountId) =>
accountRepo
.findTags(accountId)
.pipe(Effect.withSpan('AccountService.findTags'));

const embellishAccount = (target: Account) =>
Effect.gen(function* () {
const maybeAccount = yield* accountRepo.findById(target.id);
Expand Down Expand Up @@ -215,6 +220,7 @@ const make = Effect.gen(function* () {
signUp,
signIn,
findByIdFromRepo,
findTags,
findAccountByEmail,
findAccountById,
updateAccountById,
Expand Down
4 changes: 3 additions & 1 deletion src/api.mts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ export class Api extends HttpApi.empty
OpenApi.annotations({
title: '오즈 6기 심화반 챌린지 서비스를 위한 백엔드',
description: `최신변경점:
* 챌린지 태그조회 api 위치변경: tag -> challenge (2024-11-28.002)
* 게시글 태그조회 api 위치변경: tag -> post (2024-11-28.002)
* 특정 유저의 태그조회 api 위치변경: tag -> account (2024-11-28.002)
* 챌린지 / 게시글 isDeleted 반영 (2024-11-28.001)
* 태그 db에 색을 받을 수있게 함 (2024-11-27.002)
* [유저가 참여한 챌린지]와 [유저가 쓴 글], [유저가 만든 챌린지]의 태그를 찾아, 그를 프로필에 표시할 수 있게 지원하는 기능 (2024-11-27.001)
예정변경점:
* 챌린지 / 게시글의 태그를 가져올 수 있는 기능
* 챌린지 / 게시글의 태그를 삭제하는 기능
* 내가 만든 챌린지 목록을 가져오는 기능
* 내가 참여중인 챌린지 목록을 가져오는 기능
Expand Down
3 changes: 3 additions & 0 deletions src/challenge/challenge-api-live.mts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export const ChallengeApiLive = HttpApiBuilder.group(
.handle('findById', ({ path }) =>
challengeService.findByIdWithView(path.challengeId),
)
.handle('findTags', ({ path }) =>
challengeService.findTags(path.challengeId),
)
.handle('create', ({ payload }) =>
challengeService
.create(payload)
Expand Down
20 changes: 20 additions & 0 deletions src/challenge/challenge-api.mts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from './challenge-participant-error.mjs';
import { Account } from '@/account/account-schema.mjs';
import { EmptySchema } from '@/misc/empty-schema.mjs';
import { Tag } from '@/tag/tag-schema.mjs';

export class ChallengeApi extends HttpApiGroup.make('challenge')
.add(
Expand Down Expand Up @@ -50,6 +51,25 @@ export class ChallengeApi extends HttpApiGroup.make('challenge')
}),
),
)
.add(
HttpApiEndpoint.get('findTags', '/:challengeId/tags')
.setPath(
Schema.Struct({
challengeId: ChallengeId,
}),
)
.addError(ChallengeNotFound)
.addSuccess(Schema.Array(Tag.json))
.annotateContext(
OpenApi.annotations({
description:
'(사용가능) 챌린지의 태그 목록을 조회합니다. 챌린지가 존재하지 않는 경우 404를 반환합니다.',
override: {
summary: '(사용가능) 챌린지 태그 목록 조회',
},
}),
),
)
.add(
HttpApiEndpoint.post('create', '/')
.middleware(Authentication)
Expand Down
17 changes: 17 additions & 0 deletions src/challenge/challenge-repo.mts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Model, SqlClient, SqlSchema } from '@effect/sql';
import { Effect, Layer, Option, pipe, Schema } from 'effect';
import { ChallengeNotFound } from './challenge-error.mjs';
import { Challenge, ChallengeId, ChallengeView } from './challenge-schema.mjs';
import { Tag } from '@/tag/tag-schema.mjs';

const snakeCase = (str: string) =>
str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
Expand All @@ -28,6 +29,21 @@ const make = Effect.gen(function* () {
idColumn: 'id',
});

const findTags = (challengeId: ChallengeId) =>
SqlSchema.findAll({
Request: ChallengeId,
Result: Tag,
execute: (req) => sql`
SELECT DISTINCT t.*
FROM tag t
left join tag_target tt on tt.tag_id = t.id
LEFT JOIN challenge c ON tt.challenge_id = c.id
WHERE c.id = ${req};`,
})(challengeId).pipe(
Effect.orDie,
Effect.withSpan('ChallengeRepo.findTags'),
);

const findAllWithView = (params: FindManyUrlParams) =>
Effect.gen(function* () {
const challenges = yield* SqlSchema.findAll({
Expand Down Expand Up @@ -115,6 +131,7 @@ offset ${(params.page - 1) * params.limit}`,
insert,
viewRepo,
findAllWithView,
findTags,
with: with_,
withView: withView_,
} as const;
Expand Down
6 changes: 6 additions & 0 deletions src/challenge/challenge-service.mts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ const make = Effect.gen(function* () {
.findAllWithView(params)
.pipe(Effect.withSpan('ChallengeService.findChallenges'));

const findTags = (challengeId: ChallengeId) =>
challengeRepo
.findTags(challengeId)
.pipe(Effect.withSpan('ChallengeService.findTags'));

const create = (challenge: typeof Challenge.jsonCreate.Type) =>
pipe(
CurrentAccount,
Expand Down Expand Up @@ -110,6 +115,7 @@ const make = Effect.gen(function* () {
findByIdWithView,
findByIdFromRepo,
findChallenges,
findTags,
findLikeStatus,
addLikeChallengeById,
removeLikeChallengeById,
Expand Down
1 change: 1 addition & 0 deletions src/post/post-api-live.mts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const PostApiLive = HttpApiBuilder.group(Api, 'post', (handlers) =>
.handle('findById', ({ path }) =>
postService.increaseViewCountById(path.postId),
)
.handle('findTags', ({ path }) => postService.findTags(path.postId))
.handle('create', ({ payload }) =>
postService.create(payload).pipe(withSystemActor),
)
Expand Down
20 changes: 20 additions & 0 deletions src/post/post-api.mts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { HttpApiEndpoint, HttpApiGroup, OpenApi } from '@effect/platform';
import { Schema } from 'effect';
import { PostNotFound } from './post-error.mjs';
import { Post, PostId, PostView } from './post-schema.mjs';
import { Tag } from '@/tag/tag-schema.mjs';

export class PostApi extends HttpApiGroup.make('post')
.add(
Expand Down Expand Up @@ -44,6 +45,25 @@ export class PostApi extends HttpApiGroup.make('post')
}),
),
)
.add(
HttpApiEndpoint.get('findTags', '/:postId/tags')
.setPath(
Schema.Struct({
postId: PostId,
}),
)
.addError(PostNotFound)
.addSuccess(Schema.Array(Tag.json))
.annotateContext(
OpenApi.annotations({
description:
'게시글의 태그 목록을 조회합니다. 게시글이 존재하지 않는 경우 404를 반환합니다.',
override: {
summary: '(사용가능) 게시글 태그 목록 조회',
},
}),
),
)
.add(
HttpApiEndpoint.get('findLikeStatus', '/:postId/like-status')
.middleware(Authentication)
Expand Down
14 changes: 14 additions & 0 deletions src/post/post-repo.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Model, SqlClient, SqlSchema } from '@effect/sql';
import { Effect, Layer, Option, pipe } from 'effect';
import { PostNotFound } from './post-error.mjs';
import { Post, PostId, PostView } from './post-schema.mjs';
import { Tag } from '@/tag/tag-schema.mjs';

const TABLE_NAME = 'post';
const VIEW_NAME = 'post_like_counts';
Expand All @@ -26,6 +27,18 @@ const make = Effect.gen(function* () {
idColumn: 'id',
});

const findTags = (postId: PostId) =>
SqlSchema.findAll({
Request: PostId,
Result: Tag,
execute: (req) => sql`
SELECT DISTINCT t.*
FROM tag t
left join tag_target tt on tt.tag_id = t.id
LEFT JOIN post p ON tt.post_id = p.id
WHERE p.id = ${req};`,
})(postId).pipe(Effect.orDie, Effect.withSpan('PostRepo.findTags'));

const findAllWithView = (params: FindManyUrlParams) =>
Effect.gen(function* () {
const posts = yield* SqlSchema.findAll({
Expand Down Expand Up @@ -96,6 +109,7 @@ const make = Effect.gen(function* () {
...repo,
viewRepo,
findAllWithView,
findTags,
with: with_,
withView: withView_,
} as const;
Expand Down
15 changes: 9 additions & 6 deletions src/post/post-service.mts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@ const make = Effect.gen(function* () {
const postRepo = yield* PostRepo;
const likeService = yield* LikeService;

const findByIdFromRepo = (id: PostId) => postRepo.findById(id);
const findByIdFromRepo = (postId: PostId) => postRepo.findById(postId);

const findPosts = (params: FindManyUrlParams) =>
postRepo
.findAllWithView(params)
.pipe(Effect.withSpan('PostService.findPosts'));

const findByIdWithView = (id: PostId) =>
postRepo.withView(id, (post) =>
const findByIdWithView = (postId: PostId) =>
postRepo.withView(postId, (post) =>
pipe(Effect.succeed(post), Effect.withSpan('PostService.findById')),
);

const findTags = (postId: PostId) => postRepo.findTags(postId);

const create = (post: typeof Post.jsonCreate.Type) =>
pipe(
CurrentAccount,
Expand Down Expand Up @@ -56,10 +58,10 @@ const make = Effect.gen(function* () {
),
);

const deleteById = (id: PostId) =>
postRepo.with(id, (post) =>
const deleteById = (postId: PostId) =>
postRepo.with(postId, (post) =>
pipe(
postRepo.delete(id),
postRepo.delete(postId),
Effect.withSpan('PostService.deleteById'),
policyRequire('post', 'delete'),
),
Expand Down Expand Up @@ -130,6 +132,7 @@ const make = Effect.gen(function* () {
findPosts,
findByIdWithView,
findLikeStatus,
findTags,
increaseViewCountById,
addLikePostById,
removePostLikeById,
Expand Down
Loading

0 comments on commit e15a8ff

Please sign in to comment.