<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: GraceSoft</title>
    <description>The latest articles on DEV Community by GraceSoft (@gracesoftdev).</description>
    <link>https://dev.to/gracesoftdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3861707%2F4bb88ba3-4872-49c8-86bd-016d6ca57ebf.png</url>
      <title>DEV Community: GraceSoft</title>
      <link>https://dev.to/gracesoftdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gracesoftdev"/>
    <language>en</language>
    <item>
      <title>Day 9: File Uploads Are More Dangerous Than I Thought</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Sat, 25 Apr 2026 06:04:51 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-9-file-uploads-are-more-dangerous-than-i-thought-iaf</link>
      <guid>https://dev.to/gracesoftdev/day-9-file-uploads-are-more-dangerous-than-i-thought-iaf</guid>
      <description>&lt;p&gt;I already had an attachments system.&lt;/p&gt;

&lt;p&gt;It worked across all modules.&lt;/p&gt;

&lt;p&gt;Reusable. Clean. Flexible.&lt;/p&gt;




&lt;p&gt;But I hadn’t thought deeply about one thing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Privacy.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ⚠️ The Risk
&lt;/h2&gt;

&lt;p&gt;Files can contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Personal data&lt;/li&gt;
&lt;li&gt;Sensitive documents&lt;/li&gt;
&lt;li&gt;Things that should never be public&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;And if handled badly?&lt;/p&gt;

&lt;p&gt;They become a liability.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔐 What I Changed
&lt;/h2&gt;

&lt;p&gt;I redesigned attachments with privacy in mind:&lt;/p&gt;




&lt;h3&gt;
  
  
  Private by Default
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Files are private unless explicitly made public&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Signed URLs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Temporary access links&lt;/li&gt;
&lt;li&gt;Expire after a set time&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Transparency
&lt;/h3&gt;

&lt;p&gt;Each file shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who uploaded it&lt;/li&gt;
&lt;li&gt;Where it’s used&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 The Insight
&lt;/h2&gt;

&lt;p&gt;Files are not just assets.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;They are data.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;And they need the same level of care.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Bigger Picture
&lt;/h2&gt;

&lt;p&gt;Now my attachments system isn’t just reusable.&lt;/p&gt;

&lt;p&gt;It’s:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Safe by design.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Which means every future module benefits automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Final Thought
&lt;/h2&gt;

&lt;p&gt;At this point, something clicked.&lt;/p&gt;




&lt;p&gt;I’m no longer just building features.&lt;/p&gt;

&lt;p&gt;I’m building:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;defaults that shape behaviour&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>buildinpublic</category>
      <category>laravel</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Day 8: I Built a Timeline to See the Life of Data</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Wed, 22 Apr 2026 04:49:08 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-8-i-built-a-timeline-to-see-the-life-of-data-2n7i</link>
      <guid>https://dev.to/gracesoftdev/day-8-i-built-a-timeline-to-see-the-life-of-data-2n7i</guid>
      <description>&lt;p&gt;Once I added context…&lt;/p&gt;

&lt;p&gt;I still felt something was missing.&lt;/p&gt;




&lt;p&gt;Data wasn’t static.&lt;/p&gt;

&lt;p&gt;It changed over time.&lt;/p&gt;




&lt;p&gt;So I asked:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if I could see the &lt;em&gt;history&lt;/em&gt; of a piece of data?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧵 The Idea
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;Data Timeline&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 What It Shows
&lt;/h2&gt;

&lt;p&gt;For each user:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When data was created&lt;/li&gt;
&lt;li&gt;When it was updated&lt;/li&gt;
&lt;li&gt;Whether it came from Stripe / Postmark&lt;/li&gt;
&lt;li&gt;Who triggered it (admin/system)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤯 Why This Is Powerful
&lt;/h2&gt;

&lt;p&gt;Instead of guessing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What happened here?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can now see:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Here’s exactly what happened.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔍 Debugging Becomes Easier
&lt;/h2&gt;

&lt;p&gt;This also changed how I debug things.&lt;/p&gt;




&lt;p&gt;Instead of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;digging through logs&lt;/li&gt;
&lt;li&gt;checking multiple systems&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I can just:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Look at the timeline.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧠 Unexpected Benefit
&lt;/h2&gt;

&lt;p&gt;This isn’t just a dev feature.&lt;/p&gt;

&lt;p&gt;It’s also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Audit-friendly&lt;/li&gt;
&lt;li&gt;Compliance-friendly&lt;/li&gt;
&lt;li&gt;Support-friendly&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>buildinpublic</category>
      <category>laravel</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Day 7: Showing Data Without Context Is Dangerous</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Tue, 21 Apr 2026 07:34:59 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-7-showing-data-without-context-is-dangerous-gfd</link>
      <guid>https://dev.to/gracesoftdev/day-7-showing-data-without-context-is-dangerous-gfd</guid>
      <description>&lt;p&gt;After masking data, I ran into another problem.&lt;/p&gt;




&lt;p&gt;Even when data is safe…&lt;/p&gt;

&lt;p&gt;It can still be confusing.&lt;/p&gt;




&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;You see a user email.&lt;/p&gt;

&lt;p&gt;But you don’t know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where it came from&lt;/li&gt;
&lt;li&gt;Why it exists&lt;/li&gt;
&lt;li&gt;Whether it’s still needed&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤯 The Problem
&lt;/h2&gt;

&lt;p&gt;Raw data ≠ meaningful data&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 The Fix
&lt;/h2&gt;

&lt;p&gt;I redesigned the user view to include:&lt;/p&gt;




&lt;h3&gt;
  
  
  👤 Data Transparency
&lt;/h3&gt;

&lt;p&gt;Each user now shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What data is stored&lt;/li&gt;
&lt;li&gt;Why it’s stored&lt;/li&gt;
&lt;li&gt;Where it came from&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;(form, webhook, import, etc.)&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Why This Matters
&lt;/h2&gt;

&lt;p&gt;Because transparency builds trust.&lt;/p&gt;




&lt;p&gt;Not just for users.&lt;/p&gt;

&lt;p&gt;But for developers too.&lt;/p&gt;




&lt;p&gt;You don’t want to guess:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why is this field here?”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;You want to know instantly.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚧 Implementation Notes
&lt;/h2&gt;

&lt;p&gt;This reused a lot of what I already built:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Webhook metadata&lt;/li&gt;
&lt;li&gt;Logs&lt;/li&gt;
&lt;li&gt;System tracking&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Which made me realise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Good architecture makes good UI easier.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>buildinpublic</category>
      <category>laravel</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Day 6: The One Toggle That Changed My Entire System</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Mon, 20 Apr 2026 05:04:32 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-6-the-one-toggle-that-changed-my-entire-system-17ob</link>
      <guid>https://dev.to/gracesoftdev/day-6-the-one-toggle-that-changed-my-entire-system-17ob</guid>
      <description>&lt;p&gt;I wanted something simple.&lt;/p&gt;

&lt;p&gt;Not a policy.&lt;br&gt;&lt;br&gt;
Not a config file.&lt;br&gt;&lt;br&gt;
Not a checklist.&lt;/p&gt;




&lt;p&gt;Something visible.&lt;/p&gt;

&lt;p&gt;Something immediate.&lt;/p&gt;




&lt;p&gt;That’s how I landed on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Privacy Mode&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🎛️ What It Does
&lt;/h2&gt;

&lt;p&gt;When Privacy Mode is ON:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Emails are masked → &lt;code&gt;d***@gmail.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Names are masked → &lt;code&gt;D*** L***&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Attachments are blurred or hidden&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔥 The Important Part
&lt;/h2&gt;

&lt;p&gt;It’s not just a feature.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s ON by default in production.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ⚠️ Why Default Matters
&lt;/h2&gt;

&lt;p&gt;Because defaults define behaviour.&lt;/p&gt;




&lt;p&gt;If Privacy Mode was OFF by default:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Devs forget to turn it on&lt;/li&gt;
&lt;li&gt;Data gets exposed&lt;/li&gt;
&lt;li&gt;Problems happen&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;So instead, I made the safe path:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The easiest path.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧠 Design Insight
&lt;/h2&gt;

&lt;p&gt;Good systems don’t rely on memory.&lt;/p&gt;

&lt;p&gt;They rely on &lt;strong&gt;defaults&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚧 Implementation Thought
&lt;/h2&gt;

&lt;p&gt;This wasn’t hard technically.&lt;/p&gt;

&lt;p&gt;But it required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI masking logic&lt;/li&gt;
&lt;li&gt;Conditional rendering&lt;/li&gt;
&lt;li&gt;Environment awareness&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Simple idea.&lt;br&gt;&lt;br&gt;
Big impact.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>laravel</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Day 5: I Almost Over-Engineered Everything</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Fri, 17 Apr 2026 08:47:41 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-5-i-almost-over-engineered-everything-1eo5</link>
      <guid>https://dev.to/gracesoftdev/day-5-i-almost-over-engineered-everything-1eo5</guid>
      <description>&lt;p&gt;At this point, GraceSoft Core was starting to take shape.&lt;/p&gt;

&lt;p&gt;Architecture. Patterns. Principles.&lt;/p&gt;

&lt;p&gt;Everything felt… solid.&lt;/p&gt;




&lt;p&gt;And then I caught myself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I was about to over-engineer the whole thing.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ⚖️ The Tension
&lt;/h2&gt;

&lt;p&gt;There’s always this trade-off:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build it &lt;em&gt;right&lt;/em&gt;
vs&lt;/li&gt;
&lt;li&gt;Build it &lt;em&gt;fast&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;And I’ve been on both extremes before:&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 Too Fast
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hack things together&lt;/li&gt;
&lt;li&gt;Ship quickly&lt;/li&gt;
&lt;li&gt;Pay the price later&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🧱 Too Perfect
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Design everything upfront&lt;/li&gt;
&lt;li&gt;Endless planning&lt;/li&gt;
&lt;li&gt;Nothing actually ships&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤯 The Realisation
&lt;/h2&gt;

&lt;p&gt;GraceSoft Core was at risk of becoming:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A system that’s beautifully designed… but never used.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  💡 What Changed
&lt;/h2&gt;

&lt;p&gt;I asked myself a different question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What’s the smallest version of this that actually works?”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perfect architecture&lt;/li&gt;
&lt;li&gt;Full feature set&lt;/li&gt;
&lt;li&gt;Every edge case covered&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Just:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Something real I can use in my current app.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔑 New Principle
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Build just enough core to remove friction — not all friction.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🚧 What I’m Focusing On Now
&lt;/h2&gt;

&lt;p&gt;Instead of everything, I’m narrowing down to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auth (done properly once)&lt;/li&gt;
&lt;li&gt;Basic integrations (Stripe, email)&lt;/li&gt;
&lt;li&gt;Clean project structure&lt;/li&gt;
&lt;li&gt;Reusable UI foundations&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Everything else?&lt;/p&gt;

&lt;p&gt;Can come later.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Honest Truth
&lt;/h2&gt;

&lt;p&gt;I still feel the urge to overbuild.&lt;/p&gt;

&lt;p&gt;To make it “complete”.&lt;/p&gt;




&lt;p&gt;But I’m learning this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A system becomes real when it’s used — not when it’s finished.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>buildinpublic</category>
      <category>laravel</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Day 4: Why I’m Designing Security First (Not Features)</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Tue, 14 Apr 2026 01:57:25 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-4-why-im-designing-security-first-not-features-oo0</link>
      <guid>https://dev.to/gracesoftdev/day-4-why-im-designing-security-first-not-features-oo0</guid>
      <description>&lt;p&gt;Most projects start with features.&lt;/p&gt;

&lt;p&gt;I’m starting with something else:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Security.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🚨 Why?
&lt;/h2&gt;

&lt;p&gt;Because retrofitting security is painful.&lt;/p&gt;

&lt;p&gt;And I’ve felt that pain already.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔐 What “Security-First” Means Here
&lt;/h2&gt;

&lt;p&gt;For GraceSoft Core, it means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear separation of internal vs public data (ID vs UUID)&lt;/li&gt;
&lt;li&gt;Controlled integrations (Stripe, webhooks)&lt;/li&gt;
&lt;li&gt;Environment-aware configurations&lt;/li&gt;
&lt;li&gt;Safe defaults everywhere&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚖️ Trade-Off
&lt;/h2&gt;

&lt;p&gt;Security-first doesn’t mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Over-engineering&lt;/li&gt;
&lt;li&gt;Slowing everything down&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Making the &lt;em&gt;safe way&lt;/em&gt; the &lt;em&gt;default way&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧠 Design Principle
&lt;/h2&gt;

&lt;p&gt;If a developer has to &lt;em&gt;remember&lt;/em&gt; to be secure…&lt;/p&gt;

&lt;p&gt;The system is already flawed.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚧 Still in Progress
&lt;/h2&gt;

&lt;p&gt;I’m still figuring things out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vector DB support&lt;/li&gt;
&lt;li&gt;API structure boundaries&lt;/li&gt;
&lt;li&gt;Module separation&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;But one thing is clear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Security is not a feature. It’s the foundation.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>buildinpublic</category>
      <category>laravel</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Day 3: I’m Designing a System Without Writing Code (Yet)</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Mon, 13 Apr 2026 03:05:05 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-3-im-designing-a-system-without-writing-code-yet-b45</link>
      <guid>https://dev.to/gracesoftdev/day-3-im-designing-a-system-without-writing-code-yet-b45</guid>
      <description>&lt;p&gt;This might sound strange:&lt;/p&gt;

&lt;p&gt;I’m building a system…&lt;/p&gt;

&lt;p&gt;Without writing any code.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Why?
&lt;/h2&gt;

&lt;p&gt;Because I’ve made this mistake before:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jumping into coding too early&lt;/li&gt;
&lt;li&gt;Locking in bad decisions&lt;/li&gt;
&lt;li&gt;Refactoring everything later&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;So this time, I’m doing something different:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’m designing the system first.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧱 What I’m Defining
&lt;/h2&gt;

&lt;p&gt;Right now, I’m working from a requirements doc that outlines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tech stack decisions&lt;/li&gt;
&lt;li&gt;Architecture rules&lt;/li&gt;
&lt;li&gt;Integration points&lt;/li&gt;
&lt;li&gt;System boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Yes, I’m treating this like a real product 😅)&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Some Core Decisions
&lt;/h2&gt;

&lt;p&gt;Here’s what’s already shaping up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tailwind + Vite as default stack&lt;/li&gt;
&lt;li&gt;Tokenised fonts and brand system&lt;/li&gt;
&lt;li&gt;Structured asset handling (logos, wordmarks, env toggles)&lt;/li&gt;
&lt;li&gt;Stripe + webhook-first integrations&lt;/li&gt;
&lt;li&gt;REST + optional GraphQL&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Everything is being designed to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reusable&lt;/li&gt;
&lt;li&gt;Predictable&lt;/li&gt;
&lt;li&gt;Secure&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔗 Bigger Vision
&lt;/h2&gt;

&lt;p&gt;This isn’t just a boilerplate.&lt;/p&gt;

&lt;p&gt;It’s meant to connect to a bigger system:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GraceSoft HQ&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Where apps can plug into shared services like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auth&lt;/li&gt;
&lt;li&gt;Analytics&lt;/li&gt;
&lt;li&gt;Feedback&lt;/li&gt;
&lt;li&gt;Product data&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 vs ✋
&lt;/h2&gt;

&lt;p&gt;Here’s the reality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My brain is designing systems&lt;/li&gt;
&lt;li&gt;My hands are still fixing bugs in my current app&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And somehow…&lt;/p&gt;

&lt;p&gt;Both are moving forward at the same time.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>laravel</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Day 2: The Patterns I Couldn’t Ignore</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Fri, 10 Apr 2026 09:01:06 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-2-the-patterns-i-couldnt-ignore-1ejc</link>
      <guid>https://dev.to/gracesoftdev/day-2-the-patterns-i-couldnt-ignore-1ejc</guid>
      <description>&lt;p&gt;After my “breaking point”, I started looking more carefully at my projects.&lt;/p&gt;

&lt;p&gt;Not as separate apps — but as systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 What I Noticed
&lt;/h2&gt;

&lt;p&gt;Across both projects, the same patterns kept showing up:&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 Authentication
&lt;/h3&gt;

&lt;p&gt;Every app needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login&lt;/li&gt;
&lt;li&gt;User ownership checks&lt;/li&gt;
&lt;li&gt;Protected routes&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🔗 Integrations
&lt;/h3&gt;

&lt;p&gt;Every app needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stripe&lt;/li&gt;
&lt;li&gt;Email/webhooks&lt;/li&gt;
&lt;li&gt;External services&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🧱 Data Design
&lt;/h3&gt;

&lt;p&gt;I kept defaulting to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Internal IDs for performance&lt;/li&gt;
&lt;li&gt;UUIDs for public exposure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without even thinking about it anymore.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎨 UI Foundations
&lt;/h3&gt;

&lt;p&gt;Every project needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fonts&lt;/li&gt;
&lt;li&gt;Colors&lt;/li&gt;
&lt;li&gt;Layout structure&lt;/li&gt;
&lt;li&gt;Reusable components&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤯 The Real Problem
&lt;/h2&gt;

&lt;p&gt;It wasn’t just repetition.&lt;/p&gt;

&lt;p&gt;It was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Re-deciding the same things over and over again.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  💡 Insight
&lt;/h2&gt;

&lt;p&gt;Good defaults = less mental load.&lt;/p&gt;

&lt;p&gt;And right now?&lt;/p&gt;

&lt;p&gt;I had none.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 A Better Approach
&lt;/h2&gt;

&lt;p&gt;Instead of rebuilding everything:&lt;/p&gt;

&lt;p&gt;What if I had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pre-decided architecture&lt;/li&gt;
&lt;li&gt;Pre-configured integrations&lt;/li&gt;
&lt;li&gt;Pre-built foundations&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;That’s when “GraceSoft Core” started to feel real.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>laravel</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Day 1: I Got Tired of Rebuilding the Same Thing</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Thu, 09 Apr 2026 13:21:37 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-1-i-got-tired-of-rebuilding-the-same-thing-140n</link>
      <guid>https://dev.to/gracesoftdev/day-1-i-got-tired-of-rebuilding-the-same-thing-140n</guid>
      <description>&lt;p&gt;I didn’t start out trying to build a framework.&lt;/p&gt;

&lt;p&gt;I was just trying to fix my app.&lt;/p&gt;




&lt;p&gt;While working on my second project, I kept running into the same issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rewriting setup logic&lt;/li&gt;
&lt;li&gt;Rebuilding authentication&lt;/li&gt;
&lt;li&gt;Reconfiguring environments&lt;/li&gt;
&lt;li&gt;Reconnecting integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then I went back to my first project to fix bugs and improve it so I could actually use it.&lt;/p&gt;

&lt;p&gt;And that’s when it hit me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why do these two projects feel almost identical under the hood?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Even though they serve different purposes, I was rebuilding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Auth&lt;/li&gt;
&lt;li&gt;Webhooks&lt;/li&gt;
&lt;li&gt;Config systems&lt;/li&gt;
&lt;li&gt;UI foundations&lt;/li&gt;
&lt;li&gt;Database patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Again. And again.&lt;/p&gt;




&lt;h2&gt;
  
  
  💥 The Breaking Point
&lt;/h2&gt;

&lt;p&gt;At some point, it stopped feeling like progress.&lt;/p&gt;

&lt;p&gt;It felt like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why am I solving the same problem twice?”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  💡 The Shift
&lt;/h2&gt;

&lt;p&gt;Instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What does this project need?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I started asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What do &lt;em&gt;all my projects&lt;/em&gt; need?”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🚧 What Comes Next
&lt;/h2&gt;

&lt;p&gt;That question led me to something bigger:&lt;/p&gt;

&lt;p&gt;👉 A shared foundation&lt;br&gt;
👉 A reusable system&lt;br&gt;
👉 A core&lt;/p&gt;

&lt;p&gt;I’m calling it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GraceSoft Core&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;No code yet.&lt;br&gt;
Just thinking.&lt;/p&gt;

&lt;p&gt;But this might be the most important part.&lt;/p&gt;

</description>
      <category>buildinpublic</category>
      <category>laravel</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Day 3 — Smoothing Auth, Shipping Email Verification, and Making the UI Feel Real</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Wed, 08 Apr 2026 10:44:28 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-3-smoothing-auth-shipping-email-verification-and-making-the-ui-feel-real-56ik</link>
      <guid>https://dev.to/gracesoftdev/day-3-smoothing-auth-shipping-email-verification-and-making-the-ui-feel-real-56ik</guid>
      <description>&lt;p&gt;After getting the core timeline and billing foundations in place, Day 3 was about tightening the experience — especially around authentication, UI consistency, and the little things that make the product feel &lt;em&gt;alive&lt;/em&gt; instead of stitched together.&lt;/p&gt;

&lt;p&gt;A lot of this day was less about “new features” and more about removing friction.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔐 Fixing Auth Friction (The Invisible Work That Matters Most)
&lt;/h2&gt;

&lt;p&gt;Auth is one of those areas where small issues feel &lt;em&gt;huge&lt;/em&gt; to users.&lt;/p&gt;

&lt;p&gt;Today’s focus:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prevent users from getting stuck on submit buttons&lt;/li&gt;
&lt;li&gt;Avoid registration hanging during email verification&lt;/li&gt;
&lt;li&gt;Ensure protected routes behave properly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key fixes:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Deferred sending verification emails to avoid blocking registration&lt;/li&gt;
&lt;li&gt;Fixed edge cases where submit buttons could get stuck&lt;/li&gt;
&lt;li&gt;Properly gated app shell routes behind login&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result:&lt;br&gt;
Auth now feels &lt;em&gt;instant&lt;/em&gt;, not fragile.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✉️ Email Verification That Actually Feels Designed
&lt;/h2&gt;

&lt;p&gt;Instead of treating email verification as an afterthought, I gave it proper UI attention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updates:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Introduced a &lt;strong&gt;Sky-600 branded email canvas&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Designed a clean outer container for verification emails&lt;/li&gt;
&lt;li&gt;Updated logo usage for consistency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one of those subtle trust builders:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If your emails look polished, your product feels more legitimate.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🎨 UI Standardisation (Design System in Motion)
&lt;/h2&gt;

&lt;p&gt;Things started drifting visually, so I pulled everything back into alignment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improvements:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Standardised &lt;strong&gt;primary CTAs with Sky styling&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Aligned sidebar layout and GitHub connect controls&lt;/li&gt;
&lt;li&gt;Refined UI surfaces across the workspace&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also introduced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A reusable &lt;strong&gt;Lucide icon system&lt;/strong&gt; for notes-style UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result:&lt;br&gt;
The app now feels like a &lt;em&gt;system&lt;/em&gt;, not a collection of pages.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ Timeline &amp;amp; Interaction Upgrades
&lt;/h2&gt;

&lt;p&gt;The timeline is the heart of GraceSoft Story, so I focused on making it faster and more interactive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enhancements:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Added &lt;strong&gt;lazy-loaded fragments&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Introduced &lt;strong&gt;optimistic UI for label interactions&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Implemented &lt;strong&gt;mobile-first filters with preserved query state&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result:&lt;br&gt;
Snappier interactions and better mobile usability.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧱 Refactoring Toward Reusability
&lt;/h2&gt;

&lt;p&gt;Some earlier pages were getting messy, so I started consolidating patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactors:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Converted story pages into a reusable &lt;strong&gt;notes-style shell&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Cleaned up UI state handling across views&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result:&lt;br&gt;
Easier to scale features without duplicating logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Chapter &amp;amp; Dev Workflow Improvements
&lt;/h2&gt;

&lt;p&gt;Not everything is user-facing — some of the biggest wins were internal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additions:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;“Changes” section in the chapter inspector&lt;/li&gt;
&lt;li&gt;Research doc for GitHub sync improvements&lt;/li&gt;
&lt;li&gt;TODO maintenance tracker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Result:&lt;br&gt;
Better visibility into both product &lt;em&gt;and&lt;/em&gt; dev workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Takeaway
&lt;/h2&gt;

&lt;p&gt;Day 3 wasn’t about flashy features.&lt;/p&gt;

&lt;p&gt;It was about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removing friction&lt;/li&gt;
&lt;li&gt;Making interactions feel reliable&lt;/li&gt;
&lt;li&gt;Bringing consistency across the product&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the kind of work users don’t notice explicitly —&lt;br&gt;
but they &lt;em&gt;feel&lt;/em&gt; it immediately.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What’s Next
&lt;/h2&gt;

&lt;p&gt;With auth and UI stabilised, next steps are likely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deepening GitHub sync reliability&lt;/li&gt;
&lt;li&gt;Expanding chapter intelligence&lt;/li&gt;
&lt;li&gt;Continuing to refine the story experience&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>buildinpublic</category>
      <category>webdev</category>
      <category>laravel</category>
      <category>productdesign</category>
    </item>
    <item>
      <title>Day 2 — Wiring Billing Into the Story (and Bringing the UI Back)</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Tue, 07 Apr 2026 11:24:33 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-2-wiring-billing-into-the-story-and-bringing-the-ui-back-17ne</link>
      <guid>https://dev.to/gracesoftdev/day-2-wiring-billing-into-the-story-and-bringing-the-ui-back-17ne</guid>
      <description>&lt;p&gt;Today started deep in the backend… and ended with the UI finally catching up.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;GraceSoft Story started as a way to turn commits into timelines.&lt;/p&gt;

&lt;p&gt;But timelines alone aren’t a product.&lt;/p&gt;

&lt;p&gt;To make this real, I needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;billing&lt;/li&gt;
&lt;li&gt;plans&lt;/li&gt;
&lt;li&gt;feature access control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without turning the codebase into a mess of &lt;code&gt;if (plan === 'pro')&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Plans Shouldn’t Live in Code
&lt;/h2&gt;

&lt;p&gt;First thing I removed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;refactor&lt;span class="o"&gt;(&lt;/span&gt;plans&lt;span class="o"&gt;)&lt;/span&gt;: remove implicit plan seeding
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plans don’t belong in migrations or seeders.&lt;/p&gt;

&lt;p&gt;They belong in &lt;strong&gt;Stripe&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So instead of defining plans internally, I made Stripe the source of truth.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 — Sync Stripe → App
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;feat&lt;span class="o"&gt;(&lt;/span&gt;stripe&lt;span class="o"&gt;)&lt;/span&gt;: store product details when syncing catalog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now products and pricing live locally &lt;em&gt;after sync&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This unlocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fast queries&lt;/li&gt;
&lt;li&gt;feature mapping&lt;/li&gt;
&lt;li&gt;no runtime dependency on Stripe API&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 3 — Subscription Modeling
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;feat&lt;span class="o"&gt;(&lt;/span&gt;billing&lt;span class="o"&gt;)&lt;/span&gt;: integrate account-plan-subscription schemas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I avoided the typical shortcut (&lt;code&gt;user.plan&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;accounts&lt;/li&gt;
&lt;li&gt;plans&lt;/li&gt;
&lt;li&gt;subscriptions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps things flexible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;teams&lt;/li&gt;
&lt;li&gt;shared billing&lt;/li&gt;
&lt;li&gt;multiple repos per account&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 4 — The Stripe Mapping Problem
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fix&lt;span class="o"&gt;(&lt;/span&gt;stripe&lt;span class="o"&gt;)&lt;/span&gt;: persist subscriptions using metadata tier mapping
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stripe doesn’t know your app’s logic.&lt;/p&gt;

&lt;p&gt;So I used metadata to map:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stripe products → internal tiers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This avoids brittle assumptions like name matching.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 — Feature Gating as Data
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;feat&lt;span class="o"&gt;(&lt;/span&gt;plans&lt;span class="o"&gt;)&lt;/span&gt;: add pricing-gated feature schema
feat&lt;span class="o"&gt;(&lt;/span&gt;stripe&lt;span class="o"&gt;)&lt;/span&gt;: refresh plan gates from catalog tier updates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of hardcoding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'pro'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I now have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;feature definitions&lt;/li&gt;
&lt;li&gt;tied to plans&lt;/li&gt;
&lt;li&gt;dynamically synced&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the system can answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Does this account have access to this feature?”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 6 — Event-Driven Billing
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;feat&lt;span class="o"&gt;(&lt;/span&gt;api&lt;span class="o"&gt;)&lt;/span&gt;: add stripe and postmark webhook endpoints
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Billing state is now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;async&lt;/li&gt;
&lt;li&gt;event-driven&lt;/li&gt;
&lt;li&gt;consistent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No more relying on user-triggered updates.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7 — Document Before It Gets Messy
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docs&lt;span class="o"&gt;(&lt;/span&gt;readme&lt;span class="o"&gt;)&lt;/span&gt;: replace template with project documentation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Captured:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;architecture&lt;/li&gt;
&lt;li&gt;billing flow&lt;/li&gt;
&lt;li&gt;schema decisions&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 8 — Design Direction First
&lt;/h2&gt;

&lt;p&gt;Before jumping into UI, I set the tone:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;chore&lt;span class="o"&gt;(&lt;/span&gt;ui&lt;span class="o"&gt;)&lt;/span&gt;: add design inspiration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Leaning towards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pre-glass macOS feel&lt;/li&gt;
&lt;li&gt;structured, calm interfaces&lt;/li&gt;
&lt;li&gt;narrative-first layout&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 9 — UI Catches Up
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;feat&lt;span class="o"&gt;(&lt;/span&gt;ui&lt;span class="o"&gt;)&lt;/span&gt;: implement app shell and redesign core story pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;app shell in place&lt;/li&gt;
&lt;li&gt;story pages redesigned&lt;/li&gt;
&lt;li&gt;layout aligns with the “timeline as narrative” idea&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Changed Today
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Billing is no longer an afterthought&lt;/li&gt;
&lt;li&gt;Plans are externalized&lt;/li&gt;
&lt;li&gt;Features are structured data&lt;/li&gt;
&lt;li&gt;UI is catching up to the system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More importantly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The system now understands &lt;em&gt;who gets to see what part of the story.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Closing Thought
&lt;/h2&gt;

&lt;p&gt;Today wasn’t about flashy features.&lt;/p&gt;

&lt;p&gt;It was about removing shortcuts.&lt;/p&gt;

&lt;p&gt;Because the moment you introduce billing,&lt;br&gt;
you’re forced to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is valuable?&lt;/li&gt;
&lt;li&gt;What is restricted?&lt;/li&gt;
&lt;li&gt;What is part of the story?&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Tomorrow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;enforce feature gates across UI + API&lt;/li&gt;
&lt;li&gt;connect usage → pricing&lt;/li&gt;
&lt;li&gt;refine the UX around locked features&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you're building something similar,&lt;br&gt;
how are you structuring feature gating without polluting your domain logic?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>saas</category>
      <category>laravel</category>
      <category>stripe</category>
    </item>
    <item>
      <title>Day 1: Building a Timeline System on Top of Real Work</title>
      <dc:creator>GraceSoft</dc:creator>
      <pubDate>Mon, 06 Apr 2026 13:54:16 +0000</pubDate>
      <link>https://dev.to/gracesoftdev/day-1-building-a-timeline-system-on-top-of-real-work-281</link>
      <guid>https://dev.to/gracesoftdev/day-1-building-a-timeline-system-on-top-of-real-work-281</guid>
      <description>&lt;p&gt;I recently started working on something new under GraceSoft — an experiment around structuring “stories” from actual development activity.&lt;/p&gt;

&lt;p&gt;Not content.&lt;br&gt;
Not posts.&lt;br&gt;
Not documentation.&lt;/p&gt;

&lt;p&gt;Something closer to a &lt;strong&gt;timeline engine&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧩 The Idea (So Far)
&lt;/h3&gt;

&lt;p&gt;Most of our work already exists in fragments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;git commits
&lt;/li&gt;
&lt;li&gt;project updates
&lt;/li&gt;
&lt;li&gt;notes
&lt;/li&gt;
&lt;li&gt;milestones
&lt;/li&gt;
&lt;li&gt;decisions
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But they’re scattered across tools.&lt;/p&gt;

&lt;p&gt;What if they could be structured into a &lt;strong&gt;single, evolving timeline&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;Not manually written after the fact —&lt;br&gt;&lt;br&gt;
but progressively built as the work happens.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚙️ What’s Been Built (Day 1–?)
&lt;/h3&gt;

&lt;p&gt;Still early, but the current foundation includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;timeline creation (MVP structure)&lt;/li&gt;
&lt;li&gt;ownership + access control layer&lt;/li&gt;
&lt;li&gt;integration entry points (starting with GitHub)&lt;/li&gt;
&lt;li&gt;manual sync endpoint&lt;/li&gt;
&lt;li&gt;early-stage pipeline for processing activity into events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No UI direction locked in yet —&lt;br&gt;&lt;br&gt;
focusing purely on &lt;strong&gt;data modeling + system design first&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧱 Current Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Laravel (API + core logic)&lt;/li&gt;
&lt;li&gt;MySQL (structured timeline data)&lt;/li&gt;
&lt;li&gt;GitHub integration (initial source)&lt;/li&gt;
&lt;li&gt;Queue-based processing (for sync pipeline)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keeping it simple for now —&lt;br&gt;&lt;br&gt;
but designing in a way that won’t break when things scale.&lt;/p&gt;




&lt;h3&gt;
  
  
  🤔 Open Questions
&lt;/h3&gt;

&lt;p&gt;Still figuring out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How much should be automated vs curated?&lt;/li&gt;
&lt;li&gt;What makes a “meaningful” event in a timeline?&lt;/li&gt;
&lt;li&gt;How to avoid turning this into just another activity feed?&lt;/li&gt;
&lt;li&gt;Where does structure end and storytelling begin?&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  👀 What’s Next
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;expanding the sync pipeline&lt;/li&gt;
&lt;li&gt;mapping commits → structured timeline events&lt;/li&gt;
&lt;li&gt;experimenting with milestone detection&lt;/li&gt;
&lt;li&gt;exploring a minimal UI (thinking macOS-inspired)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;No roadmap to share yet.&lt;/p&gt;

&lt;p&gt;Just building, testing, and seeing where this goes.&lt;/p&gt;

&lt;p&gt;If you’ve ever thought about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;turning work into something more structured&lt;/li&gt;
&lt;li&gt;or making development progress more visible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’d be curious to hear your thoughts.&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>laravel</category>
      <category>buildinpublic</category>
      <category>softwarearchitechture</category>
    </item>
  </channel>
</rss>
