commit 431e5d299990fe932c5b97632646cffb0513234e Author: Jared Kling Date: Mon Dec 8 16:48:07 2025 -0600 Solid start at a resume generator. Should probably add an action to build the real thing so I can expose it diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cc353aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +generated_resume.html diff --git a/.zed/tasks.json b/.zed/tasks.json new file mode 100644 index 0000000..b194e50 --- /dev/null +++ b/.zed/tasks.json @@ -0,0 +1,13 @@ +[ + { + "label": "Build", + "command": "npm run build", + "use_new_terminal": false, + "allow_concurrent_runs": false, + "reveal": "always", + "reveal_target": "dock", + "hide": "never", + "shell": "system", + "tags": ["script", "build"] + } +] diff --git a/build.js b/build.js new file mode 100644 index 0000000..54d9f81 --- /dev/null +++ b/build.js @@ -0,0 +1,20 @@ +const ejs = require('ejs'); +const fs = require('fs'); +const path = require('path'); + +// File paths +const dataPath = path.join(__dirname, 'content.json'); +const templatePath = path.join(__dirname, 'template.ejs'); +const outputPath = path.join(__dirname, 'generated_resume.html'); + +// Read data and template +const jsonData = JSON.parse(fs.readFileSync(dataPath, 'utf-8')); +const template = fs.readFileSync(templatePath, 'utf-8'); + +// Render HTML +const html = ejs.render(template, jsonData); + +// Write the output +fs.writeFileSync(outputPath, html, 'utf-8'); + +console.log(`Successfully generated resume at ${outputPath}`); diff --git a/content.json b/content.json new file mode 100644 index 0000000..0d75f58 --- /dev/null +++ b/content.json @@ -0,0 +1,143 @@ +{ + "name": "Jared Kling", + "email": "jared@kling.dev", + "website": "https://portfolio.kling.dev", + "phone": "(630) 740-0130", + "header": "Experienced Engineer who transforms ideas into scalable products through technical leadership and team development. Successfully leading cross-functional teams, architecting major system migrations, and improving developer efficiency.", + "experience": { + "technologies": [ + "JavaScript", + "TypeScript", + "NodeJS", + "React", + "MySQL", + "PHP", + "C#", + "ASP.NET", + "SQL Server", + "HTML", + "CSS", + "AWS", + "Git", + "GitLab", + "Windows", + "Linux", + "Docker", + "Kubernetes" + ], + "positions": [ + { + "company": "Suralink", + "website": "https://suralink.com", + "logo": { + "path": "./logos/suralink.png", + "includesName": false + }, + "roles": [ + { + "role": "Engineering Manager", + "dates": "2023 - 2025", + "bullets": [ + "Managed 2 teams of 5 and oversaw the work of integrating with an offshore team.", + "Executed a migration to Auth0 for additional scalability and security, moving over 1M user accounts and having <10 support tickets.", + "Delivered key initiatives on time, such as: integrating with external partners, seamlessly transitioning a domain out of a monolith and into a microservice, increasing our scalability through proper metrics.", + "Built the platform to extract value of user uploaded files, enabling our users to work faster and more efficiently.", + "Reduced an external partner's API calls by 97% by introducing additional data points in our responses.", + "Assisted in revamping our processes around hiring, incident response, and deployment frequency." + ] + }, + { + "role": "Staff Software Engineer / Team Lead", + "dates": "2022 - 2023", + "bullets": [ + "I led a team of 5 engineers through all sprint ceremonies and technical planning sessions", + "Responsible for a portion customer support, including doing video calls with customers", + "Mentored multiple engineers on a regular basis, leading to promotions for two of them" + ] + }, + { + "role": "Sr Software Engineer", + "dates": "2020 - 2022", + "bullets": [ + "Improved our release cadence from a few times a year to deploying every sprint.", + "Increased developer efficiency by shifting the development environment locally and by increasing team documentation", + "Led many large projects such as migrating our Authentication to a microservice, introducing an API and creating a second product" + ] + } + ] + }, + { + "company": "Livly", + "website": "https://www.livly.io", + "logo": { + "path": "./logos/livly.png", + "includesName": true + }, + "roles": [ + { + "role": "Sr Software Engineer", + "dates": "2019 - 2020", + "bullets": [ + "Integrated getstream.io into the app to allow property managers to communicate with other members of the building.", + "Strengthened integration with 3rd party vendor to automate manual data cleansing efforts." + ] + } + ] + }, + { + "company": "PayLease (now Zego)", + "website": "https://www.gozego.com", + "logo": { + "path": "./logos/paylease.png", + "includesName": true + }, + "roles": [ + { + "role": "Jr Software Engineer - Staff Software Engineer", + "dates": "2015 - 2019", + "bullets": [ + "Progressed from Junior to Staff Software Engineer, eventually leading a squad of engineers and QA associates.", + "Architected and implemented major projects, including an in-house billing statement generation system and various partner integrations.", + "Introduced containerized testing environments using Docker and spearheaded the adoption of unit testing.", + "Managed development resources in AWS and integrated data from a company acquisition into the main platform." + ] + } + ] + }, + { + "company": "Encompass Insurance (Allstate)", + "website": "https://www.encompassinsurance.com", + "logo": { + "path": "./logos/encompass.svg", + "includesName": true + }, + "roles": [ + { + "role": "Application Developer", + "dates": "2013 - 2014 (intern), 2014 - 2015", + "bullets": [ + "Worked on a small team to build a user portal for viewing policy details", + "Built a support tool using internal APIs to search for policies" + ] + } + ] + } + ] + }, + "education": { + "university": "Illinois State University", + "location": "Normal, IL", + "dates": "2009-2010, 2011-2014", + "degree": "Bachelor of Science in Computer Science with Minor in Mathematics" + }, + "links": [ + { + "label": "Website", + "href": "https://portfolio.kling.dev" + }, + { + "label": "Git", + "href": "https://git.kling.dev/jared" + } + ] +} diff --git a/logos/Jared Kling - Resume.pdf b/logos/Jared Kling - Resume.pdf new file mode 100644 index 0000000..1b3b04a Binary files /dev/null and b/logos/Jared Kling - Resume.pdf differ diff --git a/logos/encompass.svg b/logos/encompass.svg new file mode 100644 index 0000000..6b28b3f --- /dev/null +++ b/logos/encompass.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/logos/livly.png b/logos/livly.png new file mode 100644 index 0000000..319552c Binary files /dev/null and b/logos/livly.png differ diff --git a/logos/paylease.png b/logos/paylease.png new file mode 100644 index 0000000..ef9fa3c Binary files /dev/null and b/logos/paylease.png differ diff --git a/logos/suralink.png b/logos/suralink.png new file mode 100644 index 0000000..072d349 Binary files /dev/null and b/logos/suralink.png differ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..69c429d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,95 @@ +{ + "name": "resume-builder", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "resume-builder", + "version": "1.0.0", + "dependencies": { + "ejs": "^3.1.8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..542a098 --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "name": "resume-builder", + "version": "1.0.0", + "description": "Builds an HTML resume from JSON data", + "main": "build.js", + "scripts": { + "build": "node build.js" + }, + "dependencies": { + "ejs": "^3.1.8" + } +} diff --git a/template.ejs b/template.ejs new file mode 100644 index 0000000..e866d39 --- /dev/null +++ b/template.ejs @@ -0,0 +1,260 @@ + + + + + + <%= name %> - Resume + + + +
+
+

<%= name %>

+
+ <%= email %> + + <%= phone %> +
+

<%= header %>

+
+ +
+
+

Core Technologies

+
    + <% experience.technologies.forEach(function(tech) { %> +
  • <%= tech %>
  • + <% }); %> +
+
+ +
+

Professional Experience

+ <% experience.positions.forEach(function(position) { %> +
+
+ <% if (position.logo.path.length > 0) { %> + + + + <% } %> + <% if (!position.logo.includesName) { %> +

<%= position.company %>

+ <% } %> +
+ <% position.roles.forEach(function(role) { %> +
+
+

<%= role.role %>

+ <%= role.dates %> +
+ <% if (role.bullets && role.bullets.join('').length > 0) { %> +
    + <% role.bullets.forEach(function(bullet) { %> +
  • <%= bullet %>
  • + <% }); %> +
+ <% } %> +
+ <% }); %> +
+ <% }); %> +
+ +
+

Education

+
+

<%= education.university %>

+

<%= education.location %>

+

<%= education.degree %>

+

<%= education.dates %>

+
+
+ + <% if (links.length > 0) { %> + + <% } %> +
+
+ +