Fix CommentRoutes
This commit is contained in:
parent
8865b58747
commit
d0e94808bb
@ -1,5 +1,6 @@
|
||||
import {ICredentials} from './ICredentials'
|
||||
import {ICommentTree} from './ICommentTree'
|
||||
import {IComment} from './IComment'
|
||||
import {ICredentials} from './ICredentials'
|
||||
import {IUser} from './IUser'
|
||||
|
||||
export interface IAPIDef {
|
||||
@ -34,13 +35,14 @@ export interface IAPIDef {
|
||||
}
|
||||
'/story/:storyId/comments': {
|
||||
'get': {
|
||||
response: IComment[],
|
||||
response: ICommentTree,
|
||||
params: {
|
||||
storyId: number // TODO might have to change to string (url)
|
||||
storyId: number
|
||||
}
|
||||
}
|
||||
'post': {
|
||||
response: IComment,
|
||||
body: IComment,
|
||||
params: {
|
||||
storyId: number
|
||||
}
|
||||
|
||||
@ -4,5 +4,5 @@ export * from './ICommentTree'
|
||||
export * from './ICredentials'
|
||||
export * from './IRoutes'
|
||||
export * from './ISite'
|
||||
export * from './ITeam'
|
||||
export * from './IUser'
|
||||
import * from './ITeam'
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import {AsyncRouter} from '../router'
|
||||
import {BaseRoute} from './BaseRoute'
|
||||
import {IAPIDef} from '@rondo/common'
|
||||
import {ICommentService} from '../services/ICommentService'
|
||||
import {ensureLoggedInApi} from '../middleware'
|
||||
|
||||
export class CommentRoutes extends BaseRoute<IAPIDef> {
|
||||
@ -15,53 +16,54 @@ export class CommentRoutes extends BaseRoute<IAPIDef> {
|
||||
|
||||
t.get('/story/:storyId/comments', async req => {
|
||||
const {storyId} = req.params
|
||||
// TODO retrieve comments from story
|
||||
return []
|
||||
return this.commentService.find(storyId)
|
||||
})
|
||||
|
||||
t.use(ensureLoggedInApi)
|
||||
|
||||
t.post('/story/:storyId/comments', async req => {
|
||||
const {storyId} = req.params
|
||||
const comment = req.body
|
||||
// TODO save a comment
|
||||
return comment
|
||||
comment.storyId = storyId
|
||||
return this.commentService.saveRoot(comment, req.user!.id)
|
||||
})
|
||||
|
||||
t.post('/comments/:parentId', async req => {
|
||||
const {parentId} = req.params
|
||||
const comment = req.body
|
||||
// TODO save a comment
|
||||
return comment
|
||||
comment.parentId = parentId
|
||||
return this.commentService.save(comment, req.user!.id)
|
||||
})
|
||||
|
||||
t.put('/comments/:commentId', async req => {
|
||||
const comment = req.body
|
||||
// TODO edit a comment
|
||||
return comment
|
||||
comment.id = req.params.commentId
|
||||
return this.commentService.edit(comment, req.user!.id)
|
||||
})
|
||||
|
||||
t.delete('/comments/:commentId', async req => {
|
||||
const {commentId} = req.params
|
||||
// TODO delete a comment
|
||||
return this.commentService.delete(commentId, req.user!.id)
|
||||
})
|
||||
|
||||
t.post('/comments/:commentId/vote', async req => {
|
||||
const {commentId} = req.params
|
||||
// TODO upvote a comment
|
||||
return this.commentService.upVote(commentId, req.user!.id)
|
||||
})
|
||||
|
||||
t.delete('/comments/:commentId/vote', async req => {
|
||||
const {commentId} = req.params
|
||||
// TODO delete a vote
|
||||
return this.commentService.deleteVote(commentId, req.user!.id)
|
||||
})
|
||||
|
||||
t.post('/comments/:commentId/spam', async req => {
|
||||
const {commentId} = req.params
|
||||
// TODO report comment as spam
|
||||
return this.commentService.markAsSpam(commentId, req.user!.id)
|
||||
})
|
||||
|
||||
t.delete('/comments/:commentId/spam', async req => {
|
||||
const {commentId} = req.params
|
||||
// TODO delete spam report
|
||||
return this.commentService.unmarkAsSpam(commentId, req.user!.id)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@ -89,20 +89,16 @@ export class CommentService extends BaseService implements ICommentService {
|
||||
return editedComment
|
||||
}
|
||||
|
||||
async delete(comment: IComment, userId: number) {
|
||||
new Validator(comment)
|
||||
.ensure('id')
|
||||
.throw()
|
||||
|
||||
async delete(commentId: number, userId: number) {
|
||||
await this.getRepository(Comment)
|
||||
.update({
|
||||
id: comment.id,
|
||||
id: commentId,
|
||||
userId,
|
||||
}, {
|
||||
message: '(this message has been removed by the user)',
|
||||
})
|
||||
|
||||
return this.findOne(comment.id)
|
||||
return this.findOne(commentId)
|
||||
}
|
||||
|
||||
async upVote(commentId: number, userId: number) {
|
||||
|
||||
@ -11,7 +11,7 @@ export interface ICommentService {
|
||||
|
||||
edit(comment: IComment, userId: number): Promise<IComment>
|
||||
|
||||
delete(comment: IComment, userId: number): Promise<IComment | undefined>
|
||||
delete(commentId: number, userId: number): Promise<IComment | undefined>
|
||||
|
||||
upVote(commentId: number, userId: number): Promise<void>
|
||||
|
||||
|
||||
@ -7,5 +7,7 @@ export interface ISiteService {
|
||||
|
||||
find(userId: number): Promise<ISite[]>
|
||||
|
||||
findByDomain(domain: string): Promise<ISite | undefined>
|
||||
|
||||
// TODO add other methods
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import {Site} from '../entities/Site'
|
||||
|
||||
export class SiteService extends BaseService implements ISiteService {
|
||||
async create(name: string, teamId: number, userId: number) {
|
||||
// TODO check site limit per user
|
||||
return this.getRepository(Site).save({
|
||||
name,
|
||||
teamId,
|
||||
@ -11,7 +12,7 @@ export class SiteService extends BaseService implements ISiteService {
|
||||
})
|
||||
}
|
||||
|
||||
findOne(id: number, teamId: number) {
|
||||
async findOne(id: number, teamId: number) {
|
||||
return this.getRepository(Site).findOne({
|
||||
where: {
|
||||
id,
|
||||
@ -20,6 +21,14 @@ export class SiteService extends BaseService implements ISiteService {
|
||||
})
|
||||
}
|
||||
|
||||
async findByDomain(domain: string) {
|
||||
return this.getRepository(Site).findOne({
|
||||
where: {
|
||||
domain,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async find(teamId: number) {
|
||||
return this.getRepository(Site).find({
|
||||
where: { teamId },
|
||||
|
||||
@ -1,10 +1,48 @@
|
||||
import {IStoryService} from './IStoryService'
|
||||
import {Story} from '../entities/Story'
|
||||
import URL from 'url'
|
||||
import {BaseService} from './BaseService'
|
||||
import {ISiteService} from './ISiteService'
|
||||
import {IStoryService} from './IStoryService'
|
||||
import {ITransactionManager} from '../database/ITransactionManager'
|
||||
import {Story} from '../entities/Story'
|
||||
|
||||
export class StoryService extends BaseService implements IStoryService {
|
||||
constructor(
|
||||
transactionManager: ITransactionManager,
|
||||
protected readonly siteService: ISiteService,
|
||||
) {
|
||||
super(transactionManager)
|
||||
}
|
||||
|
||||
export class StoryService implements IStoryService {
|
||||
async findOne(url: string) {
|
||||
const parsedUrl = URL.parse(url)
|
||||
const hostname = parsedUrl.hostname
|
||||
const storyRepo = this.getRepository(Story)
|
||||
const story = await storyRepo.findOne({
|
||||
where: {url},
|
||||
})
|
||||
if (story) {
|
||||
return story
|
||||
}
|
||||
|
||||
const domain = URL.parse(url).hostname
|
||||
const site = await this.siteService.findByDomain(domain!)
|
||||
|
||||
if (!site) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
try {
|
||||
return await storyRepo.save({
|
||||
url,
|
||||
siteId: site.id,
|
||||
})
|
||||
} catch (err) {
|
||||
// TODO check if unique constrint error
|
||||
|
||||
// This could happen if there are two concurrent requests coming in at
|
||||
// the same time, and they both cannot find the story, then decide to
|
||||
// create a record.
|
||||
return await storyRepo.findOne({
|
||||
where: {url},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import {ITeamService} from './ITeamService'
|
||||
import {Team} from '../entities/Team'
|
||||
|
||||
export class TeamService extends BaseService implements ITeamService {
|
||||
// TODO check team limit per user
|
||||
async create(name: string, userId: number) {
|
||||
return this.getRepository(Team).save({
|
||||
name,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user