From fcd85c381e6fa617d043fb217a66abda8b09da99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B3=E5=BB=B7=E5=AE=89?= <73953029+nrps9909@users.noreply.github.com> Date: Tue, 11 Aug 2026 19:31:17 +0800 Subject: [PATCH] chore: establish project maintenance baseline --- .env template | 1 - .env.example | 1 + .github/ISSUE_TEMPLATE/bug_report.yml | 57 +++++++++++ .github/ISSUE_TEMPLATE/config.yml | 5 + .github/ISSUE_TEMPLATE/feature_request.yml | 29 ++++++ .github/dependabot.yml | 13 +++ .github/pull_request_template.md | 15 +++ .github/workflows/quality.yml | 60 ++++++++++++ .gitignore | 3 +- CONTRIBUTING.md | 53 +++++++++++ README.md | 106 +++++++++++++++------ SECURITY.md | 37 +++++++ frontend/index.js | 2 +- frontend/package-lock.json | 2 +- frontend/package.json | 5 +- 15 files changed, 353 insertions(+), 36 deletions(-) delete mode 100644 .env template create mode 100644 .env.example create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/dependabot.yml create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/quality.yml create mode 100644 CONTRIBUTING.md create mode 100644 SECURITY.md diff --git a/.env template b/.env template deleted file mode 100644 index 3dee7daf..00000000 --- a/.env template +++ /dev/null @@ -1 +0,0 @@ -GROQ_API_KEY="" # Your GROQ API key \ No newline at end of file diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..b43e035c --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +GROQ_API_KEY= diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..a1222659 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,57 @@ +name: Bug report +description: Report a reproducible problem in EduAi +title: "[Bug]: " +labels: + - bug +body: + - type: markdown + attributes: + value: >- + Do not include API keys, credentials, student data, recordings, or + security vulnerabilities. Report vulnerabilities privately through the + repository Security page. + - type: textarea + id: description + attributes: + label: Problem + description: What happened, and what did you expect instead? + validations: + required: true + - type: textarea + id: reproduce + attributes: + label: Steps to reproduce + placeholder: | + 1. Start ... + 2. Open ... + 3. Select ... + validations: + required: true + - type: input + id: commit + attributes: + label: EduAi commit or version + description: A commit SHA is preferred. + - type: dropdown + id: component + attributes: + label: Affected component + options: + - Frontend + - Flask service + - Moodle backend + - Docker Compose or deployment + - Documentation + - Other + validations: + required: true + - type: textarea + id: environment + attributes: + label: Environment + description: Include OS, browser, Docker version, and relevant service versions. + - type: textarea + id: logs + attributes: + label: Sanitized logs or screenshots + description: Remove all credentials and personal or student information. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..8bad61e4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: true +contact_links: + - name: Security reporting guidance + url: https://github.com/NTNU-SoftwareEngineering/EduAi/blob/main/SECURITY.md + about: Read the private-reporting process before sharing vulnerability details. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 00000000..4fe7aac7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,29 @@ +name: Feature request +description: Propose a focused improvement to EduAi +title: "[Feature]: " +labels: + - enhancement +body: + - type: textarea + id: problem + attributes: + label: Problem or learning need + description: Who is affected, and what are they unable to do today? + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Proposed outcome + description: Describe the desired behavior without prescribing unnecessary implementation details. + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Alternatives considered + - type: textarea + id: privacy + attributes: + label: Privacy, security, or deployment impact + description: Explain any new data, permissions, third-party services, or migration requirements. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..90e90b06 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: npm + directory: /frontend + schedule: + interval: weekly + open-pull-requests-limit: 5 + + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly + open-pull-requests-limit: 3 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..4e33e04c --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,15 @@ +## Summary + + + +## Validation + + + +## Checklist + +- [ ] I kept this pull request focused on one change. +- [ ] I tested the affected behavior or explained why it could not be tested. +- [ ] I did not include credentials, student data, recordings, or other private data. +- [ ] I updated documentation or screenshots when user-facing behavior changed. +- [ ] My contribution is compatible with the repository's GPL-3.0 license. diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml new file mode 100644 index 00000000..1de754b6 --- /dev/null +++ b/.github/workflows/quality.yml @@ -0,0 +1,60 @@ +name: Quality + +on: + pull_request: + paths: + - ".github/workflows/quality.yml" + - ".env.example" + - "docker-compose.yml" + - "flask_server/**" + - "frontend/**" + push: + branches: + - main + paths: + - ".github/workflows/quality.yml" + - ".env.example" + - "docker-compose.yml" + - "flask_server/**" + - "frontend/**" + +permissions: + contents: read + +concurrency: + group: quality-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + first-party-checks: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + cache-dependency-path: frontend/package-lock.json + + - name: Install frontend dependencies + run: npm ci --prefix frontend + + - name: Check frontend syntax + run: npm run check --prefix frontend + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Check Python syntax + run: python -m compileall -q flask_server + + - name: Validate Docker Compose configuration + run: | + cp .env.example .env + docker compose config --quiet diff --git a/.gitignore b/.gitignore index 690c2221..63e21d88 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,4 @@ audio/*/*.wav .env .DS_Store .vscode/settings.json -config.yml - +/config.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..5a0d1c2b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,53 @@ +# Contributing to EduAi + +Thank you for helping improve EduAi. Contributions can include bug fixes, +documentation, accessibility improvements, tests, and focused feature work. + +## Before starting + +1. Search the open issues and pull requests for existing work. +2. Open an issue before a large feature, dependency migration, or architectural + change so maintainers and contributors can agree on scope. +3. Keep each pull request focused on one independently reviewable change. + +The `moodle-backend/` directory is a vendored Moodle distribution. Avoid broad +formatting or unrelated changes there. Moodle upgrades and Moodle-specific +security fixes should be isolated from first-party application changes. + +## Development setup + +Follow the setup in [README.md](README.md). Copy `.env.example` to `.env` and +keep API keys, passwords, student data, audio, and other private material out of +Git. Use synthetic data in tests and screenshots. + +## Checks + +Before opening a pull request, run the checks relevant to your change: + +```sh +npm ci --prefix frontend +npm run check --prefix frontend +python3 -m compileall -q flask_server +cp .env.example .env +docker compose config --quiet +``` + +If a check cannot run in your environment, explain why in the pull request and +describe the validation you did perform. + +## Pull requests + +- Link the issue the pull request addresses, when one exists. +- Explain the user-visible outcome and any migration or deployment impact. +- Include screenshots for interface changes. +- Add or update tests when behavior changes. +- Do not commit generated secrets, credentials, personal information, student + records, or recordings. +- Confirm that your contribution is compatible with this repository's + GPL-3.0 license. + +Dependency updates are proposed automatically by Dependabot. Maintainers still +review release notes, compatibility, and test results before merging them. + +Maintainers may ask for changes to keep the project secure, reviewable, and +consistent with its educational purpose. diff --git a/README.md b/README.md index 94eb30bf..90d0075d 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,98 @@ -## EduAi +# EduAi -**EduAi** is a web application based on **Moodle** backend that allows teachers and students to access and manage their Moodle data through a web interface. It provides a user-friendly interface for students to view their **course information**, **discussion**, and even **interact with LLM**.

At the same time, **teachers** can upload **teaching plans**, get the **feedback**, and **analysis** of students' speech in the discussion. Which means teachers can easily understand the **students' learning status** and **adjust the teaching plan** in time. +EduAi is a web application built around a Moodle backend. It gives students a +simpler interface for course discussions and LLM-assisted conversations, while +teachers can manage classes, upload teaching plans, and review learning +feedback. The project originated in the 2024 NTNU Software Engineering course. -This project is also derived from **NTNU Software Engineering Course**. +> [!NOTE] +> EduAi is an educational and research project. Review the example credentials, +> API access, privacy requirements, and network exposure before deploying it +> outside a local development environment. -#### Features +## Features -- **Student Discussion**: View the current discussing problems in **real-time**, and analyze the speech of students with **speech-to-text** and LLM analysis. -- **Conversation**: Interact with large language models (LLMs) to get answers to questions or generate content. +- Real-time student discussions with speech-to-text and LLM analysis +- Course-aware conversations with an LLM assistant +- Class, group, question, and user management through Moodle +- Teaching-plan upload and feedback +- Student learning and discussion analysis -- **Class Management**: Manage student **groups**, modify the **current question for discussion**, and get the **feedback** analyzed by **LLM** of the class. -- **Teaching Plan**: Upload teaching plans, and get the **feedback** analyzed by **LLM**. -- **Speech Analysis**: Analyze the speech of students in the discussion, and get the **feedback** analyzed by **LLM**. -- **User Management**: Manage user information, including **username**, **fullname**, **email**, and **password**. -- **Student Learning Analysis**: Analyze the learning status of students by **LLM**. +![EduAi login screen](readme_assets/login.png) +## Architecture -#### Getting Started +The repository contains these project services: -![Login](readme_assets/login.png) +| Service | Implementation | Default local URL | +| --- | --- | --- | +| Web application | Node.js and Express | | +| Reverse proxy | Nginx | | +| Learning platform | Moodle and Apache | | +| Speech-to-text API | Python and Flask | | +| Database administration | phpMyAdmin | | -Developers or schools can easily build the server by **cloning** / **downloading** the whole repo, and run the server by -`docker compose up -d` +The `moodle-backend/` directory is a vendored Moodle distribution. Project- +specific application work normally belongs in `frontend/`, `flask_server/`, +the Compose configuration, or project documentation. -You can interact the frontend at `localhost:3000` +## Getting started -backstage management system will be at `localhost:8080/moodle` +### Prerequisites -#### Technology Stack +- Git +- Docker with Docker Compose v2 +- A Groq API key for LLM-backed features -- **Frontend**: **Node.js** -- **Backend**: **Moodle** + **Python Flask** -- **Database**: **MySQL** -- **Speech-to-Text**: **Google Speech-to-Text API** -- **LLM Analysis**: **Groq API** +### Run the stack +```sh +git clone https://github.com/NTNU-SoftwareEngineering/EduAi.git +cd EduAi +cp .env.example .env +``` -#### License +Set `GROQ_API_KEY` in `.env`, then start the services: -This project is licensed under the [Apache-2.0 License](LICENSE). +```sh +docker compose up -d --build +``` -#### Contribution +Open . Moodle administration is available at +. -Contributions are welcome! Please submit a pull request. +To inspect startup problems: -#### Contact +```sh +docker compose ps +docker compose logs --tail=100 +``` -For any questions or issues, please open an issue. +Stop the stack without deleting database volumes: +```sh +docker compose down +``` + +## Local checks + +Run the same lightweight checks used by continuous integration: + +```sh +npm ci --prefix frontend +npm run check --prefix frontend +python3 -m compileall -q flask_server +cp .env.example .env +docker compose config --quiet +``` + +## Contributing and security + +Contributions are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md) before +opening a pull request. Automated dependency update proposals are configured +through Dependabot. Please report vulnerabilities through the process in +[SECURITY.md](SECURITY.md), not through a public issue. + +## License + +EduAi is licensed under the [GNU General Public License v3.0](LICENSE). diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..bcd5cb23 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,37 @@ +# Security policy + +## Supported versions + +EduAi does not currently publish versioned releases. Security fixes are made on +the `main` branch. Deployments should follow `main` and apply security updates +promptly. + +## Reporting a vulnerability + +Do not open a public issue for a suspected vulnerability or include real API +keys, credentials, student data, audio, or other sensitive information in a +report. + +If GitHub shows a **Report a vulnerability** option on the repository Security +page, use it to send maintainers a private report. If that option is not +available, open a minimal public issue asking a maintainer to establish a +private contact channel. Do not include vulnerability details in that issue. + +In the private report, include: + +- the affected component and commit or version; +- reproducible steps or a minimal proof of concept; +- the possible impact; +- any suggested mitigation; and +- a safe way to contact you for follow-up. + +Maintainers will acknowledge a complete report, investigate it, and coordinate +disclosure based on severity and available project capacity. Please allow time +for a fix before publishing details. + +## Deployment considerations + +EduAi integrates Moodle, a database, speech processing, and third-party LLM +services. Operators are responsible for replacing example credentials, +restricting network exposure, protecting API keys, obtaining appropriate data +consent, and following the security guidance of each upstream service. diff --git a/frontend/index.js b/frontend/index.js index c105b105..c8037ef5 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -189,7 +189,7 @@ app.post('/llm', async function(req, res){ var input = ""; try { input = req.body.message; // 這個是逐字稿 - lesson_plan = req.body.lesson_plan; // 這個是課程大綱 + const lesson_plan = req.body.lesson_plan; // 這個是課程大綱 const prompt = 'prompt.txt'; if (input === undefined) { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9cca7354..83636845 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "frontend", "version": "1.0.0", - "license": "ISC", + "license": "GPL-3.0-only", "dependencies": { "@langchain/core": "^0.3.22", "@langchain/groq": "^0.1.2", diff --git a/frontend/package.json b/frontend/package.json index 557d7632..87936221 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,11 +5,12 @@ "main": "index.js", "type": "module", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "check": "node --check index.js", + "test": "npm run check" }, "keywords": [], "author": "", - "license": "ISC", + "license": "GPL-3.0-only", "dependencies": { "@langchain/core": "^0.3.22", "@langchain/groq": "^0.1.2",