feat: initial commit for campfire logs blog posts and assets

This commit is contained in:
2025-09-12 22:00:22 -05:00
parent 8431627774
commit 29fc76648c
12 changed files with 418 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
---
title: #0 - Setting Up Camp
published: false
date: 2025-08-24 05:00:00 UTC
tags: fullstack,developerjourney,BuildInPublic,introduction
canonical_url: https://campfire.dlseitz.dev/0-setting-up-camp
header:
image: /assets/kemal-berkay-dogan-TcUN5sDZPZ8-unsplash.jpg
attribution: 'Photo by <a href="https://unsplash.com/@kemaldgn?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Kemal Berkay Dogan</a> on <a href="https://unsplash.com/photos/a-campfire-with-a-cup-of-coffee-sitting-in-front-of-it-TcUN5sDZPZ8?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Unsplash</a>'
---
Hey everyone! Welcome to my blog, **_Campfire Logs: The Art of Trial & Error_**. The idea behind this blog is to create a space where I can be completely transparent in my journey as a full-stack developer. We'll dive into the projects I'm building from the ground upfrom websites and backend systems to full-stack applicationsand I'll share the wins, the roadblocks, and, most importantly, the catastrophic moments when I inevitably break something (maybe intentionally, but probably not). I'll discuss the challenges I encounter, the rationale behind my design choices, and the lessons learned along the way.
Let me go ahead and say that blogging is something I havent done since the old days of Xanga and Myspace (Im only 38, calm down now). Having just spent four years writing academic papers, my wording may at times come across as a bit dry and dense, but Im working on it. My journey to becoming a developer has been a bit unconventional, and Im a firm believer in building things the hard way to truly understand how they work. That's why I've taken on the challenge of building a full digital ecosystem from scratch for my brand, [dlseitz.dev](https://dlseitz.dev). From the website to the demo sites, the backend systems and a self-hosted Gitea server, this blog is where I'll log that entire process.
The first full blog post is coming this Wednesday, Aug 27 2025, so be sure to check it out. I will be sharing how the domain-level migration of my Gitea server goes. Im excited to be pulling it into the ecosystem I mentioned above. Fingers crossed that it goes smoothly because I always get super nervous when I start changing up config files. Debugging silly typos in them has caused me so much frustration in the past. Heres to hoping Ive learned from those past mistakes and that this goes off without (much of) a hitch!
Thanks for stopping by!

View File

@@ -0,0 +1,104 @@
---
title: #1 - The Great Gitea Migration
published: false
date: 2025-08-27 20:19:51 UTC
tags: CampfireLogs,SelfHosting,Devops,gitea
canonical_url: https://campfire.dlseitz.dev/1-the-great-gitea-migration
header:
image: /assets/leon-contreras-YndHL7gQIJE-unsplash.jpg
attribution: 'Photo by <a href="https://unsplash.com/@lc_photography?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Leon Contreras</a> on <a href="https://unsplash.com/photos/selective-focus-photography-of-marshmallows-on-fire-pit-YndHL7gQIJE?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Unsplash</a>'
---
Hey everyone! Welcome to my first _full_ blog post for **_Campfire Logs: The Art of Trial & Error_**. My initial post, [#0 - Setting Up Camp: A Backstory](https://hashnode.com/post/cmeqsflzr002h02jrgpsrdcxe), introduced me a little and talked some about my goals and vision for this blog. Ill admit that when I began thinking about the direction I wanted to take this, I was worried that I wouldnt be able to come up with engaging content consistently (and maybe I havent yet).
I quickly realized, though, that topics to write about can and will just fall into your lap very easily and repeatedly. This can be especially true when learning to use different tools and techniques with your existing workflowor if youre like me, you look at something and think, Sure! How hard could it possibly be?
**The Universe to me** : Well Im glad you asked
Fair warning: this post is longer than my usual campfire chats will beits a full story with a few twists. So you may want to grab a coffee (or some marshmallows and a stick), and if youre short on time, Ive included a [TL;DR](#tldr) section just in case. Lets get to it!
## **The First Server of My Very Own**
Around the end of February, 2025, I spent a lot of time exploring the free-tier offerings of [AWS](https://aws.com) and its services ([EC2](https://aws.amazon.com/ec2/), [RDS](https://aws.amazon.com/rds/), [S3](https://aws.amazon.com/s3/), etc.). I still had just under 6 months of school left, but I was applying to tech-job after tech-job anyway because I knew it was (and still is) a long road. At the time, being 37 and still in college, transitioning from the food- and public-service industries into Tech was (and still is) pretty intimidating and overwhelming. So I was trying hard to find something (anything) that might help make me look attractive to potential employers.
At the same time, I was learning to use [Git](https://git-scm.com/) more consistently, and because of my natural tendency to look for alternatives to the mainstream options (yeah, Im rebellious like that), I stumbled upon [Gitea](https://about.gitea.com). For those who arent familiar with Gitea, its an open-source, self-hosted Git service that has a similar feel and functionality to [GitHub](https://github.com/). If youre privacy-conscious or simply just want better control over your projects and codebase, its a great alternative to the more popular Git services available. But I digress
Thinking that a self-hosted Gitea server could be a step toward standing out more and because I was already becoming more familiar with cloud infrastructure, I started [Googling](https://google.com/) and [ChatGPT-ing](https://chatgpt.com/) where to start. It turns out that setting up the server really wasnt all that difficult, but that doesnt mean I was confident building it out.
Long story short, I registered a cheap domain with [Porkbun.com](https://porkbun.com/), installed Gitea on a free-tier EC2 instance, pointed new domains [A Records](https://www.cloudflare.com/learning/dns/dns-records/dns-a-record/) to the IP address I reserved for the server, and set up a [reverse proxy](https://www.cloudflare.com/learning/cdn/glossary/reverse-proxy/) using [NGINX](https://nginx.org/). I wont lieI felt like a million bucks because I accomplished something through my own undertaking that, up until that point, I had only studied about in school.
I played around with it for a couple of weeks, and then, just like you did with that new toy you got for Christmas when you were 10, I didnt touch it again for months.
## **The Ecosystem**
Fast-forward to the near-present, and with my bachelors degree finally in hand (exactly twenty years after high school), all I have to show for a nine-month-long job search is an inbox full of rejection emails. Got it. A degree isnt enough to get a job anymore. Thats not really how they market this at universities these days, but something will come along. No rush, right?
Well, not exactly. You see, I cant just sit still. I have to keep moving, to keep doing, to keep building something I decided that I needed to build my own experience toyou guessed ittry and make myself more attractive to potential employers AND _potential clients_. How, you ask?
Well Im glad you asked
Being the resourceful person that I amor being a MacGyver of my generation, ratherI can be pretty good at doing the most while having very little to work with. So what did I have to work with? A laptop with [VS Code](https://code.visualstudio.com/), an internet connection, and a free domain through [Name.com](https://name.com)s partnership with [GitHub Educations Student Developer Pack](https://education.github.com/pack) Id find a way to make it work. Why not pull my long-forgotten Gitea server out of the back of the closet too? The [EC2](https://aws.amazon.com/ec2/) instance was still running, and I still had that domain for a few months longer. This was shaping up better than I thought already!
Cue the registration of [dlseitz.dev](https://dlseitz.dev), a sort of live portfolio that I could expand on as I go. What better way to show I can build something with modern tools and the skills I just spent four years developing, right? It didnt take long, though, before I realized just a website wasnt going to be enough.
Over the next few weeks, I decided to explore what a static site generator (SSG), particularly [11ty](https://www.11ty.dev), could do to improve my website coding. From there, I decided I needed a backend application built on [Node.js](https://nodejs.org/) with [Express](https://expressjs.com/) to securely process the contact form on the site, store it in a [PostgreSQL](https://www.postgresql.org) database, and email me the users inquiry. I also needed to come up with a way to present live demo sites, each being designed with specific business needs in mind, in a way that wouldnt complicate the website itself. Hosting them as subdomains of my site was my answer. From there, I wanted a way to share my experiences with others (my work is only possible by building from the work others put in first), but I want the solution to be my own (Im really into self-hosting if you cant tell by now). With that still being in the planning and discovery phase, I also wanted to be able to chronicle the journey of building it as I went (thanks [Hashnode](https://hashnode.com)!).
So clearly, in the natural progression of things, and with my Gitea servers domain expiring in a few short months, I decided this was the perfect time for pulling the server into the ecosystem by migrating it to its own dlseitz.dev subdomain.
Now, with all of this going on, you may be wondering if Im only saying things at this point just to say them, but Im not. I guess Ive finally started to lean into a passion for developing (we already established that Im a late bloomer). Right now, at this point at least, I _dont_ feel like Ive bitten off more than I can chew, but dont we all feel that way right before we _really_ get going on a project?
## **Domain-Level Migration Sounds kind of scary, huh?**
### **What a Domain-Level Migration Really Means**
So what exactly is a domain-level migration? Its a pretty broad term, but simply put, its moving something like a website, a web app, or even an entire Active Directory from one domain to another. This can range in scope from physically migrating from one infrastructure to another to simply changing which domains DNS records point to a particular server where a website or web app is hosted, and of course, everything in between.
### **Planning the Changes**
When performing a migration of any kind, you should always start by writing (or typing, if you prefer) a well-informed, step-by-step action plan, including contingencies for any points of failure that you can identify. Having a Plan C or D can often be just as important as Plan A is. I cant stress that enough. For my migration, I had a few options to consider, and to be honest, Im not really sure if Im happy with the route I chose, at least as a long-term solution. That doesnt mean I chose the wrong option, but it can end up affecting my other projects down the road.
### **Choosing My Migration Path**
Given my remaining time on [AWS](https://aws.com)'s fairly generous 12-month free tier, I had no immediate need to decide on a long-term home for my Gitea server. This was the main reason I opted for a simple, in-place migration, focusing on changing the domain and internal configurations. I also prefer having my ecosystem spread across multiple cloud providers to avoid vendor lock-in, as I use a [DigitalOcean](https://www.digitalocean.com) droplet (similar to an AWS EC2 instance) for the server hosting my web app . For my use case, the networking overhead is negligible, and a distributed setup helps keep me in a "separation of concerns" mindset. I believe maintaining this mindset at a more abstract level influences how I approach developing solutions as a whole, so I figure why not give it the best shot possible. I know this might sound silly to some, but I'd rather not get stuck with all my eggs in one basket.
With a simple plan for this migration (an in-place transition) now in place I was ready to get started.
### **Step One: Update DNS Records**
First, I had to update the DNS records for the new subdomain. Normally I would have done this through my domain registrar (Name.com for this particular domain), but I had just swapped to letting [Cloudflare](https://www.cloudflare.com/) manage my DNS for the domain and subdomains because they will automatically renew your [SSL](https://aws.amazon.com/what-is/ssl-certificate/) certificates from [Lets Encrypt](https://letsencrypt.org/) every 90 days. Once I configured the new A Record (DNS) to point my subdomain to the static IP address of my EC2 instance, it didnt take long to propagate. I wont lie--I was a little sad to have to say goodbye to the old domain. It was a bittersweet moment (Im not crying youre crying).
### **Step Two: Hunting Down Config Files**
My next step was to stop the Gitea process running on the server, and then get ready to make some edits to some config files. It was about now that I remembered I never got around to documenting where I installed everything on my EC2 instance back in February. Of course, me being me, I didn't use their default locations, either, so I had to go on a digital scavenger hunt to find the app.ini and the correct NGINX server block. After a good bit of searching, I finally found them (and documented their whereabouts in my dedicated [Notion](https://www.notion.so/) dashboard: Dereks Dev Infrabase catchy, right?). Now for the nerve-racking part.
I've broken a system or two by messing up a config file, so even something as small as a single out-of-place comma or semicolon can cause a total catastrophe. With that in mind, I quite anxiously tiptoed through the configuration files, changing only the settings necessary so that Gitea would recognize its new home. To my dismay, this part actually went off without a hitch. You can imagine the relief.
### **Step Three: SSL Certificate Troubles**
The real test came when I tried to download and install my Lets Encrypt [wildcard SSL certificate](https://www.digicert.com/faq/public-trust-and-certificates/what-is-a-wildcard-certificate) to secure the new [gitea.dlseitz.dev](http://gitea.dlseitz.dev) subdomain. The dominoes started to fall immediately. First, trying to install [Certbot](https://certbot.eff.org/) and the [certbot-dns-cloudflare plugin](https://certbot-dns-cloudflare.readthedocs.io/) resulted in a Python versioning issue. I had to install [pip3](https://pypi.org/project/pip/) on its own because it didnt install with Python. But even after that, getting the plugin to work was like trying to drop a toddler off at daycareSO MANY DEPENDENCY ISSUES.
To resolve this, I had to install [snapd](https://snapcraft.io/docs/installing-snapd), a separate package manager for Linux, to correctly install the plugin. Once all of that was done, I realized the config file with my Cloudflare API token had a small syntax error that was keeping Certbot from obtaining my SSL/TLS certificate. When I realized what the issue was, it was an easy thing to fix.
### **Final Hiccup: SSH Blocked by Cloudflare**
With the certificate installed and the Gitea process restarted, I was very happy that the updated domain directed as expected. I wasnt quite finished yet, though. I tried to push test commits from my local repos to the remote server, but it wouldn't work. I kept getting a rather nerve-racking error that used alarming terms like Fatal, access rights, and make sure the repository exists. After a few failed attempts and a good bit of head scratching and grounding exercises (therapy finally came in handy), I finally asked [Gemini](https://gemini.google.com/) (Googles generative AI model), explaining what I had just done with the server. It quickly told me the likely reason I couldnt push was because I was doing so using [SSH](https://www.cloudflare.com/learning/access-management/what-is-ssh/), and that Cloudflare blocks SSH connections on port 22 on all proxied subdomains for security reasons.
The solution was literally as simple as flipping a switch. I just had to turn off Cloudflare's proxy for my Gitea subdomain. And with two clicks, it was done.
### **Made It Out Alive**
All in all, the migration really wasnt that problematic. A few frustrating hiccups happened, but a good rule of thumb is to always expect that something will stray from even the most well-laid out plan.
**_The end._**
## TL;DR
I migrated my old self-hosted Gitea server onto my [dlseitz.dev](http://dlseitz.dev) subdomain. DNS went smooth, configs werent too scary, SSL certs gave me grief, and Cloudflare blocked my SSH until I flipped a switch. Lessons learned: always document installs, expect dependency hell, and dont panic when you see fatal in error logs.
## **Before You Go**
I want to say thanks again to everyone for reading this. I appreciate you sticking around for this campfire story. I know it is a little on the hefty side, but I really hope it wasnt too much of a snooze-fest to you.
I encourage you to tell me what you thought about the article (what worked for you, what didnt) in the comments. Or perhaps you have some suggestions on how I could have handled the migration betterlet me know that, too. Im always looking to learn and improve.
Also, be sure to check back soon for the next installment. I will be talking about how easy it can be to overlook a needed component of a project, what that can mean down the road, and you can bet that I have a story to go along with it!

View File

@@ -0,0 +1,76 @@
---
title: #2 - Retrofitting the Privacy Policy
published: false
date: 2025-09-02 20:41:21 UTC
tags: WebDevelopment,FullStackDevelopment,Nodejs,DevLife
canonical_url: https://campfire.dlseitz.dev/2-retrofitting-the-privacy-policy
header:
image: /assets/2-privacy-policy-head-img.png
attribution: 'Image generated with Sora. | © 2025 Derek L. Seitz'
---
Hey there everyone! Welcome to **_Campfire Logs: The Art of Trial & Error._** In my last log, "[#1 - The Great Gitea Migration](https://hashnode.com/post/cmeuf5cdo000o02l8cem786pt), I introduced you to my self-hosted [Gitea](https://about.gitea.com/) and shared the nerves, hiccups, and (eventual) success of migrating it into my [dlseitz.dev](https://dlseitz.dev) ecosystem.
Today I want to tell you about a recent blunder of mine (you guessed it, a forgotten privacy policy), and my experience trying to retrofit a solution into my existing codebase (ever tried adding a new field to your form JSON after youve already wired everything up? Yeah). Ill also talk a little bit about my philosophy on mistakes like this and explore ways to help prevent them in the future (spoiler alert: theres no absolutely foolproof way).
Let me say real quick that this log will not be as lengthy as my last, but you can still grab a coffee or some marshmallows and a stick as we get started. Theres also a **_TL;DR_** section at the bottom of the page for anyone in a hurry.
Lets get to it!
## **How Did I Miss That?**
Its true. I forgot to add a privacy policy to my website before it went live. And while that may be a very small thing to overlook in the grand scheme of thingsespecially for a solo developerbeing transparent with how you handle clients information can really help to build trust.
Now, its pretty safe to say that the vast majority of us are guilty of clicking the little checkbox saying we agree to the privacy policy and terms & conditions _without actually reading over them_. There are even studies published that back this up. In 2019, [Pew Research Center found that only about 1 in 5 Americans](https://www.pewresearch.org/internet/2019/11/15/americans-and-privacy-concerned-confused-and-feeling-lack-of-control-over-their-personal-information/?utm_source=chatgpt.com#:~:text=How%20Americans%20handle%20privacy%20policies%3A) actually read privacy policies before agreeing to them, and most of those said they dont really understand the laws surrounding them. Ill let you dive into all of that on your own, but the takeaway here is pretty clear: most people simply dont engage with privacy policies. Not in any meaningful way, at least.
So why did it matter _to me?_ Why was I a little shocked that I didnt think about it sooner?
Because integrity matters, and two of my core values are centered around **_transparency_** and **_privacy_**. Now, Im not saying Im perfect or better than anyone (far from it). What I am saying is that I make genuine effort to stay true to the things I value most, making sure the effort is clear through my work.
[So, I decided to add a privacy policy.](https://dlseitz.dev/privacy-policy/)
## **The Developers Burden**
This is where the actual fun started: coding the retrofit. No, reallyit was fun (at first). The goal was to ensure that a user consented to my websites privacy policy before they could submit their info using the contact form. However, I really dont know why I was so dead set on a checkbox being the mechanism for it. I guess my subconscious knew it was the hard way since there are _much_ simpler ways to accomplish this.
When I wrote out my course of action, I started with the front end, then the backend app, and finally the database, so this was the order I worked in. In hindsight, I think that the reversed order would have saved me a bunch of headache in the long run (sort of like stringing lights on a Christmas tree). I dont think that I did it in the _wrong_ order, just in an order that introduced more opportunity for bugs.
The front end part of this endeavor went pretty smoothly. I started by creating a new [Nunjucks](https://mozilla.github.io/nunjucks/) template for the privacy policy webpage (I use the [static site generator (SSG)](https://www.cloudflare.com/learning/performance/static-site-generator/) [11ty (Eleventy)](https://11ty.dev) to build out my site). Next, I created a new stylesheet for the page-specific CSS rules. As weird as this may sound, having separate stylesheets for different concerns does it for the neat freak inside of meI completely lit up with joy when I first realized that was even a thing (that part seemed to have been left out in school). Then, the last thing before moving on to the JavaScript was to add the policy page to my footer nav links.
So far, so good.
### Where Things Start Getting Slippery
Now, my backend application isnt really all that complicated. Its a simple [Front Controller](https://www.geeksforgeeks.org/system-design/front-controller-design-pattern/) with [Chain of Responsibility](https://medium.com/@artemkhrenov/the-chain-of-responsibility-pattern-in-javascript-building-elegant-request-handlers-b9a72a16d7cc) [design pattern](https://sourcemaking.com/design_patterns) written on [Node.js](https://nodejs.org) with [Express](https://expressjs.com). It consists of the main app that receives the forms [JSON payload](https://www.ibm.com/docs/en/baw/24.0.x?topic=protocol-common-json-payload-cases-case-types#:~:text=The%20workflow%20REST%20protocol%20defines,following%20workflow%20REST%20protocol%20resources:) through a [POST request](https://www.w3schools.com/tags/ref_httpmethods.asp) to its [API](https://www.ibm.com/think/topics/api), then three modules that handle the rest. The [router module](https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Server-side/Express_Nodejs/routes) transports the payload through the appropriate logic, the [middleware module](https://www.w3schools.com/nodejs/nodejs_middleware.asp) runs security checks (spam, bots, etc.), and the [controller module](https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Server-side/Express_Nodejs/routes) formats and stores it in my [PostgreSQL](https://www.postgresql.org/) database before emailing it to me. The backend work for the retrofit was only to make sure the router expected the added checkbox [Boolean](https://developer.mozilla.org/en-US/docs/Glossary/Boolean) in the payload, the controller knew where to insert it and a timestamp into the database, and the database had a place for the new data to go.
Simple.
After wiring everything upthe HTML, CSS, vanilla JS, database fields, router, and controllerI figured my form was ready to test. But thats when the headaches started. Submitting dummy info kept throwing me into a loop where I couldnt tell if the culprit was the checkboxs [`required` attribute](https://developer.mozilla.org/en-US/docs/Web/CSS/:required) or my custom JS validation. Alright, let me just crack my knuckles and pop my neck Ive got this.
Even after a hard refresh ( **Ctrl+Shift+R** ) finally cleared the caching issues, I was immediately hit with a new problem: [_500 Internal Server Error_](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/500). But hey, at least now my form payload was making it to the server progress nonetheless! [PM2](https://pm2.keymetrics.io/) logs insisted my timestamp column didnt exist in the table (even though it did). I tore through my controller logic and even rebuilt the table from scratch (thinking it may be a lower-level bug way above my pay grade), but nothing changed. Frustrated, I gave up for the night. It was late, and I clearly didnt have this, at least not yet.
### A Hard Refresh Makes Things Click
The next day, after a hard refresh of my own, I decided to sidestep the checkbox entirely by replacing it with a consent by affirmative action clause above the submit buttonshort, sweet, and to the point. I thought for sure this solved everythingbut nope. I think sleeping on the problem was the real hero here, because when I looked over the controller logic again, the issue was embarrassingly obvious: I had set the column type in the database table to `timestamp`, but was also trying to manually insert a timestamp value via [`NOW()`](https://www.postgresql.org/docs/current/functions-datetime.html) in the controller. Since the database automatically assigns a timestamp when a new record is created, my insert kept failing. Simply letting the database do database things made all the difference in the world.
At this point, though, the checkbox was already long gone. And honestly, I wasnt even slightly upset about it. It meant one less hurdle for potential clients trying to reach out and one less datapoint to validate and store. Sometimes, simplicity really is the best policy.
## Forgive Your Mistakes: Do Better Next Time
Heres the thing about mistakes: theyre not signs you dont belong theyre signs youre doing the work. Every overlooked field, every broken query, every duh moment is just part of the feedback loop. For me, integrity means owning those errors instead of hiding them, and transparency means being willing to talk about them openly (even in public, like this log). [Imposter syndrome](https://www.psychologytoday.com/us/basics/imposter-syndrome) loves to whisper that youll be found out as a fraud and that making mistakes proves youre not cut out for this. In reality, though, mistakes are how you learn and get better. As long as we keep building, keep refining, and keep letting our values guide the process, the mistakes stop being failures and start being steppingstones.
If theres one thing Ill do differently next time, its slowing down before I overcomplicate the solution. A quick sanity check am I letting the database do its thing, or fighting it?could have saved hours. And honestly, just walking away for the night did more for debugging than any frantic console.log ever could. No process will ever be perfect, but building in those pauses makes the next mistake easier to catch.
## TL;DR
I launched my site without a privacy policyoops. While most people dont read them, transparency and privacy are core values of mine, so I had to fix it.
The retrofit was a mix of fun and frustration: I wired up the front end, backend, and database, only to hit errors caused by my own overengineering (checkbox validation, manual timestamp insertion, etc.). After some trial, error, and sleep, I realized simpler was betterso I dropped the checkbox and used a clear consent clause instead and let my database do what databases do: _database_.
Lesson learned: mistakes happen, especially when building solo. What matters is staying true to your values, keeping the process transparent, and refining along the way.
## Before You Go
Thanks to everyone for reading! I appreciate you taking the time to learn about my developer experiences. I encourage you all to tell me what you thought about the article (what worked for you, what didnt) in the comments. Or perhaps you have a similar story you may want to share. One persons trip-up is another persons what not to do.
Be sure to check back soon for installment #3 of Campfire Logs: The Art of Trial & Error, where I will be taking a step back from the technical aspects of developing. Weve talked about retrofitting the technical aspects of the privacy policy, but I want to shift gears to discuss how I created my websites privacy policy and the data privacy concerns that came along with it.

View File

@@ -0,0 +1,77 @@
---
title: #3 - Data Privacy: Things to Consider
published: false
date: 2025-09-03 03:49:36 UTC
tags: dataprivacy,WebDevelopment,Freelancing,PrivacyPolicy
canonical_url: https://campfire.dlseitz.dev/3-data-privacy-things-to-consider
header:
image: /assets/toa-heftiba-x9I-6yoXrXE-unsplash.jpg
attribution: 'Photo by <a href="https://unsplash.com/@heftiba?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Toa Heftiba</a> on <a href="https://unsplash.com/photos/group-of-people-sitting-on-front-firepit-x9I-6yoXrXE?utm_content=creditCopyText&utm_medium=referral&utm_source=unsplash">Unsplash</a>'
---
Hey everyone! Welcome back to [_Campfire Logs: The Art of Trial & Error_](https://campfire.dlseitz.dev). In my last log, [_#2 - Retrofitting the Privacy Policy_](https://hashnode.com/post/cmf30k3cb000102i2civabgh3)_,_ I discussed forgetting to add a privacy policy to my website before it went live, why it was important to me as a solo developer to retrofit it into my contact form, and the issues I ran into during the process. Today, however, I want to shift gears away from the technical issues and dig a little deeper into how I drafted my websites privacy policy and what shaped my approach.
## **Data Privacy and Why Its Important**
Now, somebody is probably thinking, But Derek, youre just starting out as a freelance developer. You arent likely to have many clients for a privacy policy to really matter, and theyd be right (for now). Regardless, Ive found that forming good habits early on (when things are slow) can save you from a whole lot of headaches later on. This is no different when it comes to data privacy.
The term [_Data Privacy Law_](https://www.osano.com/articles/data-privacy-laws) refers to any legislation that mandates how a business or organization is allowed to collect, use, or store information on the consumers that use their services, as well as the rights consumers have to hold some control over that data. These types of laws are very common, especially in developed countries, but something very important to be aware of is how greatly data privacy laws can vary between jurisdictions. This is true not only from country to country, but even state to state.
In the U.S., for example, while there are some federal and sector-specific laws (like [HIPAA](https://www.hhs.gov/hipaa/index.html) or [COPPA](https://www.ftc.gov/legal-library/browse/rules/childrens-online-privacy-protection-rule-coppa)), the majority of data privacy laws are decided at the state level. This is why Californias data privacy laws, the [California Consumer Privacy Act](https://oag.ca.gov/privacy/ccpa) (CCPA) and the [California Privacy Rights Act](https://thecpra.org/) (CPRA), are the strictest consumer protection laws in the country, whereas states like [Arkansas](https://arkansasag.gov/divisions/public-protection/identity/security-or-data-breach/) and [Mississippi](https://securiti.ai/privacy-laws/us/mississippi/) barely have data privacy laws at all (comparatively).
By contrast, things abroad look very different. The European Unions [General Data Protection Regulation](https://gdpr-info.eu/) (GDPR) is (at the time this article was published) the most restrictive set of data privacy laws in the world, with harshest penalties for violations. Additionally, GDPR isnt solely bound within the EU, but essentially extends to any organization in any country that conducts business with any resident of the EU.
Even though data privacy laws often target larger organizations, that doesnt mean smaller businesses or solo developers like me get a free pass. Data privacy applies to everyone handling personal information, and overlooking it (even unintentionally) can create significant legal risks, impact client perception, and erode trust. Bigger organizations and enterprises often have compliance officers and legal teams to make sure these dont happen, but thats not the case for the little guys. So how did I choose to tackle this endeavor on my own?
I thought youd never ask!
## **Your Options as a Solo Dev**
Because I sometimes focus so intensely on getting things right that I end up getting in my own wayespecially when it involves something that means a lot to methis process wasnt as straightforward as I would have preferred. Thats not to say it was difficult, but there was a lot to be seriously considered. Protecting yourself and those you offer services to legally isnt something to be taken lightly.
This was my process.
### **Hire a Pro or DIY?**
Let me say first and foremost that I am not a lawyer, and I cannot give you legal advice. Because data privacy laws can vary considerably depending on location, the safest bet is to have a lawyer or attorney (those terms arent mutually inclusive necessarily) draft or help you draft legal documents that can hold up in court. What I can do, however, is suggest how you might find guidance to make an informed decision for your own use case.
For some, hiring a professional to draft their privacy policy simply isnt an option. The good news is there are alternatives to consider. Online privacy policy generators, like [Termly](https://termly.io) and [FreePrivacyPolicy.com](https://freeprivacypolicy.com), can be used to create generic policies, but its still a good idea to use them cautiously. The policies they generate are very cookie-cutter, meaning they are designed to be used by many users and many use cases. In the real world, however, one size does not fit all when it comes to legal documents, so I recommend learning as much about them as you can before committing (still not an option for everyone).
### **My DIY Approach**
My approach to creating a policy tailored to my specific business needs and values wasnt terribly complicated. I started by generating a policy with both Termly and FreePrivacyPolicy.com, but when I compared them, I was surprised by the differences. FreePrivacyPolicy.coms document covered a wide range of cases, but in a very broad manner (again, cookie-cutter). Termly, on the other hand, was much more detailed, but it included a lot of clauses that didnt apply to my needs. For me, neither of these would do, but now I had a great jumping-off point.
To write my own, I used clear and approachable language, first focusing on explaining five key points:
- **What** - What exact PII my contact form collects (name, organization, email, phone, etc.)
- **Why** - Why that information is collected (as a means to respond to inquiries of potential clients)
- **How** - How the users PII is collected (through voluntary submission via the contact form) and how that information would be used (specific ways I would use their PII for providing my services)
- **How Long** - How long that information will be retained in my database (no longer than 1 year or otherwise required by law)
- **Where** - Where I can be contacted for change or deletion requests by the person to whom the PII pertains
For added transparency, I also added what information I do not collect and addressed common points of concern (cookies, tracking, selling data, etc.). I also provided a high-level description of how I protect collected PII and touched on consumer rights to requesting the correction or deletion of their data and their right to an appeal and an explanation if those requests are rejected.
You can check out my websites policy [here](https://dlseitz.dev/privacy-policy).
To put it frankly, my goal wasnt just to protect myself legally. I also set out to put potential clients minds to rest about whether their information would be handled responsibly and with respect.
## TL;DR
In short, data privacy is something to be taken seriously. While most data privacy laws are geared toward larger businesses and organizations, responsibly handling collected consumer informationand being transparent about how that data is usedapplies to even a solo dev.
If youre considering a privacy policy for your own use case, you have options. Whether you decide to hire a professional, use an online policy generator, or draft it yourself, its important to understand which option best fits your particular situation, knowing that what may work best for one scenario may not be appropriate for all others. Your safest bet will almost always be to seek the advice of a lawyer or attorney. If you choose otherwise, do your research, make well-informed decisions, and dont make assumptions.
My approach was to draft my own policy tailored to the needs of my specific use case. While doing so, I focused on transparency and honesty to ensure any users of my website and contact form feel safe and respected.
## Before You Go
As always, thank you so much for checking out this Campfire Log! I look forward to hearing your thoughts on what is discussed here, as well as answering any questions you may have. Feel free to leave a comment and help expand the conversation. Perhaps you have a similar experience to share.
Looking ahead to #4, Ill be getting back into the more technical side of things by discussing refactoring to promote modularity and scaling. Be sure to come back and check it out.
]]>

View File

@@ -0,0 +1,108 @@
---
title: #4 - Refactoring A False Sense of Simplicity
published: false
date: 2025-09-12 01:08:54 UTC
tags: refactoring,WebDevelopment,FrontendDevelopment,CSS
canonical_url: https://campfire.dlseitz.dev/4-refactoring-a-false-sense-of-simplicity
header:
image: '/assets/20250911_2016_Coding by Campfire_simple_compose_01k4xqta8sfjyrws9ezcwjpg9x.png'
attribution: 'Image generated with Sora. | © 2025 Derek L. Seitz'
---
Hey everyone! Welcome back to [_Campfire Logs: The Art of Trial & Error_](https://campfire.dlseitz.dev). In my last log, [**_#3 - Data Privacy: Things to Consider_**](https://hashnode.com/post/cmf3futzv000102l4hgh339fv) **_,_** I walked you through how I developed the privacy policy for my website and discussed some of the considerations that developers should make when handling client data. Today, I want to get back to the technical side of things by discussing the [refactor](https://daedtech.com/refactoring-development-technique-not-project/#:~:text=Code%20refactoring%20is%20the%20process%20of%20restructuring%20existing%20computer%20code%20%E2%80%93%20changing%20the%20factoring%20%E2%80%93%20without%20changing%20its%20external%20behavior.), or restructuring of existing code, I recently did on a demo website, including the things I learned along the way.
## The Original Demo
About a year ago, I designed and built a demo [static](https://kinsta.com/knowledgebase/what-is-a-static-website/) eCommerce website for a web development course in college. The requirements werent anything crazy:
- choose a scenario from the provided list
- create four distinct HTML pages
- use a single, external CSS stylesheet
- use JavaScript to create a couple of modals, a shopping cart, and a contact form
Easy enough.
But with this having been my first web site, and not really having anybody to tell me when to put on the brakes with the creativity (it was an online course), it was the perfect way to trigger a bipolar manic episode. Some may say I went a tad overboard on the project (hence the little menty b or two that came along with it), and I wouldnt disagree with them.
While this project, in part, [acted as a catalyst for me to resume seeing my therapist](https://www.techuk.org/resource/addressing-mental-health-in-the-tech-industry.html), I have to give it props for firing up my interest in web development (sounds contradictory, but its true). When I came out on the other side of it, I finally realized Hey! I can actually do this!
So what exactly was the problem with the demo?
## The Problem
The problem with the demo was this: due to the curriculum requirements for the project, along with the fact that it was meant to be an intro-level website, the focus on best practices was more about basic fundamentals than that of the full development lifecycle. [Maintainability, scalability, and the potential for future enhancements](https://www.einfochips.com/blog/importance-of-adopting-best-practices-for-scalable-and-maintainable-systems/) werent considerations during the build. In other words, my codebase became a [tightly-coupled](https://cleancommit.io/blog/whats-the-difference-between-tight-and-loose-coupling/), [monolithic](https://www.ibm.com/think/topics/monolithic-architecture#:~:text=Monolithic%20architecture%20is%20a%20traditional%20software%20development%20model%20in%20which%20a%20single%20codebase%20executes%20multiple%20business%20functions.) behemoth that wasnt easy to read or work with, no matter how well-commented it was. I didnt understand it enough at the time, but just like with backend development, having a [loosely-coupled](https://cleancommit.io/blog/whats-the-difference-between-tight-and-loose-coupling/), [modular](https://www.institutedata.com/us/blog/modularity-in-software-engineering/#:~:text=Modularity%20in%20software%20engineering%20refers%20to%20the%20design%20approach%20that%20emphasizes%20the%20separation%20of%20concerns%2C%20where%20a%20complex%20software%20system%20is%20divided%20into%20smaller%2C%20loosely%20coupled%20modules.) front end should always be the goal.
On top of that, I tried my best to take an accessibility-first approach. At the time, I understood the importance of semantic HTML, but I didnt quite grasp that [ARIA attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) were meant for filling in gaps for [assistive technology (AT)](https://www.atia.org/home/at-resources/what-is-at/) like screen-readers _when using HTML tags without inherent semantic meaning._ This led me to over-apply attributes such as ARIA-label and ARIA-labelledby, which really cluttered up my code. But hey, A for effort, right? Ill talk about this more a little later.
Now, it really isnt uncommon for either of these to be overlooked in foundational academic settings. After all, the focus is often on making the code work more so than perfect execution. But that isnt quite the case for professional-grade work (what Im aiming for). So a few weeks ago, I decided what better way to continue practicing professional development standards than to refactor this demo. I may have slightly underestimated what I had coming
## Challenging the Notion of Simplicity
I used to associate simple programs or simple design with having as few files or components as possible. In my early days of coding (not quite the same thing as developing), I thought that meant if an application was contained to a single file, it meant that it was a single object. While in some ways, this isnt necessarily incorrect, I didnt yet understand how I was looking at it from a very abstracted or zoomed-out point of view.
I learned, however, to think about the design and architecture of software as a system of interconnected parts. Its much like the human body with its many systems (immune, digestive, etc.) all working together to function as a whole. This helped me to better understand development practices like the [separation of concerns (SoC)](https://www.geeksforgeeks.org/software-engineering/separation-of-concerns-soc/) and writing [DRY (Dont Repeat Yourself)](https://www.digitalocean.com/community/tutorials/what-is-dry-development) code.
With these things in mind, I came up with the idea to refactor the demo, because how hard could it possibly be?
### The Monolith-to-Module Challenge
One of the hardest parts about revisiting old code is trying to make sense of what its actually doing. You can do an excellent job of commenting each section of code and still end up spending a good amount of time scratching your head while trying to figure out what it all meansand that isnt necessarily a bad thing.
As I got started on this refactor, I really thought the head-scratching meant that I didnt know as much about web development as I believed I did. However, after finding several snippets of code that could have been better written another way, it didnt take very long for me to realize this wasnt the case. The initial confusion actually signaled I had a deeper understanding and that my approach to development had evolvedvery much a good thing, right? I had to think back to that first-time mentality from a year ago so that I could decipher what I had intended the code to do, then translate that functionality into a cleaner implementation.
Modularizing the HTML files was the easiest part of this whole process, at least for me. As Ive mentioned before in some of the other _Campfire Logs_, I use [11ty (Eleventy)](https://11ty.dev), a [static site generator (SSG)](https://www.cloudflare.com/learning/performance/static-site-generator/), along with the templating language [Nunjucks](https://github.com/mozilla/nunjucks), to write modular, easier to maintain static websites. It was a breeze breaking the HTML into smaller, reusable components to be injected into a base template of boilerplate HTML using Nunjucks conditional logic (for-loops and if-statements written in Nunjucks syntax). Sure, this broke up four HTML files into several other files, but this didnt make the project more complex, just more organized and DRY.
### The Cascading Nature of CSS
As I moved on from the HTML-turned-template files, the next logical step was to break up the incredibly long CSS stylesheet. Now remember, per the course projects requirements, I had to use a single stylesheet for all CSS rules. Because of this, the original `styles.css` file ended up being 1158 lines long. Fortunately, I had grouped rules by the page to which they applied using comments (`/* <comment> */`), and those comments created natural breakpoints when separating the rules into separate stylesheets.
That sounds like it made this part incredibly easy as well, but it wasnt nearly as easy as youd imagine. I didnt do the best job at keeping all style rules within their corresponding sections, so once I linked the page-specific stylesheets into the front matter of the corresponding page template and the global stylesheets (for components like the header and footer) into the base layout template, the styling across several pages broke completely.
Great! Were having so much fun here! But in all actuality, I needed this. Why, you ask? Well lets look at an example of the `<head>` section of an HTML document, and Ill explain:
![](https://cdn.hashnode.com/res/hashnode/image/upload/v1757634763445/499618b7-0af6-422f-bb3e-6793004330e1.png)
In the example here, lets say it is of `contact-page.html`. We can see that the browser will first load `styles.css`, which holds the style rules that are common to every webpage on the site. Then, the browser will load `contact-page.css`, which holds the style rules that are specific only to `contact-page.html`.
The way a browser applies these stylesheets is in the order they are listed, from top to bottom. If both stylesheets contain a style rule for the same element, the rule that is listed last in the document will override the previous one. This is because the latter styles are applied after the former. The browser prioritizes the last rule it reads.
So with the layouts for most pages across the demo breaking, I realized a few things in rapid succession:
1. I did not, in fact, have my style rules as organized as I previously thought
2. Several important base rules must have been overridden somewhere in a later part of the original stylesheet because now they werent being applied as I expected them to be
3. This would require a methodical, page-by-page approach to untangling the mess I had unknowingly created
While this seems like it would be incredibly frustrating, especially after having just broken up my original `styles.css` file into several purpose-specific stylesheets, it gave me the opportunity (yes, opportunity) to systematically improve my usage of semantic HTML, reduce my overuse of accessibility-focused HTML attributes, and leverage the cascading nature of CSS to improve my design rather than trying to work around it.
### Accessibility & Semantic HTML
I think for many, the term accessibility in the context of web design and development is believed to mostly mean contrast ratios and font sizes. Thats how I thought about it, at least, until I was taught about assistive technologies like keyboard navigation, screen-readers, and speech recognition tools (among others). I knew what screen-readers were, having messed around with them on Windows, Apple, and Android devices, and I knew I could tab through objects on a web page or desktop, but I didnt understand how they worked.
Many (but not all) HTML element tags have an inherent meaning recognized by assistive technologies. This is what creates structure and logical groupings that enable these technologies to present information in a useful way to individuals using said tech. For example, screen-readers use semantic HTML tags, like `<section>`, `<form>`, hierarchal headings (`<h1>`, `<h2>`,), and others, to navigate documents and read aloud related content in a way thats more easily understandable for individuals with visual impairments.
For tags such as `<div>` and `<span>`, which have no inherent meaning, thats where you would use [ARIA attributes](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) to give them meaning and a role. But as a rule of thumb, its best to always try and use a semantic HTML tag first and foremost, and only use ARIA as a last resort. This is often referred to as the First Rule of ARIA.
When I built the demo for class, I didnt understand accessibility and semantic HTML enough. This led me to incorrectly use semantic tags and add ARIA attributes to tags that simply didnt need them. For assistive technologies, this can cause a lot of confusion in an HTML documents structure, which can lead to bad UX for those reliant on accessibility features. Having to go over the entire HTML and CSS during the refactor meant a chance to truly make the demo accessibility-focused beyond just contrast ratios and font sizes, which was important to me.
## Looking Back
Modularizing and refactoring the demo website also introduced a few minor bugs in the JavaScript that controlled the interactive components on some of the pages, but that meant I had to make sure event listeners grabbed the corrected HTML elements from the DOM. Because I thought of JS like I did Java (because its a programming language, not the similarity in their names), separating concerns into different scripts was a little more instinctual for me and was done in the original project, saving me a bit of work.
While I thought going into the refactor it would be as simple as copying/pasting code into a more modular file structure, Im really glad that I was wrong. Not only did the refactor give me the chance to go back and visit an old project (the nostalgia was real), it really boosted my self-confidence to see where I was a year ago in my development journey versus where I am now. We often dont realize just how much we grow and evolve over a period of time because we get trapped thinking about whats in front of us. As somebody that often questions his own levels of understanding, a project like refactoring an old codebase is a great way to squash feelings of inadequacy and self-doubt. Im really glad I did it.
## TL;DR
I built an intro-level website for a college course a year ago that became a tightly-coupled, monolithic behemoth. Deciding to refactor it to a more professional standard, I learned that while modularizing the HTML was a breeze, breaking up the single, 1,158-line CSS file was much harder. This "mess" provided an opportunity to go back and fix my overuse of ARIA attributes and improve the site's overall accessibility and semantics. Ultimately, the refactor was a major confidence-booster, reminding me of the growth I've made as a developer over the past year.
## Before You Go
As always, thank you so much for checking out this _Campfire Log_! Be sure to comment with your own experiences. Maybe you had a similar one to mine, or maybe yours was way different. Id love to hear about the challenges you ran into and how you got around them.
The refactored demo is now live. You can check it and its source code out by visiting [https://dlseitz.dev/demos/](https://dlseitz.dev/demos/) and clicking the corresponding button. I recommend doing so using a desktop browser simply because the demo isnt currently mobile-friendly. Making it [responsive for smaller screens](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/CSS_layout/Responsive_Design), as well as improving the custom alerts and shopping cart feature, is next on my list of things, however. Additional dynamic features have also been added, such as an interactive events page and a dedicated page to attributions for the royalty-free media I used, so you may be interested in seeing how some of those work.
Looking ahead to #5, Ill be talking more about those expanded features. Ill also explore what it meant to separate the presentation, data, and logic layers of the demo and how that enhanced its modularity, dynamism, and interactivity. Be sure to check back soon!