diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ab5afb2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,176 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +\*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +\*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +\*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +\*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.cache +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +.cache/ + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp +.cache + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.\* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store + diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 0000000..b8e1fd1 --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1,8 @@ +module.exports = { + tabWidth: 2, + trailingComma: 'all', + singleQuote: true, + semi: false, + arrowParens: 'avoid', + plugins: [], +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..3cbb602 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# resume + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.ts +``` + +This project was created using `bun init` in bun v1.0.3. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/assets/IosevkaAile-Bold.woff2 b/assets/IosevkaAile-Bold.woff2 new file mode 100644 index 0000000..94ee089 Binary files /dev/null and b/assets/IosevkaAile-Bold.woff2 differ diff --git a/assets/IosevkaAile-BoldItalic.woff2 b/assets/IosevkaAile-BoldItalic.woff2 new file mode 100644 index 0000000..eb32b85 Binary files /dev/null and b/assets/IosevkaAile-BoldItalic.woff2 differ diff --git a/assets/IosevkaAile-BoldOblique.woff2 b/assets/IosevkaAile-BoldOblique.woff2 new file mode 100644 index 0000000..a07bf1b Binary files /dev/null and b/assets/IosevkaAile-BoldOblique.woff2 differ diff --git a/assets/IosevkaAile-ExtraBold.woff2 b/assets/IosevkaAile-ExtraBold.woff2 new file mode 100644 index 0000000..43c7bdb Binary files /dev/null and b/assets/IosevkaAile-ExtraBold.woff2 differ diff --git a/assets/IosevkaAile-ExtraBoldItalic.woff2 b/assets/IosevkaAile-ExtraBoldItalic.woff2 new file mode 100644 index 0000000..2007538 Binary files /dev/null and b/assets/IosevkaAile-ExtraBoldItalic.woff2 differ diff --git a/assets/IosevkaAile-ExtraBoldOblique.woff2 b/assets/IosevkaAile-ExtraBoldOblique.woff2 new file mode 100644 index 0000000..c085df0 Binary files /dev/null and b/assets/IosevkaAile-ExtraBoldOblique.woff2 differ diff --git a/assets/IosevkaAile-ExtraLight.woff2 b/assets/IosevkaAile-ExtraLight.woff2 new file mode 100644 index 0000000..74ccfb9 Binary files /dev/null and b/assets/IosevkaAile-ExtraLight.woff2 differ diff --git a/assets/IosevkaAile-ExtraLightItalic.woff2 b/assets/IosevkaAile-ExtraLightItalic.woff2 new file mode 100644 index 0000000..5818cf8 Binary files /dev/null and b/assets/IosevkaAile-ExtraLightItalic.woff2 differ diff --git a/assets/IosevkaAile-ExtraLightOblique.woff2 b/assets/IosevkaAile-ExtraLightOblique.woff2 new file mode 100644 index 0000000..f89287d Binary files /dev/null and b/assets/IosevkaAile-ExtraLightOblique.woff2 differ diff --git a/assets/IosevkaAile-Heavy.woff2 b/assets/IosevkaAile-Heavy.woff2 new file mode 100644 index 0000000..db2f8f3 Binary files /dev/null and b/assets/IosevkaAile-Heavy.woff2 differ diff --git a/assets/IosevkaAile-HeavyItalic.woff2 b/assets/IosevkaAile-HeavyItalic.woff2 new file mode 100644 index 0000000..4c49f06 Binary files /dev/null and b/assets/IosevkaAile-HeavyItalic.woff2 differ diff --git a/assets/IosevkaAile-HeavyOblique.woff2 b/assets/IosevkaAile-HeavyOblique.woff2 new file mode 100644 index 0000000..57aec16 Binary files /dev/null and b/assets/IosevkaAile-HeavyOblique.woff2 differ diff --git a/assets/IosevkaAile-Italic.woff2 b/assets/IosevkaAile-Italic.woff2 new file mode 100644 index 0000000..162cb12 Binary files /dev/null and b/assets/IosevkaAile-Italic.woff2 differ diff --git a/assets/IosevkaAile-Light.woff2 b/assets/IosevkaAile-Light.woff2 new file mode 100644 index 0000000..bfc8b81 Binary files /dev/null and b/assets/IosevkaAile-Light.woff2 differ diff --git a/assets/IosevkaAile-LightItalic.woff2 b/assets/IosevkaAile-LightItalic.woff2 new file mode 100644 index 0000000..3fbcc34 Binary files /dev/null and b/assets/IosevkaAile-LightItalic.woff2 differ diff --git a/assets/IosevkaAile-LightOblique.woff2 b/assets/IosevkaAile-LightOblique.woff2 new file mode 100644 index 0000000..11195a1 Binary files /dev/null and b/assets/IosevkaAile-LightOblique.woff2 differ diff --git a/assets/IosevkaAile-Medium.woff2 b/assets/IosevkaAile-Medium.woff2 new file mode 100644 index 0000000..d09bb9b Binary files /dev/null and b/assets/IosevkaAile-Medium.woff2 differ diff --git a/assets/IosevkaAile-MediumItalic.woff2 b/assets/IosevkaAile-MediumItalic.woff2 new file mode 100644 index 0000000..b9392c0 Binary files /dev/null and b/assets/IosevkaAile-MediumItalic.woff2 differ diff --git a/assets/IosevkaAile-MediumOblique.woff2 b/assets/IosevkaAile-MediumOblique.woff2 new file mode 100644 index 0000000..01f45f1 Binary files /dev/null and b/assets/IosevkaAile-MediumOblique.woff2 differ diff --git a/assets/IosevkaAile-Oblique.woff2 b/assets/IosevkaAile-Oblique.woff2 new file mode 100644 index 0000000..2d87d22 Binary files /dev/null and b/assets/IosevkaAile-Oblique.woff2 differ diff --git a/assets/IosevkaAile-Regular.woff2 b/assets/IosevkaAile-Regular.woff2 new file mode 100644 index 0000000..e1ba131 Binary files /dev/null and b/assets/IosevkaAile-Regular.woff2 differ diff --git a/assets/IosevkaAile-SemiBold.woff2 b/assets/IosevkaAile-SemiBold.woff2 new file mode 100644 index 0000000..e1f58a3 Binary files /dev/null and b/assets/IosevkaAile-SemiBold.woff2 differ diff --git a/assets/IosevkaAile-SemiBoldItalic.woff2 b/assets/IosevkaAile-SemiBoldItalic.woff2 new file mode 100644 index 0000000..e4425c3 Binary files /dev/null and b/assets/IosevkaAile-SemiBoldItalic.woff2 differ diff --git a/assets/IosevkaAile-SemiBoldOblique.woff2 b/assets/IosevkaAile-SemiBoldOblique.woff2 new file mode 100644 index 0000000..f931de3 Binary files /dev/null and b/assets/IosevkaAile-SemiBoldOblique.woff2 differ diff --git a/assets/IosevkaAile-Thin.woff2 b/assets/IosevkaAile-Thin.woff2 new file mode 100644 index 0000000..abc504c Binary files /dev/null and b/assets/IosevkaAile-Thin.woff2 differ diff --git a/assets/IosevkaAile-ThinItalic.woff2 b/assets/IosevkaAile-ThinItalic.woff2 new file mode 100644 index 0000000..61ab742 Binary files /dev/null and b/assets/IosevkaAile-ThinItalic.woff2 differ diff --git a/assets/IosevkaAile-ThinOblique.woff2 b/assets/IosevkaAile-ThinOblique.woff2 new file mode 100644 index 0000000..f43a105 Binary files /dev/null and b/assets/IosevkaAile-ThinOblique.woff2 differ diff --git a/assets/iosevka.css b/assets/iosevka.css new file mode 100644 index 0000000..193a19e --- /dev/null +++ b/assets/iosevka.css @@ -0,0 +1,233 @@ +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 100; + font-stretch: normal; + font-style: normal; + src: url('./IosevkaAile-Thin.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 100; + font-stretch: normal; + font-style: oblique; + src: url('./IosevkaAile-ThinOblique.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 100; + font-stretch: normal; + font-style: italic; + src: url('./IosevkaAile-ThinItalic.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 200; + font-stretch: normal; + font-style: normal; + src: url('./IosevkaAile-ExtraLight.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 200; + font-stretch: normal; + font-style: oblique; + src: url('./IosevkaAile-ExtraLightOblique.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 200; + font-stretch: normal; + font-style: italic; + src: url('./IosevkaAile-ExtraLightItalic.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 300; + font-stretch: normal; + font-style: normal; + src: url('./IosevkaAile-Light.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 300; + font-stretch: normal; + font-style: oblique; + src: url('./IosevkaAile-LightOblique.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 400; + font-stretch: normal; + font-style: normal; + src: url('./IosevkaAile-Regular.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 400; + font-stretch: normal; + font-style: oblique; + src: url('./IosevkaAile-Oblique.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 400; + font-stretch: normal; + font-style: italic; + src: url('./IosevkaAile-Italic.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 500; + font-stretch: normal; + font-style: normal; + src: url('./IosevkaAile-Medium.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 500; + font-stretch: normal; + font-style: oblique; + src: url('./IosevkaAile-MediumOblique.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 500; + font-stretch: normal; + font-style: italic; + src: url('./IosevkaAile-MediumItalic.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 600; + font-stretch: normal; + font-style: normal; + src: url('./IosevkaAile-SemiBold.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 600; + font-stretch: normal; + font-style: oblique; + src: url('./IosevkaAile-SemiBoldOblique.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 600; + font-stretch: normal; + font-style: italic; + src: url('./IosevkaAile-SemiBoldItalic.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 700; + font-stretch: normal; + font-style: normal; + src: url('./IosevkaAile-Bold.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 700; + font-stretch: normal; + font-style: oblique; + src: url('./IosevkaAile-BoldOblique.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 700; + font-stretch: normal; + font-style: italic; + src: url('./IosevkaAile-BoldItalic.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 800; + font-stretch: normal; + font-style: normal; + src: url('./IosevkaAile-ExtraBold.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 800; + font-stretch: normal; + font-style: oblique; + src: url('./IosevkaAile-ExtraBoldOblique.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 800; + font-stretch: normal; + font-style: italic; + src: url('./IosevkaAile-ExtraBoldItalic.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 900; + font-stretch: normal; + font-style: normal; + src: url('./IosevkaAile-Heavy.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 900; + font-stretch: normal; + font-style: oblique; + src: url('./IosevkaAile-HeavyOblique.woff2') format('woff2'); +} + +@font-face { + font-family: 'Iosevka Aile'; + font-display: swap; + font-weight: 900; + font-stretch: normal; + font-style: italic; + src: url('./IosevkaAile-HeavyItalic.woff2') format('woff2'); +} diff --git a/assets/orion.jpg b/assets/orion.jpg new file mode 100644 index 0000000..7b9ff0b Binary files /dev/null and b/assets/orion.jpg differ diff --git a/assets/star_0.0.png b/assets/star_0.0.png new file mode 100644 index 0000000..851ab56 Binary files /dev/null and b/assets/star_0.0.png differ diff --git a/assets/star_0.5.png b/assets/star_0.5.png new file mode 100644 index 0000000..ec849b7 Binary files /dev/null and b/assets/star_0.5.png differ diff --git a/assets/star_1.0.png b/assets/star_1.0.png new file mode 100644 index 0000000..4ab1a97 Binary files /dev/null and b/assets/star_1.0.png differ diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000..1053083 Binary files /dev/null and b/bun.lockb differ diff --git a/bun/fmt.js b/bun/fmt.js new file mode 100644 index 0000000..030d4cf --- /dev/null +++ b/bun/fmt.js @@ -0,0 +1,15 @@ +/** @type {(parser: string, ps: string[]) => import("bun").Subprocess} */ +const prettier = (parser, ps) => + Bun.spawn(['bun', 'x', 'prettier', '--write', '--parser', parser, ...ps], { + stdout: 'inherit', + stderr: 'inherit', + }) + +const procs = [ + prettier('babel', ['./index.js', './bun/**/*.js', './.prettierrc.cjs']), + prettier('json', ['./package.json', './jsconfig.json']), + prettier('html', ['./resume.html']), + prettier('css', ['./assets/iosevka.css']), +] + +await Promise.all(procs.map(p => p.exited)) diff --git a/index.js b/index.js new file mode 100644 index 0000000..b24cd04 --- /dev/null +++ b/index.js @@ -0,0 +1,41 @@ +import { $ } from 'zx' +import * as Fs from 'fs' +import * as Path from 'path' +import * as Stream from 'stream/promises' +import * as Puppeteer from 'puppeteer' + +/** @type {import('puppeteer').PDFOptions} */ +const PDF_OPTIONS = { + format: 'letter', + printBackground: true, + margin: { bottom: '0.25in', top: '0.25in', left: '0.25in', right: '0.25in' }, +} + +const DEBUG = !!process.env['DEBUG'] + +const root = 'file://' + Path.resolve(import.meta.dir, './dist') +console.log(root) + +await $`bun bundle --public-url ${root}` + +const pup = await Puppeteer.launch({ headless: DEBUG ? false : 'new' }) +const page = await pup.newPage() +await page.goto(root + '/resume.html') +await page.waitForNetworkIdle() +const pdf = await page.createPDFStream(PDF_OPTIONS) +const out = Fs.createWriteStream('./resume.pdf', { flags: 'w+' }) +await Stream.pipeline(pdf, out) +if (!DEBUG) await pup.close() +console.log('wrote ./resume.pdf') + +process.on('SIGINT', () => { + pup.close() +}) + +process.on('SIGHUP', () => { + pup.close() +}) + +process.on('exit', () => { + pup.close() +}) diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..532ae6c --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "types": ["bun-types"], + "lib": ["esnext"], + "target": "esnext", + "module": "esnext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "jsx": "react", + "allowJs": true, + "checkJs": true, + "noEmit": true, + "strict": true + }, + "include": ["index.js", "bun/**/*.js"] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..5cf6f40 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "resume", + "type": "module", + "scripts": { + "bundle": "parcel build --no-cache ./resume.html", + "export": "bun index.js", + "fmt": "bun bun/fmt.js" + }, + "devDependencies": { + "bun-types": "latest", + "prettier": "^3.1.1" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "parcel": "latest", + "puppeteer": "^21.7.0", + "zx": "^7.2.3" + } +} diff --git a/resume.html b/resume.html new file mode 100644 index 0000000..ffd5c96 --- /dev/null +++ b/resume.html @@ -0,0 +1,932 @@ + + + + + + + +
+

Orion Kindel

+
+ + +
+
+
+

Brief

+
+ A flexible and experienced tech professional who can reliably leverage his + insights to empower and accelerate teams and organizations. +
+
+ Orion is a powerful force multiplier with 7 years’ experience as a + software engineer, leader, systems architect, and product manager. +
+
+
+

Key Skills

+
+
+
Expert
+
+
+
+
+
+
+
+
+
Very Strong
+
+
+
+
+
+
+
+
+
Strong
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Javascript
+ 8 years +
+

+ Designed and implemented full-stack high scale production systems at + every position held. +

+

+ Deep understanding of language semantics, exception handling, + runtimes, performance characteristics and tooling. +

+

+ Architected & implemented complex production interfaces in React, as + well as angular, vue and svelte. Deep experience using hooks & + functional components to manage state and complexity as the product + scales. +

+

+ Guided teams to best practices, building systems with 5-40 active + contributors handling 1MM requests / second with %99.999 uptime +

+
+
+
+
+
+
+
+
+
+
Rust
+ 6 years +
+

+ Active Open Source community member; language contributions and + discussions. +

+

+ Deep understanding of language semantics, exception handling, + runtimes, performance characteristics and tooling. +

+

+ Owner of the primary implementation of the CoAP networking protocol, + which brings high performance REST semantics to bare metal and + distributed systems. +

+

+ Built teams using the language, training teammates reaching productive + and capable in <2mo. +

+
+
+
+
+
+
+
+
+
+
Purescript
+ 5 years +
+

+ Active Open Source community member; language contributions, + discussions, discord member. +

+

Owner of many popular packages and abstractions.

+

+ Deep understanding of language semantics, exception handling, + runtimes, performance characteristics, abstractions and tooling. +

+

+ Built teams using the language, training teammates reaching productive + and capable in <2mo. +

+
+
+
+
+
+
+
+
+
+
Git
+ 7 years +
+

+ Manage 100s of open source repositories, highly active open source + member and contributor. +

+

+ Managed & built git teams at scale, with some repos having hundreds of + daily contributors. +

+
+
+
+
+
+
+
+
+
+
Systems Architecture
+ 6 years +
+

+ Have designed, implemented and modified systems across scales and + stacks. +

+

+ Have designed and implemented Distributed (Microservices or Services), + Monolithic, and Event Driven systems - choosing the model based on the + product and organization’s requirements, capacity, and time + constraints. +

+
+
+
+
+
+
+
+
+
+
Docker
+ 6 years +
+

+ Use docker in most projects for 4 years for making version management, + reproducible deploy artifacts, pull-based deployment models and + security isolation. +

+

+ Have used kubernetes to manage deployments of complex distributed + systems handling millions of requests and $500K MRR with high + reliability. +

+
+
+
+
+
+
+
+
+
+
CICD
+ 6 years +
+

+ Use comprehensive automated testing and CI platforms to automate + quality checks and deployment, significantly accelerating product + development. +

+
+
+
+
+
+
+
+
+
+
Linux
+ 6 years +
+

+ Have used linux personally & in production. Choose VMs (EC2) in lieu + of kubernetes or managed environments for almost all production needs + for many reasons. +

+

+ Deep understanding of systems semantics, filesystems, security model, + networking, resource management, shells, scripting and tooling. +

+

+ Guided teams to best practices, building systems with 5-40 active + contributors handling 1MM requests / second with %99.999 uptime +

+
+
+
+
+
+
+
+
+
+
SQL
+ 7 years +
+

+ Have designed & implemented highly normalized and scalable relational + schemas (both for monolithic and distributed systems) +

+

+ Have used read replication, partitioning and indexing to manage pain + points inherent in maintaining a relational database while the product + and organization scale. +

+

+ Have used many strategies to integrate relational databases with + dynamic and strongly-typed business logic layers from highly-managed + ORMs (ex. Flask, Entity Framework, PrismaJS) to mini-ORMs. +

+
+
+
+
+
+
+
+
+
+
Player-Coach
+ 6 years +
+

+ Have managed teams of sizes 3-10 as a team lead (player-coach), + accountable for success of individual team members as well as the + team. Able to consistenly make & meet data-driven commitments, develop + and maintain excellent relationships with team members and + stakeholders based on accountability, candor and transparency. +

+

+ Use tools like CICD, Scrum, TDD and pair programming to increase team + velocity without applying pressure to individual team members. +

+

+ Use frequent touchpoints with team members and a shared understanding + of my expectations and their goals, decomposing them into measurable + actionable steps and holding them accountable. +

+
+
+
+
+
+
+
+
+
+
AWS
+ 7 years +
+

+ Have used AWS to deploy and manage systems at scale, both persistent + and on-demand (serverless) applications. +

+

+ Deep understanding of networking model (VPC), database hosting (RDS), + persistent managed or unmanaged servers (EC2), on-demand compute + (Lambda), event-driven architecture (SQS), machine learning + (SageMaker), permissions management (IAM). +

+
+
+
+
+
+
+
+
+
+
Scrum
+ 7 years +
+

+ Have led 5 scrum-informed process transformations to improve team + performance, transparency and clarity. +

+

+ Trained and mentored product managers on their role and + responsibilities, solving many sources of friction and conflict on + under-performing teams. +

+

+ Have filled roles of scrum master and product owner on several product + teams to much success. +

+
+
+

Other Skills

+
+
+
+
+
+
+
+
+
REST
+
+
+
+
+
+
+
+
+
HATEOAS
+
+
+
+
+
+
+
+
+
JIRA
+
+
+
+
+
+
+
+
+
Figma
+
+
+
+
+
+
+
+
+
Slack API
+
+
+
+
+
+
+
+
+
OSS Mgmt
+
+
+
+
+
+
+
+
+
OAuth, OIDC
+
+
+
+
+
+
+
+
+
Networking
+
+
+
+
+
+
+
+
+
Python
+
+
+
+
+
+
+
+
+
Scala
+
+
+
+
+
+
+
+
+
Java
+
+
+
+
+
+
+
+
+
OCaml
+
+
+
+
+
+
+
+
+
C#
+
+
+
+
+
+
+
+
+
Java
+
+
+
+
+
+
+
+
+
GraphQL
+
+
+
+
+
+
+
+
+
NoSQL
+
+
+
+
+
+
+
+
+
Data Insights
+
+
+
+
+
+
+
+
+
Machine Learning
+
+
+
+
+
+
+
+
+
Cryptography
+
+
+
+
+
+
+
+
+
Terraform
+
+
+
+
+
+
+
+
+
gRPC
+
+
+
+
+
+
+
+
+
Embedded
+
+
+
+
+

Experience

+
+

thunderstrike.ai

+

Technical Founder & CTO

+

2023 - Present

+ +
+
+

Qwick

+

Senior Software Engineer

+

2021 - 2023

+ +
+
+

TheoremOne

+

Senior Lead Software Engineer

+

2020 - 2021

+ +
+
+

Software Engineering Manager

+

2021

+ +
+
+

Product Manager

+

2021

+ +
+
+

Strongmind

+

Software Engineer

+

2017 - 2020

+ +
+
+

Education

+
+

Associate’s of Science, Physics

+

Scottsdale Community College, 2014 - 2016

+
+
+

Certified Scrum Developer

+

Scrum Alliance, 2019

+
+
+

Certified Scrum Product Owner

+

Scrum Alliance, 2020

+
+
+ + diff --git a/resume.pdf b/resume.pdf new file mode 100644 index 0000000..84070c1 Binary files /dev/null and b/resume.pdf differ