diff --git a/example/api/common.api b/example/api/common.api new file mode 100755 index 0000000..808dba5 --- /dev/null +++ b/example/api/common.api @@ -0,0 +1,33 @@ +syntax = "v1" + +// ================ 通用響應 ================ +type ( + // 成功響應 + OKResp { + Code int `json:"code"` + Msg string `json:"msg"` + Data interface{} `json:"data,omitempty"` + } + + // 分頁響應 + PagerResp { + Total int64 `json:"total"` + Size int64 `json:"size"` + Index int64 `json:"index"` + } + + // 錯誤響應 + ErrorResp { + Code int `json:"code"` + Msg string `json:"msg"` + Details string `json:"details,omitempty"` + Error interface{} `json:"error,omitempty"` // 可選的錯誤信息 + } + + BaseReq {} + + VerifyHeader { + Token string `header:"token" validate:"required"` + } +) + diff --git a/example/api/gateway.api b/example/api/gateway.api new file mode 100755 index 0000000..051d28d --- /dev/null +++ b/example/api/gateway.api @@ -0,0 +1,20 @@ +syntax = "v1" + +info ( + title: "Digimon Platform API Gateway" + description: "This is Digimon Platform " + version: "v1" + contactName: "Daniel Wang" + contactEmail: "igs170911@gmail.com" + consumes: "application/json" + produces: "application/json" + schemes: "http,https" + host: "127.0.0.1:8888" +) + +import ( + "common.api" + "ping.api" + "member.api" +) + diff --git a/example/api/member.api b/example/api/member.api new file mode 100644 index 0000000..b78d151 --- /dev/null +++ b/example/api/member.api @@ -0,0 +1,555 @@ +syntax = "v1" + +// ================ 請求/響應結構 ================ +type ( + // 創建用戶帳號請求 + CreateUserAccountReq { + LoginID string `json:"login_id" validate:"required,min=3,max=50"` + Platform int `json:"platform" validate:"required,oneof=1 2 3 4"` + Token string `json:"token" validate:"required,min=8,max=128"` + } + + // 綁定用戶請求 + BindingUserReq { + UID string `json:"uid" validate:"required,min=1,max=50"` + LoginID string `json:"login_id" validate:"required,min=3,max=50"` + Type int `json:"type" validate:"required,oneof=1 2 3"` + } + + // 綁定用戶響應 + BindingUserResp { + UID string `json:"uid"` + LoginID string `json:"login_id"` + Type int `json:"type"` + } + + // 創建用戶資料請求 + CreateUserInfoReq { + UID string `json:"uid" validate:"required,min=1,max=50"` + AlarmType int `json:"alarm_type" validate:"required,oneof=0 1 2"` + Status int `json:"status" validate:"required,oneof=0 1 2 3"` + Language string `json:"language" validate:"required,min=2,max=10"` + Currency string `json:"currency" validate:"required,min=3,max=3"` + Avatar *string `json:"avatar,omitempty"` + NickName *string `json:"nick_name,omitempty" validate:"omitempty,min=1,max=50"` + FullName *string `json:"full_name,omitempty" validate:"omitempty,min=1,max=100"` + Gender *int64 `json:"gender,omitempty" validate:"omitempty,oneof=0 1 2"` + Birthdate *int64 `json:"birthdate,omitempty" validate:"omitempty,min=19000101,max=21001231"` + PhoneNumber *string `json:"phone_number,omitempty" validate:"omitempty,min=10,max=20"` + Email *string `json:"email,omitempty" validate:"omitempty,email"` + Address *string `json:"address,omitempty" validate:"omitempty,max=200"` + } + + // 獲取帳號資訊響應 + GetAccountInfoResp { + Data CreateUserAccountReq `json:"data"` + } + + // 更新用戶資料請求 + UpdateUserInfoReq { + UID string `json:"uid" validate:"required,min=1,max=50"` + Language *string `json:"language,omitempty" validate:"omitempty,min=2,max=10"` + Currency *string `json:"currency,omitempty" validate:"omitempty,min=3,max=3"` + NickName *string `json:"nick_name,omitempty" validate:"omitempty,min=1,max=50"` + Avatar *string `json:"avatar,omitempty"` + AlarmType *int `json:"alarm_type,omitempty" validate:"omitempty,oneof=0 1 2"` + Status *int `json:"status,omitempty" validate:"omitempty,oneof=0 1 2 3"` + FullName *string `json:"full_name,omitempty" validate:"omitempty,min=1,max=100"` + Gender *int64 `json:"gender,omitempty" validate:"omitempty,oneof=0 1 2"` + Birthdate *int64 `json:"birthdate,omitempty" validate:"omitempty,min=19000101,max=21001231"` + Address *string `json:"address,omitempty" validate:"omitempty,max=200"` + } + + // 獲取 UID 請求 + GetUIDByAccountReq { + Account string `json:"account" validate:"required,min=3,max=50"` + } + + // 獲取 UID 響應 + GetUIDByAccountResp { + UID string `json:"uid"` + Account string `json:"account"` + } + + // 更新密碼請求 + UpdateTokenReq { + Account string `json:"account" validate:"required,min=3,max=50"` + Token string `json:"token" validate:"required,min=8,max=128"` + Platform int `json:"platform" validate:"required,oneof=1 2 3 4"` + } + + // 生成驗證碼請求 + GenerateRefreshCodeReq { + Account string `json:"account" validate:"required,min=3,max=50"` + CodeType int `json:"code_type" validate:"required,oneof=1 2 3"` + } + + // 驗證碼響應 + VerifyCodeResp { + VerifyCode string `json:"verify_code"` + } + + // 生成驗證碼響應 + GenerateRefreshCodeResp { + Data VerifyCodeResp `json:"data"` + } + + // 驗證碼請求 + VerifyRefreshCodeReq { + Account string `json:"account" validate:"required,min=3,max=50"` + CodeType int `json:"code_type" validate:"required,oneof=1 2 3"` + VerifyCode string `json:"verify_code" validate:"required,min=4,max=10"` + } + + // 更新狀態請求 + UpdateStatusReq { + UID string `json:"uid" validate:"required,min=1,max=50"` + Status int `json:"status" validate:"required,oneof=0 1 2 3"` + } + + // 獲取用戶資訊請求 + GetUserInfoReq { + UID string `json:"uid,omitempty" validate:"omitempty,min=1,max=50"` + NickName *string `json:"nick_name,omitempty" validate:"omitempty,min=1,max=50"` + } + + // 用戶資訊 + UserInfo { + UID string `json:"uid"` + AvatarURL *string `json:"avatar_url,omitempty"` + FullName *string `json:"full_name,omitempty"` + NickName *string `json:"nick_name,omitempty"` + GenderCode *int64 `json:"gender_code,omitempty"` + Birthday *int64 `json:"birthday,omitempty"` + Phone *string `json:"phone,omitempty"` + Email *string `json:"email,omitempty"` + Address *string `json:"address,omitempty"` + AlarmType int `json:"alarm_type"` + Status int `json:"status"` + Language string `json:"language"` + Currency string `json:"currency"` + CreateTime int64 `json:"create_time"` + UpdateTime int64 `json:"update_time"` + } + + // 獲取用戶資訊響應 + GetUserInfoResp { + Data UserInfo `json:"data"` + } + + // 用戶列表請求 + ListUserInfoReq { + AlarmType *int `json:"alarm_type,omitempty" validate:"omitempty,oneof=0 1 2"` + Status *int `json:"status,omitempty" validate:"omitempty,oneof=0 1 2 3"` + CreateStartTime *int64 `json:"create_start_time,omitempty"` + CreateEndTime *int64 `json:"create_end_time,omitempty"` + PageSize int `json:"page_size" validate:"required,min=1,max=100"` + PageIndex int `json:"page_index" validate:"required,min=1"` + } + + // 用戶列表響應 + ListUserInfoResp { + Data []UserInfo `json:"data"` + Pager PagerResp `json:"pager"` + } + + // 驗證認證結果請求 + VerifyAuthResultReq { + Token string `json:"token" validate:"required,min=1"` + Account *string `json:"account,omitempty" validate:"omitempty,min=3,max=50"` + } + + // 驗證認證結果響應 + VerifyAuthResultResp { + Status bool `json:"status"` + } + + // Google 認證結果響應 + VerifyGoogleAuthResultResp { + Status bool `json:"status"` + Iss *string `json:"iss,omitempty"` + Sub *string `json:"sub,omitempty"` + Aud *string `json:"aud,omitempty"` + Exp *string `json:"exp,omitempty"` + Iat *string `json:"iat,omitempty"` + Email *string `json:"email,omitempty"` + EmailVerified *string `json:"email_verified,omitempty"` + Name *string `json:"name,omitempty"` + Picture *string `json:"picture,omitempty"` + } + + // 綁定驗證 Email 請求 + BindVerifyEmailReq { + UID string `json:"uid" validate:"required,min=1,max=50"` + Email string `json:"email" validate:"required,email"` + } + + // 綁定驗證 Phone 請求 + BindVerifyPhoneReq { + UID string `json:"uid" validate:"required,min=1,max=50"` + Phone string `json:"phone" validate:"required,min=10,max=20"` + } + + // LINE 獲取 Token 請求 + LineGetTokenReq { + Code string `json:"code" validate:"required,min=1"` + } + + // LINE Access Token 響應 + LineAccessTokenResp { + Token string `json:"token"` + } + + // LINE 用戶資料 + LineUserProfile { + DisplayName string `json:"display_name"` + UserID string `json:"user_id"` + PictureURL string `json:"picture_url"` + StatusMessage string `json:"status_message"` + } + + // LINE 獲取用戶資訊請求 + LineGetUserInfoReq { + Token string `json:"token" validate:"required,min=1"` + } +) + +// ================ API 路由 ================ +@server( + group: account + prefix: /api/v1/account +) +service gateway { + @doc( + summary: "創建用戶帳號" + description: "創建新的用戶帳號,支援多平台登入" + ) +/* + @respdoc-200 (OKResp) // 創建成功 + @respdoc-400 ( + 40001: (ErrorResp) 帳號格式錯誤 + 40002: (ErrorResp) 密碼強度不足 + 40003: (ErrorResp) 平台類型無效 + ) // 客戶端錯誤 + @respdoc-409 (ErrorResp) // 帳號已存在 + @respdoc-422 (ErrorResp) // 請求格式正確但語義錯誤 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler CreateUserAccount + post /create (CreateUserAccountReq) returns (OKResp) + + @doc( + summary: "獲取帳號資訊" + description: "根據帳號獲取用戶的帳號資訊" + ) +/* + @respdoc-200 (GetAccountInfoResp) // 獲取成功 + @respdoc-400 ( + 40001: (ErrorResp) 帳號格式錯誤 + 40004: (ErrorResp) 參數驗證失敗 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 帳號不存在 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler GetUserAccountInfo + post /info (GetUIDByAccountReq) returns (GetAccountInfoResp) + + @doc( + summary: "更新用戶密碼" + description: "更新指定帳號的密碼" + ) +/* + @respdoc-200 (OKResp) // 更新成功 + @respdoc-400 ( + 40001: (ErrorResp) 帳號格式錯誤 + 40002: (ErrorResp) 密碼強度不足 + 40003: (ErrorResp) 平台類型無效 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 帳號不存在 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler UpdateUserToken + post /update-token (UpdateTokenReq) returns (OKResp) + + @doc( + summary: "獲取用戶 UID" + description: "根據帳號獲取對應的用戶 UID" + ) +/* + @respdoc-200 (GetUIDByAccountResp) // 獲取成功 + @respdoc-400 ( + 40001: (ErrorResp) 帳號格式錯誤 + 40004: (ErrorResp) 參數驗證失敗 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 帳號不存在 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler GetUIDByAccount + post /uid (GetUIDByAccountReq) returns (GetUIDByAccountResp) + + @doc( + summary: "綁定帳號" + description: "將帳號綁定到指定的用戶 UID" + ) +/* + @respdoc-200 (BindingUserResp) // 綁定成功 + @respdoc-400 ( + 40001: (ErrorResp) 帳號格式錯誤 + 40004: (ErrorResp) 參數驗證失敗 + 40005: (ErrorResp) UID 格式錯誤 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 帳號不存在 + @respdoc-409 (ErrorResp) // 帳號已綁定 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler BindAccount + post /bind (BindingUserReq) returns (BindingUserResp) + + @doc( + summary: "綁定用戶資料" + description: "初次綁定用戶的詳細資料" + ) +/* + @respdoc-200 (OKResp) // 綁定成功 + @respdoc-400 ( + 40004: (ErrorResp) 參數驗證失敗 + 40005: (ErrorResp) UID 格式錯誤 + 40006: (ErrorResp) 郵箱格式錯誤 + 40007: (ErrorResp) 電話格式錯誤 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 用戶不存在 + @respdoc-409 (ErrorResp) // 用戶資料已存在 + @respdoc-422 (ErrorResp) // 用戶資料不完整 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler BindUserInfo + post /bind-info (CreateUserInfoReq) returns (OKResp) + + @doc( + summary: "綁定驗證 Email" + description: "綁定並驗證用戶的 Email 地址" + ) +/* + @respdoc-200 (OKResp) // 綁定成功 + @respdoc-400 ( + 40005: (ErrorResp) UID 格式錯誤 + 40006: (ErrorResp) 郵箱格式錯誤 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 用戶不存在 + @respdoc-409 (ErrorResp) // 郵箱已綁定 + @respdoc-422 (ErrorResp) // 郵箱未驗證 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler BindVerifyEmail + post /bind-email (BindVerifyEmailReq) returns (OKResp) + + @doc( + summary: "綁定驗證 Phone" + description: "綁定並驗證用戶的電話號碼" + ) +/* + @respdoc-200 (OKResp) // 綁定成功 + @respdoc-400 ( + 40005: (ErrorResp) UID 格式錯誤 + 40007: (ErrorResp) 電話格式錯誤 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 用戶不存在 + @respdoc-409 (ErrorResp) // 電話已綁定 + @respdoc-422 (ErrorResp) // 電話未驗證 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler BindVerifyPhone + post /bind-phone (BindVerifyPhoneReq) returns (OKResp) + + @doc( + summary: "更新用戶資料" + description: "更新用戶的個人資料資訊" + ) +/* + @respdoc-200 (OKResp) // 更新成功 + @respdoc-400 ( + 40004: (ErrorResp) 參數驗證失敗 + 40005: (ErrorResp) UID 格式錯誤 + 40006: (ErrorResp) 郵箱格式錯誤 + 40007: (ErrorResp) 電話格式錯誤 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 用戶不存在 + @respdoc-422 (ErrorResp) // 用戶資料無效 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler UpdateUserInfo + post /update-info (UpdateUserInfoReq) returns (OKResp) + + @doc( + summary: "更新用戶狀態" + description: "更新用戶的帳號狀態" + ) +/* + @respdoc-200 (OKResp) // 更新成功 + @respdoc-400 ( + 40004: (ErrorResp) 參數驗證失敗 + 40005: (ErrorResp) UID 格式錯誤 + 40008: (ErrorResp) 狀態值無效 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 用戶不存在 + @respdoc-422 (ErrorResp) // 狀態更新無效 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler UpdateStatus + post /update-status (UpdateStatusReq) returns (OKResp) + + @doc( + summary: "獲取用戶資訊" + description: "根據 UID 或暱稱獲取用戶詳細資訊" + ) +/* + @respdoc-200 (GetUserInfoResp) // 獲取成功 + @respdoc-400 ( + 40004: (ErrorResp) 參數驗證失敗 + 40005: (ErrorResp) UID 格式錯誤 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 用戶不存在 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler GetUserInfo + post /user-info (GetUserInfoReq) returns (GetUserInfoResp) + + @doc( + summary: "獲取用戶列表" + description: "分頁獲取用戶列表,支援篩選條件" + ) +/* + @respdoc-200 (ListUserInfoResp) // 獲取成功 + @respdoc-400 ( + 40004: (ErrorResp) 參數驗證失敗 + 40009: (ErrorResp) 分頁參數無效 + ) // 客戶端錯誤 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler ListMember + post /list (ListUserInfoReq) returns (ListUserInfoResp) + + @doc( + summary: "生成驗證碼" + description: "為指定帳號生成驗證碼,用於忘記密碼等功能" + ) +/* + @respdoc-200 (GenerateRefreshCodeResp) // 生成成功 + @respdoc-400 ( + 40001: (ErrorResp) 帳號格式錯誤 + 40004: (ErrorResp) 參數驗證失敗 + 40010: (ErrorResp) 驗證碼類型無效 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 帳號不存在 + @respdoc-429 (ErrorResp) // 請求過於頻繁 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler GenerateRefreshCode + post /generate-code (GenerateRefreshCodeReq) returns (GenerateRefreshCodeResp) + + @doc( + summary: "驗證驗證碼" + description: "驗證並使用驗證碼,驗證後會刪除驗證碼" + ) +/* + @respdoc-200 (OKResp) // 驗證成功 + @respdoc-400 ( + 40001: (ErrorResp) 帳號格式錯誤 + 40004: (ErrorResp) 參數驗證失敗 + 40010: (ErrorResp) 驗證碼類型無效 + 40011: (ErrorResp) 驗證碼格式錯誤 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 驗證碼不存在 + @respdoc-422 (ErrorResp) // 驗證碼無效或已過期 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler VerifyRefreshCode + post /verify-code (VerifyRefreshCodeReq) returns (OKResp) + + @doc( + summary: "檢查驗證碼" + description: "檢查驗證碼是否正確,但不刪除驗證碼" + ) +/* + @respdoc-200 (OKResp) // 檢查成功 + @respdoc-400 ( + 40001: (ErrorResp) 帳號格式錯誤 + 40004: (ErrorResp) 參數驗證失敗 + 40010: (ErrorResp) 驗證碼類型無效 + 40011: (ErrorResp) 驗證碼格式錯誤 + ) // 客戶端錯誤 + @respdoc-404 (ErrorResp) // 驗證碼不存在 + @respdoc-422 (ErrorResp) // 驗證碼無效或已過期 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler CheckRefreshCode + post /check-code (VerifyRefreshCodeReq) returns (OKResp) + + @doc( + summary: "驗證 Google 認證" + description: "驗證 Google OAuth 登入是否有效" + ) +/* + @respdoc-200 (VerifyGoogleAuthResultResp) // 驗證成功 + @respdoc-400 ( + 40004: (ErrorResp) 參數驗證失敗 + 40012: (ErrorResp) Token 格式錯誤 + ) // 客戶端錯誤 + @respdoc-401 (ErrorResp) // Token 無效或過期 + @respdoc-422 (ErrorResp) // Google 認證失敗 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler VerifyGoogleAuthResult + post /verify-google (VerifyAuthResultReq) returns (VerifyGoogleAuthResultResp) + + @doc( + summary: "驗證平台認證" + description: "驗證平台登入認證是否有效" + ) +/* + @respdoc-200 (VerifyAuthResultResp) // 驗證成功 + @respdoc-400 ( + 40004: (ErrorResp) 參數驗證失敗 + 40012: (ErrorResp) Token 格式錯誤 + ) // 客戶端錯誤 + @respdoc-401 (ErrorResp) // Token 無效或過期 + @respdoc-422 (ErrorResp) // 平台認證失敗 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler VerifyPlatformAuthResult + post /verify-platform (VerifyAuthResultReq) returns (VerifyAuthResultResp) + + @doc( + summary: "LINE 獲取 Access Token" + description: "使用 LINE 授權碼獲取 Access Token" + ) +/* + @respdoc-200 (LineAccessTokenResp) // 獲取成功 + @respdoc-400 ( + 40004: (ErrorResp) 參數驗證失敗 + 40013: (ErrorResp) 授權碼格式錯誤 + ) // 客戶端錯誤 + @respdoc-401 (ErrorResp) // 授權碼無效或過期 + @respdoc-422 (ErrorResp) // LINE 認證失敗 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler LineCodeToAccessToken + post /line/token (LineGetTokenReq) returns (LineAccessTokenResp) + + @doc( + summary: "LINE 獲取用戶資料" + description: "使用 LINE Access Token 獲取用戶資料" + ) +/* + @respdoc-200 (LineUserProfile) // 獲取成功 + @respdoc-400 ( + 40004: (ErrorResp) 參數驗證失敗 + 40012: (ErrorResp) Token 格式錯誤 + ) // 客戶端錯誤 + @respdoc-401 (ErrorResp) // Token 無效或過期 + @respdoc-422 (ErrorResp) // LINE 用戶資料獲取失敗 + @respdoc-500 (ErrorResp) // 服務器錯誤 +*/ + @handler LineGetProfileByAccessToken + post /line/profile (LineGetUserInfoReq) returns (LineUserProfile) +} diff --git a/example/api/ping.api b/example/api/ping.api new file mode 100644 index 0000000..4d41de7 --- /dev/null +++ b/example/api/ping.api @@ -0,0 +1,21 @@ +syntax = "v1" + +// =========================================== +// 系統健康檢查 API 端點定義 +// =========================================== + +@server( + group: ping + prefix: /api/v1 + schemes: https + timeout: 10s +) + +service gateway { + @doc( + summary: "系統健康檢查" + description: "檢查系統服務狀態,用於監控和負載均衡器健康檢查。返回系統運行狀態信息。" + ) + @handler Ping + get /health () returns () +} \ No newline at end of file