Skip to content

Commit 9177c51

Browse files
feat: Create the whole CRUD for topics threads posts and user
Signed-off-by: amanraj <raj.aman4001@gmail.com>
1 parent c5daeab commit 9177c51

36 files changed

+2356
-2367
lines changed

apps/server/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ fastify.register(fastifyOauth2, {
4040
auth: fastifyOauth2.GOOGLE_CONFIGURATION,
4141
},
4242
scope: ["openid", "profile", "email"],
43-
startRedirectPath: "/auth/google",
43+
startRedirectPath: "/api/auth/google",
4444
callbackUri: env.GOOGLE_REDIRECT_URI,
4545
cookie: {
4646
secure: env.NODE_ENV === "production",

apps/server/src/routers/index.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
import type { FastifyInstance } from "fastify";
22
import { authRoutes } from "./auth";
33
import { postRoutes } from "./posts";
4+
import { statsRoutes } from "./stats";
45
import { threadRoutes } from "./threads";
56
import { topicRoutes } from "./topics";
67
import { userRoutes } from "./user";
78

89
export async function appRouter(fastify: FastifyInstance) {
9-
// Ensure the request object has a userId property at runtime
10-
// Middleware will assign the real ID when authenticated
1110
fastify.decorateRequest("userId", undefined);
12-
fastify.register(authRoutes, { prefix: "/auth" });
13-
fastify.register(userRoutes, { prefix: "/user" });
14-
fastify.register(topicRoutes);
15-
fastify.register(threadRoutes);
16-
fastify.register(postRoutes);
11+
fastify.register(authRoutes, { prefix: "/api/auth" });
12+
fastify.register(userRoutes, { prefix: "/api/user" });
13+
fastify.register(topicRoutes, { prefix: "/api" });
14+
fastify.register(threadRoutes, { prefix: "/api" });
15+
fastify.register(postRoutes, { prefix: "/api" });
16+
fastify.register(statsRoutes, { prefix: "/api" });
1717
}

apps/server/src/routers/posts.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,18 @@ export async function postRoutes(fastify: FastifyInstance) {
4444
const threadId = params.data.id;
4545
try {
4646
const postsQuery = DrizzleClient.select({
47-
// Post Data
4847
postId: postsTable.id,
4948
content: postsTable.content,
5049
createdAt: postsTable.createdAt,
51-
// Assuming we will track likes/votes later
5250
likes: postsTable.vote,
5351

54-
// Author/User Data
5552
authorId: usersTable.id,
5653
authorName:sql<string>`
5754
CASE
5855
WHEN ${usersTable.username} IS NOT NULL THEN ${usersTable.username}
5956
ELSE ${usersTable.firstName}
6057
END
6158
`.as('authorName'),
62-
// authorRole: usersTable.role,
6359

6460

6561

@@ -71,7 +67,6 @@ export async function postRoutes(fastify: FastifyInstance) {
7167
.limit(limit)
7268
.offset(offset);
7369

74-
// --- 🎯 COUNT QUERY (remains the same) ---
7570
const countQuery = DrizzleClient.select({ total: count() })
7671
.from(postsTable)
7772
.where(eq(postsTable.threadId, threadId));
@@ -138,7 +133,6 @@ export async function postRoutes(fastify: FastifyInstance) {
138133
.status(400)
139134
.send({ success: false, error: "Invalid request body" });
140135

141-
// Ensure thread exists
142136
const thread = await DrizzleClient.query.threads.findFirst({
143137
where: (t, { eq }) => eq(t.id, body.data.threadId),
144138
});

apps/server/src/routers/stats.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { count } from "drizzle-orm";
2+
import type { FastifyInstance } from "fastify";
3+
import { DrizzleClient } from "../db/index";
4+
import { posts as postsTable } from "../db/schema/post.schema";
5+
import { threads as threadsTable } from "../db/schema/thread.schema";
6+
import { topics as topicsTable } from "../db/schema/topic.schema";
7+
import { users as usersTable } from "../db/schema/user.schema";
8+
import { optionalAuth } from "./auth";
9+
10+
export async function statsRoutes(fastify: FastifyInstance) {
11+
fastify.get(
12+
"/stats",
13+
{
14+
preHandler: optionalAuth,
15+
},
16+
async (request, reply) => {
17+
try {
18+
const [topicsCount, threadsCount, postsCount, usersCount] =
19+
await Promise.all([
20+
DrizzleClient.select({ total: count() }).from(topicsTable),
21+
DrizzleClient.select({ total: count() }).from(threadsTable),
22+
DrizzleClient.select({ total: count() }).from(postsTable),
23+
DrizzleClient.select({ total: count() }).from(usersTable),
24+
]);
25+
26+
return reply.status(200).send({
27+
success: true,
28+
stats: {
29+
totalTopics: topicsCount[0]?.total ?? 0,
30+
totalThreads: threadsCount[0]?.total ?? 0,
31+
totalPosts: postsCount[0]?.total ?? 0,
32+
totalMembers: usersCount[0]?.total ?? 0,
33+
},
34+
});
35+
} catch (error) {
36+
fastify.log.error("Error fetching stats:", error);
37+
return reply.status(500).send({
38+
success: false,
39+
error: "Failed to fetch stats",
40+
});
41+
}
42+
},
43+
);
44+
}
45+

0 commit comments

Comments
 (0)