# wallet_backend_design
express.js + mysql
## DATABASE:
#### 資料型態:
Primary Key: varchar或是int
(用int可以使用自動遞增,缺點是debug不方便)
整數:int
字串:varchar
時間:datetime
非必填的欄位設為可NULL
created_time跟updated_time自動生成)(不確定mysql是否可以)
#### TABLE:
user
id,channel,channel_id,email,username,nick_name,created_time,updated_time
wallet
id,user_id,selected,name,total,title,desc,created_time,updated_time
wallet_record
id,wallet_id,wallet_record_tag_id,ordinary,name,description,amount,type(吃/交通..),date,created_time,updated_time
wallet_record_tag_id
id,wallet_id,ordinary,name,type(支出/收入),created_time,updated_time
---
## API:
#### 目錄:
A.使用者登入登出系統
一. google登入
二. 註冊(需經過google登入後判斷未註冊回到註冊頁)
三. google登入成功且已註冊
B.wallet
一. 使用者選擇超出buffer的月份時,拿該月+-6個月的資料
二. wallet:
二-a.讀取
二-b.新增
二-c.修改
二-d.刪除
三. wallet紀錄:
三-a.讀取
三-b.新增
三-c.修改
三-d.刪除
四. 標籤:
四-a.讀取
四-b.新增
四-c.修改
四-d.刪除
五. 報表
四-a.讀取
六. 使用者設定
六-a.修改暱稱
### A.使用者登入登出系統
#### [一. google登入]:
request:
HTTP: GET
url: "/user/login/google"
SERVER內流程:
1.轉至google登入介面,使用者填google帳密後按確認:
1-a.google登入成功:
使用Google回來的資料查詢資料庫是否已有該使用者紀錄:
使用該使用者email帳號加密後產生使用者id(sha-256固定產生32位元的字串)
用該使用者id判斷是否已存在在資料庫裡
SELECT EXIST(*)
FROM user
WHERE user_id=?
若有:
製作該用戶token跟jwt(驗證使用者使否過期用)
redirect回前端並用url將token傳給前端登入待轉頁(前端收到token後再發一次request拿取該使用者全部資料)
若無:
製作該用戶token
redirect回前端並用url將token傳給前端註冊頁
1-b.google登入失敗:
redirect回前端登入頁
response:
直接redirect
#### [二. 註冊]:
request:
url: "user/signup"
HTTP: POST
header:
jwt(json web token字串)
content-type: "application/json utf-8"
body:
{
user_token: // [一.google登入]會給token
nick_name:
}
SERVER端驗證:
驗證jwt是否過期
驗證session是否有該使用者紀錄
SERVER內流程:
使用使用者email帳號加密後產生使用者id(sha-256固定產生32位元的字串)
利用session取得該使用者的channel跟channel_id
寫入資料庫:
INSERT INTO user
values(user_id=?,nick_name=?,channel=?,channel_id=?,created_time=?)
//幫該使用者新增一個預設錢包
//幫該使用者的預設錢包新增多個預設標籤(吃/交通/...)
response:
{
status:"error"/"success"
message:"註冊成功/失敗"
data:{
//無
}
}
#### [三. google登入成功且已註冊,在重新倒回到前端後再發一次request取得完整資料]:
request:
POST
url: "user/data/get"
SERVER端驗證:
驗證jwt是否過期
驗證session是否有該使用者紀錄
SERVER內流程:
從資料庫取得該使用者資料
SELECT *
FROM user
JOIN wallet
ON wallet.user_id=user.id
JOIN wallet_record
ON wallet_record.wallet_id=wallet.id
將取出的資料轉成以下格式
response:
{
status:"error"/"success"
message:""
data:{
user_id:
user_name:
user_nick_name:
selected_wallet_id:"a",
wallets:[
"wallet-a":{
wallet_id,
wallet_name:
selected: //true/false
records:[
{
record_id:"wallet-a-record-1"
wallet_record_tag_id:
record_ordinary:
record_name:
record_description:
record_amount:
record_type:
record_date:
record_created_time:
},
{
record_id:"wallet-a-record-2"
wallet_record_tag_id:
record_ordinary:
record_name:
record_description:
record_amount:
record_type:
record_date:
record_created_time:
},
]
},
"wallet-b":{
wallet_id,
wallet_name:
selected: //若selected==false則records為空陣列
records:[
]
}
]
}
}
### B.wallet
#### [一.取得給定錢包給定月份+-6個月的record]:
reuqest:
SERVER端驗證:
驗證jwt是否過期
驗證session是否有該使用者紀錄
SERVER內流程:
從資料庫取得該使用者資料
response:
### SERVER規則:
1.response status code:
200: GET 成功
201: POST 成功
400: 網路問題
500: SERVER問題
2.登入成功只會回傳selected錢包的所有資料
3.一個錢包只會包含 當月+-6個月的資料
4.除了google登入外的API 都有以下規則:
1.使用cookie跟session驗證該使用者的瀏覽器先前曾經google登入成功過,並利用cookie會過期的特性,驗證使用者是否過期
若要再更安全:
2.使用json web token驗證使用者是否過期
(
登入成功後將會發送一個jwt給前端,存在local storage或vues內
(放在Local Storage的好處:若關掉再重開瀏覽器則不需要再重新登入 且該字串為加密字串毋須擔心資訊安全問題)
每次request的時候將該token字串放到header內
給後端驗證使用者是否過期
)
5.若使用google登入跟使用FB登入的email是同一個,則視為同一個帳戶(我們使用加密後的email作為Primary Key)
6.每次增刪改紀錄後會需要重新拿該月+-6個月的資料(在同一個requset/response)
7.使用url傳遞變數時一率採用後端加密前端解密
### 檔案結構:
-model
-user
-user_service
-wallet
-wallet_service
-wallet_record
-wallet_record_service
-controller
-user
-wallet
-wallet_record
-route
-user
-wallet
-wallet_record
-middleware
index.js
### model結構: