---
# System prepended metadata

title: 預選系統 api
tags: [course]

---

---
tags: course
---


# 預選系統 api


<table>
  <tr>
    <th>Method</th>
    <th>Route</th>
    <th>Request Body</th>
    <th>Response</th>
    <th>Description</th>
  </tr>

  <tr>
    <td>GET</td>
    <td>/api/session</td>
    <td></td>
    <td>
      Success: 200<br />
      JSON Response:<br />
<pre>
{
  userID: 學號(String)
}
</pre>
      Failed:<br />
      403: 沒登入
    </td>
    <td>Get user session data</td>
  </tr>

  <tr>
    <td>POST</td>
    <td>/api/session</td>
    <td>
      type: <code>x-www-form-urlencoded</code><br />
      content:
      <table>
        <tr>
          <th>KEY</th>
          <th>VALUE</th>
        </tr>
        <tr>
          <td>userID</td>
          <td>學號(String)</td>
        </tr>
        <tr>
          <td>password</td>
          <td>密碼(String)</td>
        </tr>
      </table>
    </td>
    <td>
        Success: 201<br />
        JSON Response:<br />
<pre>
{
  userID: 學號(String)
}
</pre>
      Failed:<br />
      400: Request body格式錯誤<br />
      401: 密碼錯誤
    </td>
    <td>Login</td>
  </tr>

  <tr>
    <td>DELETE</td>
    <td>/api/session</td>
    <td></td>
    <td>
      Success: 204
    </td>
    <td>Logout</td>
  </tr>

  <tr>
    <td>GET</td>
    <td>/api/courses</td>
    <td></td>
    <td>
      Success: 200<br />
<pre>
{
  type(String, 課程種類)：[
    {
      courseID: 課程 ID(String),
      name: 課程名稱(String),
    },
    ...
  ],
  ...
}
</pre>
      Failed:<br />
      403: 沒登入
    </td>
    <td>Get all courses</td>
  </tr>

  <tr>
    <td>GET</td>
    <td>/api/selections/:courseID</td>
    <td></td>
    <td>
      Success: 200<br />
      JSON Response:<br />
<pre>
{
  name: 課程名稱(String),
  type: 課程種類,
  description: 課程描述(String),
  selected(String, 選的選項照志願序順序): [選項名稱(String), ...],
  unselected(String, 沒選的選項無排序): [選項名稱(String), ...],
}
</pre>
      Failed:<br />
      403: 沒登入<br />
      404: 不合法的courseID
    </td>
    <td>Get course selection</td>
  </tr>

  <tr>
    <td>PUT</td>
    <td>/api/selections/:courseID</td>
    <td>
      type: <code>json</code><br />
      content:<br />
<pre>
(一條Array裡面都是選項名稱，照志願序排序)
[選項名稱(String)]
</pre>
    </td>
    <td>
      Success: 204<br />
      Failed:<br />
      403: 沒登入<br />
      404: 不合法的courseID<br />
      400: Request body 格式錯誤
    </td>
    <td>Update course selection</td>
  </tr>

</table>


- Main Page
    - 登陸功能
    - 使用教學
    - 課程課的時間 & 教室
    - 小遊戲 (optional)
        - 玩贏可以跳過去
    - 公告系統 (optional, new)
    - 學生改密 (optional)
- Course Page
    - 看所有當前的課 (跟後端要課程表)
    - 排得美美的
    - 點進去可以到 course select page
- Course Select Page
    - 可以排課程的順序
    - 課程說明
    - 存檔 (跟後端說要存檔)
    - 選課人數 (?
    - 確定按鈕
- Admin Page
    - 可以登錄
    - 上傳學生資料
        - 上傳 csv
    - 上傳課程資料
        - 上傳 csv
    - 更新課程資訊
        - embed code editor
    - 設定選課開始與結束時間
        - 要可以點
    - 跑分發，得結果
        - 下載 csv
    - 改 admin 人密碼
        - 忘記密碼 (optional)
        - stay login
    - 發公告 (new)
        - embed code editor

# 3/26 工作

- [x] 消滅 constants.json(蔡仲廷)
- [x] 消滅 redis folder(寫到mongo)，將opentime寫入reset.js(張創渝, 賴群貿)
- [x] gen_password.py 寫另一份 js 檔，同功能的(只要 function ，不用寫檔)(陳亮瑜)
- [x] 消滅 private data(把students.json 搬到data，砍csv，reset.js吃data裡的東西)(justin huang)
- [x] 把server 的 .gitignore 消滅掉（justin huang)
- [ ] 整理data folder 裡的東西(鄧旭辰)
    - [ ] eliminate openTime.json
- [x] 人腦生 testing data, 密碼不一樣(justin huang)
- [x] 生測試資料(data資料夾裡)
- [ ] 研究 [swagger](https://swagger.io/)
- [ ] 研究 [jest](https://www.albertgao.xyz/2017/05/24/how-to-test-expressjs-with-jest-and-supertest/)

```
git reset --hard HEAD 
```

---
先 pull 再 push
如果遇到這個問題
![](https://i.imgur.com/FOSmlD5.png)

```
git branch --set-upstream-to=origin/backend backend
```

# 4/9

- [x] 合併 opentime 兩個 collection，field 改成用 string 存(Michael Lai)
- [x] 刪掉 opentime.json (unix timestamp)(Michael Lai)
- [x] 研究 [swagger](https://swagger.io/)(Michael Lai)
- [ ] 研究 [jest](https://www.albertgao.xyz/2017/05/24/how-to-test-expressjs-with-jest-and-supertest/) (張創渝)
- [x] model.js 中 userschema 加 name(String) 跟 authority("admin", "maintainer", "user")
- [ ] reset 時幫admin生密碼
- [x] 寫middleware擋opentime以外maintainer以下權限的人(Michael Lai)

<table>
  <tr>
    <th>Method</th>
    <th>Route</th>
    <th>Request Body</th>
    <th>Response</th>
    <th>Description</th>
    <th>負責人(完成?)</th>
    </tr>
  <tr>
    <td>GET/POST</td>
    <td>/api/session
    <br />authority: none
    </td>
    <td>type: <code>JSON</code><br />
      content:
      <table>
        <tr>
          <th>KEY</th>
          <th>VALUE</th>
        </tr>
        <tr>
          <td>userID</td>
          <td>學號(String)</td>
        </tr>
        <tr>
          <td>password</td>
          <td>密碼(String)</td>
        </tr>
      </table></td>
    <td>
      Success: 200<br />
      JSON Response:<br />
    <pre>
    {
      userID: 學號(String)
      authority: 權限等級(String)
    }
    </pre>
    Failed:<br />
      400: Request body格式錯誤<br />
      401: 密碼錯誤
    </td>
    <td>Login<br />
    加admin登入功能<br />
    分三個level:
    <pre>
    1. admin
    2. maintainer
    3. user
    </pre>
    </td>
    <td>賴群貿(done)</td>
  </tr>
  <tr>
    <td>PUT</td>
    <td>/api/opentime
    <br />authority: maintainer</td>
    <td>type: <code>JSON</code><br/>
    content:
    <table>
        <tr>
          <th>KEY</th>
          <th>VALUE</th>
        </tr>
        <tr>
          <td>start</td>
          <td>開始時間(Unix timestamp)</td>
        </tr>
        <tr>
          <td>end</td>
          <td>結束時間(Unix timestamp)</td>
        </tr>
      </table>
    </td>
    <td>Success: 204</td>
    <td>改開放時間</td>
    <td>Michael Lai (done)</td>
  </tr>
  <tr>
  <td>GET</td>
  <td>/api/courses
    <br />authority: user</td>
  <td>Query Parameter: keys(array of Strings)<br />options:
  <pre>
  id (default)
  name
  type
  description
  </pre>
  </td>
  <td>
  <pre>
  [
    {
      id: ___,
      ...
    },
    {
      id: ___,
      ...
    }
  ]
  </pre>
  </td>
  <td>/course?keys=name&keys=type
  回傳[ { id, name, type },{  },{  }...]<br />拿課程資料(可指定項目)</td>
    <td>蔡仲廷(OK)</td>
  </tr>
  <tr>
    <td>GET</td>
    <td>/api/users
    <br />authority: maintainer</td>
    <td>Query Parameter: keys(array of Strings)<br />options:
  <pre>
  id (default)
  name (存userschema)
  grade
  
  </pre></td>
    <td>同上</td>
    <td>給全部user
    不能給密碼?</td>
    <td>蔡仲廷(OK)</td>
  </tr>
  <tr>
    <td>POST</td>
    <td>/api/users
    <br />authority: maintainer</td>
    <td>array of user struct
    <pre>
    userID
    grade
    password
    name
    authority
    </pre>
    </td>
    <td>Success: 204</td>
    <td>前端送密碼給後端<br />
    重複的忽略，沒出現過的合併
    </td>
    <td></td>
  </tr>
  <tr>
    <td>DELETE</td>
    <td>/api/users
    <br />authority: maintainer</td>
    <td>Array of userID</td>
    <td>Success: 204</td>
    <td>刪掉指定的 users</td>
    <td>蔡仲廷</td>
  </tr>
  <tr>
    <td>PUT</td>
    <td>/api/password
    <br />authority: admin</td>
    <td></td>
    <td>Success: 204</td>
    <td>改密碼</td>
    <td>黃宥翔(ok)</td>
  </tr>
  <tr>
    <td>POST</td>
    <td>/api/course
    <br />authority: maintainer</td>
    <td>有啥給啥</td>
    <td>Success: 201</td>
    <td>新增課程</td>
    <td>Michael(ok)</td>
  </tr>
  <tr>
    <td>DELETE</td>
    <td>/api/course
    <br />authority: maintainer</td>
    <td>給id</td>
    <td>Success: 204</td>
    <td>刪除課程</td>
    <td>Michael(ok)</td>
  </tr>
  <tr>
    <td>PUT</td>
    <td>/api/course
    <br />authority: maintainer</td>
    <td>有啥給啥</td>
    <td>Success: 204</td>
    <td>改課程內容</td>
    <td>Michael(ok)</td>
  </tr>
  <tr>
    <td>POST</td>
    <td>/api/distribute
    <br />authority: admin</td>
    <td></td>
    <td>分發結果</td>
    <td>跑分發得結果</td>
    <td></td>
  </tr>
  <tr>
    <td>PUT</td>
    <td>/api/authority
    <br />authority: admin</td>
    <td>usedID、authority</td>
    <td>Success: 204</td>
    <td>admin 拉 user 變成 maintainer</td>
    <td>陳亮瑜(ok)</td>
  </tr>
</table>


[Query Parameter 參考網站](http://expressjs.com/en/5x/api.html#req.query)

```
git add <file>
git commit -m "commit message"
git push
```

## 5/14 and 5/21 google meet

- [x] 把其他檔案裡的 constants 用 constants.js 替換掉（黃宥翔）
- [x] change all api to json (michael)
- [x] update password 防呆（黃宥翔）
- [x] 新增了 Selection Schema，修改相關的 api code（張創渝）
- [x] post /users(蔡仲廷)
- [x] delete /users(蔡仲廷)
- [x] 檢查所有的 api 有沒有做好型別檢查 ( 陳亮瑜 )
- [x] 把所有權限檢查改成用 permissionRequired middleware（張創渝）
- [x] authority 改成 number

```
git config --global branch.autosetuprebase always
```

### conda


創 conda 環境
```
conda create -n 環境名字 python=3.8
```

看有哪些環境

```
conda env list
```

啟動環境

```
conda activate 環境名字
```

### pip

把裝了什麼套件輸出成 `requirements.txt` (每次有裝新套件就要跑這個指令)

```
pip freeze > requirements.txt
```

下載所有 `requirements.txt` 的套件

```
pip install -r requirements.txt
```

![](https://i.imgur.com/8xPlHoc.png)

## 0604
- [x] fronend丟api立刻return 204
- [x] 研究分發演算法 (Michael)
- [x] 加一個schema in model.js
- [x] 研究用pymongo讀mongo

前端打 api 時立刻將日期時間存進 db，算好時 response 附帶說最新的 result 是啥時弄的

## 6/11

- [x] Course schema option 有變，看看有哪爆了(張創渝)
- [x] Swagger 加 get result.csv (陳亮瑜)
- [x] Course, Student class 的 attribute 看需要有哪些(黃宥翔)
- [x] 寫 Algorithm(Michael)
- [x] 寫 test(蔡仲廷)

## 7/2
- [x] Course Schema 加 priority
- [x] modify algorith.py(preselect, priority)(Michael)
- [x] add a route of preselect in api.js(黃宥翔)
- [x] read preselect from db in server.py(黃宥翔)
- [x] 處理數電實驗
    - [x] 在 db 存數電實驗分發結果(黃宥翔)
    - [x] 分發時可以抓數電實驗的分發結果(Michael(應該完成了吧？這啥意思))
- [x] 把 test 的結果轉成 json 的 string 裝到 set 裡面再比較(陳亮瑜)
- [x] test 排版

## 7/9
- [x] 把以下內容弄成dict(?)
```python=1
priority type{
"高年級優先" : -1
"無高年級優先" : 0
"一年級優先" : 1
...
}
```

- [x] 改genCourse的格式以符合distribute
- [x] courses.json 加 priority
- [ ] 把test改到會動
    - [ ] 加註解
    - [ ] 排版美觀(?)
    - [ ] 加測資

## 7/23

- [x] 把 swagger 寫清楚 (有帶 request body 的每個欄位都寫清楚)(黃宥翔)
  - `_id` 不用傳前端
  - `/result.csv` 加上說要先跑 distribute 的說明，`/api/statistics.csv` 也一樣
- [x] 分發結果志願統計(`GET /api/statistics.csv`)（張創渝）
  - 以前的統計
    ![](https://i.imgur.com/U9NaMxR.png)
  - 想一下 response 格式(csv)
- [x] 測試
  - [x] 少量測試(現在的`test_algorithm.py`) (陳亮瑜)
    - 確保程式邏輯正確
    - Todo: 加更多測資
        - test_10: 有2種可能的結果，不太確定是不是對的
            1) `Michael: 電力電子； Mecoli: 自動控制、嵌入式系統`
            2) `Michael: 電力電子、嵌入式系統； Mecoli: 自動控制、半導體`
        ```python=
        student1 = Student("Michael", "B09901186",
                           {"course1": ["電力電子", "自動控制", "嵌入式系統"]}, 1)
        student2 = Student("Mecoli", "610736",
                           {"course1": ["自動控制", "嵌入式系統", "半導體"]}, 3)
        students = [student1, student2]

        course1 = Course({
            "id": "course1",
            "name": "Ten-Select-Two",
            "type": "Ten-Select-Two",
            "description": "",
            "options": {
                "電力電子": {"limit": 1, "priority": 0},
                "自動控制": {"limit": 1, "priority": 0},
                "半導體": {"limit": 1, "priority": 0},
                "嵌入式系統": {"limit": 1, "priority": 0}
            }
        })
        ```
        - <p style="color:red">test_12: 有機率(而且不低)會只有2個人上，但理論上應該3人都會上吧(?)</p>
        ```python=
        student1 = Student("Michael", "B09901186",
                           {"Electronic-Circuits-Experiment": ["teacher1a", "teacher1b", "teacher1c"]}, 2)
        student2 = Student("Mecoli", "610736",
                           {"Electronic-Circuits-Experiment": ["teacher1a", "teacher1c", "teacher1b"]}, 3)
        student3 = Student("Pekoli", "VIP8888",
                           {"Electronic-Circuits-Experiment": ["teacher1c"]}, 4)
        students = [student1, student2, student3]

        course1 = Course({
            "id": "Electronic-Circuits-Experiment",
            "name": "電路學實驗",
            "type": "EE-Lab",
            "description": "",
            "options": {
                "teacher1a": {"limit": 1, "priority": 0},
                "teacher1b": {"limit": 1, "priority": 0},
                "teacher1c": {"limit": 1, "priority": 0}
            }
        })
        ```
  - [x] 大量測試 (宏恩)
    - 測試分發的志願分佈情形
    - Todo: 用程式生成大約幾百個學生做測試、做統計
- [x] course priority 5 代表大三大四優先(應急用)(Michael)
- [x] course type 改成以下幾類，swagger 記得寫清楚
  - [x] "EE-Lab" "Ten-Select-Two" "1" "2" "3" "4" (Michael)
  - `test_algorithm` 的 `Required` 改成 `1234`，確保改完會動
  - [x] `api` 的 course 傳進來時就要確保格式正確，不然會沒辦法分發(蔡仲廷)
    - 不要一邊 loop 一邊增減 array 長度，而是創一個新陣列

## 7/30
- [x] algorithm修正 (過test_12)
- [x] 分發過1次後又重新分發會有bug (algorithm.py裡面要清空results)
- [ ] 解決廣哥說的403問題 (先放著)
- [x] algorithm處理光電和電磁波實驗「保障名額」問題

## 8/6
- [x] PUT /password、PUT /authority，整併成 PUT /api/users ，可以改 name grade password authority (userID 不能變，後端要判斷驗證一下)
- [x] GET /users 權限是 maintainer、POST 和 PUT 都改成 admin (我DELETE也改admin)
- [x] swagger 寫清楚 maintainer 還是 admin 還是 user (張創渝)