<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ia on Christian Martínez De La Rosa</title><link>https://christt105.github.io/tags/ia/</link><description>Recent content in Ia on Christian Martínez De La Rosa</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Fri, 16 Oct 2026 00:00:00 +0200</lastBuildDate><atom:link href="https://christt105.github.io/tags/ia/index.xml" rel="self" type="application/rss+xml"/><item><title>My relationship with mouth sores and vibecoding</title><link>https://christt105.github.io/blog/llagas-vibecoding/</link><pubDate>Fri, 16 Oct 2026 00:00:00 +0200</pubDate><guid>https://christt105.github.io/blog/llagas-vibecoding/</guid><enclosure url="https://christt105.github.io/blog/llagas-vibecoding/cover.png" length="1828023" type="image/png"/><description>&lt;p&gt;Hi again. Today&amp;rsquo;s post is a bit different. I&amp;rsquo;m not going to talk about one of those projects I&amp;rsquo;m fond of and look after line by line, but the exact opposite: a web app I made in five minutes, whose code I haven&amp;rsquo;t reviewed at all, and which I&amp;rsquo;m perfectly happy to keep that way.&lt;/p&gt;&#10;&lt;p&gt;It&amp;rsquo;s called &lt;strong&gt;Llagas&lt;/strong&gt; (Spanish for mouth sores), it keeps track of the sores I get in my mouth, and it&amp;rsquo;s my excuse to talk about how I live with &lt;em&gt;vibecoding&lt;/em&gt;.&lt;/p&gt;&#10;&lt;a class="github-repo-card" href="https://github.com/christt105/llagas" target="_blank" rel="noopener"&gt;&#10; &lt;img src="https://avatars.githubusercontent.com/u/36189169?v=4" alt="christt105 avatar" class="repo-avatar"&gt;&#10; &lt;h3&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-github" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"&gt;&#10; &lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&#10; &lt;path d="M9 19c-4.3 1.4 -4.3 -2.5 -6 -3m12 5v-3.5c0 -1 .1 -1.4 -.5 -2c2.8 -.3 5.5 -1.4 5.5 -6a4.6 4.6 0 0 0 -1.3 -3.2a4.2 4.2 0 0 0 -.1 -3.2s-1.1 -.3 -3.5 1.3a12.3 12.3 0 0 0 -6.2 0c-2.4 -1.6 -3.5 -1.3 -3.5 -1.3a4.2 4.2 0 0 0 -.1 3.2a4.6 4.6 0 0 0 -1.3 3.2c0 4.6 2.7 5.7 5.5 6c-.6 .6 -.6 1.2 -.5 2v3.5" /&gt;&#10;&lt;/svg&gt;&#10;&#10;&#10; christt105/llagas&lt;/h3&gt;&#10; &lt;p&gt;Self-hosted mouth ulcer tracker: quick logging from the phone, stats, a tappable mouth map and Immich photos. PWA.&lt;/p&gt;&#10; &lt;div class="repo-stats"&gt;&#10; &lt;span&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor" class="icon icon-tabler icons-tabler-filled icon-tabler-star"&gt;&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&lt;path d="M8.243 7.34l-6.38 .925l-.113 .023a1 1 0 0 0 -.44 1.684l4.622 4.499l-1.09 6.355l-.013 .11a1 1 0 0 0 1.464 .944l5.706 -3l5.693 3l.1 .046a1 1 0 0 0 1.352 -1.1l-1.091 -6.355l4.624 -4.5l.078 -.085a1 1 0 0 0 -.633 -1.62l-6.38 -.926l-2.852 -5.78a1 1 0 0 0 -1.794 0l-2.853 5.78z" /&gt;&lt;/svg&gt; 0&lt;/span&gt;&#10; &lt;span&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-git-fork"&gt;&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&lt;path d="M10 18a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /&gt;&lt;path d="M5 6a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /&gt;&lt;path d="M15 6a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" /&gt;&lt;path d="M7 8v2a2 2 0 0 0 2 2h6a2 2 0 0 0 2 -2v-2" /&gt;&lt;path d="M12 12l0 4" /&gt;&lt;/svg&gt; 0&lt;/span&gt;&#10; &lt;span&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-calendar-event"&gt;&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/&gt;&lt;path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2l0 -12" /&gt;&lt;path d="M16 3l0 4" /&gt;&lt;path d="M8 3l0 4" /&gt;&lt;path d="M4 11l16 0" /&gt;&lt;path d="M8 15h2v2h-2l0 -2" /&gt;&lt;/svg&gt; 2026-10-07&lt;/span&gt;&#10; &lt;/div&gt;&#10; &lt;/a&gt;&#10;&lt;p&gt;&lt;img alt="Llagas home screen and statistics, with demo data" class="gallery-image" data-flex-basis="427px" data-flex-grow="178" height="855" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/blog/llagas-vibecoding/cover.webp" srcset="https://christt105.github.io/blog/llagas-vibecoding/cover_hu_49e310f1c19d0405.webp 800w, https://christt105.github.io/blog/llagas-vibecoding/cover.webp 1524w" width="1524"&gt;&lt;/p&gt;&#10;&lt;h2 id="the-problem"&gt;The problem&#10;&lt;/h2&gt;&lt;p&gt;I get mouth sores quite often. Nothing serious, but enough that I want to know when they show up, how long they last, where, whether it was a bite or stress, and what helped them heal. Geek moment, the kind that makes a doctor look at you a little worried.&lt;/p&gt;&#10;&lt;h2 id="what-i-already-had-in-obsidian"&gt;What I already had in Obsidian&#10;&lt;/h2&gt;&lt;p&gt;I wasn&amp;rsquo;t starting from zero. I&amp;rsquo;d been logging them in Notion for a while. Later they moved to my Obsidian vault, one note per sore with a few properties:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1&#10;&lt;/span&gt;&lt;span class="lnt"&gt;2&#10;&lt;/span&gt;&lt;span class="lnt"&gt;3&#10;&lt;/span&gt;&lt;span class="lnt"&gt;4&#10;&lt;/span&gt;&lt;span class="lnt"&gt;5&#10;&lt;/span&gt;&lt;span class="lnt"&gt;6&#10;&lt;/span&gt;&lt;span class="lnt"&gt;7&#10;&lt;/span&gt;&lt;span class="lnt"&gt;8&#10;&lt;/span&gt;&lt;span class="lnt"&gt;9&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;llaga&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;fecha_aparicion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ld"&gt;2026-06-19&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;fecha_desaparicion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ld"&gt;2026-07-03&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;ubicacion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Paladar&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;dolor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;causa_sospechada&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;tratamiento&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;And it worked. With a Bases view I had a table of all of them, and not much else. But it fell short in very specific ways:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Logging a new sore from my phone had more friction than I wanted. If I have to open Obsidian, create the note, fill in the properties&amp;hellip; I end up leaving it for later, and later means never.&lt;/li&gt;&#10;&lt;li&gt;The location was free text. &amp;ldquo;Lower lip&amp;rdquo;, &amp;ldquo;bottom lip&amp;rdquo;, &amp;ldquo;lwr lip&amp;rdquo;. Impossible to get decent statistics.&lt;/li&gt;&#10;&lt;li&gt;Photos. Taking a picture of a sore to see how it evolves is useful, but my photos already live in &lt;a class="link" href="https://immich.app/" target="_blank" rel="noopener"&#10; &gt;Immich&lt;/a&gt;, and I didn&amp;rsquo;t want to duplicate them inside the vault.&lt;/li&gt;&#10;&lt;li&gt;I wanted to &lt;strong&gt;see where&lt;/strong&gt; they show up. Not a list of names, but a drawing of the mouth with the spots marked.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;I could have made an Obsidian plugin or worked harder on the templates, but for what I wanted, something exclusive to this topic with exactly the tools I could think of, I needed something of my own.&lt;/p&gt;&#10;&lt;h2 id="the-solution-ask-claude"&gt;The solution: ask Claude&#10;&lt;/h2&gt;&lt;p&gt;So I sat down with Claude, told it what I wanted and kept asking for things. In about five minutes I had a first working version. I asked for everything straight from my phone, and since it lives on my home server, it was done in no time. I&amp;rsquo;ve polished it since, but the important parts were there from the start:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Quick entry from the phone&lt;/strong&gt;, as an installable PWA. One button and done.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;A map of the mouth&lt;/strong&gt;. A drawing of an open mouth, and you pick the location by tapping where the sore is. The location text fills itself in.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Immich photos&lt;/strong&gt;. The app only stores the photo IDs, it doesn&amp;rsquo;t copy them. When editing a sore it shows me the photos I took on the days it lasted, I select them and they&amp;rsquo;re added to an Immich album. I can also take a photo from the app itself.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Statistics&lt;/strong&gt;: how many per year, average duration, the longest one, how often they appear, in which areas, and a map with all of them.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;img alt="Picking the location by tapping the mouth drawing, and the map with every sore in the history" class="gallery-image" data-flex-basis="427px" data-flex-grow="178" height="855" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/blog/llagas-vibecoding/mapa.webp" srcset="https://christt105.github.io/blog/llagas-vibecoding/mapa_hu_4fc81c423d229a9e.webp 800w, https://christt105.github.io/blog/llagas-vibecoding/mapa.webp 1524w" width="1524"&gt;&lt;/p&gt;&#10;&lt;p&gt;All the images use generated demo data. I&amp;rsquo;m in bad shape but I can live well.&lt;/p&gt;&#10;&lt;p&gt;The Immich photos work the same way: I choose the date range and the app shows me the photos from that period so I can link them.&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="Immich photo picker and the history grouped by month (the photos in the screenshot are placeholders)" class="gallery-image" data-flex-basis="427px" data-flex-grow="178" height="855" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://christt105.github.io/blog/llagas-vibecoding/immich.webp" srcset="https://christt105.github.io/blog/llagas-vibecoding/immich_hu_78bf473445ca2ed.webp 800w, https://christt105.github.io/blog/llagas-vibecoding/immich.webp 1524w" width="1524"&gt;&lt;/p&gt;&#10;&lt;p&gt;Afterwards I migrated all the sores I had in Obsidian to the new database with an import script, which also looks for the photos already linked in the notes and attaches them.&lt;/p&gt;&#10;&lt;h2 id="i-havent-reviewed-any-code"&gt;I haven&amp;rsquo;t reviewed any code&#10;&lt;/h2&gt;&lt;p&gt;And here&amp;rsquo;s what I really want to talk about: &lt;strong&gt;I haven&amp;rsquo;t looked at the code&lt;/strong&gt;. Not a single line. I don&amp;rsquo;t know how it&amp;rsquo;s structured, I don&amp;rsquo;t know if there&amp;rsquo;s anything weird in there, and I don&amp;rsquo;t mind.&lt;/p&gt;&#10;&lt;p&gt;This, which in any of my other projects would be heresy, makes complete sense here for several reasons:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;It&amp;rsquo;s a simple project.&lt;/strong&gt; A web app for me, on my local network, with no accounts or users other than me. If it breaks, the worst that happens is I can&amp;rsquo;t log a sore for a while.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;The risk is minimal.&lt;/strong&gt; It doesn&amp;rsquo;t touch anything important. It only stores some dates and photo identifiers.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;It tests itself by being used.&lt;/strong&gt; If it works when I use it, it works. If something fails, I notice right away and tell Claude.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Its goal is to make my life easier&lt;/strong&gt;, not to be perfect. Not every project has to be.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;And there&amp;rsquo;s a point that seems even more important to me: &lt;strong&gt;without AI I wouldn&amp;rsquo;t even have considered it&lt;/strong&gt;. It would have taken far longer, I&amp;rsquo;d have had to learn things I don&amp;rsquo;t care about for something so small, and I&amp;rsquo;d most likely have stayed with the Obsidian note. Vibecoding here didn&amp;rsquo;t replace a project I would have made, it made possible one that wouldn&amp;rsquo;t have existed.&lt;/p&gt;&#10;&lt;h2 id="the-other-side-the-projects-i-do-care-about"&gt;The other side: the projects I do care about&#10;&lt;/h2&gt;&lt;p&gt;I don&amp;rsquo;t want this to read as &amp;ldquo;leave everything in the hands of AI&amp;rdquo;, because my relationship with it is &lt;strong&gt;completely different depending on the project&lt;/strong&gt;.&lt;/p&gt;&#10;&lt;p&gt;I have other, more important projects that I&amp;rsquo;m very fond of, like &lt;a class="link" href="https://christt105.github.io/projects/elit3d/" &gt;Elit3D&lt;/a&gt; or &lt;a class="link" href="https://christt105.github.io/projects/godosters/" &gt;Godosters&lt;/a&gt;. With those I go much slower. I also use AI to help, but I review every line, I don&amp;rsquo;t let it get out of hand, and I decide how the code is organized and what gets accepted and what doesn&amp;rsquo;t. If I have to choose between going fast and understanding everything, there I choose understanding everything.&lt;/p&gt;&#10;&lt;p&gt;I think part of &amp;ldquo;living with vibecoding&amp;rdquo; is exactly that: knowing when to let go and when not to. What I&amp;rsquo;d consider a mistake is applying the same criterion to everything, in either direction. Reviewing every line of Llagas would be a waste of time, and not reviewing anything in Elit3D would be irresponsible.&lt;/p&gt;&#10;&lt;h2 id="how-its-deployed"&gt;How it&amp;rsquo;s deployed&#10;&lt;/h2&gt;&lt;p&gt;Since it&amp;rsquo;s such a pleasant project to tinker with, I also published it as a Docker image on GitHub, and I run it on my home server next to the rest of my services. The basic setup is a &lt;code&gt;docker-compose&lt;/code&gt; file with the address of my Immich and an API key:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;&#10;&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 2&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 3&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 4&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 5&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 6&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 7&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 8&#10;&lt;/span&gt;&lt;span class="lnt"&gt; 9&#10;&lt;/span&gt;&lt;span class="lnt"&gt;10&#10;&lt;/span&gt;&lt;span class="lnt"&gt;11&#10;&lt;/span&gt;&lt;span class="lnt"&gt;12&#10;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#10;&lt;td class="lntd"&gt;&#10;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;llagas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;ghcr.io/christt105/llagas:${LLAGAS_TAG:-latest}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;unless-stopped&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;8097:8080&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;TZ&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Europe/Madrid&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;IMMICH_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;http://immich.lan:2283&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;env_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;.env&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./data:/data&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#10;&lt;/div&gt;&#10;&lt;/div&gt;&lt;p&gt;It has no authentication, because it&amp;rsquo;s meant for my local network (and Tailscale when I&amp;rsquo;m away from home). It&amp;rsquo;s exactly the kind of decision you can make lightly in a project like this and would never make in one that serves other people&amp;rsquo;s data.&lt;/p&gt;&#10;&lt;h2 id="conclusion"&gt;Conclusion&#10;&lt;/h2&gt;&lt;p&gt;Llagas isn&amp;rsquo;t a project I&amp;rsquo;d show in a job interview, and I don&amp;rsquo;t want to. It&amp;rsquo;s a small tool that solves a small problem, and I made it in five minutes.&lt;/p&gt;&#10;&lt;p&gt;If I take one thing away from this, it&amp;rsquo;s that vibecoding doesn&amp;rsquo;t have to be a label for &amp;ldquo;my code is bad&amp;rdquo; or a flag for &amp;ldquo;you no longer need to know how to program&amp;rdquo;. It&amp;rsquo;s one more tool, and what matters is choosing well where to use it. For the things I care about, I&amp;rsquo;ll keep going slowly and checking everything. For the ones I just want to exist, I let myself go with the flow.&lt;/p&gt;&#10;&lt;p&gt;AI is here to stay, whether we like it or not, so now everyone can use it however they please.&lt;/p&gt;&#10;&lt;p&gt;If you&amp;rsquo;re in the same boat as me and want to run it on your own server, the code is on &lt;a class="link" href="https://github.com/christt105/llagas" target="_blank" rel="noopener"&#10; &gt;GitHub&lt;/a&gt; with instructions. At your own risk though, since I haven&amp;rsquo;t read it either, haha.&lt;/p&gt;&#10;&lt;p&gt;See you in the next post!&lt;/p&gt;&#10;</description></item></channel></rss>