Init
Build and Push Telemt Panel Docker Image / build-and-push (push) Failing after 38s
Build and Push Telemt Panel Docker Image / create-release (push) Skipped

This commit is contained in:
Denozordec committed 2026-08-04 18:33:48 +07:00
commit b5f31c1083
227 files changed
+31375

No files matched your search

+104
View File
@@ -0,0 +1,104 @@
import Database from 'better-sqlite3'
import { drizzle } from 'drizzle-orm/better-sqlite3'
import * as schema from './schema/index.js'
export type Sqlite = Database.Database
export type AppDb = ReturnType<typeof drizzle<typeof schema>>
export * from './schema/index.js'
export function resolveDatabasePath(databaseUrl: string): string {
return databaseUrl.startsWith('sqlite:')
? databaseUrl.slice('sqlite:'.length)
: databaseUrl
}
export function createDb(databaseUrl: string): { db: AppDb; sqlite: Sqlite } {
const path = resolveDatabasePath(databaseUrl)
const sqlite = new Database(path)
sqlite.pragma('journal_mode = WAL')
sqlite.pragma('foreign_keys = ON')
sqlite.pragma('synchronous = NORMAL')
const db = drizzle(sqlite, { schema })
return { db, sqlite }
}
export function healthCheck(sqlite: Sqlite): void {
sqlite.prepare('SELECT 1').get()
}
export function migrateSchema(sqlite: Sqlite): void {
sqlite.exec(`
CREATE TABLE IF NOT EXISTS operators (
id TEXT PRIMARY KEY NOT NULL,
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'admin',
disabled INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY NOT NULL,
value TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS agents (
id TEXT PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
token_hash TEXT,
last_seen_at TEXT,
agent_version TEXT,
hostname TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS enrollment_tokens (
id TEXT PRIMARY KEY NOT NULL,
token_hash TEXT NOT NULL,
label TEXT,
expires_at TEXT NOT NULL,
used_at TEXT,
created_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS jobs (
id TEXT PRIMARY KEY NOT NULL,
agent_id TEXT NOT NULL,
type TEXT NOT NULL,
payload_json TEXT NOT NULL DEFAULT '{}',
status TEXT NOT NULL DEFAULT 'pending',
result_json TEXT,
error TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS managed_clients (
id TEXT PRIMARY KEY NOT NULL,
username TEXT NOT NULL UNIQUE,
secret TEXT,
meta_json TEXT NOT NULL DEFAULT '{}',
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS audit_log (
id TEXT PRIMARY KEY NOT NULL,
action TEXT NOT NULL,
actor_id TEXT,
actor_username TEXT,
summary TEXT NOT NULL,
details_json TEXT,
created_at TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_jobs_agent ON jobs(agent_id, status);
CREATE INDEX IF NOT EXISTS idx_agents_status ON agents(status);
CREATE INDEX IF NOT EXISTS idx_audit_created ON audit_log(created_at);
`)
}
+69
View File
@@ -0,0 +1,69 @@
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core'
export const operators = sqliteTable('operators', {
id: text('id').primaryKey(),
username: text('username').notNull().unique(),
passwordHash: text('password_hash').notNull(),
role: text('role').notNull().default('admin'),
disabled: integer('disabled', { mode: 'boolean' }).notNull().default(false),
createdAt: text('created_at').notNull(),
updatedAt: text('updated_at').notNull(),
})
export const settings = sqliteTable('settings', {
key: text('key').primaryKey(),
value: text('value').notNull(),
updatedAt: text('updated_at').notNull(),
})
export const agents = sqliteTable('agents', {
id: text('id').primaryKey(),
name: text('name').notNull(),
status: text('status').notNull().default('pending'),
tokenHash: text('token_hash'),
lastSeenAt: text('last_seen_at'),
agentVersion: text('agent_version'),
hostname: text('hostname'),
createdAt: text('created_at').notNull(),
updatedAt: text('updated_at').notNull(),
})
export const enrollmentTokens = sqliteTable('enrollment_tokens', {
id: text('id').primaryKey(),
tokenHash: text('token_hash').notNull(),
label: text('label'),
expiresAt: text('expires_at').notNull(),
usedAt: text('used_at'),
createdAt: text('created_at').notNull(),
})
export const jobs = sqliteTable('jobs', {
id: text('id').primaryKey(),
agentId: text('agent_id').notNull(),
type: text('type').notNull(),
payloadJson: text('payload_json').notNull().default('{}'),
status: text('status').notNull().default('pending'),
resultJson: text('result_json'),
error: text('error'),
createdAt: text('created_at').notNull(),
updatedAt: text('updated_at').notNull(),
})
export const managedClients = sqliteTable('managed_clients', {
id: text('id').primaryKey(),
username: text('username').notNull().unique(),
secret: text('secret'),
metaJson: text('meta_json').notNull().default('{}'),
createdAt: text('created_at').notNull(),
updatedAt: text('updated_at').notNull(),
})
export const auditLog = sqliteTable('audit_log', {
id: text('id').primaryKey(),
action: text('action').notNull(),
actorId: text('actor_id'),
actorUsername: text('actor_username'),
summary: text('summary').notNull(),
detailsJson: text('details_json'),
createdAt: text('created_at').notNull(),
})