Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c093072
🚀 Add deploy yaml
lapidix Apr 27, 2025
e59907b
♻️ Refactoring code
lapidix May 1, 2025
25e1124
🥅 Fix type error
lapidix May 1, 2025
764fe76
🥅 Fix export error
lapidix May 1, 2025
45eb0dc
🔧 Udpate config file
lapidix May 1, 2025
eac905d
🥅 Fix api url error
lapidix May 1, 2025
f270f31
🔧 Modify api url
lapidix May 1, 2025
4af8b01
🔇 Remove debug logs
lapidix May 1, 2025
1b8d07c
🐛 Fix bug add post hook
lapidix May 1, 2025
c0d85f6
🚚 Rename api method
lapidix May 1, 2025
79508c3
:sparkles: implement use case interfaces for post, user, and comment …
lapidix Jun 22, 2025
6017f5b
:construction: update import path and remove package manager metadata
lapidix Jun 22, 2025
618839a
:recycle: refactor: implement domain-driven design for comment featur…
lapidix Jun 22, 2025
3bd9c8b
:recycle: implement domain-driven design for user and comment entitie…
lapidix Jun 23, 2025
268ddc8
:recycle: migrate user-related types to DTO pattern and update refer…
lapidix Jun 23, 2025
1535afc
:recycle: rename data interfaces to entity types and add address/comp…
lapidix Jun 23, 2025
a3ba0f8
:recycle: standardize file naming convention across entities and feat…
lapidix Jun 23, 2025
33fa27a
:recycle: implement domain-driven design for comment feature
lapidix Jun 23, 2025
e79da42
:recycle: implement user repository pattern and update service depend…
lapidix Jun 23, 2025
02b8665
:recycle: migrate API layer to adapter pattern and consolidate servic…
lapidix Jun 23, 2025
eb1c9db
:truck: rename userApi to userAdapter for consistent naming convention
lapidix Jun 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Deploy to GitHub Pages
on:
push:
branches:
- main

permissions:
contents: read
pages: write
id-token: write

jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: latest

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: "20"
cache: "pnpm"

- name: Install dependencies
run: pnpm install

- name: Build with Vite
run: pnpm run build

- name: Create 404 page
run: cp dist/index.html dist/404.html

- name: Disable Jekyll
run: touch dist/.nojekyll

- name: Setup Pages
uses: actions/configure-pages@v4

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: "./dist"

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
"coverage": "vitest run --coverage"
},
"dependencies": {
"@tanstack/react-query": "^5.74.7",
"react": "^19.1.0",
"react-dom": "^19.1.0"
"react-dom": "^19.1.0",
"zustand": "^5.0.3"
},
"devDependencies": {
"@eslint/js": "^9.25.1",
Expand Down Expand Up @@ -41,5 +43,6 @@
"vite": "^6.3.3",
"vitest": "^3.1.2",
"vitest-browser-react": "^0.1.1"
}
},
"packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
}
46 changes: 45 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 0 additions & 20 deletions src/App.tsx

This file was deleted.

25 changes: 25 additions & 0 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { PostsManagerPage } from "@/pages/posts/manager"

import { Footer } from "@/widgets/common/footer"
import { Header } from "@/widgets/common/header"
import { BrowserRouter as Router } from "react-router-dom"
import { TanstackQueryProvider } from "./provider/tanstack-query"
import "./styles/index.css"

const App = () => {
return (
<TanstackQueryProvider>
<Router>
<div className="flex flex-col min-h-screen">
<Header />
<main className="flex-grow container mx-auto px-4 py-8">
<PostsManagerPage />
</main>
<Footer />
</div>
</Router>
</TanstackQueryProvider>
)
}

export default App
1 change: 0 additions & 1 deletion src/app/assets/react.svg

This file was deleted.

1 change: 1 addition & 0 deletions src/app/provider/tanstack-query/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { TanstackQueryProvider } from "./tanstack-query-provider";
7 changes: 7 additions & 0 deletions src/app/provider/tanstack-query/tanstack-query-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { queryClient } from "@/shared/api"
import { QueryClientProvider } from "@tanstack/react-query"
import * as React from "react"

export const TanstackQueryProvider = ({ children }: { children: React.ReactNode }) => {
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
}
File renamed without changes.
52 changes: 52 additions & 0 deletions src/entities/comment/api/comment.adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ApiClient } from "@/shared/api/api"
import { ApiResponse } from "@/shared/types"
import { CommentResponseDto } from "../dto/comment.dto"
import { CommentEntity } from "../types"

export const commentAdapter = (apiClient: ApiClient) => ({
listByPost: async (postId: number): Promise<CommentResponseDto> => {
return await apiClient
.get<ApiResponse<CommentResponseDto>>(`/comments/post/${postId}`)
.then((response) => response.data)
.catch((error) => {
console.error("Comments List Error: ", error)
return error
})
},
create: async (body: string, postId: number, userId: number): Promise<CommentEntity> => {
return await apiClient
.post<ApiResponse<CommentEntity>>(`/comments/add`, { body, postId, userId })
.then((response) => response.data)
.catch((error) => {
console.error("Comment Create Error: ", error)
return error
})
},
update: async (id: number, body: string): Promise<CommentEntity> => {
return await apiClient
.put<ApiResponse<CommentEntity>>(`/comments/${id}`, { body })
.then((response) => response.data)
.catch((error) => {
console.error("Comment Update Error: ", error)
return error
})
},
remove: async (id: number): Promise<boolean> => {
return await apiClient
.delete<ApiResponse<void>>(`/comments/${id}`)
.then((response) => response.ok)
.catch((error) => {
console.error("Comment Remove Error: ", error)
return error
})
},
likeComment: async (id: number): Promise<boolean> => {
return await apiClient
.patch<ApiResponse<void>>(`/comments/${id}/like`)
.then((response) => response.ok)
.catch((error) => {
console.error("Comment Like Error: ", error)
return error
})
},
})
3 changes: 3 additions & 0 deletions src/entities/comment/api/comment.query-key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const COMMENT_QUERY_KEY = {
byPostId: (postId: number) => ["comments", postId] as const,
}
2 changes: 2 additions & 0 deletions src/entities/comment/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { commentAdapter } from "./comment.adapter"
export { COMMENT_QUERY_KEY } from "./comment.query-key"
77 changes: 77 additions & 0 deletions src/entities/comment/core/comment.domain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { CommentEntity, UserReference } from "@/entities/comment/types"
import { CommentBody, Timestamp, UserReferenceVO } from "../value-objects"

/**
* Comment 도메인 엔티티
* Value Object를 활용하여 비즈니스 규칙과 불변성을 강화
*/
export class Comment implements CommentEntity {
private readonly _id: number
private _body: CommentBody
private readonly _postId: number
private readonly _user: UserReferenceVO
private readonly _createdAt: Timestamp
private _likes: number
private _updatedAt: Timestamp | null

constructor(
id: number,
body: string,
postId: number,
user: UserReference,
createdAt: Date | string | number = new Date(),
likes: number = 0,
updatedAt: Date | string | number | null = null,
) {
this._id = id
this._body = new CommentBody(body)
this._postId = postId
this._user = new UserReferenceVO(user)
this._createdAt = new Timestamp(createdAt)
this._likes = likes
this._updatedAt = updatedAt ? new Timestamp(updatedAt) : null
}

updateBody(newBody: string): void {
this._body = new CommentBody(newBody)
this._updatedAt = Timestamp.now()
}

like(): void {
this._likes += 1
}

unlike(): void {
if (this._likes > 0) {
this._likes -= 1
}
}

get id(): number {
return this._id
}

get body(): string {
return this._body.text
}

get postId(): number {
return this._postId
}

get user(): UserReference {
return this._user.toDTO()
}

get createdAt(): Date {
return this._createdAt.toDate()
}

get updatedAt(): Date | null {
return this._updatedAt ? this._updatedAt.toDate() : null
}

get likes(): number {
return this._likes
}
}
Loading