iT邦幫忙

2024 iThome 鐵人賽

DAY 16
1
Software Development

透過 nestjs 框架,讓 nodejs 系統維護度增加系列 第 17

nestjs 系統設計 - 活動訂票管理系統 - User Module part 4

  • 分享至 

  • xImage
  •  

nestjs 系統設計 - 活動訂票管理系統 - User Module part 4

目標

image

今天目標會是先處理, UserModule 的關於初始化狀態處理設計與說明。

概念

每個正式系統都有其初始化的狀態,比如說後台管理系統,會有一個預設的管理者。類似資料庫預設的 admin 帳密一樣。然後才能對後續的商務流程做處理。

Ticket Booking System 在系統啟動之初,也是需要設定一位管理員來建制系統。前面所說的針對資料庫異動做處理的 migration 流程,除了可以管控 schema 異動。針對資料狀態的管理也是在這裡。

本篇會透過 typeorm migration 機制,來在應用啟動之前寫入資料。

migration 與系統啟動流程

撰寫 ADD ADMIN migration

  1. 透過 script 產生 migration 初始檔案
npm run typeorm:create-migration --name=ADD_AMDIN

備註: 因為 typeorm 是根據檔名的時間序來決定執行順序,所以透過 typeorm cli 來處理比較方便處理。
2. 新增初始化 script 到 migration 檔案

import { MigrationInterface, QueryRunner } from 'typeorm';
import * as bcrypt from 'bcrypt';
export class ADDADMIN1725112383651 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<void> {
    const id = crypto.randomUUID();
    const email = process.env.ADMIN_USER;
    const password = process.env.ADMIN_PASSWORD;
    const hashedPassword = await bcrypt.hash(password, 10);
    await queryRunner.query(`
      INSERT INTO users(id, email, password, role)
      VALUES($1, $2, $3, 'admin');  
    `, [id, email, hashedPassword]); 
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    const email = process.env.ADMIN_USER;
    await queryRunner.query(`
      DELETE FROM users
      WHERE users.email=$1;
    `, [email]);
  }
}
  1. 新增對應的參數到 test container 執行設定
import { PostgreSqlContainer } from '@testcontainers/postgresql';
import { getDataSource } from '../data_source/test_container.source';
export const initPostgresql = async() => {
  const postgresql = await new PostgreSqlContainer('postgres:14')
    .withExposedPorts(5432, 5432)
    .withUsername('admin')
    .withPassword('password')
    .withDatabase('ticket_system_db')
    .start();
  global.postgresql = postgresql;
  const DB_URI = global.postgresql.getConnectionUri();
  process.env.DB_URI = DB_URI;
  process.env.ADMIN_USER='admin@hotmail.com';
  process.env.ADMIN_PASSWORD='1@q#Abz%';
  const datasource = await getDataSource(DB_URI);
  await datasource.runMigrations();
}
const init =  async () => {
  await initPostgresql();
}
export default init;
  1. 啟動 app 前,需要先執行 migration
pnpm run typeorm:run-migrations

驗證 e2e

image

明天接著就是繼續往 event 權限管理繼續。

結論

狀態設定是每個系統一個重要的環節,也是系統之所複雜的地方。雖然這邊使用 typeorm 作為 schema 管理工具。但因為會依賴於 typoerm 與 typescript 所以對於系統重有跨語言的團隊其實並非是理想的工具。一般來而言,會是透過能不依賴於程式語言,而直接管理 sql 的工具為優先,比如 flyway 這種工具。避免造成維護者,被程式語言綁架。

DB schema 本身是不是該直接跟應用的程式碼共同管控,本身就是另一個值得討論的議題。一般而言,最關鍵的是怎麼讓程式碼與 DB schema 能夠一致。這就是看每個團隊如何去完成這件事情。當然,如果你是一人團隊,跟鐵人賽一樣。為了方便,也是可以一起管控,如這篇的範例就是把 schema migration 跟程式碼放在一起管控。


上一篇
nestjs 系統設計 - 活動訂票管理系統 - User Module part 3
下一篇
nestjs 核心架構nestjs 系統設計 - 活動訂票管理系統 - Event Module part 1
系列文
透過 nestjs 框架,讓 nodejs 系統維護度增加31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言