added endpoint for getting postTags and fixed follow bug

This commit is contained in:
Kai Ritthaler 2025-06-27 09:57:08 +02:00
parent f035635df2
commit 748676c38f
8 changed files with 92 additions and 14 deletions

View file

@ -2,11 +2,12 @@ import express, { Request, Response } from "express";
import { StatusCodes } from "http-status-codes";
import { PrismaClient, Post } from "../../prisma/app/generated/prisma/client";
import { feedQuerySchema } from "../schemas/feedSchemas";
import { z } from "zod";
const prisma = new PrismaClient();
export const feed = async (req: Request, res: Response) => {
try {
const query = feedQuerySchema.parse(req.query);
const take = query.limit || 10;
const take = query.limit;
const posts = await prisma.post.findMany({
take: take + 1,
@ -25,6 +26,13 @@ export const feed = async (req: Request, res: Response) => {
res.status(200).json({ posts, nextCursor });
} catch (err) {
if (err instanceof z.ZodError) {
res.status(400).json({
error: "Invalid query parameters",
details: err.errors,
});
return;
}
console.error(err);
res.status(400).json({ error: "Invalid query parameters" });
}

View file

@ -3,6 +3,7 @@ import express, { Request, Response } from "express";
import { JwtPayload } from "jsonwebtoken";
import { PrismaClient, Follow } from "../../prisma/app/generated/prisma/client";
const prisma = new PrismaClient();
export const followUser = async (req: Request, res: Response) => {
const username: string = req.params.username;
const followingUser: JwtPayload = req.user!;
@ -27,7 +28,7 @@ export const followUser = async (req: Request, res: Response) => {
});
return;
}
if (user.username == username) {
if (user.id == followingUser.sub) {
res.status(StatusCodes.BAD_REQUEST).json({
error: "Bad Request",
details: [{ message: "You can`t follow yourself" }],

View file

@ -4,7 +4,6 @@ import { StatusCodes } from "http-status-codes";
import { JwtPayload } from "jsonwebtoken";
import { PrismaClient, Post } from "../../prisma/app/generated/prisma/client";
import { minioClient } from "../server";
import { object } from "zod";
import { uploadPostSchema } from "../schemas/postSchemas";
dotenv.config();
const prisma = new PrismaClient();
@ -190,11 +189,20 @@ export const getPost = async (req: Request, res: Response) => {
// get all posts from a user
export const getUserPosts = async (req: Request, res: Response) => {
try {
const user: JwtPayload | undefined = req.user;
const username: string = req.params.username;
const posts = await prisma.post.findMany({
where: {
...(user
? {
OR: [
{ status: "PRIVATE", userId: user.id },
{ status: "PUBLIC" },
],
}
: { status: "PUBLIC" }),
user: {
username: username, // hier greifst du auf die relationierte User-Tabelle zu
username: username,
},
},
});
@ -329,3 +337,31 @@ export const removeLike = async (req: Request, res: Response) => {
});
}
};
export const getTags = async (req: Request, res: Response) => {
try {
const tags = await prisma.tag.findMany({
take: 150,
include: {
_count: {
select: {
posts: true,
},
},
},
orderBy: {
posts: {
_count: "desc",
},
},
});
const data: string[] = tags.map((tag) => tag.name);
res.status(StatusCodes.OK).json(data);
} catch (err) {
console.error(err);
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
error: "Failed to retrieve tags",
details: [{ message: "Internal server error" }],
});
}
};

View file

@ -19,6 +19,7 @@ type PublicUser = {
profilePictureUrl: string | null;
followers: number;
following: number;
posts: number;
};
const getUser: (userId: string) => Promise<PublicUser | undefined> = async (
userId: string
@ -47,6 +48,11 @@ const getUser: (userId: string) => Promise<PublicUser | undefined> = async (
followingUserId: userId,
},
});
const postCount = await prisma.post.count({
where: {
userId: userId,
},
});
const publicUser: PublicUser = {
id: user.id,
username: user.username,
@ -54,6 +60,7 @@ const getUser: (userId: string) => Promise<PublicUser | undefined> = async (
profilePictureUrl,
followers: followerCount,
following: followingCount,
posts: postCount,
};
return publicUser;
}

View file

@ -1,6 +1,7 @@
import express from "express";
import {
getPost,
getTags,
getUserPosts,
like,
removeLike,
@ -156,4 +157,29 @@ router.post("/like/:postId", authenticateToken(), like);
*/
router.delete("/removeLike/:postId", authenticateToken(), removeLike);
/**
* @swagger
* /api/posts/tags:
* get:
* summary: Get posttags
* description: Returns posttags
* tags:
* - Posts
* responses:
* 200:
* description: List of tags
* content:
* application/json:
* schema:
* type: object
* properties:
* tags:
* type: array
* items:
* type: string
* 500:
* description: Server error
*/
router.get("/tags", getTags);
export default router;

View file

@ -8,7 +8,7 @@ import {
} from "../controllers/profileController";
const profileRouter = express.Router();
import { upload } from "../middleware/uploadSingle";
import { updateBioSchema } from "../schemas/feedSchemas";
import { updateBioSchema } from "../schemas/profileSchemas";
import { validateData } from "../middleware/validationMiddleware";
/**
* @swagger
@ -97,7 +97,7 @@ profileRouter.get("/getProfilePicture/:username", getProfilePicture);
* 401:
* description: Unauthorized
*/
profileRouter.post(
profileRouter.put(
"/updateBio",
authenticateToken(),
validateData(updateBioSchema),
@ -105,7 +105,7 @@ profileRouter.post(
);
/**
* @swagger
* /api/profile/get/{username}:
* /api/profile/{username}:
* get:
* summary: Get user data
* tags: [Profile]
@ -124,5 +124,5 @@ profileRouter.post(
* 401:
* description: Ungültige Anmeldedaten
*/
profileRouter.get("/get/:username", getProfile);
profileRouter.get("/:username", getProfile);
export default profileRouter;

View file

@ -1,4 +1,4 @@
import { string, z } from "zod";
import { z } from "zod";
export const feedQuerySchema = z.object({
createdAt: z.string().datetime().optional(),
@ -7,9 +7,5 @@ export const feedQuerySchema = z.object({
.transform((val) => parseInt(val, 10))
.refine((num) => num > 0 && num <= 30, {
message: "Limit must be between 1 and 30",
})
.optional(),
});
export const updateBioSchema = z.object({
bio: z.string(),
}),
});

View file

@ -0,0 +1,4 @@
import { z } from "zod";
export const updateBioSchema = z.object({
bio: z.string(),
});