chore(dev): 添加本地 MySQL seed 环境

This commit is contained in:
2026-05-11 20:51:43 +08:00
parent 3040608959
commit ddd077eb37
6 changed files with 175 additions and 107 deletions
+116
View File
@@ -0,0 +1,116 @@
import { reset } from 'drizzle-seed'
import { drizzle } from 'drizzle-orm/mysql2'
import { datetime, index, int, mysqlTable, tinyint, varchar } from 'drizzle-orm/mysql-core'
import mysql from 'mysql2/promise'
type SeedRow = {
userId: number
mac: string
devModel: string
devName: string
isLowPower: 'true' | 'false'
powerStatus: 0 | 1 | 2
power: number
createTime: Date
remark: string | null
}
const lsBatteryInfo = mysqlTable(
'ls_battery_info',
{
id: int('id').autoincrement().primaryKey(),
userId: int('user_id').notNull(),
mac: varchar('mac', { length: 50 }).notNull(),
devModel: varchar('dev_model', { length: 20 }).notNull(),
devName: varchar('dev_name', { length: 50 }).notNull(),
isLowPower: varchar('is_low_power', { length: 10 }).notNull(),
powerStatus: tinyint('power_status').notNull(),
power: tinyint('power').notNull(),
createTime: datetime('create_time').notNull(),
remark: varchar('remark', { length: 500 }),
},
(table) => [index('idx_ls_battery_info_mac_time_id').on(table.mac, table.createTime, table.id)],
)
const databaseUrl = process.env.DATABASE_URL
if (!databaseUrl) {
throw new Error('DATABASE_URL is required, for example mysql://battery:battery@localhost:3306/battery_soh')
}
const parsedUrl = new URL(databaseUrl)
const safeSeedHosts = new Set(['localhost', '127.0.0.1', '0.0.0.0', 'db', 'mysql'])
if (!safeSeedHosts.has(parsedUrl.hostname) && process.env.SEED_ALLOW_REMOTE !== 'true') {
throw new Error(
`Refusing to seed non-local MySQL host "${parsedUrl.hostname}". Set SEED_ALLOW_REMOTE=true only for disposable test databases.`,
)
}
const devices = [
{ mac: 'RING-A03', model: 'SR-01', name: '样机-A03', basePower: 96, status: 2, remark: 'v3.8.2' },
{ mac: 'RING-B11', model: 'SR-01', name: '样机-B11', basePower: 91, status: 1, remark: 'v3.8.2' },
{ mac: 'RING-C07', model: 'SR-02', name: '样机-C07', basePower: 88, status: 0, remark: 'v3.8.1' },
{ mac: 'RING-D19', model: 'SR-02', name: '样机-D19', basePower: 84, status: 0, remark: 'v3.7.9' },
{ mac: 'RING-E21', model: 'SR-03', name: '样机-E21', basePower: 79, status: 1, remark: 'v3.7.9' },
{ mac: 'RING-F02', model: 'SR-03', name: '样机-F02', basePower: 73, status: 0, remark: null },
{ mac: 'RING-G15', model: 'SR-04', name: '样机-G15', basePower: 93, status: 2, remark: 'v3.9.0' },
{ mac: 'RING-H09', model: 'SR-04', name: '样机-H09', basePower: 86, status: 0, remark: 'v3.8.1' },
] satisfies Array<{
mac: string
model: string
name: string
basePower: number
status: 0 | 1 | 2
remark: string | null
}>
function createSeedRows(now = new Date()): SeedRow[] {
return devices.flatMap((device, deviceIndex) =>
Array.from({ length: 8 }, (_, historyIndex) => {
const createdAt = new Date(now.getTime() - (historyIndex * 24 + deviceIndex * 2) * 60 * 60 * 1000)
const power = Math.max(1, Math.min(100, device.basePower - historyIndex * 2 + (deviceIndex % 3)))
return {
userId: 1001 + (deviceIndex % 3),
mac: device.mac,
devModel: device.model,
devName: device.name,
isLowPower: power <= 20 || device.basePower <= 80 ? 'true' : 'false',
powerStatus: historyIndex === 0 ? device.status : 0,
power,
createTime: createdAt,
remark: device.remark,
}
}),
)
}
const connection = await mysql.createConnection({ uri: databaseUrl })
const db = drizzle(connection)
try {
await db.execute(`
CREATE TABLE IF NOT EXISTS ls_battery_info (
id int(11) NOT NULL AUTO_INCREMENT,
user_id int(11) NOT NULL,
mac varchar(50) NOT NULL,
dev_model varchar(20) NOT NULL,
dev_name varchar(50) NOT NULL,
is_low_power varchar(10) NOT NULL,
power_status tinyint(4) NOT NULL,
power tinyint(4) NOT NULL,
create_time datetime NOT NULL,
remark varchar(500) DEFAULT NULL,
PRIMARY KEY (id),
KEY idx_ls_battery_info_mac_time_id (mac, create_time, id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
`)
await reset(db, { lsBatteryInfo })
await db.insert(lsBatteryInfo).values(createSeedRows())
process.stdout.write(`Seeded ${devices.length} devices into ls_battery_info.\n`)
} finally {
await connection.end()
}