<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Justin B Kay's Blog</title><link>https://blog.jbkconsultingllc.com/</link><description>Recent content on Justin B Kay's Blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 30 Jul 2026 15:00:00 -0600</lastBuildDate><atom:link href="https://blog.jbkconsultingllc.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Keeping Property Work on Track with PMDB</title><link>https://blog.jbkconsultingllc.com/posts/keeping-property-work-on-track-with-pmdb/</link><pubDate>Thu, 30 Jul 2026 15:00:00 -0600</pubDate><guid>https://blog.jbkconsultingllc.com/posts/keeping-property-work-on-track-with-pmdb/</guid><description>&lt;p&gt;Managing affordable housing properties involves far more than keeping a list of buildings and units. Every property comes with recurring reports, inspections, renewals, financial obligations, important contacts, and years of supporting documents.&lt;/p&gt;
&lt;p&gt;When that information is spread across calendars, shared drives, inboxes, and individual staff members, even routine work can become difficult to track. A missed deadline or an unavailable document can create delays for the entire team.&lt;/p&gt;
&lt;p&gt;This is one of the problems I built PMDB to solve.&lt;/p&gt;</description></item><item><title>Updating deeply nested elixir maps</title><link>https://blog.jbkconsultingllc.com/posts/updating-deeply-nested-elixir-maps/</link><pubDate>Thu, 04 Jan 2024 14:42:55 -0700</pubDate><guid>https://blog.jbkconsultingllc.com/posts/updating-deeply-nested-elixir-maps/</guid><description>&lt;p&gt;In some cases it is necessary to update a deeply nested attribute in a map. I went searching for a way to do this and came across several approaches, the one that worked for me was this, a combination of &lt;a href="https://hexdocs.pm/elixir/Kernel.html#put_in/2"&gt;Kernel.put_in&lt;/a&gt; and &lt;a href="https://hexdocs.pm/elixir/1.12.3/Access.html#key/2"&gt;Access.key&lt;/a&gt;, here I&amp;rsquo;m using it to update a socket struct nested assigns map.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-elixir" data-lang="elixir"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;put_in(socket, &lt;span style="color:#a6e22e"&gt;Enum&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;map([&lt;span style="color:#e6db74"&gt;:assigns&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;:beacon_live_data&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;:form_submitted&lt;/span&gt;], &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Access&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;key(&amp;amp;1, %{})), &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The put_in function is pretty easy to understand, it &lt;code&gt;Puts a value in a nested structure via the given path&lt;/code&gt;. The tricky bit is the path.&lt;/p&gt;</description></item><item><title>Running Quantum in an Elixir Cluster</title><link>https://blog.jbkconsultingllc.com/posts/running-quantum-in-elixir-cluster/</link><pubDate>Thu, 17 Feb 2022 14:42:55 -0700</pubDate><guid>https://blog.jbkconsultingllc.com/posts/running-quantum-in-elixir-cluster/</guid><description>&lt;p&gt;In one of the projects that I work on, for the sake of availability and reliability, we are running our Phoenix app in a cluster of 3 servers using libcluster. Initially, it was just running on a single server and I had configured &lt;a href="https://github.com/quantum-elixir/quantum-core"&gt;Quantum&lt;/a&gt; to run our recurring tasks on a cron like schedule. This worked well, and I had no issues with the setup. When we decided to move to a clustered setup, there was a consideration concerning Quantum. I didn&amp;rsquo;t want the jobs to run on multiple servers, I wanted to have a single server responsible for handling all the scheduled jobs so as to keep duplicate jobs from running. I looked around and found someone who had written about using &lt;a href="https://github.com/derekkraan/highlander"&gt;Highlander&lt;/a&gt; to make sure there was only a single instance of Quantum running on the cluster at a time. I decided to try this out.&lt;/p&gt;</description></item><item><title>Decoding TypeORM-Encrypted Data With Elixir</title><link>https://blog.jbkconsultingllc.com/posts/decoding-typeorm-encrypted-data-with-elixir/</link><pubDate>Sun, 21 Nov 2021 15:17:26 -0700</pubDate><guid>https://blog.jbkconsultingllc.com/posts/decoding-typeorm-encrypted-data-with-elixir/</guid><description>&lt;p&gt;Today&amp;rsquo;s challege was to figure out how to decrypt an encrypted field created by the TypeORM plugin &lt;a href="https://www.npmjs.com/package/typeorm-encrypted"&gt;typeorm-encrypted&lt;/a&gt;. Typeorm-encrypted allows you to automatically encrypt/decrypt a field on save/fetch when using TypeORM. This allows you to encrypt sensitive data while at rest in your database.&lt;/p&gt;
&lt;p&gt;The Typeorm-encrypted module saves the encrypted (aes-256-gcm) field as a Base64 encoded string in the database. Our challege is to be able to read that field from our database and decrypt the sensitive data for use in our Elixir application.&lt;/p&gt;</description></item><item><title>Ecto Preload Nested Associations with joins</title><link>https://blog.jbkconsultingllc.com/posts/ecto-preload-nested-associations/</link><pubDate>Fri, 15 Oct 2021 10:06:51 -0600</pubDate><guid>https://blog.jbkconsultingllc.com/posts/ecto-preload-nested-associations/</guid><description>&lt;p&gt;Recently I had an issue where I was loading some &amp;ldquo;models&amp;rdquo; in ecto, and I needed to preload some of the associations along with the parent record. I had it working with a very simple bit of code.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-elixir" data-lang="elixir"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; get_franchises &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Franchise&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&amp;gt;&lt;/span&gt; preload(&lt;span style="color:#e6db74"&gt;merchants&lt;/span&gt;: [&lt;span style="color:#e6db74"&gt;stores&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;:shopify&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Repo&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;all()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As you can see from this bit of code, some of the associations were nested, Franchise has many Merchants, Merchants have many stores, and a store can have a Shopify record. What I noticed when I started using the returned data was that some of the stores didn&amp;rsquo;t have a Shopify record. For my purposes, I wasn&amp;rsquo;t interested in the stores without a Shopify record, so I wanted to exclude them from my query results. In its original form, there were several queries being made to satisfy the ecto results. I struggled with how to include a where clause in the preload statement, until I came across something that led me to my desired result. Here&amp;rsquo;s the end game, a single SQL query resulting from an ecto statement with a preload that limits the stores to those with a Shopify record. You could further fine tune your query to return a subset of these results if you desired.&lt;/p&gt;</description></item><item><title>Heroku Git Transport Feature Retirement</title><link>https://blog.jbkconsultingllc.com/posts/heroku-git-transport-feature-retirement/</link><pubDate>Wed, 29 Sep 2021 08:16:17 -0600</pubDate><guid>https://blog.jbkconsultingllc.com/posts/heroku-git-transport-feature-retirement/</guid><description>&lt;p&gt;We recently received an email from Heroku telling us that we would need to transition our deployments away from the ssh transport that we&amp;rsquo;ve been using on &lt;a href="https://semaphoreci.com/"&gt;Semaphore CI&lt;/a&gt; to deploy our Elixir Phoenix app. The &lt;a href="https://docs.semaphoreci.com/examples/heroku-deployment/"&gt;Semaphore deployment documentation&lt;/a&gt; only covers the ssh transport route. We needed to figure out how to move to the https deployments from our CI server. The &lt;a href="https://help.heroku.com/6JAIBWLM/how-do-i-deploy-my-app-with-heroku-s-http-git-transport-instead-of-ssh-git-transport"&gt;instructions&lt;/a&gt; in the email were&amp;rsquo;t too helpful as those steps had already been taken in our project, the Semaphore solution replaces https with ssh for deployments. The real issue was how to authenticate to Heroku now that SSH was off the table.&lt;/p&gt;</description></item><item><title>Add Sass to Phoenix 1.6 with Esbuild</title><link>https://blog.jbkconsultingllc.com/posts/add-sass-to-phoenix-with-esbuild/</link><pubDate>Sun, 12 Sep 2021 20:49:30 -0600</pubDate><guid>https://blog.jbkconsultingllc.com/posts/add-sass-to-phoenix-with-esbuild/</guid><description>&lt;p&gt;If you are starting a new project with The &lt;a href="https://www.phoenixframework.org/"&gt;Phoenix Framework&lt;/a&gt; version 1.6, you&amp;rsquo;ll notice there has been a change with regard to asset handling.
Chris McCord and The Phoenix Team have made the choice to move away from WebPack and start using &lt;a href="https://esbuild.github.io/"&gt;Esbuild&lt;/a&gt; to deal with the Javascript files. One
side effect of this is you lose the ability to use Sass files by default. Have no fear, there&amp;rsquo;s a way to add Sass back into your project.&lt;/p&gt;</description></item></channel></rss>