feat: add address source tracking (source_meta field) (#794)

- Add source_meta field to address table for tracking creation source
- Web: records client IP address (with fallback to 'web:unknown')
- Telegram: records 'tg:{userId}'
- Admin: records 'admin'
- Add database migration with field existence check
- Add frontend display in admin Account page
- Backward compatible: fallback if field doesn't exist

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Dream Hunter
2025-12-28 13:44:52 +08:00
committed by GitHub
co-authored by Claude
parent 499f65078b
commit 3b3968f3b4
11 changed files with 99 additions and 16 deletions
+38 -7
View File
@@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS address (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE,
password TEXT,
source_meta TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
@@ -31,6 +32,8 @@ CREATE INDEX IF NOT EXISTS idx_address_created_at ON address(created_at);
CREATE INDEX IF NOT EXISTS idx_address_updated_at ON address(updated_at);
CREATE INDEX IF NOT EXISTS idx_address_source_meta ON address(source_meta);
CREATE TABLE IF NOT EXISTS auto_reply_mails (
id INTEGER PRIMARY KEY,
source_prefix TEXT,
@@ -138,14 +141,42 @@ export default {
},
migrate: async (c: Context<HonoCustomType>) => {
const version = await utils.getSetting(c, CONSTANTS.DB_VERSION_KEY);
if (version == "v0.0.2") {
// example migration from v0.0.2 to v0.0.3
const query = `ALTER TABLE address ADD password TEXT;`
await c.env.DB.exec(query);
if (version && version <= "v0.0.2") {
// migration to v0.0.3: add password column
const tableInfo = await c.env.DB.prepare(
`PRAGMA table_info(address)`
).all();
const hasPassword = tableInfo.results?.some(
(col: any) => col.name === 'password'
);
if (!hasPassword) {
await c.env.DB.exec(`ALTER TABLE address ADD COLUMN password TEXT;`);
}
}
if (version == "v0.0.3") {
// migration from v0.0.3 to v0.0.4
await c.env.DB.exec(`ALTER TABLE raw_mails ADD COLUMN metadata TEXT;`);
if (version && version <= "v0.0.3") {
// migration to v0.0.4: add metadata column
const tableInfo = await c.env.DB.prepare(
`PRAGMA table_info(raw_mails)`
).all();
const hasMetadata = tableInfo.results?.some(
(col: any) => col.name === 'metadata'
);
if (!hasMetadata) {
await c.env.DB.exec(`ALTER TABLE raw_mails ADD COLUMN metadata TEXT;`);
}
}
if (version && version <= "v0.0.4") {
// migration to v0.0.5: add source_meta column
const tableInfo = await c.env.DB.prepare(
`PRAGMA table_info(address)`
).all();
const hasSourceMeta = tableInfo.results?.some(
(col: any) => col.name === 'source_meta'
);
if (!hasSourceMeta) {
await c.env.DB.exec(`ALTER TABLE address ADD COLUMN source_meta TEXT;`);
await c.env.DB.exec(`CREATE INDEX IF NOT EXISTS idx_address_source_meta ON address(source_meta);`);
}
}
if (version != CONSTANTS.DB_VERSION) {
// remove all \r and \n characters from the query string