---
title: Dev-in.tw 架構規劃
description: Dev-in.tw是一個由HACO和OnCloud聯合構思的專案,打造一個給予台灣得開法者建立個人子網域的平台,提供 A、AAAA、CNAME、URI......等功能。
tag: Website
lang: zh-TW
---

# Dev-in.tw 網域網站架構規劃
---
## 介紹
**Dev-in.tw是一個由HACO和OnCloud聯合構思的專案,
打造一個給予台灣的開發者建立個人子網域的平台,
提供 A、AAAA、CNAME、URI......等功能。**
---
## 發起人
**<a href="http://discord.com/users/508964901415550976" target="_blank">haco.tw</a>
<a href="http://discord.com/users/755269122597585018" target="_blank">OnCloud</a>**
---
## 聯絡方式
* 使用Discord私訊 [HACO#8888](http://discord.com/users/508964901415550976)
* 加入 [Discord](https://discord.gg/ZvwTZqXjYf) 在聊天之地提出問題
* Instagram搜尋 <a href="https://instagram.com/lazco.dev" target="_blank">lazco.dev</a> 並私訊我們
* 使用電子郵件寄送至 <a href="mailto:lazco.team@gmail.com" target="_blank">lazco.team@gmail.com</a>
<br />
聯絡時請遵守以下規則
* [No Hello](https://www.nohello.com/)
* [正確的提出技術問題](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)
---
## 網站架構
```
SubdomainName => 子網域名稱如 lazco
SubdomainID => 子網域申請後會自動生成的一組ID
```
#### 前端 - 客戶
`GET /` - 首頁
`GET /account` - 查看帳戶
`GET /account/edit` - 編輯帳戶
`GET /login` - 登入帳戶
`GET /logout` - 登出帳戶
`GET /account/verify` - 驗證帳戶
`GET /find?sub={SubdomainName}` - 子網域存在查詢
`GET /domain` - 管理子網域
`GET /domain/register` - 註冊子網域
`GET /domain/edit/{SubdomainID}` - 編輯子網域
<br />
#### 前端 - 管理
`GET /lazco/account` - 管理所有帳戶
`GET /lazco/account/{accountID}` - 管理單一帳戶
`GET /lazco/account/{accountID}/edit` - 編輯帳戶
`GET /lazco/account/{accountID}/verify` - 審查帳戶驗證
`GET /lazco/domain/` - 管理所有子網域
`GET /lazco/domain/verify` - 子網域申請審查列表
`GET /lazco/domain/verify/{SubdomainID}` - 審查單一子網域申請
`GET /lazco/domain/{SubdomainID}` - 管理單一子網域
`GET /lazco/domain/{SubdomainID}/edit` - 編輯子網域
<br />
#### 後端
##### Tech / Framework
- Language: TypeScript
- Schema validation: Zod
- Framework: NestJS
- Database: MongoDB
##### Database schema
**1. Domain**
```json
{
_id: String, // 此欄位為DB自動生成之欄位, will be used as domain id.
cloudflare_id: String, // POST到CF後所生成的id,預設 0
name: String, // 子網域名稱 如:lazco
description: String, // 子網域介紹
owner: String, // 使用者採用id制抓id獲取資料
verify: Boolean, // true 即代表申請通過,預設為 false
status: String, //
apply_time: Date, // 申請送出的timestamp
last_update: Date, // 最後變更的timestamp,預設同apply_time
expire_time: Date, // 到期timestamp,申請通過當下後一年
ssl: String, // Will only be one of ["off", "flexible", "full", "strict"]
premium: Boolean, // 是否否為精選子網域
exclusive: Boolean, // 使否為特殊子網域
disable: Boolean, // 是被管理員停用
}
```
**2. User**
```json
{
_id: String, // 此欄位為DB自動生成之欄位, will be used as user id.
githubId: String, // User's Github ID
email: String, // User's email
name: String, // User's display name.
first_name: String, // 申請網域時身份驗證用
last_name: String, // 申請網域時身份驗證用
birth: Date, // 申請網域時身份驗證用
identy_id: String, // 申請網域時身份驗證用
address: String, // 申請網域時身份驗證用
phone: String, // 申請網域時身份驗證用
avatar: String, // Base64 encoded image.
description: String, // User's description.
domain_names: [String], // e.g. lazco, haco, oncloud.
badage: [String], // Just for future. e.g. Premium badage, Domain badage.
beta: Boolean, // Just for future. Get beta program.
warn: Number, // Admin warning time.
disable: Boolean, // Banned
premium: Boolean, // Yup, VIP mode.
ip: [String], // 記錄使用者 IP
create_time: Date, // Account created time.
last_update: Date, // Account last edit time.
}
```
Rate limit:
- `/search` 50reqs / 10min
<br />
##### Github
透過以下網址帶入`code`獲得Github `access_token`
https://github.com/login/oauth/access_token
<br />
以下兩個網址皆需帶入 Bearer `access_token`
https://api.github.com/user
https://api.github.com/user/emails
<br />
如果使用者有很多個email
就挑選primary = true
我們也需要GitHub ID
因為使用者有可能會改primary mail
因此每次登入都要抓取
<br />
範例程式碼 1 `code get acces_token from github`
```ts=
// GITHUB CLIENT ID 和 SECRET 請洽 HACO
const github_response = await fetch(
"https://github.com/login/oauth/access_token",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
client_id: process.env.GITHUB_CLIENT_ID,
client_secret: process.env.GITHUB_CLIENT_SECRET,
scope: "user:email",
code,
}),
}
);
const { access_token } = await github_response.json();
```
<br />
範例程式碼 2 `acces_token get user info from github`
```ts=
const github_user_response =
await fetch("https://api.github.com/user", {
headers: {
Authorization: `Bearer ${access_token}`,
},
});
const userData = await github_user_response.json();
```
<br />
範例程式碼 3 `acces_token get user email from github`
```ts=
const github_user_response =
await fetch("https://api.github.com/user", {
headers: {
Authorization: `Bearer ${access_token}`,
},
});
const userData = await github_user_response.json();
```
<br />
##### 路由
**Main**
`ANY` `/`
```json
200
{
message: "Welcome to Dev-in.tw backend API"
}
```
`ANY` `/*`
```json
404
{
message: "Welcome to Dev-in.tw backend API"
}
```
<br />
**Authentication**
`POST` `/auth/github`
> Pass in Github authentication code, return user's Bearer for dev-in.tw.
> Create new user if necessary.
> Please refer to [API Document](https://dev-in-tw-api-dev.zeabur.app/docs#/default/GithubController_getGitHubAccountData).
<br />
**User**
`GET` `/user` List all user, required bearer from lazco team member
`PATCH` `/user/${userId}` Update user, required bearer from lazco team member
`DELETE` `/user/${userId}` DELETE user, required bearer from lazco member
`GET` `/user/info` Required Bearer to get user info
`PATCH` `/user/info` Required Bearer to update user info
`GET` `/user/info/${userId}` Get user public info
<br />
**Domain**
`GET` `/domain/find/${SubdomainName}` Search the subdomain.
`POST` `/domain/register/${SubdomainName}` Register subdomain. Required user Bearer
<br />
dev-in.tw
www.dev-in.tw
api.dev-in.tw
{%hackmd @lazco/dracula %}