code100x/cms

repository·main·Indexed 23 days ago

https://github.com/code100x/cms

An open-source application serving as the backend and frontend for app.100xdevs.com. Built with PostgreSQL, Prisma, and pnpm, the CMS includes server actions for managing answers, bookmarks, bounties, and comments, as well as administrative tools for bounty confirmation and comment approval.

Tokens
9.7K
Snippets
12
Records
67
Agent score
81%

What's inside code100x-cms

  1. Install and run CMS locally via Instant Docker Setup

    main

    If you have Docker running, you can use the provided setup script to automate the environment configuration. This is the fastest way to get the project running.

    1. Clone the repository.
    2. Make the setup script executable.
    3. Run the script.
    git clone https://github.com/code100x/cms.git
    cd cms
    chmod +x setup.sh
    ./setup.sh
  2. Contribute to the CMS repository

    main

    To contribute code to the project, follow the standard fork-and-pull-request workflow:

    1. Fork the repository on GitHub.
    2. Clone your fork locally.
    3. Branch: Create a new feature branch (e.g., feature/fooBar).
    4. Commit: Make changes and commit them.
    5. Push: Push the branch to your GitHub fork.
    6. PR: Open a Pull Request against the main repository.

    Note: For major changes, open an issue first to discuss your proposal.

    git clone https://github.com/<your username>/cms.git
    cd cms
    git checkout -b feature/fooBar
    git commit -am 'Add some fooBar'
    git push origin feature/fooBar
  3. Install and run CMS via Traditional Docker Setup

    main

    Use this method if you want to manually manage the PostgreSQL database and the application lifecycle using pnpm.

    1. Start PostgreSQL: Run a PostgreSQL container using Docker.
    2. Environment Variables: Copy .env.example to .env.
    3. Dependencies: Install using pnpm install.
    4. Database Setup: Run migrations, generate the Prisma client, and seed the database.
    5. Development: Start the server with pnpm dev.
    # 1. Start PostgreSQL
    docker run -d \
    --name cms-db \
    -e POSTGRES_USER=myuser \
    -e POSTGRES_PASSWORD=mypassword \
    -e POSTGRES_DB=mydatabase \
    -p 5432:5432 \
    postgres
    
    # 2. Setup environment
    cp .env.example .env
    
    # 3. Install dependencies
    pnpm install
    
    # 4. Database operations
    pnpm prisma:migrate
    pnpm prisma generate
    pnpm db:seed
    
    # 5. Start server
    pnpm dev
  4. Manage questions with server actions

    main

    The src/actions/question/index.ts module provides a set of secure server actions for performing CRUD operations on questions. These actions are wrapped using createSafeAction to ensure schema validation and safe execution.

    Permissions and Authorization

    • Create: Requires an authenticated user session.
    • Update: Requires an authenticated user session and the user must be the original author of the question.
    • Delete: Requires an authenticated user session. Only the original author or a user with the ROLES.ADMIN role can delete a question.

    Automatic Slug Generation

    When creating or updating a question, the system automatically generates a URL-friendly slug based on the title. If a slug collision is detected, a random suffix is appended to ensure uniqueness.

  5. Configure the PostgreSQL database service

    main

    The db service uses the postgres:alpine image to provide the database backend.

    Key configuration details:

    • Environment Variables:
      • POSTGRES_USER: postgres
      • POSTGRES_PASSWORD: postgres
      • POSTGRES_DB: cms
    • Ports: Exposes port 5432 to the host.
    • Persistence: Uses a named volume postgres-data mapped to /var/lib/postgresql/data to ensure data persists across container restarts.
    • Healthcheck: Uses pg_isready to verify connectivity, with a 10s interval, 5s timeout, and 5 retries.
    db:
        image: postgres:alpine
        container_name: db
        restart: always
        environment:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: cms
        ports:
          - 5432:5432
        volumes:
          - postgres-data:/var/lib/postgresql/data
        healthcheck:
          test: [ 'CMD-SHELL', 'pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}' ]
          interval: 10s
          timeout: 5s
          retries: 5
    
    volumes:
      postgres-data:
  6. Configure Admin API authentication and Discord notifications

    main

    The Admin API relies on the following environment variables for security and notifications:

    • ADMIN_SECRET: The password required in the adminPassword field of the POST request body to authorize content creation.
    • NEXT_PUBLIC_DISCORD_WEBHOOK_URL: The webhook URL used to send automated updates to Discord when new notion, video, or appx content is added (if discordChecked is set to true).
  7. Configure the CMS application service

    main

    The app service runs the CMS application using the Dockerfile.dev build context. It relies on a db service being healthy before starting.

    Key configuration details:

    • Ports: The application exposes port 3000 (web) and 5555.
    • Environment Variables:
      • DATABASE_URL: Set to postgresql://postgres:postgres@db:5432/cms?schema=public by default.
      • NEXT_WEBPACK_USEPOLLING: Set to 1 to enable polling for Next.js development.
    • Volumes: Uses anonymous volumes for /usr/src/app/.next and /usr/src/app/node_modules to ensure build artifacts and dependencies are managed within the container.
    services:
      app:
        build:
          context: .
          dockerfile: Dockerfile.dev
          args:
            - DATABASE_URL=postgresql://postgres:postgres@db:5432/cms?schema=public
        container_name: cms-docker
        environment:
          - DATABASE_URL=postgresql://postgres:postgres@db:5432/cms?schema=public
          - NEXT_WEBPACK_USEPOLLING=1
        ports:
          - '3000:3000'
          - '5555:5555'
        volumes:
          - /usr/src/app/.next
          - /usr/src/app/node_modules
        depends_on:
          db:
            condition: service_healthy
  8. Create a 3D card effect using CardContainer, CardBody, and CardItem

    main

    To implement a 3D tilt effect, compose the CardContainer, CardBody, and CardItem components.

    1. CardContainer: The outermost wrapper that handles the perspective and mouse movement tracking. It calculates the rotation based on mouse position.
    2. CardBody: A container that sets up the 3D transform style for its children.
    3. CardItem: Individual elements inside the card that can be animated (translated or rotated) when the user hovers over the CardContainer.

    CardItem accepts several props to define its 'hover state' transformation:

    • translateX, translateY, translateZ: Movement in pixels.
    • rotateX, rotateY, rotateZ: Rotation in degrees.

    When the mouse leaves the CardContainer, all CardItem components automatically reset to their default (0) positions.

  9. Delete an event with deleteEvent()

    main

    Removes an event from the database by its unique identifier.

    Permissions: Requires administrative privileges (user email must match an entry in the ADMINS environment variable).

    Input: The numeric id of the event to delete.

    Side Effects: Triggers a revalidation of the '/' path.

  10. GetAppxVideoPlayerUrl

    main

    The GetAppxVideoPlayerUrl server action generates a secure, watermarked video player URL for a specific course and video. It internally calls GetAppxAuthToken to authenticate the request against the Appx API.

    Parameters:

    • courseId (string): The unique identifier for the course.
    • videoId (string): The unique identifier for the video.

    Returns:

    • A Promise<string> containing the full, watermarked video URL.

    Required Environment Variables:

    • APPX_BASE_API: The base URL for the Appx API.
    • APPX_AUTH_KEY: The authentication key for the Appx API.

    Note: The resulting URL includes a watermark containing the user's name and email.

  11. Update an existing event with updateEvent()

    main

    Updates an existing event record in the database.

    Permissions: Requires administrative privileges (user email must match an entry in the ADMINS environment variable).

    Input: A complete Event object including its id.

    Side Effects: Triggers a revalidation of the '/' path.