notsoocool / codecache

CodeCache is a dynamic web application designed to streamline the way developers manage and access code snippets. The platform provides a comprehensive library of code snippets, allowing users to save, organize, and retrieve useful code snippets for various programming languages and use cases.
https://codecache.tech
MIT License
18 stars 54 forks source link

Mismatching models and data fetching #20

Closed inkerton closed 2 months ago

inkerton commented 2 months ago

Describe the bug A new snippet is being saved in SnippetRequest collection but snippets are being fetched from Snippet collection.

To Reproduce Steps to reproduce the behavior:

  1. Go to 'app/api/snippets/route.ts'
  2. Scroll down to 'GET' and 'POST' requests
  3. See error

Expected behavior It should either save in both or should fetch from Snippets collection. If there is a prior list of snippet collections like a template then that should be provided but since when running on local system their is no such thing it is causing many issues.

Screenshots If applicable, add screenshots to help explain your problem. image image

Desktop (please complete the following information):

Smartphone (please complete the following information):

inkerton commented 2 months ago

I am currently working on it so @notsoocool assign it to me under gssoc-extnd and hacktoberfest.

inkerton commented 2 months ago

I can save the same snippet in both collection that would be easier or I can change every api call like in bookmark. A.

import { NextResponse } from "next/server";
import Snippet from "@/lib/db/snippetModel";
import SnippetRequest from "@/lib/db/snippetRequestModel";
import dbConnect from "@/lib/db/connect";
import { currentUser } from "@clerk/nextjs/server";

export async function GET() {
    try {
        await dbConnect();
        const snippets = await Snippet.find({});
        console.log("Fetched Snippets"); // Add debug log
        return NextResponse.json(snippets);
    } catch (error) {
        console.error("Error fetching snippets:", error); // Add debug log
        return NextResponse.json(
            { error: "Error fetching snippets" },
            { status: 500 }
        );
    }
}

export async function POST(req: Request) {
    try {
        await dbConnect();
        const { title, language, code, description, tags, category, difficulty, usage } = await req.json();
        // console.log("Request body:", { title, language, code, description, tags, category, difficulty, usage }); // Log the incoming data
        // console.log("Database Connection Status:", mongoose.connection.readyState);

        const user = await currentUser();
        const userId = user?.id;

        if (!userId) {
            return NextResponse.json(
                { error: "User not authenticated" },
                { status: 401 }
            );
        }
        const newSnippet = new SnippetRequest({
            title,
            language,
            code,
            description,
            tags,
            category,          // Ensure this is included
            difficulty,        // Ensure this is included
            usage,             // Ensure this is included
            submittedBy: userId,
        });

        await newSnippet.save();

        const newsnippet = new Snippet({
            title,
            language,
            code,
            description,
            tags,
            category,          // Ensure this is included
            difficulty,        // Ensure this is included
            usage,             // Ensure this is included
            // submittedBy: userId,
        });

        await newsnippet.save();

        return NextResponse.json(
            { message: "Snippet submitted for approval" },
            { status: 201 }
        );
    } catch (error) {
        console.error("Error saving snippet request:", error); // Log the error
        return NextResponse.json(
            { message: "Failed to add snippet" },
            { status: 500 }
        );
    }
}

OR B.

import { NextResponse } from "next/server";
import Snippet from "@/lib/db/snippetModel";
import dbConnect from "@/lib/db/connect";
import { currentUser } from "@clerk/nextjs/server";
import SnippetRequest from "@/lib/db/snippetRequestModel";

export async function PATCH(req: Request, { params }: { params: { id: string } }) {
    const { id } = params;

    try {
        const user = await currentUser();
        const userId = user?.id;

        if (!userId) {
            return NextResponse.json({ error: "User not authenticated" }, { status: 401 });
        }

        await dbConnect();

        // Step 1: Find the snippet by ID
        let snippet = await Snippet.findById(id);

        // Step 2: If snippet doesn't exist, check SnippetRequest collection
        if (!snippet) {
            const snippetReq = await SnippetRequest.findById(id);

            if (!snippetReq) {
                // If snippet not found in either collection, return error
                return NextResponse.json({ error: "Snippet not found" }, { status: 404 });
            }

            // Step 3: Create a new snippet in Snippet collection using SnippetRequest data
            snippet = await Snippet.create({
                title: snippetReq.title,
                language: snippetReq.language,
                code: snippetReq.code,
                description: snippetReq.description,
                tags: snippetReq.tags,
                category: snippetReq.category,
                difficulty: snippetReq.difficulty,
                usage: snippetReq.usage,
                bookmarkedBy: [userId], // Start with the current user bookmarking it
            });

        } else {
            // Step 4: If the snippet exists, toggle the bookmark
            const isBookmarked = snippet.bookmarkedBy.includes(userId);
            if (isBookmarked) {
                // User is already bookmarked, remove userId
                snippet.bookmarkedBy = snippet.bookmarkedBy.filter((uid) => uid !== userId);
            } else {
                // User is not bookmarked, add userId
                snippet.bookmarkedBy.push(userId);
            }
        }

        // Step 5: Save snippet with the updated bookmarkedBy array
        const updatedSnippet = await Snippet.findByIdAndUpdate(
            snippet._id, // Use the newly created snippet or existing one
            { bookmarkedBy: snippet.bookmarkedBy }, // Only update the bookmarkedBy field
            { new: true } // Return the modified document
        );

        return NextResponse.json(updatedSnippet, { status: 200 });
    } catch (error) {
        console.error("Error updating bookmark:", error);
        return NextResponse.json({ error: "Error updating bookmark" }, { status: 500 });
    }
}
notsoocool commented 2 months ago

Hi @inkerton ,

Thank you for your detailed report! However, I wanted to clarify a bit about the role of the SnippetRequestcollection in our system.

The SnippetRequest model was specifically created for admin review purposes. When a user submits a new snippet, it is stored in SnippetRequest first so that an admin can approve or reject the submission. Once approved, the snippet is then moved to the main Snippet collection, which is where all active snippets are fetched from for display.

Therefore, the behavior you're experiencing is actually intended: snippets should be fetched from the Snippet collection, not SnippetRequest. The latter is only for unapproved submissions that are pending admin review.

notsoocool commented 2 months ago

@inkerton If you have any more questions, feel free to ask me. I'll plan to close this issue and PR after an hour.

inkerton commented 2 months ago

how do I approve the snippets i am running it on local right now. Explain that process to me since on sign in their is no role assigned or asked and I was working on bookmarks page. I won't be able to fetch the snippets. @notsoocool

inkerton commented 2 months ago

How do I get admin access while running it locally? @notsoocool

notsoocool commented 2 months ago

Hi @inkerton,

The admin role is only limited to certain users, so it's not required for working on the bookmarks page. You won't need admin permission to access the bookmarks, as they are stored in theSnippetmodel, not the SnippetRequest model.

To access the bookmarks, you can fetch snippets directly from the Snippet model. Each snippet has a field that tracks which users have bookmarked it. You can use this field to filter and display only the snippets bookmarked by the current user.

Screenshot 2024-10-02 at 11 15 40 PM

as you can see on the Left side the Snippet Model has boomarkedBy field but on the right side in SnippetRequest model there is no such field. So no need of admin role, required to implement this feature.

Let me know if you need more details on how to implement this, and feel free to reach out if you have any further questions!

Still if you need admin perms do tell me i will temporarily give it to you