{"id":27235283,"url":"https://github.com/ah-naf/course-flow","last_synced_at":"2026-04-11T14:05:34.053Z","repository":{"id":286955864,"uuid":"946803257","full_name":"ah-naf/Course-Flow","owner":"ah-naf","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-09T06:22:03.000Z","size":266538,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"origin","last_synced_at":"2025-04-09T07:26:49.710Z","etag":null,"topics":["golang","postgr","react","zustand"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ah-naf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-11T17:42:50.000Z","updated_at":"2025-04-09T07:22:27.000Z","dependencies_parsed_at":"2025-04-09T07:27:07.115Z","dependency_job_id":"3903ef8a-4706-44b3-88dd-a1063d08b405","html_url":"https://github.com/ah-naf/Course-Flow","commit_stats":null,"previous_names":["ah-naf/course-flow"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ah-naf%2FCourse-Flow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ah-naf%2FCourse-Flow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ah-naf%2FCourse-Flow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ah-naf%2FCourse-Flow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ah-naf","download_url":"https://codeload.github.com/ah-naf/Course-Flow/tar.gz/refs/heads/origin","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248252730,"owners_count":21072702,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","postgr","react","zustand"],"created_at":"2025-04-10T16:38:41.019Z","updated_at":"2025-12-30T21:57:30.493Z","avatar_url":"https://github.com/ah-naf.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Course Flow\n\n**Course Flow** is a modern classroom management system inspired by Google Classroom. It is built with a **React** frontend (leveraging shadcn UI, React Query, and Zustand) and a **Go** backend (using Gorilla Mux for routing and Gorilla WebSocket for real-time communication).\n\n---\n\n## Demo\n\nFor a visual demonstration of Course-Flow in action, check out our video demo:\n\n\u003ccenter\u003e\n  \u003ca href=\"https://youtu.be/plxhcOpebKM\"\u003e\n    \u003cimg src=\"https://img.youtube.com/vi/plxhcOpebKM/0.jpg\" alt=\"\" width=\"480\" height=\"360\"\u003e\n  \u003c/a\u003e\n\u003c/center\u003e\n\n## Table of Contents\n\n- [Course Flow](#course-flow)\n  - [Demo](#demo)\n  - [Table of Contents](#table-of-contents)\n  - [Features](#features)\n  - [Technologies Used](#technologies-used)\n  - [Project Structure](#project-structure)\n  - [Getting Started](#getting-started)\n    - [Prerequisites](#prerequisites)\n    - [Installation](#installation)\n    - [Environment Configuration](#environment-configuration)\n    - [Running the Application](#running-the-application)\n  - [API Overview](#api-overview)\n  - [File Uploads \\\u0026 Media](#file-uploads--media)\n  - [WebSocket \\\u0026 Real-Time Communication](#websocket--real-time-communication)\n  - [Contributing](#contributing)\n  - [Contact](#contact)\n\n---\n\n## Features\n\n1. **User Authentication \u0026 OAuth**\n\n   - Login, registration, and logout using email and password.\n   - OAuth integrations with Google and GitHub.\n   - JWT-based session management for secure API and WebSocket access.\n\n2. **Course (Class) Management**\n\n   - Create, delete, archive, and restore courses.\n   - Public or private courses, each with configurable permissions.\n   - Join courses using invite links or join codes.\n\n3. **Posting \u0026 Commenting**\n\n   - Create, edit, and delete posts.\n   - Upload files (stored in the backend) with Markdown support.\n   - Add, edit, and delete comments on posts.\n\n4. **Notifications**\n\n   - Real-time notifications for post creation, comments, messages, and role changes.\n   - Mark notifications as read or clear them.\n\n5. **Real-Time Chat**\n\n   - WebSocket-based class-specific chat.\n   - Authentication ensures only enrolled members can access a course’s chat.\n\n6. **Profile Management**\n\n   - Update user details (e.g., avatar, personal info).\n\n7. **State Management**\n   - **React Query** for server-state caching and synchronization.\n   - **Zustand** for local state (e.g., UI states, ephemeral data).\n\n---\n\n## Technologies Used\n\n- **Frontend:**\n\n  - **React** with **shadcn UI** components\n  - **React Query** for data fetching and caching\n  - **Zustand** for local state management\n  - **Axios** (or Fetch) for API calls\n\n- **Backend:**\n\n  - **Go**\n  - **Gorilla Mux** for routing\n  - **Gorilla WebSocket** for real-time communication\n  - **PostgreSQL** as the primary database\n  - **JWT** for token-based authentication\n\n- **File Storage:**\n  - Uploaded files are stored on the backend filesystem in the `./media` directory.\n\n---\n\n## Project Structure\n\nBelow is a simplified view of the **backend** folder structure. (The frontend is not shown here because there is no `.env` configuration on the frontend side, and its structure may vary depending on your setup.)\n\n```\nbackend/\n├── bin/                          # Compiled binaries (if any)\n├── db.sql                        # SQL file for database schema and initial setup\n├── internal/\n│   ├── handlers/                 # HTTP handlers for various endpoints\n│   │   ├── attachment_handler.go\n│   │   ├── auth_handler.go\n│   │   ├── chat_handler.go\n│   │   ├── course_handler.go\n│   │   ├── notification_handler.go\n│   │   ├── post_handler.go\n│   │   └── user_handler.go\n│   ├── middleware/\n│   │   ├── error_mapping.go\n│   │   └── middleware.go         # Auth and other middleware\n│   ├── notifications/            # Notification logic (real-time and otherwise)\n│   │   ├── comment_added.go\n│   │   ├── message_sent.go\n│   │   ├── post_created.go\n│   │   └── role_changed.go\n│   ├── router/\n│   │   ├── attachment_routes.go\n│   │   ├── auth_routes.go\n│   │   ├── chat_routes.go\n│   │   ├── course_member_routes.go\n│   │   ├── course_routes.go\n│   │   ├── notif_routes.go\n│   │   ├── post_routes.go\n│   │   └── user_routes.go\n│   ├── services/                 # Core business logic for each feature\n│   │   ├── attachment_service.go\n│   │   ├── auth_service.go\n│   │   ├── chat_service.go\n│   │   ├── course_service.go\n│   │   ├── member_service.go\n│   │   ├── notification_service.go\n│   │   └── post_service.go\n│   ├── storage/                  # Database interactions (CRUD)\n│   │   ├── attachment_storage.go\n│   │   ├── auth_storage.go\n│   │   ├── chat_storage.go\n│   │   ├── course_member_storage.go\n│   │   ├── course_storage.go\n│   │   ├── document_storage.go\n│   │   ├── notification_storage.go\n│   │   ├── post_storage.go\n│   │   └── user_storage.go\n│   ├── utils/\n│   │   └── utils.go              # Utility functions\n│   └── websocket/\n│       ├── hub.go\n│       └── ...\n├── pkg/\n│   └── database/\n│       └── db.go                 # Database connection setup\n├── .env                          # Environment variables (see below)\n├── .gitignore\n└── main.go                       # Application entry point\n```\n\n---\n\n## Getting Started\n\n### Prerequisites\n\n- **Go** (v1.16+)\n- **PostgreSQL** (or a compatible Postgres service)\n- **Node.js** (if you are running a separate React frontend)\n- **Git** for version control\n\n### Installation\n\n1. **Clone the Repository:**\n\n   ```bash\n   git clone https://github.com/ah-naf/course-flow.git\n   cd course-flow\n   ```\n\n2. **Backend Dependencies:**\n\n   ```bash\n   cd server\n   go mod tidy\n   ```\n\n3. **(Optional) Frontend Dependencies:**\n\n   If you have a separate frontend folder (not shown in the snippet), navigate there and install dependencies (e.g., `npm install` or `yarn install`).\n\n### Environment Configuration\n\nIn the **backend** folder, you should have a `.env` file with the following variables (example values shown below):\n\n```\nDATABASE_URL=user=ahnaf dbname=collab_editor password=your_pass sslmode=disable\nSECRET_KEY=\nMEDIA_DIR=./media\nGOOGLE_REDIRECT_URL=\nGOOGLE_CLIENT_ID=\nGOOGLE_CLIENT_SECRET=\nGITHUB_REDIRECT_URL=\nGITHUB_CLIENT_ID=\nGITHUB_CLIENT_SECRET=\nOAUTH_COOKIE_FALLBACK=\nBASE_URL=http://localhost:8080/\n```\n\n\u003e **Note:**\n\u003e\n\u003e - `DATABASE_URL` should match your PostgreSQL connection string.\n\u003e - `SECRET_KEY` is used for JWT signing.\n\u003e - `MEDIA_DIR` is the local directory for storing uploaded files.\n\u003e - OAuth credentials (`GOOGLE_CLIENT_ID`, `GITHUB_CLIENT_ID`, etc.) should match your registered apps.\n\u003e - `BASE_URL` might be used for constructing callback URLs or for other service integrations.\n\n### Running the Application\n\n1. **Start the Backend:**\n\n   ```bash\n   cd server\n   go run main.go\n   ```\n\n   The server should start on the port specified in your code (e.g., `8080` or whatever is configured).\n\n2. **Frontend (if applicable):**\n\n   If you have a separate React frontend:\n\n   ```bash\n   cd ../client\n   npm run dev\n   ```\n\n   By default, the frontend might run on [http://localhost:5173](http://localhost:5173), but this can vary.\n\n---\n\n## API Overview\n\nThe backend exposes a RESTful API under routes such as `/api/v1`. Below are key endpoint groups:\n\n- **Auth Routes** (`/auth`)\n\n  - `POST /register` – Register a new user.\n  - `POST /login` – Login and obtain JWT tokens.\n  - `POST /refresh` – Refresh expired tokens.\n  - `POST /logout` – Logout user, invalidating tokens.\n  - `GET /google/login`, `GET /google/callback` – Google OAuth flow.\n  - `GET /github/login`, `GET /github/callback` – GitHub OAuth flow.\n\n- **User Routes** (`/users`)\n\n  - `GET /` – Get user details (admin or self usage).\n  - `GET /me` – Get current user info.\n  - `PUT /edit` – Update user details (avatar, name, etc.).\n\n- **Course (Class) Routes** (`/courses`)\n\n  - `POST /` – Create a course.\n  - `GET /` – Get courses for the authenticated user.\n  - `PUT /archive` – Archive a course.\n  - `PUT /restore` – Restore an archived course.\n  - `DELETE /{id}` – Delete a course.\n  - `POST /join` – Join a course by code or invite link.\n  - Additional endpoints for course preview, leaving a course, updating settings, etc.\n\n- **Course Members** (`/members`)\n\n  - `GET /{id}` – Get all members in a course.\n  - `PUT /change-role/{id}` – Change a user’s role (teacher, student, etc.).\n\n- **Posts \u0026 Comments** (`/posts`)\n\n  - `GET /{course_id}` – Fetch all posts for a course.\n  - `POST /{course_id}` – Create a new post.\n  - `PUT /{post_id}` – Edit a post.\n  - `DELETE /{post_id}` – Delete a post.\n  - `POST /comment/{post_id}` – Add a comment.\n  - `PUT /comment/{comment_id}` – Edit a comment.\n  - `DELETE /comment/{comment_id}` – Delete a comment.\n\n- **Attachments** (`/attachments`)\n\n  - `GET /{id}` – Get all attachments for a specific course (or post).\n\n- **Notifications** (`/notifications`)\n\n  - `GET /` – Retrieve all notifications for a user.\n  - `POST /read` – Mark a notification as read.\n  - `POST /read-all` – Mark all notifications as read.\n  - `POST /clear` – Clear all notifications.\n\n- **Chat** (`/chat`)\n  - `GET /{course_id}` – Retrieve chat messages for a specific course.\n\n---\n\n## File Uploads \u0026 Media\n\n- **Upload Handling:**\n  - Files attached to posts are uploaded to the backend and stored in the directory specified by `MEDIA_DIR` (e.g., `./media`).\n- **Serving Files:**\n  - The backend exposes these files under the `/media/` path. A `FileServer` or similar approach strips the prefix and serves files from the `MEDIA_DIR`.\n\n---\n\n## WebSocket \u0026 Real-Time Communication\n\n- **Gorilla WebSocket:**\n  - A central `Hub` manages all active connections.\n  - Each user connects via `/api/v1/ws` with a valid JWT token (provided in query params).\n- **Use Cases:**\n  - **Chat:** Class-specific real-time messaging.\n  - **Notifications:** Broadcast new post/comment notifications or role changes to the relevant users.\n\n---\n\n## Contributing\n\n1. **Fork** the repository.\n2. **Create** a feature branch:\n   ```bash\n   git checkout -b feature/your-feature\n   ```\n3. **Commit** your changes:\n   ```bash\n   git commit -m \"Add a new feature\"\n   ```\n4. **Push** to your branch:\n   ```bash\n   git push origin feature/your-feature\n   ```\n5. **Open a Pull Request** for review.\n\n---\n\n## Contact\n\n- **Project Maintainer:** [Ahnaf Hasan Shifat](mailto:sheikhahnafshifatl@gmail.com)\n- **GitHub:** [github.com/ah-naf](https://github.com/ah-naf)\n\nFor any inquiries, issues, or suggestions, please reach out via GitHub or email.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fah-naf%2Fcourse-flow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fah-naf%2Fcourse-flow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fah-naf%2Fcourse-flow/lists"}