Checkpoint SHD dashboard design system

This commit is contained in:
JB
2026-07-24 21:31:35 -04:00
commit 5e113454ee
52 changed files with 3128 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
import { connect } from '@tursodatabase/database';
import { mkdir, readFile } from 'node:fs/promises';
import { dirname, resolve } from 'node:path';
import process from 'node:process';
const databasePath = resolve(process.env.TDR_DATABASE_PATH || './data/shd-build.db');
const schemaPath = resolve('./database/schema.sql');
await mkdir(dirname(databasePath), { recursive: true });
const database = await connect(databasePath);
const schema = await readFile(schemaPath, 'utf8');
// The project schema deliberately avoids semicolons inside string literals.
const statements = schema
.split(';')
.map((statement) => statement.trim())
.filter(Boolean);
for (const statement of statements) {
await database.exec(statement);
}
console.log(`Applied ${statements.length} schema statements to ${databasePath}`);
+32
View File
@@ -0,0 +1,32 @@
import { spawnSync } from 'node:child_process';
import { resolve } from 'node:path';
import process from 'node:process';
const files = ['.env.development', '.env.production'];
const action = process.argv[2];
const gitCommand = process.platform === 'win32' ? 'git.exe' : 'git';
const dotenvxCli = resolve('node_modules/@dotenvx/dotenvx/src/cli/dotenvx.js');
function run(command, args) {
const result = spawnSync(command, args, { cwd: process.cwd(), stdio: 'inherit' });
if (result.error) throw result.error;
if (result.status !== 0) process.exit(result.status ?? 1);
}
function dotenvx(command, file) {
run(process.execPath, [dotenvxCli, command, '-f', file]);
}
if (!['encrypt', 'decrypt', 'stage'].includes(action)) {
console.error('Usage: node scripts/env-files.mjs <encrypt|decrypt|stage>');
process.exit(2);
}
for (const file of files) {
dotenvx(action === 'decrypt' ? 'decrypt' : 'encrypt', file);
}
if (action === 'stage') {
run(gitCommand, ['add', '--', ...files]);
console.log('Encrypted and staged environment files.');
}
+48
View File
@@ -0,0 +1,48 @@
import { connect } from '@tursodatabase/database';
import { argon2id, hash } from 'argon2';
import { randomBytes, randomUUID } from 'node:crypto';
import { resolve } from 'node:path';
import process from 'node:process';
const databasePath = resolve(process.env.TDR_DATABASE_PATH || './data/shd-build.db');
const database = await connect(databasePath);
const users = [
{ username: 'Aewyn', role: 'admin' },
{ username: 'Quartermaster', role: 'user' }
];
const findUser = await database.prepare(
'SELECT id, username, role FROM users WHERE username = ? COLLATE NOCASE'
);
const insertUser = await database.prepare(
'INSERT INTO users (id, username, password_hash, role, created_at) VALUES (?, ?, ?, ?, ?)'
);
for (const user of users) {
const existing = await findUser.get(user.username);
if (existing) {
console.log(`${user.username}: already exists (${existing.role}); left unchanged`);
continue;
}
// 120 bits of entropy encoded without punctuation that is awkward to paste.
const temporaryPassword = randomBytes(15).toString('base64url');
const passwordHash = await hash(temporaryPassword, {
type: argon2id,
memoryCost: 19_456,
timeCost: 2,
parallelism: 1
});
await insertUser.run(
randomUUID(),
user.username,
passwordHash,
user.role,
new Date().toISOString()
);
console.log(`${user.username} (${user.role}) temporary password: ${temporaryPassword}`);
}