王琪驊 (Emily Wang)
--- 持續學習、自省
工作以來,持續透過下班時間學習軟體開發技能,勇於挑戰與嘗試新事物,做好當下的每一件事,不放棄任何機會。
平時參與技術社群活動,包含 React 培訓、GraphQL應用,後端讀書會,以及演算法讀書會。
專案簡介
鋼構設計流程自動化
曾在外部讀書會分享於此專案上應用 design pattern ,相關的說明與 sample code 請見此:Design pattern 在專案上的應用 (slides.com)
結構分析軟體
BIM 整合軟體
鋼接頭檢核軟體
Data Standardlization
Via API
ref:
https://bit.ly/3e58D9I; https://bit.ly/3gTVIJt; https://bit.ly/3aUQglT
專案簡介
Lodestar 內容商務系統
我在目前公司主要是做 SaaS 系統的功能擴充與開發,應用程式的核心架構分為前台、後台與後端,前端 repo 皆為開源專案
後端的部分,我參與了多個外部系統串接的需求,主要的架構設計為使用 class 封裝外部 api 的操作 (詳見下頁
class PaypalClient {
  appId: string
  dryRun: boolean
  environment: any | null
  constructor(appId: string) {
    this.appId = appId
    this.dryRun = Boolean(process.env.NODE_ENV !== 'production')
  }
  public setup = async () => {
	// ...
  }
  public createOrder = async (orderDetails: CreateOrderRequestBody) => {
    // ...
  }
  public captureOrder = async (paypalOrderId: string) => {
   // ...
  }
}跨境金流 PayPal 串接
// ...
      const host = await getAppHost(appId)
      const paypalClient = new PaypalClient(appId)
      try {
        await paypalClient.setup()
      } catch (error) {
        return res.redirect(`https://${host}/orders/${orderId}?code=E_SETUP_PAYPAL&error=${error.message}`)
      }
      // capture order
      let capturedOrderResponse: OrderResponse | any
      try {
        capturedOrderResponse = await paypalClient.captureOrder(paymentId)
      } catch (error) {
        return res.redirect(`https://${host}/orders/${orderId}?code=E_PAYPAL_CAPTURE&error=${error.message}`)
      }封裝外部 api 之 Client class
在 controller 內使用 client
外部 CRM 串接
class VitalClient {
  appId: string
  private _baseUri: string = ''
  private _storeName: string = ''
  private _apiKey: string = ''
  private _apiBaseCaller: AxiosInstance = axios
  constructor(appId: string) {
    this.appId = appId
  }
  public init = async () => {
    const appModules = await getAppModules(this.appId)
    if (!appModules.includes('vital_crm')) {
      throw new Error(`app: ${this.appId} did not support vital crm. Please add vital_crm module`)
    }
    // ...
    this._baseUri = 'https://www.videgree.com/' + this._storeName
    this._apiBaseCaller = axios.create({
      headers: {
        Authorization: `ApiKey ${this._apiKey}`,
      },
      baseURL: this._baseUri,
    })
  }
  private _composeMemberData = (memberData: { email: string; name: string; id: string }) => {
	// ...
  }
  private _composeOrderData = (orderData) => {
	// ...
  }
  public insertMember = async (memberData: { [key: string]: any }) => {
    // memberData to vital req.body
  }
  public updateMember = async (memberData: { [key: string]: any }) => {
	// ...
  }
  public insertOrUpdateOrder = async (orderData) => {
   // ...
  }
}封裝外部 api 之 Client class
// ...  
private static _handleMemberInsertOrUpdate = async (event: TriggerEvent) => {
    // get app Id if there have vital_crm module
    const appId = event.data.new?.app_id
    const appModules = await getAppModules(appId)
    if (!appModules.includes('vital_crm')) return
    // get vitalClient
    const vitalClient = new VitalClient(appId)
    try {
      await vitalClient.init()
    } catch (error) {
      throw new Error(`vital Client init failed: ${error.stack}`)
    }
    const newMemberData = event.data.new || {}
    const vitalCustomerNo = newMemberData?.metadata?.vital?.CustomerNo
    // insert
    if (!vitalCustomerNo) {
      await vitalClient.insertMember(newMemberData)
      return
    }
    // update
    await vitalClient.updateMember(newMemberData)
  }外部 CRM 串接
在 event trigger 內使用 client
公司內部 code review,由我畫系統架構圖,並與 scrum team 講解目前的架構
Any Question?