Testing
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
* Generate Hyperschema + HyperDB definitions for PearData.
|
||||
*
|
||||
* Usage: node scripts/build-db.js
|
||||
*
|
||||
* SCHEMA SAFETY (Holepunch rules):
|
||||
* 1. Fields are append-only — deprecate instead of removing
|
||||
* 2. Do not delete/reset committed files under spec/
|
||||
* 3. After merge to main, schema changes are permanent
|
||||
*/
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import Hyperschema from 'hyperschema'
|
||||
import HyperDB from 'hyperdb/builder'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const ROOT = path.join(__dirname, '..')
|
||||
const SCHEMA_DIR = path.join(ROOT, 'spec', 'hyperschema')
|
||||
const DB_DIR = path.join(ROOT, 'spec', 'hyperdb')
|
||||
|
||||
setupSchema()
|
||||
setupDb()
|
||||
console.log('Wrote', SCHEMA_DIR)
|
||||
console.log('Wrote', DB_DIR)
|
||||
|
||||
function setupSchema() {
|
||||
const schema = Hyperschema.from(SCHEMA_DIR)
|
||||
const ns = schema.namespace('peardata')
|
||||
|
||||
ns.register({
|
||||
name: 'node',
|
||||
fields: [
|
||||
{ name: 'nodeId', type: 'string', required: true },
|
||||
{ name: 'hostname', type: 'string', required: true },
|
||||
{ name: 'publicKeyHex', type: 'string', required: false },
|
||||
{ name: 'platform', type: 'string', required: false },
|
||||
{ name: 'arch', type: 'string', required: false },
|
||||
{ name: 'cpus', type: 'uint', required: false },
|
||||
{ name: 'totalMemMiB', type: 'uint', required: false },
|
||||
{ name: 'agentVersion', type: 'string', required: false },
|
||||
{ name: 'labelsJson', type: 'string', required: false },
|
||||
{ name: 'updatedAt', type: 'uint', required: true },
|
||||
],
|
||||
})
|
||||
|
||||
ns.register({
|
||||
name: 'peer-link',
|
||||
fields: [
|
||||
{ name: 'localNodeId', type: 'string', required: true },
|
||||
{ name: 'remotePublicKey', type: 'string', required: true },
|
||||
{ name: 'role', type: 'string', required: false },
|
||||
{ name: 'alias', type: 'string', required: false },
|
||||
{ name: 'dbKeyHex', type: 'string', required: false },
|
||||
{ name: 'syncMode', type: 'string', required: false }, // push | pull | both
|
||||
{ name: 'linkedAt', type: 'uint', required: true },
|
||||
{ name: 'lastSeen', type: 'uint', required: false },
|
||||
],
|
||||
})
|
||||
|
||||
ns.register({
|
||||
name: 'alert-config',
|
||||
fields: [
|
||||
{ name: 'id', type: 'string', required: true },
|
||||
{ name: 'chart', type: 'string', required: true },
|
||||
{ name: 'dimension', type: 'string', required: true },
|
||||
{ name: 'warn', type: 'float64', required: false },
|
||||
{ name: 'crit', type: 'float64', required: false },
|
||||
{ name: 'comparator', type: 'string', required: false },
|
||||
{ name: 'enabled', type: 'bool', required: false },
|
||||
{ name: 'info', type: 'string', required: false },
|
||||
{ name: 'updatedAt', type: 'uint', required: true },
|
||||
],
|
||||
})
|
||||
|
||||
ns.register({
|
||||
name: 'alert-event',
|
||||
fields: [
|
||||
{ name: 'id', type: 'string', required: true },
|
||||
{ name: 'ts', type: 'uint', required: true },
|
||||
{ name: 'chart', type: 'string', required: true },
|
||||
{ name: 'dimension', type: 'string', required: false },
|
||||
{ name: 'severity', type: 'string', required: true },
|
||||
{ name: 'value', type: 'float64', required: false },
|
||||
{ name: 'threshold', type: 'float64', required: false },
|
||||
{ name: 'message', type: 'string', required: false },
|
||||
{ name: 'cleared', type: 'bool', required: false },
|
||||
],
|
||||
})
|
||||
|
||||
// Warm / downsampled metric buckets (NOT 1s hot path)
|
||||
ns.register({
|
||||
name: 'metric-point',
|
||||
fields: [
|
||||
{ name: 'chart', type: 'string', required: true },
|
||||
{ name: 'ts', type: 'uint', required: true }, // unix ms
|
||||
{ name: 'context', type: 'string', required: true },
|
||||
{ name: 'tier', type: 'uint', required: true }, // 1 = ~1m, 2 = future coarser
|
||||
{ name: 'valuesJson', type: 'string', required: true },
|
||||
],
|
||||
})
|
||||
|
||||
ns.register({
|
||||
name: 'job',
|
||||
fields: [
|
||||
{ name: 'id', type: 'string', required: true },
|
||||
{ name: 'name', type: 'string', required: true },
|
||||
{ name: 'status', type: 'string', required: true },
|
||||
{ name: 'startedAt', type: 'uint', required: false },
|
||||
{ name: 'finishedAt', type: 'uint', required: false },
|
||||
{ name: 'resultJson', type: 'string', required: false },
|
||||
{ name: 'error', type: 'string', required: false },
|
||||
],
|
||||
})
|
||||
|
||||
Hyperschema.toDisk(schema, { esm: true })
|
||||
}
|
||||
|
||||
function setupDb() {
|
||||
const db = HyperDB.from(SCHEMA_DIR, DB_DIR)
|
||||
const ns = db.namespace('peardata')
|
||||
|
||||
ns.collections.register({
|
||||
name: 'node',
|
||||
schema: '@peardata/node',
|
||||
key: ['nodeId'],
|
||||
})
|
||||
|
||||
ns.collections.register({
|
||||
name: 'peer-link',
|
||||
schema: '@peardata/peer-link',
|
||||
key: ['localNodeId', 'remotePublicKey'],
|
||||
})
|
||||
|
||||
ns.collections.register({
|
||||
name: 'alert-config',
|
||||
schema: '@peardata/alert-config',
|
||||
key: ['id'],
|
||||
})
|
||||
|
||||
ns.collections.register({
|
||||
name: 'alert-event',
|
||||
schema: '@peardata/alert-event',
|
||||
key: ['id', 'ts'],
|
||||
})
|
||||
|
||||
ns.collections.register({
|
||||
name: 'metric-point',
|
||||
schema: '@peardata/metric-point',
|
||||
key: ['chart', 'ts'],
|
||||
})
|
||||
|
||||
ns.collections.register({
|
||||
name: 'job',
|
||||
schema: '@peardata/job',
|
||||
key: ['id'],
|
||||
})
|
||||
|
||||
ns.indexes.register({
|
||||
name: 'node-by-hostname',
|
||||
collection: '@peardata/node',
|
||||
key: ['hostname'],
|
||||
})
|
||||
|
||||
ns.indexes.register({
|
||||
name: 'peer-link-by-remote',
|
||||
collection: '@peardata/peer-link',
|
||||
key: ['remotePublicKey'],
|
||||
})
|
||||
|
||||
ns.indexes.register({
|
||||
name: 'alert-event-by-chart',
|
||||
collection: '@peardata/alert-event',
|
||||
key: ['chart', 'ts'],
|
||||
})
|
||||
|
||||
ns.indexes.register({
|
||||
name: 'metric-point-by-context',
|
||||
collection: '@peardata/metric-point',
|
||||
key: ['context', 'ts'],
|
||||
})
|
||||
|
||||
ns.indexes.register({
|
||||
name: 'metric-point-by-tier',
|
||||
collection: '@peardata/metric-point',
|
||||
key: ['tier', 'chart', 'ts'],
|
||||
})
|
||||
|
||||
HyperDB.toDisk(db)
|
||||
}
|
||||
Reference in New Issue
Block a user