Skip to content

Commit

Permalink
feat(api): implement db integration for /news/annotate api with user …
Browse files Browse the repository at this point in the history
…id as null
  • Loading branch information
swalahamani committed Nov 12, 2023
1 parent c770ccc commit bb50737
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 15 deletions.
4 changes: 3 additions & 1 deletion src/api/routes/newsRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ const newsRoute: RouteType = (apiRouter) => {
);

try {
const result = await newsService.annotateNews(uniqueRequestId);
const {body} = req;

const result = await newsService.annotateNews(uniqueRequestId, body);

logger.debug(
uniqueRequestId,
Expand Down
10 changes: 9 additions & 1 deletion src/constants/errors/newsServiceErrors.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import {asTypeIServiceError} from "@customTypes/commonServiceTypes";

const newsServiceError = asTypeIServiceError({
predictAnnotations: {
generic: {
NewsDoesNotExists: {
error: "NewsDoesNotExists",

message: "News doesn't exists",
},
},

annotateNews: {
InvalidAnnotation: {
error: "InvalidAnnotation",

message: "Invalid annotation options",
},
},
});

export {newsServiceError};
10 changes: 10 additions & 0 deletions src/db/repositories/AnnotationsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,14 @@ export default class AnnotationsRepository {
async all(): Promise<iAnnotationModel[]> {
return this.db.any("SELECT * FROM annotations");
}

// Returns a single annotation by id;
async findById(id: string): Promise<iAnnotationModel | null> {
return this.db.oneOrNone("SELECT * FROM annotations WHERE id = $1", id);
}

// Returns multiple annotations by ids;
async findByIds(ids: string[]): Promise<iAnnotationModel[]> {
return this.db.any("SELECT * FROM annotations WHERE id IN ($1:csv)", [ids]);
}
}
13 changes: 13 additions & 0 deletions src/db/repositories/NewsAnnotationRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,17 @@ export default class NewsAnnotationRepository {
userId,
});
}

// Add multiple news_annotation_map records, and returns the new objects;
async addMultiple(
newsAnnotationMapRecords: iNewsAnnotationMapModel[]
): Promise<iNewsAnnotationMapModel[]> {
return this.db.tx("add-multiple-news-annotation-map", async (t) => {
const queries = newsAnnotationMapRecords.map((record) => {
return t.none(sql.add, record);
});

return t.batch(queries);
});
}
}
71 changes: 58 additions & 13 deletions src/services/NewsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import {iGenericServiceResult} from "@customTypes/commonServiceTypes";
import {httpStatusCodes} from "@customTypes/networkTypes";

import {NullableString, StringArray} from "@customTypes/commonTypes";
import {iNewsSubmissionDTO} from "@customTypes/appDataTypes/newsTypes";
import {
iNewsAnnotationsInputDTO,
iNewsSubmissionDTO,
} from "@customTypes/appDataTypes/newsTypes";
import securityUtil from "@util/securityUtil";
import {newsServiceError} from "@constants/errors/newsServiceErrors";
import {DBTaskType} from "@db/repositories";
Expand Down Expand Up @@ -44,14 +47,61 @@ export default class NewsService {
}

public async annotateNews(
uniqueRequestId: NullableString
uniqueRequestId: NullableString,
annotationInputDTO: iNewsAnnotationsInputDTO
): Promise<iGenericServiceResult<null>> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return db.task("annotate-news", async (task) => {
logger.silly("Annotating the news");
return db.tx("annotate-news", async (transaction) => {
const {newsId, annotations} = annotationInputDTO;

logger.silly("Checking if news exists");
const newsRecord = await transaction.news.findById(newsId);

if (!newsRecord) {
return serviceUtil.buildResult(
false,
httpStatusCodes.CLIENT_ERROR_BAD_REQUEST,
uniqueRequestId,
newsServiceError.generic.NewsDoesNotExists
);
}

// await task.newsAnnotations.annotate();
console.log("hello");
// check if the annotations exists
logger.silly("Checking if annotations exists");
const annotationRecords = await transaction.annotations.findByIds(
annotations
);

if (annotationRecords.length !== annotations.length) {
return serviceUtil.buildResult(
false,
httpStatusCodes.CLIENT_ERROR_BAD_REQUEST,
uniqueRequestId,
newsServiceError.annotateNews.InvalidAnnotation
);
}

logger.silly("Inserting all annotations to annotation map table");
const newsAnnotationMapRecords = annotations.map((annotationId) => {
return {
id: securityUtil.generateUUID(),
newsId,
annotationId,
annotatedBy: "USER",
userId: null, // FIXME: Add userId from request
};
});

await transaction.batch(
newsAnnotationMapRecords.map((record) => {
return transaction.newsAnnotationMap.add(
record.id,
record.newsId,
record.annotationId,
record.annotatedBy,
record.userId
);
})
);

return serviceUtil.buildResult(
true,
Expand All @@ -68,17 +118,12 @@ export default class NewsService {
): Promise<iGenericServiceResult<{annotationIds: StringArray} | null>> {
return db.task("predict-annotation", async (task) => {
const newsRecord = await task.news.findById(newsId);
console.log(
"🚀 ~ file: NewsService.ts:52 ~ NewsService ~ returndb.task ~ newsRecord:",
newsRecord
);

if (!newsRecord) {
return serviceUtil.buildResult(
false,
httpStatusCodes.CLIENT_ERROR_BAD_REQUEST,
uniqueRequestId,
newsServiceError.predictAnnotations.NewsDoesNotExists
newsServiceError.generic.NewsDoesNotExists
);
}

Expand Down

0 comments on commit bb50737

Please sign in to comment.