Skip to content

Commit ef30fa3

Browse files
authored
Release dev to master (#390)
## RecNet auto-release action This is an auto-generated PR by recnet-release-action 🤖 Please make sure to test your changes in staging before merging. ## Related Issues - #392 - #371 ## Related PRs - #394 - #391 ## Staging links recnet-web: [https://vercel.live/link/recnet-git-dev-recnet-542617e7.vercel.app](https://vercel.live/link/recnet-git-dev-recnet-542617e7.vercel.app) recnet-api: [https://dev-api.recnet.io/api](https://dev-api.recnet.io/api)
2 parents b3a6c60 + 88e48f4 commit ef30fa3

37 files changed

+2517
-257
lines changed

apps/recnet-api/.env.sample

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,10 @@ export SMTP_PASS="ask for password"
2323
export SLACK_TOKEN="ask for token" # to be deprecated
2424
export SLACK_CLIENT_ID="ask for client id"
2525
export SLACK_CLIENT_SECRET="ask for client secret"
26-
export SLACK_TOKEN_ENCRYPTION_KEY="ask for token encryption key"
26+
export SLACK_TOKEN_ENCRYPTION_KEY="ask for token encryption key"
27+
28+
# AWS S3
29+
export AWS_BUCKET_NAME="ask for AWS bucket name"
30+
export AWS_ACCESS_KEY_ID="ask for AWS access key id"
31+
export AWS_SECRET_ACCESS_KEY="ask for AWS secret access key"
32+
export AWS_BUCKET_REGION="ask for AWS bucket region"

apps/recnet-api/.env.test

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,10 @@ SMTP_USER=test_user
55
SMTP_PASS=test_password
66
SLACK_CLIENT_ID=test_client_id
77
SLACK_CLIENT_SECRET=test_client_secret
8-
SLACK_TOKEN_ENCRYPTION_KEY=test_token_encryption_key
8+
SLACK_TOKEN_ENCRYPTION_KEY=test_token_encryption_key
9+
10+
# AWS S3
11+
export AWS_BUCKET_NAME=test_aws_bucket_name
12+
export AWS_ACCESS_KEY_ID=test_aws_access_key_id
13+
export AWS_SECRET_ACCESS_KEY=test_aws_secret_access_key
14+
export AWS_BUCKET_REGION=test_aws_bucket_region

apps/recnet-api/prisma/migrations/20240505220332_create_announcement_table/down.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
ALTER TABLE "Announcement" DROP CONSTRAINT "Announcement_createdById_fkey";
33

44
-- DropTable
5-
DROP TABLE "Announcement";
5+
DROP TABLE "Announcement";

apps/recnet-api/src/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { ArticleModule } from "./modules/article/article.module";
99
import { EmailModule } from "./modules/email/email.module";
1010
import { HealthModule } from "./modules/health/health.module";
1111
import { InviteCodeModule } from "./modules/invite-code/invite-code.module";
12+
import { PhotoStorageModule } from "./modules/photo-storage/photo-storage.module";
1213
import { RecModule } from "./modules/rec/rec.module";
1314
import { StatModule } from "./modules/stat/stat.module";
1415
import { SubscriptionModule } from "./modules/subscription/subscription.module";
@@ -32,6 +33,7 @@ import { LoggerMiddleware } from "./utils/middlewares/logger.middleware";
3233
EmailModule,
3334
AnnouncementModule,
3435
SubscriptionModule,
36+
PhotoStorageModule,
3537
],
3638
controllers: [],
3739
providers: [],

apps/recnet-api/src/config/common.config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,10 @@ export const SlackConfig = registerAs("slack", () => ({
3838
clientSecret: parsedEnv.SLACK_CLIENT_SECRET,
3939
tokenEncryptionKey: parsedEnv.SLACK_TOKEN_ENCRYPTION_KEY,
4040
}));
41+
42+
export const S3Config = registerAs("s3", () => ({
43+
bucketName: parsedEnv.AWS_BUCKET_NAME,
44+
accessKeyId: parsedEnv.AWS_ACCESS_KEY_ID,
45+
secretAccessKey: parsedEnv.AWS_SECRET_ACCESS_KEY,
46+
s3Region: parsedEnv.AWS_BUCKET_REGION,
47+
}));

apps/recnet-api/src/config/env.schema.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ export const EnvSchema = z.object({
3030
SLACK_TOKEN_ENCRYPTION_KEY: z
3131
.string()
3232
.transform((val) => Buffer.from(val, "base64")),
33+
// AWS S3 config
34+
AWS_BUCKET_NAME: z.string(),
35+
AWS_ACCESS_KEY_ID: z.string(),
36+
AWS_SECRET_ACCESS_KEY: z.string(),
37+
AWS_BUCKET_REGION: z.string(),
3338
});
3439

3540
export const parseEnv = (env: Record<string, string | undefined>) => {

apps/recnet-api/src/database/repository/article.repository.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ export default class ArticleRepository {
2020
});
2121
}
2222

23+
public async findArticleById(id: string): Promise<Article | null> {
24+
return this.prisma.article.findFirst({
25+
where: {
26+
id: id,
27+
},
28+
select: article.select,
29+
});
30+
}
31+
2332
public async createArticle(
2433
articleData: CreateArticleInput
2534
): Promise<Article> {
@@ -28,4 +37,15 @@ export default class ArticleRepository {
2837
select: article.select,
2938
});
3039
}
40+
41+
public async updateArticle(
42+
articleId: string,
43+
data: Partial<CreateArticleInput>
44+
): Promise<Article> {
45+
return this.prisma.article.update({
46+
where: { id: articleId },
47+
data,
48+
select: article.select,
49+
});
50+
}
3151
}

apps/recnet-api/src/database/repository/article.repository.type.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ export type CreateArticleInput = Omit<
1919
Article,
2020
"id" | "isVerified" | "abstract"
2121
> & {
22-
abstract?: string;
22+
abstract?: string | null;
2323
isVerified?: boolean;
2424
};

apps/recnet-api/src/database/repository/rec.repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export default class RecRepository {
173173
where.cutoff = filter.cutoff;
174174
} else if (filter.cutoff) {
175175
where.cutoff = {
176-
gte: filter.cutoff.from,
176+
gt: filter.cutoff.from,
177177
lte: filter.cutoff.to,
178178
};
179179
}

apps/recnet-api/src/modules/article/article.controller.ts

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,34 @@
1-
import { Controller, Get, Query, UseFilters, UsePipes } from "@nestjs/common";
1+
import {
2+
Body,
3+
Controller,
4+
Get,
5+
NotFoundException,
6+
Param,
7+
Patch,
8+
Query,
9+
UseFilters,
10+
UsePipes,
11+
} from "@nestjs/common";
212
import {
313
ApiOkResponse,
414
ApiOperation,
515
ApiTags,
616
ApiBearerAuth,
717
} from "@nestjs/swagger";
818

19+
import { AdminUpdateArticleDto } from "@recnet-api/modules/article/dto/update.article.admin.dto";
20+
import { UpdateArticleDto } from "@recnet-api/modules/rec/dto/update.rec.dto";
921
import { Auth } from "@recnet-api/utils/auth/auth.decorator";
1022
import { RecnetExceptionFilter } from "@recnet-api/utils/filters/recnet.exception.filter";
11-
import { ZodValidationQueryPipe } from "@recnet-api/utils/pipes/zod.validation.pipe";
23+
import {
24+
ZodValidationBodyPipe,
25+
ZodValidationQueryPipe,
26+
} from "@recnet-api/utils/pipes/zod.validation.pipe";
1227

13-
import { getArticlesParamsSchema } from "@recnet/recnet-api-model";
28+
import {
29+
patchArticlesAdminRequestSchema,
30+
getArticlesParamsSchema,
31+
} from "@recnet/recnet-api-model";
1432

1533
import { GetArticleByLinkResponse } from "./article.response";
1634
import { ArticleService } from "./article.service";
@@ -25,7 +43,7 @@ export class ArticleController {
2543
@ApiOperation({
2644
summary: "Get Article By Link",
2745
description:
28-
"Get article by link. If the article is not found in the database, it will try to get metadata using the digital library service. Now it only supports arXiv.",
46+
"Get article by link. If the useDigitalLibrary option is true and article is not found in the database, it will try to get metadata using the digital library service.Otherwise it will only query from database. Now it only supports arXiv.",
2947
})
3048
@ApiOkResponse({ type: GetArticleByLinkResponse })
3149
@ApiBearerAuth()
@@ -35,7 +53,30 @@ export class ArticleController {
3553
public async getArticleByLink(
3654
@Query() dto: QueryArticleDto
3755
): Promise<GetArticleByLinkResponse> {
38-
const { link } = dto;
39-
return this.articleService.getArticleByLink(link);
56+
const { link, useDigitalLibraryFallback } = dto;
57+
return this.articleService.getArticleByLink(
58+
link,
59+
useDigitalLibraryFallback
60+
);
61+
}
62+
63+
@ApiOperation({
64+
summary: "Admin update article by id",
65+
description: "Update an existing article's fields (title, link, etc.)",
66+
})
67+
@ApiOkResponse({
68+
description: "Return the updated article",
69+
})
70+
@ApiBearerAuth()
71+
@Patch("admin/:id")
72+
@Auth({ allowedRoles: ["ADMIN"] })
73+
@UsePipes(new ZodValidationBodyPipe(patchArticlesAdminRequestSchema))
74+
public async updateArticleById(
75+
@Param("id") id: string,
76+
@Body() dto: AdminUpdateArticleDto
77+
) {
78+
const updatedArticle = await this.articleService.updateArticleById(id, dto);
79+
80+
return { article: updatedArticle };
4081
}
4182
}

0 commit comments

Comments
 (0)