Initial commit: CV website with ElysiaJS, SQLite, and TailwindCSS

This commit is contained in:
Tuan-Dat Tran
2025-11-21 20:07:05 +01:00
parent 378487efc8
commit 88aeaa9002
14 changed files with 759 additions and 109 deletions

121
src/db/schema.ts Normal file
View File

@@ -0,0 +1,121 @@
import { Database } from "bun:sqlite";
const db = new Database("cv.sqlite", { create: true });
// Enable foreign keys
db.run("PRAGMA foreign_keys = ON;");
export function initDB() {
// 1. Languages Table (to ensure referential integrity)
db.run(`
CREATE TABLE IF NOT EXISTS languages (
code TEXT PRIMARY KEY
);
`);
// 2. Profile (Singleton - structural info)
db.run(`
CREATE TABLE IF NOT EXISTS profile (
id INTEGER PRIMARY KEY CHECK (id = 1), -- Ensure only one profile exists
email TEXT NOT NULL,
phone TEXT,
website TEXT,
github_url TEXT,
linkedin_url TEXT,
avatar_url TEXT
);
`);
// 3. Profile Translations
db.run(`
CREATE TABLE IF NOT EXISTS profile_translations (
profile_id INTEGER NOT NULL,
language_code TEXT NOT NULL,
name TEXT NOT NULL,
job_title TEXT NOT NULL,
summary TEXT,
location TEXT,
PRIMARY KEY (profile_id, language_code),
FOREIGN KEY (profile_id) REFERENCES profile(id) ON DELETE CASCADE,
FOREIGN KEY (language_code) REFERENCES languages(code)
);
`);
// 4. Experience (Structural)
db.run(`
CREATE TABLE IF NOT EXISTS experience (
id INTEGER PRIMARY KEY AUTOINCREMENT,
start_date TEXT NOT NULL, -- ISO8601 YYYY-MM
end_date TEXT, -- NULL = Current
company_url TEXT,
display_order INTEGER DEFAULT 0
);
`);
// 5. Experience Translations
db.run(`
CREATE TABLE IF NOT EXISTS experience_translations (
experience_id INTEGER NOT NULL,
language_code TEXT NOT NULL,
company_name TEXT NOT NULL,
role TEXT NOT NULL,
description TEXT, -- Supports Markdown/HTML
location TEXT,
PRIMARY KEY (experience_id, language_code),
FOREIGN KEY (experience_id) REFERENCES experience(id) ON DELETE CASCADE,
FOREIGN KEY (language_code) REFERENCES languages(code)
);
`);
// 6. Education (Structural)
db.run(`
CREATE TABLE IF NOT EXISTS education (
id INTEGER PRIMARY KEY AUTOINCREMENT,
start_date TEXT NOT NULL,
end_date TEXT,
institution_url TEXT,
display_order INTEGER DEFAULT 0
);
`);
// 7. Education Translations
db.run(`
CREATE TABLE IF NOT EXISTS education_translations (
education_id INTEGER NOT NULL,
language_code TEXT NOT NULL,
institution TEXT NOT NULL,
degree TEXT NOT NULL,
description TEXT,
PRIMARY KEY (education_id, language_code),
FOREIGN KEY (education_id) REFERENCES education(id) ON DELETE CASCADE,
FOREIGN KEY (language_code) REFERENCES languages(code)
);
`);
// 8. Skills (Categories & Items)
// Simply storing skills as items with a category.
db.run(`
CREATE TABLE IF NOT EXISTS skills (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category TEXT NOT NULL, -- e.g., "frontend", "backend", "tools" (Internal key)
icon TEXT, -- class name for an icon library
display_order INTEGER DEFAULT 0
);
`);
db.run(`
CREATE TABLE IF NOT EXISTS skill_translations (
skill_id INTEGER NOT NULL,
language_code TEXT NOT NULL,
name TEXT NOT NULL, -- The display name
category_display TEXT, -- "Frontend Development" vs "Frontend Entwicklung"
PRIMARY KEY (skill_id, language_code),
FOREIGN KEY (skill_id) REFERENCES skills(id) ON DELETE CASCADE,
FOREIGN KEY (language_code) REFERENCES languages(code)
);
`);
console.log("Database schema initialized.");
}
export { db };