Skip to content

Commit

Permalink
List all articles
Browse files Browse the repository at this point in the history
  • Loading branch information
fdaciuk committed Oct 13, 2021
1 parent 32f8a67 commit 4c83a9a
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/ports/adapters/db/db.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// import * as db from '@/ports/db-in-memory'
import * as db from '@/ports/prisma'
import * as db from '@/ports/db-in-memory'
// import * as db from '@/ports/prisma'
export { db as database }
13 changes: 13 additions & 0 deletions src/ports/adapters/db/modules/article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ export const createArticleInDB: CreateArticleInDB = async (data) => {
}
}

export const getArticlesFromDB = async () => {
const articles = await db.getArticlesFromDB()
return articles.map(article => ({
...article,
author: {
username: article.author.username,
bio: article.author.bio ?? '',
image: article.author.image ?? '',
following: false,
},
}))
}

type AddCommentToAnArticleInDB = (data: CreateComment) => Promise<CommentOutput>
export const addCommentToAnArticleInDB: AddCommentToAnArticleInDB = async (data) => {
const comment = await db.addCommentToAnArticleInDB(data)
Expand Down
29 changes: 28 additions & 1 deletion src/ports/adapters/http/modules/article.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { pipe } from 'fp-ts/function'
import * as TE from 'fp-ts/TaskEither'
import * as E from 'fp-ts/Either'
import { CreateArticle, ArticleOutput } from '@/core/article/types'
import { CreateComment } from '@/core/comment/types'
import { CreateComment, CommentOutput } from '@/core/comment/types'
import * as db from '@/ports/adapters/db'
import * as article from '@/core/article/use-cases'

import { getError } from '@/ports/adapters/http/http'
import { DBArticle } from '@/ports/adapters/db/types'

export function registerArticle (data: CreateArticle) {
return pipe(
Expand All @@ -16,10 +18,29 @@ export function registerArticle (data: CreateArticle) {
)
}

export function fetchArticles () {
return pipe(
TE.tryCatch(
() => db.getArticlesFromDB(),
E.toError,
),
TE.map(getArticlesResponse),
TE.mapLeft(getError),
)
}

function getArticlesResponse (articles: DBArticle[]) {
return {
articles,
articlesCount: articles.length,
}
}

export function addCommentToAnArticle (data: CreateComment) {
return pipe(
data,
article.addCommentToAnArticle(db.addCommentToAnArticleInDB),
TE.map(getCommentResponse),
TE.mapLeft(getError),
)
}
Expand All @@ -37,3 +58,9 @@ const getArticleResponse = (article: GetArticleResponseInput) => {
},
}
}

const getCommentResponse = (comment: CommentOutput) => {
return {
comment,
}
}
23 changes: 22 additions & 1 deletion src/ports/db-in-memory/article.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { v4 as uuidv4 } from 'uuid'

import { NotFoundError } from '@/helpers/errors'
import { dbInMemory as db } from './db'

Expand Down Expand Up @@ -41,6 +40,28 @@ export const createArticleInDB: CreateArticleInDB<ArticleReturned> = async (data
}
}

export const getArticlesFromDB = async () => {
const articles = db.articles

return Object.values(articles)
.map(article => {
const { authorId, ...rest } = article
const author = db.users[authorId]

if (!author) {
throw new NotFoundError('User does not exist')
}

return {
...rest,
favorited: false, // TODO: Mock
authorId,
author,
}
})
.sort((a, b) => a.createdAt > b.createdAt ? -1 : 1)
}

type CommentReturned = DBComment & {
author: DBUser
}
Expand Down
8 changes: 8 additions & 0 deletions src/ports/express/modules/article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ articleRoutes.post('/api/articles', auth, async (req: Request, res: Response) =>
)()
})

articleRoutes.get('/api/articles', (_req: Request, response: Response) => {
pipe(
article.fetchArticles(),
TE.map(result => response.json(result)),
TE.mapLeft(result => response.status(result.code).json(result.error)),
)()
})

articleRoutes.post('/api/articles/:slug/comments', auth, async (req: Request, res: Response) => {
const payload = getPayload(req.auth)
const slugProp = 'slug'
Expand Down
8 changes: 8 additions & 0 deletions src/ports/fastify/modules/article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ app.post<CreateArticleApi>('/api/articles', authOptions, (req, reply) => {
)()
})

app.get('/api/articles', (_req, reply) => {
pipe(
article.fetchArticles(),
TE.map(result => reply.send(result)),
TE.mapLeft(result => reply.code(result.code).send(result.error)),
)()
})

type AddCommentApi = {
Body: {
comment: CreateComment
Expand Down
21 changes: 21 additions & 0 deletions src/ports/prisma/modules/article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,27 @@ export const createArticleInDB: CreateArticleInDB<ArticleReturned> = async (data
}
}

export const getArticlesFromDB = async () => {
const articles = await prisma.article.findMany({
orderBy: {
createdAt: 'desc',
},
include: {
author: true,
tagList: true,
},
})

return articles.map(article => ({
...article,
favorited: false, // TODO: Mock
favoritesCount: 0, // TODO: Mock
tagList: article.tagList.map(({ name }) => name),
createdAt: article.createdAt.toISOString(),
updatedAt: article.updatedAt.toISOString(),
}))
}

type CommentReturned = Omit<Comment, 'createdAt' | 'updatedAt'> & {
createdAt: string
updatedAt: string
Expand Down

0 comments on commit 4c83a9a

Please sign in to comment.