{"$schema":"https://ejfox.com/schema/page-twin@1.json","kind":"blog_post","url":"https://ejfox.com/blog/week-notes/2025-18","json_url":"https://ejfox.com/blog/week-notes/2025-18.json","generator":"ejfox.com/json-twin@1","data":{"cacheVersion":"2026-05-13-gear-cards","html":"<figure role=\"figure\" aria-label=\"Article by Frank Bruni titled &#x27;The F Word Won&#x27;t Save Democrats,&#x27; a 9-minute read about Democratic political strategy.\" class=\"\">\n<img src=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746150081/Screenshot_2025-05-01_at_9.41.08_PM.png\" alt=\"Article by Frank Bruni titled &#x27;The F Word Won&#x27;t Save Democrats,&#x27; a 9-minute read about Democratic political strategy.\" loading=\"lazy\" decoding=\"async\" srcset=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_640/v1746150081/Screenshot_2025-05-01_at_9.41.08_PM.png 640w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_960/v1746150081/Screenshot_2025-05-01_at_9.41.08_PM.png 960w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746150081/Screenshot_2025-05-01_at_9.41.08_PM.png 1280w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1920/v1746150081/Screenshot_2025-05-01_at_9.41.08_PM.png 1920w\" sizes=\"(max-width: 430px) 92vw, (max-width: 768px) 85vw, 900px\" title=\"Article by Frank Bruni titled &#x27;The F Word Won&#x27;t Save Democrats,&#x27; a 9-minute read about Democratic political strategy.\" width=\"682\" height=\"228\" style=\"--splay-rot:1.32deg;\" data-dimensions=\"682×228\" class=\"img-full my-8 rounded-sm img-splay w-full mx-auto py-4\" crossorigin=\"anonymous\">\n<figcaption class=\"\">Article by Frank Bruni titled 'The F Word Won't Save Democrats,' a 9-minute read about Democratic political strategy.</figcaption>\n</figure>\n<figure role=\"figure\" aria-label=\"Rhymestone keyboard build guide documenting assembled components, PCBs, stabilizers, and OLED displays for a custom mechanical keyboard kit.\" class=\"\">\n<img src=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746155284/Screenshot_2025-05-01_at_11.07.47_PM.png\" alt=\"Rhymestone keyboard build guide documenting assembled components, PCBs, stabilizers, and OLED displays for a custom mechanical keyboard kit.\" loading=\"lazy\" decoding=\"async\" srcset=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_640/v1746155284/Screenshot_2025-05-01_at_11.07.47_PM.png 640w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_960/v1746155284/Screenshot_2025-05-01_at_11.07.47_PM.png 960w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746155284/Screenshot_2025-05-01_at_11.07.47_PM.png 1280w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1920/v1746155284/Screenshot_2025-05-01_at_11.07.47_PM.png 1920w\" sizes=\"(max-width: 430px) 92vw, (max-width: 768px) 85vw, 900px\" title=\"Rhymestone keyboard build guide documenting assembled components, PCBs, stabilizers, and OLED displays for a custom mechanical keyboard kit.\" width=\"2620\" height=\"2486\" style=\"--splay-rot:-0.7deg;\" data-dimensions=\"2620×2486\" class=\"img-full my-8 rounded-sm img-splay aspect-square w-full mx-auto py-4\" crossorigin=\"anonymous\">\n<figcaption class=\"\">Rhymestone keyboard build guide documenting assembled components, PCBs, stabilizers, and OLED displays for a custom mechanical keyboard kit.</figcaption>\n</figure>\n<figure role=\"figure\" aria-label=\"Robot and golden Labrador dog in tug-of-war with rope toy, text reads &#x22;VS&#x22; and &#x22;Balancing AI + Humanity&#x22;\" class=\"\">\n<img src=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746209427/Screenshot_2025-05-02_at_2.10.14_PM.png\" alt=\"Robot and golden Labrador dog in tug-of-war with rope toy, text reads &#x22;VS&#x22; and &#x22;Balancing AI + Humanity&#x22;\" loading=\"lazy\" decoding=\"async\" srcset=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_640/v1746209427/Screenshot_2025-05-02_at_2.10.14_PM.png 640w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_960/v1746209427/Screenshot_2025-05-02_at_2.10.14_PM.png 960w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746209427/Screenshot_2025-05-02_at_2.10.14_PM.png 1280w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1920/v1746209427/Screenshot_2025-05-02_at_2.10.14_PM.png 1920w\" sizes=\"(max-width: 430px) 92vw, (max-width: 768px) 85vw, 900px\" title=\"Robot and golden Labrador dog in tug-of-war with rope toy, text reads &#x22;VS&#x22; and &#x22;Balancing AI + Humanity&#x22;\" width=\"962\" height=\"534\" style=\"--splay-rot:0.6deg;\" data-dimensions=\"962×534\" class=\"img-full my-8 rounded-sm img-splay aspect-video w-full mx-auto py-4\" crossorigin=\"anonymous\">\n<figcaption class=\"\">Robot and golden Labrador dog in tug-of-war with rope toy, text reads \"VS\" and \"Balancing AI + Humanity\"</figcaption>\n</figure>\n<ul class=\"list-disc\">\n<li class=\"\">Sat 4<div class=\"\"></div> PM: Added Umami analytics to Grafana dashboard. Connected PostgreSQL db to Grafana, wrote SQL queries to track visitors, browsers, countries. Fixed CSP issues in Nuxt. All analytics now viewable alongside other metrics in one place. Privacy-focused Google Analytics alternative working.\n<figure role=\"figure\" aria-label=\"Search and action menu showing options to append &#x27;o+&#x27; to scratchpad or search for it across Google, Vault, ChatGPT, 1Password, and Wolfram Alpha.\" class=\"\"><img src=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746304848/Screenshot_2025-05-03_at_4.40.35_PM.png\" alt=\"Search and action menu showing options to append &#x27;o+&#x27; to scratchpad or search for it across Google, Vault, ChatGPT, 1Password, and Wolfram Alpha.\" loading=\"lazy\" decoding=\"async\" srcset=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_640/v1746304848/Screenshot_2025-05-03_at_4.40.35_PM.png 640w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_960/v1746304848/Screenshot_2025-05-03_at_4.40.35_PM.png 960w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746304848/Screenshot_2025-05-03_at_4.40.35_PM.png 1280w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1920/v1746304848/Screenshot_2025-05-03_at_4.40.35_PM.png 1920w\" sizes=\"(max-width: 430px) 92vw, (max-width: 768px) 85vw, 900px\" title=\"Search and action menu showing options to append &#x27;o+&#x27; to scratchpad or search for it across Google, Vault, ChatGPT, 1Password, and Wolfram Alpha.\" width=\"2204\" height=\"1904\" style=\"--splay-rot:-2.94deg;\" data-dimensions=\"2204×1904\" class=\"img-full my-8 rounded-sm img-splay w-full mx-auto py-4\" crossorigin=\"anonymous\"><figcaption class=\"\">Search and action menu showing options to append 'o+' to scratchpad or search for it across Google, Vault, ChatGPT, 1Password, and Wolfram Alpha.</figcaption></figure></li>\n</ul>\n<figure role=\"figure\" aria-label=\"Blog post explaining how personal APIs track individual KPIs like health data, chess ratings, typing speed, and writing output to measure life improvements.\" class=\"\">\n<img src=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746310959/Screenshot_2025-05-03_at_6.22.26_PM.png\" alt=\"Blog post explaining how personal APIs track individual KPIs like health data, chess ratings, typing speed, and writing output to measure life improvements.\" loading=\"lazy\" decoding=\"async\" srcset=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_640/v1746310959/Screenshot_2025-05-03_at_6.22.26_PM.png 640w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_960/v1746310959/Screenshot_2025-05-03_at_6.22.26_PM.png 960w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746310959/Screenshot_2025-05-03_at_6.22.26_PM.png 1280w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1920/v1746310959/Screenshot_2025-05-03_at_6.22.26_PM.png 1920w\" sizes=\"(max-width: 430px) 92vw, (max-width: 768px) 85vw, 900px\" title=\"Blog post explaining how personal APIs track individual KPIs like health data, chess ratings, typing speed, and writing output to measure life improvements.\" width=\"2620\" height=\"2486\" style=\"--splay-rot:-2.53deg;\" data-dimensions=\"2620×2486\" class=\"img-full my-8 rounded-sm img-splay aspect-square w-full mx-auto py-4\" crossorigin=\"anonymous\">\n<figcaption class=\"\">Blog post explaining how personal APIs track individual KPIs like health data, chess ratings, typing speed, and writing output to measure life improvements.</figcaption>\n</figure>\n<figure role=\"figure\" aria-label=\"Writing activity dashboard showing 103 total blog posts, 65,820 words published, 15.6 annual posting velocity, and 6 active days in the past 52 days.\" class=\"\">\n<img src=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746310985/Screenshot_2025-05-03_at_6.22.53_PM.png\" alt=\"Writing activity dashboard showing 103 total blog posts, 65,820 words published, 15.6 annual posting velocity, and 6 active days in the past 52 days.\" loading=\"lazy\" decoding=\"async\" srcset=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_640/v1746310985/Screenshot_2025-05-03_at_6.22.53_PM.png 640w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_960/v1746310985/Screenshot_2025-05-03_at_6.22.53_PM.png 960w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746310985/Screenshot_2025-05-03_at_6.22.53_PM.png 1280w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1920/v1746310985/Screenshot_2025-05-03_at_6.22.53_PM.png 1920w\" sizes=\"(max-width: 430px) 92vw, (max-width: 768px) 85vw, 900px\" title=\"Writing activity dashboard showing 103 total blog posts, 65,820 words published, 15.6 annual posting velocity, and 6 active days in the past 52 days.\" width=\"1592\" height=\"1626\" style=\"--splay-rot:-1.74deg;\" data-dimensions=\"1592×1626\" class=\"img-full my-8 rounded-sm img-splay aspect-square w-full mx-auto py-4\" crossorigin=\"anonymous\">\n<figcaption class=\"\">Writing activity dashboard showing 103 total blog posts, 65,820 words published, 15.6 annual posting velocity, and 6 active days in the past 52 days.</figcaption>\n</figure>\n<figure role=\"figure\" aria-label=\"Terminal showing Node.js task runner build process with npm commands and celebration message updates for completed tasks.\" class=\"\">\n<img src=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746318237/Screenshot_2025-05-03_at_8.23.45_PM.png\" alt=\"Terminal showing Node.js task runner build process with npm commands and celebration message updates for completed tasks.\" loading=\"lazy\" decoding=\"async\" srcset=\"https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_640/v1746318237/Screenshot_2025-05-03_at_8.23.45_PM.png 640w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_960/v1746318237/Screenshot_2025-05-03_at_8.23.45_PM.png 960w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1280/v1746318237/Screenshot_2025-05-03_at_8.23.45_PM.png 1280w, https://res.cloudinary.com/ejf/image/upload/c_scale,f_auto,q_auto:good,w_1920/v1746318237/Screenshot_2025-05-03_at_8.23.45_PM.png 1920w\" sizes=\"(max-width: 430px) 92vw, (max-width: 768px) 85vw, 900px\" title=\"Terminal showing Node.js task runner build process with npm commands and celebration message updates for completed tasks.\" width=\"3600\" height=\"2338\" style=\"--splay-rot:-0.6deg;\" data-dimensions=\"3600×2338\" class=\"img-full my-8 rounded-sm img-splay w-full mx-auto py-4\" crossorigin=\"anonymous\">\n<figcaption class=\"\">Terminal showing Node.js task runner build process with npm commands and celebration message updates for completed tasks.</figcaption>\n</figure>","title":"2025 18","metadata":{"date":"2025-05-02T01:41:22.000Z","modified":"2025-08-28T19:08:25.000Z","tags":["development","personal"],"words":186,"images":7,"imageDetails":{"total":7,"cloudinary":7,"withDimensions":0},"links":7,"codeBlocks":0,"headers":{},"toc":[],"type":"post"}},"_links":{"self":"https://ejfox.com/blog/week-notes/2025-18.json","html":"https://ejfox.com/blog/week-notes/2025-18","index":"/blog.json"}}