今天目標會是先處理, UserModule 的關於初始化狀態處理設計與說明。
每個正式系統都有其初始化的狀態,比如說後台管理系統,會有一個預設的管理者。類似資料庫預設的 admin 帳密一樣。然後才能對後續的商務流程做處理。
Ticket Booking System 在系統啟動之初,也是需要設定一位管理員來建制系統。前面所說的針對資料庫異動做處理的 migration 流程,除了可以管控 schema 異動。針對資料狀態的管理也是在這裡。
本篇會透過 typeorm 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]);
}
}
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;
pnpm run typeorm:run-migrations
明天接著就是繼續往 event 權限管理繼續。
狀態設定是每個系統一個重要的環節,也是系統之所複雜的地方。雖然這邊使用 typeorm 作為 schema 管理工具。但因為會依賴於 typoerm 與 typescript 所以對於系統重有跨語言的團隊其實並非是理想的工具。一般來而言,會是透過能不依賴於程式語言,而直接管理 sql 的工具為優先,比如 flyway 這種工具。避免造成維護者,被程式語言綁架。
DB schema 本身是不是該直接跟應用的程式碼共同管控,本身就是另一個值得討論的議題。一般而言,最關鍵的是怎麼讓程式碼與 DB schema 能夠一致。這就是看每個團隊如何去完成這件事情。當然,如果你是一人團隊,跟鐵人賽一樣。為了方便,也是可以一起管控,如這篇的範例就是把 schema migration 跟程式碼放在一起管控。