---
# System prepended metadata

title: NTOUber 軟體設計文件(SDD)

---

# NTOUber 軟體設計文件(SDD)
- 專案名稱 : NTOUber
- 撰寫日期 : 2025/11/23
- 發展者 : 王鈞宇、劉長諺、郭家齊、郭晉佑、翁世華

---

## 版次變更紀錄


| 版次 | 變更項目 | 變更日期 |
| -------- | -------- | -------- |
| 0.1     | 初版     | 11/23     |
| 0.2     | 修正細項     | 1/1     |


---
## 目錄
1. 系統模型與架構 (System Model / System Architecture)
2. 介面需求與設計 (Interface Requirement and Design)
3. 流程設計 (Process Design)
4. 使用者畫面設計 (User Interface Design)
5. 資料設計 (Data Design)
6. 類別圖設計 (Class Diagram)
7. 實作方案 (Implementation Languages and Platforms)
8. 設計議題 (Design Issue)

---
## 1. 系統模型與架構(System Model / System Architecture)
C4 Container diagram
![未命名绘图-第 2 页.drawio (1)](https://hackmd.io/_uploads/r1LdMrO7bg.png)


C4 Component![未命名绘图-第 3 页.drawio (1)](https://hackmd.io/_uploads/BJRKMruQbg.png)



---
## 2. 介面需求與設計 (Interface Requirement and Design)

| 介面名稱                | 介面提供者 | 介面使用者          | 連結方式                                                       | 輸入資料                          | 輸出資料                         | 介面描述                   |
| ----------------------- | ---------- | ------------------- | -------------------------------------------------------------- | --------------------------------- | -------------------------------- | -------------------------- |
| create_driver_post      | Post-serv  | UploadPost.jsx      | https://ntouber-gateway.zeabur.app/api/posts/                  | post's info                       | post's id                        | 提供前端新增貼文至資料庫   |
| get_all_driver_post     | Post-serv  | LogInPage.jsx       | https://ntouber-gateway.zeabur.app/api/posts/all               | NA                                | all of the posts in the database | 提供前端提取所有貼文       |
| get_post_by_id          | Post-serv  | UserPage.jsx        | https://ntouber-gateway.zeabur.app/api/posts/getpost/{post_id} | post's id                         | post                             | 提供前端提取特定貼文       |
| delete_all_post         | Post-serv  | N/A                 | https://ntouber-gateway.zeabur.app/api/posts/deleteall         | NA                                | All posts has been deleted       | 提供前端刪除所有貼文       |
| delete_post_by_id       | Post-serv  | N/A                 | https://ntouber-gateway.zeabur.app/api/posts/delete/{post_id}  | post's id                         | {post_id} has been deleted       | 提供前端刪除特定貼文       |
| PostDriver              | User-serv  | RegisterPage.jsx    | https://ntouber-gateway.zeabur.app/v1/users/driver             | driver's info                     | driver's info                    | 提供前端創建Driver         |
| EditUser                | User-serv  | EditProfilePage.jsx | https://ntouber-gateway.zeabur.app/v1/users/mod                | user_id and modified info of user | user info                        | 讓前端可以修改user的資訊   |
| GetUserByID             | User-serv  | UserContext.jsx     | https://ntouber-gateway.zeabur.app/v1/users/:id                | user_id                           | user's info                      | 讓前端提取user的資訊       |
| GetDriverByUserID       | User-serv  | UserContext.jsx     | https://ntouber-gateway.zeabur.app/v1/drivers/user/:user_id    | user_id                           | driver's info                    | 提取該使用者駕駛身分的資訊 |
| googleCredentialHandler | User-serv  | LogInPage.jsx       | https://ntouber-gateway.zeabur.app/v1/auth/google              | google auth credential            | google account info              | 前端oAuth登入              |
| addToBlacklist          | Admin-serv |                     | https://ntouber-gateway.zeabur.app/admin/blacklist             | user id and banned reason         | User added to blacklist.         | 將違規使用者加入黑名單     |
| getBlacklist            | Admin-serv |                     | https://ntouber-gateway.zeabur.app/admin/blacklist             |           NA                        | users in blacklist               | 列出在黑名單內的違規使用者 |
|deleteBlacklist                         |Admin-serv            |                     |https://ntouber-gateway.zeabur.app/admin/blacklist/{id}                                                                |user id                                   |delete blacklist successfully!.                                  |刪除在黑名單內的使用者                            |





---
## 3. 流程設計 (Process Design)
| 圖片                                                  | 名稱     |
| ---------------------------------------------------    | ------------ |
| ![image](https://hackmd.io/_uploads/H1hRs08XWe.png) | 使用者登入流程|
| ![image](https://hackmd.io/_uploads/rJKx20Lm-e.png)| 使用者流程|
| ![image](https://hackmd.io/_uploads/r15MhCImWg.png)|管理員流程|

---
## 4. 使用者畫面設計 (User Interface Design)
| 圖片                                                  | 功能     |
| ---------------------------------------------------    | ------------ |
| ![image](https://hackmd.io/_uploads/HkcUFcZbbg.png)| 未登入使用者：可以查看貼文|
| ![image](https://hackmd.io/_uploads/Sye3Fc-ZWe.png)| 已登入使用者：可以查看貼文跟紀錄|
| ![image](https://hackmd.io/_uploads/B1g0tqbZWe.png)|登入畫面：|
| ![image](https://hackmd.io/_uploads/r1MPT9q--Ze.png)|SideBar：|
|![image](https://hackmd.io/_uploads/rJROj9bZbe.png) |車主發布貼文畫面：|
|![image](https://hackmd.io/_uploads/SkmolYApll.png)  | 管理員主頁：|
|![image](https://hackmd.io/_uploads/r153xK0Tlg.png) | 管理員管理貼文：|

---
## 5. 資料設計 (Data Design)

### 5.1 資料庫 Schema
- Driver Post
```sql=
   CREATE TABLE `driver_posts` (
    `id` VARCHAR(36) NOT NULL,
    `driver_id` VARCHAR(255) NOT NULL,
    `client_id` VARCHAR(255) NOT NULL,
    `vehicle_info` VARCHAR(255) DEFAULT NULL,

    `status` ENUM('open', 'matched', 'closed') NOT NULL DEFAULT 'open',

    `time_stamp` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),

    `start_point` JSON NOT NULL,
    `destination` JSON NOT NULL,

    `meet_point` JSON NOT NULL,
    `departure_time` DATETIME(6) NOT NULL,

    `notes` TEXT DEFAULT NULL,
    `description` TEXT DEFAULT NULL,

    `helmet` TINYINT(1) NOT NULL DEFAULT 0,
    `contact` JSON NOT NULL,
    `leave` TINYINT(1) NOT NULL DEFAULT 0,
    `image_url` VARCHAR(255) DEFAULT NULL,

    PRIMARY KEY (`id`),

    INDEX `ix_driver_posts_driver_id` (`driver_id`),
    INDEX `ix_driver_posts_status` (`status`),

    INDEX `ix_driver_posts_driver_status` (`driver_id`, `status`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

```
- User
```sql=
CREATE TABLE `user_models` (
    `user_id` VARCHAR(255) NOT NULL,
    `user_name` VARCHAR(255) DEFAULT NULL,
    `provider` VARCHAR(255) DEFAULT NULL,
    `provider_user_id` VARCHAR(255) DEFAULT NULL,
    `user_email` VARCHAR(255) DEFAULT NULL,
    `phone_number` VARCHAR(50) DEFAULT NULL,
    `AvatarURL` VARCHAR(50),
    `Admin` BOOLEAN NOT NULL DEFAULT FALSE,

    PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

```
- Driver
```sql=
CREATE TABLE `driver_models` (
    `user_id` VARCHAR(255) NOT NULL,
    `driver_name` VARCHAR(255) DEFAULT NULL,
    `contact_info` VARCHAR(255) DEFAULT NULL,
    `scooter_type` VARCHAR(255) DEFAULT NULL,
    `plate_num` VARCHAR(255) DEFAULT NULL,
    `DriverLicense` VARCHAR(255) NOT NULL,
    `Status` VARCHAR(255) DEFAULT NULL,

    PRIMARY KEY (`user_id`),

    CONSTRAINT `fk_driver_user`
        FOREIGN KEY (`user_id`) REFERENCES `user_models`(`user_id`)
        ON UPDATE CASCADE
        ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

```

- Blacklist
```sql=
CREATE TABLE Blacklist (
    id CHAR(36) NOT NULL PRIMARY KEY,
    user_id VARCHAR(255) NOT NULL,
    reason VARCHAR(255),
    created_at DATETIME NOT NULL
    
    CONSTRAINT `blacklist_user`
        FOREIGN KEY (`user_id`) REFERENCES `user_models`(`user_id`)
        ON UPDATE CASCADE
        ON DELETE CASCADE
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

```

- Notify
```sql=
CREATE TABLE Notify (
    id CHAR(36) NOT NULL PRIMARY KEY,
    reciever_id VARCHAR(255) NOT NULL,
    sender_id VARCHAR(255) NOT NULL,
    message TEXT,
    status VARCHAR(100),
    time_stamp VARCHAR(255)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

```
   

### 5.2 檔案結構
- Post-serv

```bash=
SE/
│
├── alembic/                   # Alembic migration scripts
│   ├── versions/              # 每次 migration 的版本檔
│   └── env.py
│
├── API/
│   ├── dto/                   # DTO (Pydantic models)
│   │   ├── driver_post.py
│   │   └── __init__.py
│   │
│   ├── post_route.py          # Router: /api/posts/*
│   └── __init__.py
│
├── domain/                    # Domain layer (ORM models, business entities)
│   ├── driverPost.py          # SQLAlchemy ORM Model
│   └── __init__.py
│
├── infrastructure/
│   ├── database.py            # engine, SessionLocal, database instance
│   └── __init__.py
│
├── repository/
│   ├── driverPost_repository.py   # DB access logic
│   └── __init__.py
│
├── .env                        # DB credentials
├── alembic.ini                 # Alembic config
├── app_logging.py
├── main.py                     # FastAPI application root
├── rate_limiting.py
├── README.md
├── requirements.txt
└── requirements-win.txt

```

- User-serv
```bash=
USER-SERV/
│
├── delivery/
│   └── http/
│       ├── AuthHandler.go          # 處理 OAuth / Login / Callback API（僅負責 HTTP I/O，不含業務邏輯）
│       ├── ImageHandler.go         # 處理 Image Upload / Get API
│       ├── NotifyHandler.go        # 處理 Notify 發送 / 查詢 API
│       └── UserHandler.go          # 處理 User CRUD / Profile API
│
├── entity/
│   └── user.go                     # Domain Entity（核心業務模型，不依賴 DB 或框架）
│
├── infrastructure/
│   ├── model/
│   │   ├── user_model.go           # GORM Model（User Table 映射）
│   │   ├── driver_model.go         # GORM Model（Driver Table 映射）
│   │   └── notify_model.go         # GORM Model（Notify Table 映射）
│   │
│   ├── auth.go                     # OAuth Provider 設定（goth）
│   ├── database.go                 # DB 連線設定、GORM 初始化、Migration
│   └── s3.go                       # S3 / Object Storage 客戶端初始化與設定
│
├── repositories/
│   ├── image_repository.go         # Image 資料存取（S3 / DB 等抽象封裝）
│   ├── notify_repository.go        # Notify 資料存取（封裝 DB Query）
│   └── user_repository.go          # User 資料存取（封裝 DB Query）
│
├── usecase/
│   ├── auth_usecase.go             # OAuth / Login / Callback 業務邏輯
│   ├── notifyService.go            # Notify 建立 / 查詢等業務邏輯
│   ├── uploadImageService.go       # 圖片上傳與管理業務邏輯
│   ├── userService.go              # User CRUD 與 Profile 業務邏輯
│   └── interface.go                # Usecase 與 Repository 介面定義（解耦實作）
│
├── .gitignore                      # Git 忽略規則
├── go.mod                          # Go Modules 設定
├── go.sum                          # 依賴版本鎖定
└── main.go                         # Server 啟動、DI、路由綁定與應用程式入口


```

- Admin-serv
```bash=
com.example.admin
│
├── configs/                     # 系統層設定（攔截器、CORS、Filter、全域設定等）
│   └── WebConfig.java
│
├── controllers/                 # API 入口層（接收 HTTP Request、回傳 Response）
│   └── BlackListController.java # 提供 Blacklist 相關 API
│
├── dto/                         # 請求/回應資料傳輸物件（避免直接暴露 Entity）
│   └── BlacklistDto.java
│
├── entity/                      # Domain/業務實體模型（與 DB 模型邏輯一致）
│   └── BlacklistEntity.java
│
├── repository/                  # 資料存取層（負責與 DB 溝通，通常繼承 JPA Repository）
│   └── BlacklistRepository.java
│
├── services/                    # 服務/商業邏輯層（封裝業務規則，避免寫在 Controller）
│   └── BlacklistService.java
│
└── AdminApplication.java        # Spring Boot 入口（Main 方法所在）

```

### 5.3 XML / JSON 結構
- User schema
```jsonld=
{
	"ID":             "string",
	"Provider":       "string",
	"ProviderUserID": "string",
	"Email":          "string",
	"Name":           "string",
	"PhoneNumber":    "string"
}
```
- Driver schema
```jsonld=
{
	"UserID":      "string",
	"Name":        "string",
	"ContactInfo": "string",
	"ScooterType": "string",
	"PlateNum":    "string"
}
```
- Post schema
```jsonld=
{
  	"driver_id": "string",
  	"vehicle_info": "string",
  	"status": "open",
  	"timestamp": "2025-11-24T08:44:13.477Z",
  	"starting_point": {},
  	"destination": {},
  	"meet_point": {},
  	"departure_time": "2025-11-24T08:44:13.477Z",
  	"notes": "string",
  	"description": "string",
  	"helmet": false,
  	"contact_info": {
  	  "additionalProp1": "string",
  	  "additionalProp2": "string",
  	  "additionalProp3": "string"
  	},
  	"leave": false
}
```

- Blacklist schema
```jsonld=
{
    private String id;
    private String userId;
    private String reason;
    private LocalDateTime createdAt;
}
```

---
## 6. 類別圖設計 (Class Diagram)
前端
![前端UML](https://hackmd.io/_uploads/rJ-U34XbWg.png)
後端 User-serv
![image](https://hackmd.io/_uploads/BJEvG8mWbx.png)
後端 Post-serv
![image](https://hackmd.io/_uploads/B1M_48XbZx.png)
後端 admin-serv
![image](https://hackmd.io/_uploads/B1nMPpEVZl.png)




---
## 7. 實作方案 (Implementation Languages and Platforms)
- 平台：NTOUber
- 前端技術與框架：JS/React
- 後端技術與框架：Python/FastAPI, Golang/Gin,Java/Spring Boot
- 主要函式庫與服務：User-serv, Post-serv, Admin-serv
- 部署方式：Zeabur


---
## 8. 設計議題 (Design Issue)
### 議題 1：貼文 Post 失敗

- 議題內容： 前端貼文發布時無法POST到後端 (CORS)
- 可能解決方案： 與後端重新溝通，確認問題點 / 請後端開啟權限
- 最後解決方案與理由： 重新確認Schema架構，發現Schema名稱沒有對上

### 議題 2：如何提交請求

- 議題內容：提交請求 Schema
- 可能解決方案：Post Schema中新增一屬性，存取當前乘客的請求狀態
- 最後解決方案與理由： 新增屬性ClientID 儲存貼文請求者的ID

### 議題 3：若車主改名了要如何儲存行程

- 議題內容：若車主post行程後，改名了，行程的車主名稱不會更改
- 可能解決方案：Post中的 `Driver_id` 不再存 `UserName` 改存 `UserId`
- 最後解決方案與理由：把 `Post` 和 `Driver` 連起來  

### 議題 4：authorization header

- 議題內容：若傳資料到後端時，沒有authorization header，可能會讓傳資料時不安全。
- 可能解決方案：實作authorization header 以及 不做authorization header。
- 最後解決方案與理由：加入Gateway系統

### 議題 5：admin post view

- 議題內容：admin 的 post 頁面沒有更新
- 可能解決方案：blank
- 最後解決方案與理由：blank

### 議題 6：admin login

- 議題內容：admin 需重新整理頁面才會抓取到管理員身分
- 可能解決方案：登入後強制刷新頁面
- 最後解決方案與理由：blank