<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[coders.fail writings]]></title><description><![CDATA[Progress reports, experiences, failures, lessons learned, the journey and projects of coders.fail]]></description><link>https://writings.coders.fail</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 21:40:22 GMT</lastBuildDate><atom:link href="https://writings.coders.fail/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[My first day as an intern at coders.fail]]></title><description><![CDATA[Greetings, everyone!
My name is Seva, and I'm thrilled to share my first day as an intern at coders.fail! It was a day filled with learning, good vibes, and valuable experiences.
Right from the start, as I joined the virtual space, Joda Stößer provid...]]></description><link>https://writings.coders.fail/my-first-day-as-an-intern-at-codersfail</link><guid isPermaLink="true">https://writings.coders.fail/my-first-day-as-an-intern-at-codersfail</guid><category><![CDATA[internships]]></category><category><![CDATA[coding]]></category><category><![CDATA[CSS]]></category><category><![CDATA[HTML]]></category><category><![CDATA[newbie]]></category><category><![CDATA[#codenewbies]]></category><dc:creator><![CDATA[Vsevolod Diachenko]]></dc:creator><pubDate>Thu, 18 Apr 2024 14:26:59 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/jR4Zf-riEjI/upload/07d1ec745784d76c5c79972786e59e0d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Greetings, everyone!</strong></p>
<p>My name is Seva, and I'm thrilled to share my first day as an intern at <a target="_blank" href="https://coders.fail">coders.fail</a>! It was a day filled with learning, good vibes, and valuable experiences.</p>
<p>Right from the start, as I joined the virtual space, <a class="user-mention" href="https://hashnode.com/@SimJoSt">Joda Stößer</a> provided me with insights into the intriguing project the team is currently working on, known as <a target="_blank" href="http://mai.bio">mAI.bio</a>. What caught my attention was its ability to condense the social media platforms I provide into a digital business card, presenting me uniquely to potential followers.</p>
<p>Eager to contribute, I immersed myself in the project, offering feedback and brainstorming ideas. Being part of this collaborative effort felt empowering, and I cherished the opportunity to share my thoughts with the team.</p>
<hr />
<p>Next, my training task involved creating a one-pager. For this, I worked in <a target="_blank" href="http://versoly.com">Versoly</a>. It was my first time creating a web page entirely on my own. Initially daunting, I approached it with curiosity. After some trial and error, I successfully created a sleek one-page site for a conceptual "anti-vintage" clothing store. Seeing my creation come to life was immensely gratifying.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1713443046937/b74bec1b-6da7-4d85-bf6e-7fc417e7ac3b.png" alt="Screenshot of a mockup one-page website for futuristic fashion" class="image--center mx-auto" /></p>
<p>Reflecting on the day's experiences, I'm amazed by the wealth of knowledge gained in just one day. The accessibility of modern tools has truly revolutionized the landscape of coding and web design.</p>
<p>A heartfelt thank you to <a target="_blank" href="https://coders.fail">coders.fail</a> for fostering an environment of growth and learning. I eagerly anticipate the adventures that lie ahead!</p>
<p>Until next time,</p>
<p><a class="user-mention" href="https://hashnode.com/@scorched">Vsevolod Diachenko</a></p>
]]></content:encoded></item><item><title><![CDATA[Stripe silently launches PayPal beta, supporting Connect]]></title><description><![CDATA[Stripe just silently launched their PayPal integration beta.
https://www.paypal.com/
 
Just a few days ago, we noticed PayPal showing up in some of the Stripe modals for possible payment methods. Searching the interface to enable it or add it to the ...]]></description><link>https://writings.coders.fail/stripe-paypal-beta</link><guid isPermaLink="true">https://writings.coders.fail/stripe-paypal-beta</guid><category><![CDATA[beta]]></category><category><![CDATA[infrastructure]]></category><category><![CDATA[stripe]]></category><category><![CDATA[payment]]></category><category><![CDATA[PayPal]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Wed, 18 Jan 2023 07:34:33 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1641350625112-3b1d73c71418?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fHBheXBhbHxlbnwwfHx8fDE2NzQwMjc0NTI&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Stripe just silently launched their PayPal integration beta.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.paypal.com/">https://www.paypal.com/</a></div>
<p> </p>
<p>Just a few days ago, we noticed PayPal showing up in some of the Stripe modals for possible payment methods. Searching the interface to enable it or add it to the checkout, didn't turn up any results.</p>
<p>So did searching the web. Nada.</p>
<p>Crawling through the docs, we finally found the information we were looking for! The following docs are only accessible when logged in:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://stripe.com/docs/payments/paypal">https://stripe.com/docs/payments/paypal</a></div>
<p> </p>
<p>This allows PayPal to show a "join beta" form, with the account email address already prefilled.</p>
<p>This beta is available for Stripe customers in the European Economic Area, the United Kingdom and Switzerland.<br />Of course, we immediately applied and will test it as soon as possible.</p>
<p>Other than simplifying the checkout experience, making it easier to set up new shops and billing, being able to manage everything in one service and dashboard, is the option to use Stripe Connect with it.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://stripe.com/en-de/connect">https://stripe.com/en-de/connect</a></div>
<p> </p>
<p>This would allow marketplaces and services wanting to split a payment between different fulfillers, to support PayPal payments as well.<br />In the past, supporting PayPal meant building a custom payout system.<br />No more!</p>
]]></content:encoded></item><item><title><![CDATA[Ghost Admin errors on post list since version 5.21.0]]></title><description><![CDATA[Issue Summary
Since updating to Ghost version 5.22.10 the following error message popped up when opening any of the admin post lists/views:Request not understood error, cannot list posts. Could not understand request.

Testing a bit around and downgr...]]></description><link>https://writings.coders.fail/ghost-admin-errors-on-post-list-since-version-5-21-0</link><guid isPermaLink="true">https://writings.coders.fail/ghost-admin-errors-on-post-list-since-version-5-21-0</guid><category><![CDATA[admin]]></category><category><![CDATA[blog]]></category><category><![CDATA[bug]]></category><category><![CDATA[cms]]></category><category><![CDATA[ghost]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Sat, 12 Nov 2022 16:39:59 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1593510987046-1f8fcfc512a0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fGNvbXB1dGVyJTIwZXJyb3IlMjB3YXJuaW5nfGVufDB8fHx8MTY2ODI3MTE2Ng&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-issue-summary">Issue Summary</h3>
<p>Since updating to Ghost version 5.22.10 the following error message popped up when opening any of the admin post lists/views:<br /><code>Request not understood error, cannot list posts. Could not understand request.</code></p>
<ul>
<li><p>Testing a bit around and downgrading showed, that the first affected version is 5.21.0.</p>
</li>
<li><p>Version 5.22.0 through 5.22.10 are also affected.</p>
</li>
<li><p>Version 5.20.0 is the last unaffected one.</p>
</li>
</ul>
<h3 id="heading-steps-to-reproduce">Steps to Reproduce</h3>
<ol>
<li><p>Install Ghost version 5.22.10</p>
<ul>
<li><p>Either through an update or a clean install.</p>
</li>
<li><p>It doesn't matter if there are already posts created or not.</p>
</li>
</ul>
</li>
<li><p>Open the Ghost admin backend</p>
</li>
<li><p>Open one of the post lists/views.</p>
</li>
</ol>
<h3 id="heading-relevant-log-error-output">Relevant log / error output</h3>
<h4 id="heading-browser-http-request">Browser HTTP Request</h4>
<h5 id="heading-url">URL</h5>
<p>Browser HTTP Request URL:</p>
<pre><code class="lang-plaintext">/ghost/api/admin/posts/?formats=mobiledoc%2Clexical&amp;limit=30&amp;page=1&amp;filter=status%3A%5Bdraft%2Cscheduled%2Cpublished%2Csent%5D
</code></pre>
<h5 id="heading-response">Response</h5>
<p>Browser HTTP Request Response:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"errors"</span>: [
    {
      <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Request not understood error, cannot list posts."</span>,
      <span class="hljs-attr">"context"</span>: <span class="hljs-string">"Could not understand request."</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"BadRequestError"</span>,
      <span class="hljs-attr">"details"</span>: <span class="hljs-literal">null</span>,
      <span class="hljs-attr">"property"</span>: <span class="hljs-literal">null</span>,
      <span class="hljs-attr">"help"</span>: <span class="hljs-literal">null</span>,
      <span class="hljs-attr">"code"</span>: <span class="hljs-string">"ER_BAD_FIELD_ERROR"</span>,
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"c1801070-6273-11ed-8e21-c102c3d5082c"</span>,
      <span class="hljs-attr">"ghostErrorCode"</span>: <span class="hljs-literal">null</span>
    }
  ]
}
</code></pre>
<h4 id="heading-server">Server</h4>
<p>Server/Backend log entry:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Log"</span>,
  <span class="hljs-attr">"hostname"</span>: <span class="hljs-string">"**REDACTED**"</span>,
  <span class="hljs-attr">"pid"</span>: **REDACTED**,
  <span class="hljs-attr">"level"</span>: <span class="hljs-number">50</span>,
  <span class="hljs-attr">"req"</span>: {
    <span class="hljs-attr">"meta"</span>: {
      <span class="hljs-attr">"requestId"</span>: <span class="hljs-string">"88c4655a-1137-40fe-b3e4-9c2c85456430"</span>,
      <span class="hljs-attr">"userId"</span>: <span class="hljs-string">"1"</span>
    },
    <span class="hljs-attr">"url"</span>: <span class="hljs-string">"/posts/?formats=mobiledoc%2Clexical&amp;limit=30&amp;page=1&amp;filter=status%3A%5Bdraft%2Cscheduled%2Cpublished%2Csent%5D"</span>,
    <span class="hljs-attr">"method"</span>: <span class="hljs-string">"GET"</span>,
    <span class="hljs-attr">"originalUrl"</span>: <span class="hljs-string">"/ghost/api/admin/posts/?formats=mobiledoc%2Clexical&amp;limit=30&amp;page=1&amp;filter=status%3A%5Bdraft%2Cscheduled%2Cpublished%2Csent%5D"</span>,
    <span class="hljs-attr">"params"</span>: {},
    <span class="hljs-attr">"headers"</span>: {
      <span class="hljs-attr">"host"</span>: <span class="hljs-string">"**REDACTED**"</span>,
      <span class="hljs-attr">"sec-ch-ua"</span>: <span class="hljs-string">"\"Google Chrome\";v=\"107\", \"Chromium\";v=\"107\", \"Not=A?Brand\";v=\"24\""</span>,
      <span class="hljs-attr">"dnt"</span>: <span class="hljs-string">"1"</span>,
      <span class="hljs-attr">"sec-ch-ua-mobile"</span>: <span class="hljs-string">"?0"</span>,
      <span class="hljs-attr">"app-pragma"</span>: <span class="hljs-string">"no-cache"</span>,
      <span class="hljs-attr">"user-agent"</span>: <span class="hljs-string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"</span>,
      <span class="hljs-attr">"content-type"</span>: <span class="hljs-string">"application/json; charset=UTF-8"</span>,
      <span class="hljs-attr">"accept"</span>: <span class="hljs-string">"application/json, text/javascript, */*; q=0.01"</span>,
      <span class="hljs-attr">"x-requested-with"</span>: <span class="hljs-string">"XMLHttpRequest"</span>,
      <span class="hljs-attr">"x-ghost-version"</span>: <span class="hljs-string">"5.22"</span>,
      <span class="hljs-attr">"sec-ch-ua-platform"</span>: <span class="hljs-string">"\"macOS\""</span>,
      <span class="hljs-attr">"sec-fetch-site"</span>: <span class="hljs-string">"same-origin"</span>,
      <span class="hljs-attr">"sec-fetch-mode"</span>: <span class="hljs-string">"cors"</span>,
      <span class="hljs-attr">"sec-fetch-dest"</span>: <span class="hljs-string">"empty"</span>,
      <span class="hljs-attr">"referer"</span>: <span class="hljs-string">"https://**REDACTED**/ghost/"</span>,
      <span class="hljs-attr">"accept-encoding"</span>: <span class="hljs-string">"gzip, deflate, br"</span>,
      <span class="hljs-attr">"accept-language"</span>: <span class="hljs-string">"de,de-DE;q=0.9,en-GB;q=0.8,en;q=0.7,en-US;q=0.6,en-DE;q=0.5"</span>,
      <span class="hljs-attr">"cookie"</span>: <span class="hljs-string">"**REDACTED**"</span>,
      <span class="hljs-attr">"sec-gpc"</span>: <span class="hljs-string">"1"</span>,
      <span class="hljs-attr">"x-forwarded-proto"</span>: <span class="hljs-string">"https"</span>,
      <span class="hljs-attr">"x-forwarded-for"</span>: <span class="hljs-string">"**REDACTED**"</span>,
      <span class="hljs-attr">"x-forwarded-host"</span>: <span class="hljs-string">"**REDACTED**"</span>,
      <span class="hljs-attr">"x-forwarded-server"</span>: <span class="hljs-string">"**REDACTED**"</span>,
      <span class="hljs-attr">"connection"</span>: <span class="hljs-string">"close"</span>
    },
    <span class="hljs-attr">"query"</span>: {
      <span class="hljs-attr">"formats"</span>: <span class="hljs-string">"mobiledoc,lexical"</span>,
      <span class="hljs-attr">"limit"</span>: <span class="hljs-string">"30"</span>,
      <span class="hljs-attr">"page"</span>: <span class="hljs-string">"1"</span>,
      <span class="hljs-attr">"filter"</span>: <span class="hljs-string">"status:[draft,scheduled,published,sent]"</span>
    }
  },
  <span class="hljs-attr">"res"</span>: {
    <span class="hljs-attr">"_headers"</span>: {
      <span class="hljs-attr">"x-powered-by"</span>: <span class="hljs-string">"Express"</span>,
      <span class="hljs-attr">"vary"</span>: <span class="hljs-string">"Accept-Version, Accept-Encoding"</span>,
      <span class="hljs-attr">"cache-control"</span>: <span class="hljs-string">"no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0"</span>,
      <span class="hljs-attr">"content-type"</span>: <span class="hljs-string">"application/json; charset=utf-8"</span>,
      <span class="hljs-attr">"content-length"</span>: <span class="hljs-string">"279"</span>,
      <span class="hljs-attr">"etag"</span>: <span class="hljs-string">"W/\"117-g2i2/Ll57qIbCQdZFnvScK7Hl3c\""</span>
    },
    <span class="hljs-attr">"statusCode"</span>: <span class="hljs-number">400</span>,
    <span class="hljs-attr">"responseTime"</span>: <span class="hljs-string">"30ms"</span>
  },
  <span class="hljs-attr">"err"</span>: {
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"c1801070-6273-11ed-8e21-c102c3d5082c"</span>,
    <span class="hljs-attr">"domain"</span>: <span class="hljs-string">"https://**REDACTED**/"</span>,
    <span class="hljs-attr">"code"</span>: <span class="hljs-string">"ER_BAD_FIELD_ERROR"</span>,
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"BadRequestError"</span>,
    <span class="hljs-attr">"statusCode"</span>: <span class="hljs-number">400</span>,
    <span class="hljs-attr">"level"</span>: <span class="hljs-string">"normal"</span>,
    <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Could not understand request."</span>,
    <span class="hljs-attr">"stack"</span>: <span class="hljs-string">"Error: select `posts`.*, (with `k` as (select `member_id` from `members_subscription_created_events` where posts.id = members_subscription_created_events.attribution_id union select `member_id` from `members_created_events` where posts.id = members_created_events.attribution_id) select count(*) from `k`) as `count__conversions`, `posts`.*, (select count(distinct `members_click_events`.`member_id`) from `members_click_events` inner join `redirects` on `members_click_events`.`redirect_id` = `redirects`.`id` where posts.id = redirects.post_id) as `count__clicks`, `posts`.*, (select COALESCE(ROUND(AVG(score) * 100), 0) from `members_feedback` where posts.id = members_feedback.post_id) as `count__sentiment`, `posts`.*, (select count(*) from `members_feedback` where posts.id = members_feedback.post_id AND members_feedback.score = 0) as `count__negative_feedback`, `posts`.*, (select sum(`score`) from `members_feedback` where posts.id = members_feedback.post_id) as `count__positive_feedback` from `posts` where (`posts`.`status` in ('draft', 'scheduled', 'published', 'sent') and `posts`.`type` = 'post') order by CASE WHEN posts.status = 'scheduled' THEN 1 WHEN posts.status = 'draft' THEN 2 ELSE 3 END ASC,CASE WHEN posts.status != 'draft' THEN posts.published_at END DESC,posts.updated_at DESC,posts.id DESC limit 30 - Unknown column 'posts.id' in 'where clause'\n    at **REDACTED**/versions/5.22.10/node_modules/@tryghost/bookshelf-pagination/lib/bookshelf-pagination.js:259:27\n    at Packet.asError (**REDACTED**/versions/5.22.10/node_modules/mysql2/lib/packets/packet.js:728:17)\n    at Query.execute (**REDACTED**/versions/5.22.10/node_modules/mysql2/lib/commands/command.js:29:26)\n    at Connection.handlePacket (**REDACTED**/versions/5.22.10/node_modules/mysql2/lib/connection.js:456:32)\n    at PacketParser.onPacket (**REDACTED**/versions/5.22.10/node_modules/mysql2/lib/connection.js:85:12)\n    at PacketParser.executeStart (**REDACTED**/versions/5.22.10/node_modules/mysql2/lib/packet_parser.js:75:16)\n    at Socket.&lt;anonymous&gt; (**REDACTED**/versions/5.22.10/node_modules/mysql2/lib/connection.js:92:25)\n    at Socket.emit (node:events:513:28)\n    at addChunk (node:internal/streams/readable:315:12)\n    at readableAddChunk (node:internal/streams/readable:289:9)\n    at Socket.Readable.push (node:internal/streams/readable:228:10)\n    at TCP.onStreamRead (node:internal/stream_base_commons:190:23)"</span>,
    <span class="hljs-attr">"hideStack"</span>: <span class="hljs-literal">false</span>
  },
  <span class="hljs-attr">"msg"</span>: <span class="hljs-string">"Could not understand request."</span>,
  <span class="hljs-attr">"time"</span>: <span class="hljs-string">"2022-11-12T10:21:22.564Z"</span>,
  <span class="hljs-attr">"v"</span>: <span class="hljs-number">0</span>
}
</code></pre>
<hr />
<p>GitHub issue:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/TryGhost/Ghost/issues/15813">https://github.com/TryGhost/Ghost/issues/15813</a></div>
<p> </p>
<h2 id="heading-workarounds-tips-and-hints">Workarounds, tips and hints</h2>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Downgrade to Ghost version 5.20.0.</div>
</div>]]></content:encoded></item><item><title><![CDATA[Ghost CLI version downgrade leads to broken install]]></title><description><![CDATA[Summary
The Ghost CLI removes old versions while updating. In the easiest-to-find search results, it is documented or mentioned, that the last 5 versions are kept, e.g.:
https://github.com/TryGhost/Ghost-CLI/issues/646#issuecomment-365882661
 
That i...]]></description><link>https://writings.coders.fail/ghost-cli-version-downgrade-leads-to-broken-install</link><guid isPermaLink="true">https://writings.coders.fail/ghost-cli-version-downgrade-leads-to-broken-install</guid><category><![CDATA[blog]]></category><category><![CDATA[bug]]></category><category><![CDATA[cli]]></category><category><![CDATA[cms]]></category><category><![CDATA[ghost]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Sat, 12 Nov 2022 15:42:28 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1516031190212-da133013de50?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fGNsaXxlbnwwfHx8fDE2NjgyNjc5NTQ&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-summary">Summary</h3>
<p>The Ghost CLI removes old versions while updating. In the easiest-to-find search results, it is documented or mentioned, that the last 5 versions are kept, e.g.:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/TryGhost/Ghost-CLI/issues/646#issuecomment-365882661">https://github.com/TryGhost/Ghost-CLI/issues/646#issuecomment-365882661</a></div>
<p> </p>
<p>That includes the most current version, that was likely just installed through the update. So only 4 "old" versions are kept.</p>
<p>This has been changed in version <a target="_blank" href="https://github.com/TryGhost/Ghost-CLI/releases/tag/1.15.0">1.15.0</a> with no mention in the short changelog through the commit <a target="_blank" href="https://github.com/TryGhost/Ghost-CLI/commit/badb662c462084d2b2f8cd9b6e9f566c09d2e8f2">badb662</a>, so I just missed it.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/TryGhost/Ghost-CLI/commit/badb662c462084d2b2f8cd9b6e9f566c09d2e8f2">https://github.com/TryGhost/Ghost-CLI/commit/badb662c462084d2b2f8cd9b6e9f566c09d2e8f2</a></div>
<p> </p>
<p>Since then, only the 2 most current versions are kept, because of disk space concerns: <a target="_blank" href="https://github.com/TryGhost/Ghost-CLI/issues/201#issuecomment-647124236">#201 (comment)</a></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/TryGhost/Ghost-CLI/issues/201#issuecomment-647124236">https://github.com/TryGhost/Ghost-CLI/issues/201#issuecomment-647124236</a></div>
<p> </p>
<p>As this includes the most current version, only 1 "old" version is kept.</p>
<p>Checking the code, it seems like the version removal feature only takes <a target="_blank" href="https://semver.org/">Semver</a> sorting into account:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/TryGhost/Ghost-CLI/blob/1.15.0/lib/commands/update.js#L145-L160">https://github.com/TryGhost/Ghost-CLI/blob/1.15.0/lib/commands/update.js#L145-L160</a></div>
<p> </p>
<p>Lines 149 to 164 of <a target="_blank" href="https://github.com/TryGhost/Ghost-CLI/blob/1.15.0/lib/commands/update.js#L145-L160"><code>update.js</code></a>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">async</span> removeOldVersions({instance}, task) {
    <span class="hljs-keyword">const</span> semver = <span class="hljs-built_in">require</span>(<span class="hljs-string">'semver'</span>);

    <span class="hljs-keyword">const</span> versionDirs = <span class="hljs-keyword">await</span> fs.readdir(path.join(instance.dir, <span class="hljs-string">'versions'</span>));
    <span class="hljs-keyword">const</span> versions = versionDirs.filter(semver.valid).sort(semver.compare);

    <span class="hljs-keyword">if</span> (versions.length &lt;= <span class="hljs-number">2</span>) {
        task.skip();
        <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">const</span> promises = versions.slice(<span class="hljs-number">0</span>, <span class="hljs-number">-2</span>)
        .map(<span class="hljs-function"><span class="hljs-params">version</span> =&gt;</span> fs.remove(path.join(instance.dir, <span class="hljs-string">'versions'</span>, version)));

    <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all(promises);
}
</code></pre>
<p>It does not check for the currently active or just installed version or sort the version by last use.</p>
<p>This leads to the unfortunate scenario, of just having downgraded to an older version and Ghost not being able to start, as it was promptly removed again and the <code>current</code> symlink points to a version directory that does not exist.</p>
<h3 id="heading-steps-to-reproduce">Steps to Reproduce</h3>
<ol>
<li><p>Have a Ghost install with the 2 most current versions installed</p>
</li>
<li><p>Run <code>ghost update</code> with an older version, like <code>ghost update 5.2.0 --force</code></p>
</li>
<li><p>Observe, that old Ghost versions are being removed</p>
</li>
<li><p>Try to start Ghost and see errors or check the <code>current</code> symlink pointing to a version directory that does not exist.</p>
</li>
</ol>
<p><code>ghost update 5.2.0 --force</code> CLI command log:</p>
<pre><code class="lang-bash">$ ghost update 5.2.0 --force

Love open <span class="hljs-built_in">source</span>? We’re hiring JavaScript Engineers to work on Ghost full-time.
https://careers.ghost.org

Running <span class="hljs-keyword">in</span> development mode

✔ Checking system Node.js version - found v16.18.1
✔ Ensuring user is not logged <span class="hljs-keyword">in</span> as ghost user
✔ Checking <span class="hljs-keyword">if</span> logged <span class="hljs-keyword">in</span> user is directory owner
✔ Checking current folder permissions
✔ Checking memory availability
✔ Checking free space
✔ Checking <span class="hljs-keyword">for</span> available migrations
✔ Checking <span class="hljs-keyword">for</span> latest Ghost version
✔ Release notes were not found
✔ Downloading and updating Ghost to v5.2.0
✔ Linking latest Ghost and recording versions
✔ Removing old Ghost versions
ghost update 5.2.0 --force  15.27s user 9.01s system 137% cpu 17.708 total
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">The version the update command just downgraded to, should not be removed.</div>
</div>

<h3 id="heading-possible-solutions-not-mutually-exclusive">Possible solutions, not mutually exclusive</h3>
<h4 id="heading-always-keep-the-current-active-version">Always keep the current active version</h4>
<p>Add a check, to never delete the currently active version or exclude it from the removal feature outright.<br />The latter would increase the number of kept versions to 3 if the feature is not adjusted for that.</p>
<h4 id="heading-add-a-config-option-andor-cli-flag-for-the-number-of-versions-to-keep">Add a config option and/or CLI flag for the number of versions to keep</h4>
<p>The change from keeping 5 versions to just 2 went by unnoticed, and it would have been great if users/admins could define the number themselves. Everybody has different infrastructure, storage requirements and rollback needs.<br />This would be great as a config option as well as a CLI command flag.</p>
<h4 id="heading-keep-the-last-active-versions">Keep the last active versions</h4>
<p>Instead of just keeping the latest versions according to <a target="_blank" href="https://semver.org/">Semver</a>, it would be cleaner to keep track of the <em>active</em> and used versions. People might not just upgrade to newer versions, but jump around.<br />Keeping previous versions according to the history of used versions would simplify things a lot.</p>
<p>GitHub issue:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/TryGhost/Ghost-CLI/issues/1714">https://github.com/TryGhost/Ghost-CLI/issues/1714</a></div>
<p> </p>
<h3 id="heading-workarounds-tips-and-hints">Workarounds, tips and hints</h3>
<p>Make sure to have a "free slot" for keeping versions available. With only 2 versions being kept, this means removing all (typically 1) but the most current one. That way, the feature won't be triggered, and the downgrade version is not deleted.</p>
]]></content:encoded></item><item><title><![CDATA[Ghost CLI installs wrong minor version]]></title><description><![CDATA[Summary
The Ghost CLI allows for updating (and installing) specific versions/tags of Ghost. It is possible to provide them with v as a prefix, or without, as well as only providing the major version or the major and minor versions, omitting the patch...]]></description><link>https://writings.coders.fail/ghost-cli-installs-wrong-minor-version</link><guid isPermaLink="true">https://writings.coders.fail/ghost-cli-installs-wrong-minor-version</guid><category><![CDATA[bug]]></category><category><![CDATA[cli]]></category><category><![CDATA[cms]]></category><category><![CDATA[ghost]]></category><category><![CDATA[blog]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Sat, 12 Nov 2022 12:39:22 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1585776245991-cf89dd7fc73a?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fHVwZGF0ZXxlbnwwfHx8fDE2NjgyNjc5OTg&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-summary">Summary</h3>
<p>The Ghost CLI allows for updating (and installing) specific versions/tags of Ghost. It is possible to provide them with <code>v</code> as a prefix, or without, as well as only providing the major version or the major and minor versions, omitting the patch version.<br />If the minor version is a multiple of 10 (10, 20, ...), having at least 2 digits and ending in <code>0</code>, the wrong version gets installed. The 2 digits are split, and the first is used as the minor version and the <code>0</code> as the patch version.</p>
<h3 id="heading-steps-to-reproduce">Steps to Reproduce</h3>
<ol>
<li><p>Have a Ghost install<br /> Preferably, with version &lt;5.20, so the <code>--force</code> flag doesn't need to be used</p>
</li>
<li><p>Run <code>ghost update</code> and provide a specific version, that has a minor version of a multiple of 10 and don't provide the patch version, like <code>ghost update 5.20</code></p>
</li>
<li><p>Observe, that Ghost version 5.2.0 is getting installed</p>
</li>
</ol>
<p>CLI command <code>ghost update 5.20</code> log:</p>
<pre><code class="lang-bash">$ ghost update 5.20

Love open <span class="hljs-built_in">source</span>? We’re hiring JavaScript Engineers to work on Ghost full-time.
https://careers.ghost.org

Running <span class="hljs-keyword">in</span> development mode

✔ Checking system Node.js version - found v16.18.1
✔ Ensuring user is not logged <span class="hljs-keyword">in</span> as ghost user
✔ Checking <span class="hljs-keyword">if</span> logged <span class="hljs-keyword">in</span> user is directory owner
✔ Checking current folder permissions
✔ Checking memory availability
✔ Checking free space
✔ Checking <span class="hljs-keyword">for</span> available migrations
✔ Checking <span class="hljs-keyword">for</span> latest Ghost version
✔ Release notes were not found
✔ Downloading and updating Ghost to v5.2.0
✔ Linking latest Ghost and recording versions
✔ Removing old Ghost versions
ghost update 5.20  15.27s user 9.01s system 137% cpu 17.708 total
</code></pre>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Like with <code>ghost update 5.21</code>, it should install the correct minor version. Preferably, with the current patch version.</div>
</div>

<hr />
<p>GitHub issue:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/TryGhost/Ghost-CLI/issues/1713">https://github.com/TryGhost/Ghost-CLI/issues/1713</a></div>
<p> </p>
<h3 id="heading-workarounds-tips-and-hints">Workarounds, tips and hints</h3>
<p>Specify the full version including the patch version, like: <code>ghost update v5.22.10</code></p>
]]></content:encoded></item><item><title><![CDATA[Cloudflare Workers Shop]]></title><description><![CDATA[Having to smooth out the edges of our Worker router approach to allow for multiple workers on the Cloudflare Workers platform on a single request, we decided to come full circle and return to the roots: Building and marketing our workers.
Instead of ...]]></description><link>https://writings.coders.fail/cloudflare-workers-shop</link><guid isPermaLink="true">https://writings.coders.fail/cloudflare-workers-shop</guid><category><![CDATA[cloudflare]]></category><category><![CDATA[marketplace]]></category><category><![CDATA[Nuxt]]></category><category><![CDATA[cloudflare-worker]]></category><category><![CDATA[Build In Public]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Mon, 17 Oct 2022 16:56:00 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1634973357973-f2ed2657db3c?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDV8fG9ubGluZSUyMHNob3B8ZW58MHx8fHwxNjY4NjExOTM2&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Having to smooth out the edges of our Worker router approach to allow for multiple workers on the Cloudflare Workers platform on a single request, we decided to come full circle and return to the roots: Building and marketing our workers.</p>
<p>Instead of providing a fully automated and integrated marketplace, we'll either provide the source files or compiled <a target="_blank" href="https://webassembly.org/">WASM</a> assets to upload and update yourself.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590835702048362496">https://twitter.com/coders_fail/status/1590835702048362496</a></div>
<p> </p>
<p>Of course, providing them in a shop built on Swell: https://www.swell.is/</p>
<p>All our other approaches, a public Marketplace for all vendors, automated deployment, integrated configuration, multi-worker configuration and automated share distribution.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590835706167197697">https://twitter.com/coders_fail/status/1590835706167197697</a></div>
<p> </p>
<p>This will be the shortest amount of development to get to a magnetizable product and the first version of our worker shop and workshop.<br />In the spirit of getting as quickly to v1 and building atop it, we decided to go with this approach first.</p>
]]></content:encoded></item><item><title><![CDATA[Cloudflare Workers Workshop and Router]]></title><description><![CDATA[After having to shift from developing Workers, to developing a Worker marketplace, we ended up with a new challenge: To solve the issue of only one Worker being active and answering each request and route.
https://twitter.com/coders_fail/status/15908...]]></description><link>https://writings.coders.fail/cloudflare-workers-workshop-and-router</link><guid isPermaLink="true">https://writings.coders.fail/cloudflare-workers-workshop-and-router</guid><category><![CDATA[cloudflare]]></category><category><![CDATA[cloudflare-worker]]></category><category><![CDATA[Indie Maker]]></category><category><![CDATA[Build In Public]]></category><category><![CDATA[Bootstrapping]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Wed, 05 Oct 2022 18:02:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/Rz8mkGw-G3w/upload/fc2558382ce9389c942ff68ce34df6d0.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>After having to shift from developing Workers, to developing a Worker marketplace, we ended up with a new challenge: To solve the issue of only one Worker being active and answering each request and route.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590835713133936640">https://twitter.com/coders_fail/status/1590835713133936640</a></div>
<p> </p>
<p>With multiple registered Cloudflare Workers, just one with the more specific route matcher will process the current request. This prohibits any chance of having multiple workers process the request.<br />This is needed, especially when using highly specialized workers, which optimize the content of the requests. Like caching and image optimizations.</p>
<p>This is hindered by the fact, that the obvious solution of having one router worker which proxies the original request to the first worker and sends its response and the modified request to the subsequent worker, following the same logic for any additional workers, just doesn't work.</p>
<p>Cloudflare does not allow for sending the response of the previous worker to the subsequent one but forwards the original request.<br />To solve this, some workarounds need to be used to make it possible.</p>
<p>We've managed to find multiple solution approaches, at least one of which already showed promising results and works. There is still room for improvement, and try to find the cleanest approach.</p>
<p>Obviously, every worker, every request, and every additional step adds latency and makes the request-response take longer to reach the client. To prevent this from happening to each request, this system needs to heavily rely on a good caching strategy.</p>
<p>To be able to make this approach work, there needs to be a proper setup for the worker to capture all the routes of the other workers. It needs to be configured to be able to proxy to all necessary workers.</p>
<p>We've already started building an interface to manage those workers and routes, to extend the possibilities offered in Cloudflare's web interface. The possibility to integrate into the future worker marketplace is already set up and conceptualized.</p>
<p>Like with the last pivot to a worker marketplace, the development complexity is much higher than originally planned for our first ideas. This won't keep us from trying, might lead to another pivot.</p>
<p>Stay tuned!</p>
]]></content:encoded></item><item><title><![CDATA[Boot camp #1]]></title><description><![CDATA[To make some real progress on our ideas, we decided to have recurring "boot camps" at irregular intervals. They consist of in-person meetings for up to 2 weeks, allowing us to keep communication direct, quick and efficient.
If possible, we schedule t...]]></description><link>https://writings.coders.fail/boot-camp-1</link><guid isPermaLink="true">https://writings.coders.fail/boot-camp-1</guid><category><![CDATA[Bootstrapping]]></category><category><![CDATA[Indie Maker]]></category><category><![CDATA[Build In Public]]></category><category><![CDATA[Startups]]></category><category><![CDATA[bootcamp]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Thu, 15 Sep 2022 21:11:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/uyfohHiTxho/upload/b9a83c73102a4378e920a7afe04dcd94.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>To make some real progress on our ideas, we decided to have recurring "boot camps" at irregular intervals. They consist of in-person meetings for up to 2 weeks, allowing us to keep communication direct, quick and efficient.</p>
<p>If possible, we schedule them during vacations or public holidays, to spend more time on the project.<br />It helps to be working at the same company, with the same clients and projects, as well as work mentality and benefits. This reduces the disconnect during the day and helps us stay in sync.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/SimJoSt/status/1567959732891316224">https://twitter.com/SimJoSt/status/1567959732891316224</a></div>
<p> </p>
<p>Our first boot camp ended up being 7 days after we scheduled it up for up to 2 weeks. Other responsibilities came up and the intensity of the first days made us need to take a breather.</p>
<p>We spent most of the time setting up the basics, finding the name for our project, registering the domain, setting up our tools like Notion, Stripe, Swell and Google Workspace and email as well as rating our business ideas.</p>
<p>The rest was getting into the thick of Cloudflare Workers' technical details, Swell setup and customization and discussing our pivots from idea to idea after finding roadblocks in our original approach.<br />During this, we connected with the communities of the chosen tech stack, started some discussion and collected some contact details.</p>
<p>We are looking forward to our second boot camp, which will not be held in the same country, but digital slowmading together.</p>
]]></content:encoded></item><item><title><![CDATA[Cloudflare Workers Marketplace]]></title><description><![CDATA[Having rated our business ideas, we were not surprised to see, that all our ideas based on the Cloudflare Workers platform came out on top, with a pretty high rating. Just by how much and how many.
Overall, it does make sense. They scale well, there ...]]></description><link>https://writings.coders.fail/cloudflare-workers-marketplace</link><guid isPermaLink="true">https://writings.coders.fail/cloudflare-workers-marketplace</guid><category><![CDATA[cloudflare]]></category><category><![CDATA[marketplace]]></category><category><![CDATA[Nuxt]]></category><category><![CDATA[cloudflare-worker]]></category><category><![CDATA[Build In Public]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Sun, 11 Sep 2022 20:17:00 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1532079563951-0c8a7dacddb3?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDl8fG9ubGluZSUyMG1hcmtldHBsYWNlfGVufDB8fHx8MTY2ODYxMTkxNQ&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Having rated our business ideas, we were not surprised to see, that all our ideas based on the Cloudflare Workers platform came out on top, with a pretty high rating. Just by how much and how many.</p>
<p>Overall, it does make sense. They scale well, there is near to no upfront financial investment, they are fairly easily built with no frontend necessary, target infrastructure and thus are not dependent on user-generated content.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590835703998709760">https://twitter.com/coders_fail/status/1590835703998709760</a></div>
<p> </p>
<p>After the first worker was already built and ready, we realized the <a target="_blank" href="https://blog.cloudflare.com/introducing-apps-with-workers/">originally announced Apps with Workers</a> feature, which would have allowed using the Apps marketplace to sell bundled workers, surprisingly never got out of the closed beta.<br />It was even actively closed as noted in the docs:</p>
<blockquote>
<p><a target="_blank" href="https://www.cloudflare.com/apps/developer/docs/workers">Cloudflare's App Workers Beta is now closed. We are no longer accepting new apps that contain Workers scripts to focus on improving the Workers development experience.</a></p>
</blockquote>
<p>That is very atypical for Cloudflare features that typically go to general availability after the closed and then open beta. A more detailed explanation was <a target="_blank" href="https://community.cloudflare.com/t/workers-embedded-in-apps-still-supported/147305/14">posted on the forum</a>. Coupled with a promise to be working on another solution.</p>
<p>Learning all this, a defeated feeling set in, and we felt it was the first big lesson of our journey. Not the idea being bad, not having no customers, but our assured monetization platform not existing at all.<br />Scrutinizing ideas and vetting and validating monetization options, will become a bigger part of the process.</p>
<p>Luckily, accepting this small loss, a few minutes later the next idea formed: Our own Worker marketplace!<br />Offering a place for everyone, including us, to sell their workers.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590835707874258944">https://twitter.com/coders_fail/status/1590835707874258944</a></div>
<p> </p>
<p>Of course, this idea would be much bigger and more complex, crushing our limitation of only spending a month on any specific idea.<br />Being confident in this idea, we accepted this and were willing to make an exception.</p>
<p>Especially after putting our heads together, and jotting down the first version of the concept. Building on our e-commerce development experience, pretty wide knowledge of possible technologies and tools and the willingness to try something new.</p>
<p>The main advantage for us here was <a target="_blank" href="https://www.swell.is/">Swell</a> e-commerce SaaS:</p>
<p>They offer loads of flexibility for developers, solid docs, flexible API, switching out the checkout completely and the option to change the database models for every entity, instead of just using meta fields / custom fields like competing options.</p>
<p>Landing page on why Swell makes sense for building marketplaces: https://www.swell.is/for/marketplaces</p>
<p>A few things stood out:</p>
<ol>
<li><p>A great pricing scheme for startups, where you don't pay anything until you earn the first buck and the ability to switch to a more profitable plan later on when the revenue is big enough.</p>
</li>
<li><p>Supporting the frontend stack out of the box and hosted, which we wanted to use anyway: <a target="_blank" href="https://nuxtjs.org/">Nuxt</a><br /> As well as allowing you to host the headless frontend yourself, like on Cloudflare Workers.</p>
</li>
<li><p>A preexisting guide to build a marketplace with Swell, from Swell itself:</p>
</li>
</ol>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://developers.swell.is/guides/build-a-marketplace">https://developers.swell.is/guides/build-a-marketplace</a></div>
<p> </p>
<p>This guide is based on Stripe Connect, which allows easy distribution of revenue shares to multiple partners. It simplifies the booking immensely, as it immediately transfers the appropriate share to each vendor.<br />Meaning, we would never have that money in our accounts and don't need to deal with it.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://stripe.com/en-de/connect">https://stripe.com/en-de/connect</a></div>
<p> </p>
<p>Of course, every idea comes with its new challenges. This time, it was the limitation of Cloudflare Workers to have only one Worker active on each request route at each given time.</p>
<p>Having some client prospects in mind, that could benefit from at least one of our Worker idea, while already using a Worker for caching, this limitation was to be circumvented.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590835713133936640">https://twitter.com/coders_fail/status/1590835713133936640</a></div>
<p> </p>
<p>As hoped, this led to the next idea: A Worker router!</p>
]]></content:encoded></item><item><title><![CDATA[Rating our business ideas]]></title><description><![CDATA[Having collected over 70 ideas, it was not obvious which we would build first. Especially, since we didn't know all the details of all the ideas when the other just wrote down the name or a rough description.Also, we had very different gut feelings a...]]></description><link>https://writings.coders.fail/rating-our-business-ideas</link><guid isPermaLink="true">https://writings.coders.fail/rating-our-business-ideas</guid><category><![CDATA[Bootstrapping]]></category><category><![CDATA[lessons]]></category><category><![CDATA[ideas]]></category><category><![CDATA[Build In Public]]></category><category><![CDATA[Indie Maker]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Sat, 10 Sep 2022 19:53:00 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1633613286991-611fe299c4be?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fHJhdGluZ3xlbnwwfHx8fDE2Njg2MTEyMjg&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Having collected over 70 ideas, it was not obvious which we would build first. Especially, since we didn't know all the details of all the ideas when the other just wrote down the name or a rough description.<br />Also, we had very different gut feelings about what constitutes a "good idea". Our interest in the different stacks also differed.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590828963156615168">https://twitter.com/coders_fail/status/1590828963156615168</a></div>
<p> </p>
<p>Going through the first batch of ideas, explaining them to each other and trying to rate them consistently, it became clear we would be there a while.<br />We took a few steps back and started with our rating rubric. We defined 5 areas and assigned a value from 1 to 5 to each of them, with 5 being the best and 1 being the worst.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590828966491090944">https://twitter.com/coders_fail/status/1590828966491090944</a></div>
<p> </p>
<h2 id="heading-financial-potential">Financial potential</h2>
<p><strong>What kind of MRR can we expect?</strong></p>
<ol>
<li><p>no monetization potential</p>
</li>
<li><p>0 to 200 bucks per month</p>
</li>
<li><p>200 to 2k bucks per month</p>
</li>
<li><p>2k to 4k bucks per month</p>
</li>
<li><p>over 4k bucks per month</p>
</li>
</ol>
<h2 id="heading-feasibility">Feasibility</h2>
<p><strong>How long does it take to build?</strong></p>
<ol>
<li><p>not feasible for us at all</p>
</li>
<li><p>over a month</p>
</li>
<li><p>2 to 3 weeks</p>
</li>
<li><p>1 to 2 weeks</p>
</li>
<li><p>under a week</p>
</li>
</ol>
<h2 id="heading-automation-potential">Automation potential</h2>
<ol>
<li><p>every purchase requires repeated effort</p>
</li>
<li><p>every customer requires effort for onboarding in addition to constant content management and creation</p>
</li>
<li><p>no customer onboarding, but constant content management and creation</p>
</li>
<li><p>no customer onboarding, but some manual effort on occasion, like support rare requests</p>
</li>
<li><p>no product content management and no customer onboarding</p>
</li>
</ol>
<h2 id="heading-user-generated-content-independence">User-generated content independence</h2>
<p><strong>How much of the value is based on user-generated content?</strong></p>
<ol>
<li><p>the whole product value is based on user-generated content</p>
</li>
<li><p>the ratio of independence to user-generated content is 25 / 75</p>
</li>
<li><p>the ratio of independence to user-generated content is 50 / 50</p>
</li>
<li><p>the ratio of independence to user-generated content is 75 / 25</p>
</li>
<li><p>the product value is not based on user-generated content at all</p>
</li>
</ol>
<h2 id="heading-marketing-potential">Marketing potential</h2>
<ol>
<li><p>the niche is difficult to define and hard to capture</p>
</li>
<li><p>the in-between state, as defined by a gut feeling</p>
</li>
<li><p>the niche is neither difficult nor simple to define and neither hard nor easy to capture</p>
</li>
<li><p>the in-between state, as defined by a gut feeling</p>
</li>
<li><p>the niche is easily defined and easy to capture</p>
</li>
</ol>
<hr />
<p>Not all the values were easy to associate with real word representations, especially with low to non-experience launching a bootstrapped startup. Finding a common rating rubric, that we both agreed on and would result in the same values if rated by either of us.</p>
<p>It took us an entire day to go through all of them, getting sidetracked often while getting into heated discussions by our enthusiasm for an idea or an argument about whether we want to pursue something.<br />Keeping each other accountable to only spend a few minutes on each rating, disregarding our drive for perfectionism, helped immensely.</p>
<p>At the end of the day, we had a few ideas with an average score of over 3 or even 4. Most of them relied on Cloudflare Workers, making them mostly easy to build, low cost, extremely scalable and easy to install.<br />They would be the first ideas we would build.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://workers.cloudflare.com/">https://workers.cloudflare.com/</a></div>
<p> </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590835702048362496">https://twitter.com/coders_fail/status/1590835702048362496</a></div>
]]></content:encoded></item><item><title><![CDATA[Collecting business and startup ideas]]></title><description><![CDATA[With the initial brainstorming done for how we want to work, collaborate and achieve our goals, outlining a kind of framework, we were due for some actual ideas to start building.
https://twitter.com/coders_fail/status/1590820994327121920
 
Our previ...]]></description><link>https://writings.coders.fail/collecting-business-and-startup-ideas</link><guid isPermaLink="true">https://writings.coders.fail/collecting-business-and-startup-ideas</guid><category><![CDATA[Bootstrapping]]></category><category><![CDATA[Startups]]></category><category><![CDATA[Build In Public]]></category><category><![CDATA[ideas]]></category><category><![CDATA[Indie Maker]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Sat, 03 Sep 2022 13:34:00 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1589561253898-768105ca91a8?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDd8fGlkZWF8ZW58MHx8fHwxNjY4NjExMjQy&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>With the initial brainstorming done for how we want to work, collaborate and achieve our goals, outlining a kind of framework, we were due for some actual ideas to start building.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590820994327121920">https://twitter.com/coders_fail/status/1590820994327121920</a></div>
<p> </p>
<p>Our previously defined framework provided some inspiration in which direction we wanted to look for ideas. Immediately looking for ideas that scale, are minimal to be built in 2 weeks, don't rely on user-generated content, are easy for us to market and have a real value proposition.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590821012786270208">https://twitter.com/coders_fail/status/1590821012786270208</a></div>
<p> </p>
<p>After our meetup at the <a target="_blank" href="https://www.aboutyoupangea-festival.de/">About You Pangea festival</a> <a target="_blank" href="https://www.youtube.com/watch?v=qpz56IPtnZE">2022</a>, we stayed in contact and had a lot of calls every few days. We migrated all of our ideas into <a target="_blank" href="https://www.notion.so/">Notion</a> and typed all of them down as soon as they came to mind.</p>
<p>Quickly, we realized there were some idea groups and categories, so we created a second database named "Inspirations" and grouped our ideas under them.<br />Over a few weeks, the list grew to over 70 entries.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590828963156615168">https://twitter.com/coders_fail/status/1590828963156615168</a></div>
<p> </p>
<p>Surprised by the sheer amount, we realized our constant exchange as well as being exposed to different technologies and mediums in our day-to-day lives kept our brains fresh and brainstorming became easy.<br />It is a real skill that can be learned, and you get better at it when trained.</p>
<p>It is very important not to get fixated too much to not block yourself. Take enough time to think and talk, as well as enough space to write things down.<br />Be sure to get enough sleep, food, movement and sun. Every bit helps.</p>
]]></content:encoded></item><item><title><![CDATA[Setting up the basic infrastructure]]></title><description><![CDATA[When starting out, there are a lot of menial tasks that need to get done before the first project can be up and running. We massively underestimated how much time this would take and still haven't finished setting up all of them.
https://twitter.com/...]]></description><link>https://writings.coders.fail/setting-up-the-basic-infrastructure</link><guid isPermaLink="true">https://writings.coders.fail/setting-up-the-basic-infrastructure</guid><category><![CDATA[Indie Maker]]></category><category><![CDATA[infrastructure]]></category><category><![CDATA[Build In Public]]></category><category><![CDATA[Bootstrapping]]></category><category><![CDATA[Startups]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Sat, 27 Aug 2022 11:07:00 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1492551557933-34265f7af79e?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fGJhc2ljc3xlbnwwfHx8fDE2Njg2MTExNTg&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When starting out, there are a lot of menial tasks that need to get done before the first project can be up and running. We massively underestimated how much time this would take and still haven't finished setting up all of them.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590829830626775041">https://twitter.com/coders_fail/status/1590829830626775041</a></div>
<p> </p>
<p>We tried integrating the setup in between coding and brainstorming sessions. Due to a lack of time and interrupting the process often to deal with more important things prolonged the process immensely.</p>
<p>We aimed at finding tools that would come at no cost for us for now and would allow us to grow into their paid versions, as soon as we had recurring revenue.</p>
<h2 id="heading-notion">Notion</h2>
<p><strong>Documentation and workflows</strong></p>
<p><a target="_blank" href="https://www.notion.so/">Notion</a> is a great tool for notes, documentation, databases, tasks, calendars and just generally organizing the knowledge and processes of a team.</p>
<p><a target="_blank" href="https://www.notion.so/startups">Learn more about Notions Startup credit program and apply</a></p>
<h2 id="heading-cloudflare">Cloudflare</h2>
<p><strong>Domains, infrastructure and analytics</strong></p>
<p>Working with Cloudflare on the regular at our employer, it was a no-brainer to use it to improve our infrastructure or even base service completely on it with its workers.</p>
<p>Especially, since most services are completely free or have a very generous fair-use / free limit.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.cloudflare.com/">https://www.cloudflare.com/</a></div>
<p> </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://workers.cloudflare.com/">https://workers.cloudflare.com/</a></div>
<p> </p>
<p>Even providing a registrar service that supports more and more TLDs which charges transparent prices of the main registrar of that domain, we used it to buy most of our domain.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.cloudflare.com/products/registrar/">https://www.cloudflare.com/products/registrar/</a></div>
<p> </p>
<p>In addition, hosting static pages on Cloudflare Pages is completely free of charge and the limit of 500 CI builds per month won't be reached for a long time.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://pages.cloudflare.com/">https://pages.cloudflare.com/</a></div>
<p> </p>
<p>Cloudflare also provides an analytics feature that can be automatically installed through the proxy feature or a JavaScript snippet. Even though we want to tinker with open-source and self-hosted services like Plausible and Fathom, for now, we can start easily for free and with no additional setup effort.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.cloudflare.com/analytics/">https://www.cloudflare.com/analytics/</a></div>
<p> </p>
<h2 id="heading-bitwarden">Bitwarden</h2>
<p><strong>Shared passwords and MFA/2FA</strong></p>
<p><a target="_blank" href="https://bitwarden.com/">Bitwarden</a> is an open-source Manager that is free for most use cases. The free version allows for unlimited personal use and allows for the creation of one organization with 2 members, for sharing and collaborating entries and logins.</p>
<p>Even though the generation of 2FA/MFA codes is a paid feature, the free version allows you to save the base string to enable that feature later or share the string with all members to enter them into their own 2FA/MFA apps.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://bitwarden.com/">https://bitwarden.com/</a></div>
<p> </p>
<h2 id="heading-google-workspace">Google Workspace</h2>
<p><strong>Email and data storage</strong></p>
<p>Email is one of those issues you don't want to deal with yourself. Hosting your own email server can be painful, time-intensive and quite difficult to get right. We knew from the start this to be a topic we were not supposed to be cheap with.</p>
<p>Google Workspace was an easy choice, as it is cheap, offers a lot of features, integrates well on mobile and is already known to us.<br />To begin with we didn't need personalized accounts, so we only created on users and added email aliases with our names to it.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://workspace.google.com/">https://workspace.google.com/</a></div>
<p> </p>
<h2 id="heading-twitter">Twitter</h2>
<p><strong>Work log and engagement with the community</strong></p>
<p><a target="_blank" href="https://twitter.com/">Twitter</a> is very actively used by the SaaS, bootstrap and <a target="_blank" href="https://twitter.com/hashtag/buildinpublic">#buildinpublic</a> community as well as a lot of developers. We will use it to document our progress and engage with the community.</p>
<p><a target="_blank" href="https://twitter.com/coders_fail">@coders.fail on Twitter</a></p>
<h2 id="heading-stripe">Stripe</h2>
<p><strong>Getting paid and marketplace automations</strong></p>
<p>As one of the biggest payment processors and gateways, we knew we needed an account. Especially, since we were interested in building marketplaces, which is much easier to do with Stripe Connect.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://stripe.com/">https://stripe.com/</a></div>
<p> </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://stripe.com/connect">https://stripe.com/connect</a></div>
<p> </p>
<h2 id="heading-paypal">PayPal</h2>
<p><strong>Getting paid and paying</strong></p>
<p>PayPal has become a main staple of online payments and cannot be ignored. Not only for receiving payments, but also for paying for services needed in our infrastructure.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.paypal.com/en/business">https://www.paypal.com/en/business</a></div>
<p> </p>
<h2 id="heading-servers">Servers</h2>
<p><strong>Hosting and testing ground</strong></p>
<p>Cloudflare Workers and Pages being great for static content and frontends, we needed a place to host our backends and to play around. A lot of cool services rely on Docker containers.</p>
<p>The big hosters offer startup credit programs, but we decided to start with our already available private resources and migrate to a hoster later.<br />This makes sense especially, as applying to the credit programs is only allowed for new customers, not existing ones, and we wanted to deploy our blog and site first.</p>
<h2 id="heading-chartmogul">Chartmogul</h2>
<p><strong>Recurring revenue analytics and public data</strong></p>
<p>To properly <a target="_blank" href="https://twitter.com/hashtag/buildinpublic">#buildinpublic</a> we wanted to display our MRR (Monthly Recurring Revenue) in our Twitter bio as the location, like so many others. The main service used for this is <a target="_blank" href="https://tweetsync.io/">TweetSync</a> in connection with <a target="_blank" href="https://chartmogul.com/">ChartMogul</a>, which can pull in data from Stripe.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://chartmogul.com/">https://chartmogul.com/</a></div>
<p> </p>
<h2 id="heading-github">GitHub</h2>
<p><strong>Code, project management and sponsors</strong></p>
<p>As the biggest service for Git repositories, GitHub was the obvious choice. Wanting to use GitHub Actions for our CI in the future, cemented that decision.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/">https://github.com/</a></div>
<p> </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/features/actions">https://github.com/features/actions</a></div>
<p> </p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://docs.github.com/en/actions">https://docs.github.com/en/actions</a></div>
<p> </p>
<p>Creating an organization is free now and allows us to keep private repositories, as well as public ones.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/codersfail">https://github.com/codersfail</a></div>
<p> </p>
<p>The GitHub sponsor program, similar to Patreon or similar services, allows for receiving direct support.</p>
<h2 id="heading-bunq">bunq</h2>
<p><strong>Banking, account and credit card</strong></p>
<p>bunq is a Dutch bank built by developers. It provides great features, like 25 subaccounts and cards as well as local bank account numbers (IBAN) for some European countries as well as holding money in different currencies.</p>
<p>It provides a lot of benefits to those who enjoy technology and know what should be possible with it, even in the banking sector.<br />It provides APIs for automation, etc.</p>
<p>As we were already paying for private accounts and Germany allows freelancers to use their private bank accounts for their work, we started out using it.<br />Creating a free (limited) business account is easy and we can switch to more features are soon as we deem it sensible to create our business entity.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.bunq.com/">https://www.bunq.com/</a></div>
<p> </p>
<p><a target="_blank" href="https://www.bunq.me/codersfail">Link to directly support us</a></p>
<p><a target="_blank" href="https://web.bunq.com/invite/SimJoSt">Affiliate link to sign-up and give us 10 trees</a></p>
]]></content:encoded></item><item><title><![CDATA[Structuring and documenting in Notion]]></title><description><![CDATA[A structured home for our thoughts and data
Having just found and defined our vision and framework, we needed a place to put down all our thoughts, decisions, workflows and ideas.
Being already familiar with it from personal use and at the company we...]]></description><link>https://writings.coders.fail/structuring-and-documenting-in-notion</link><guid isPermaLink="true">https://writings.coders.fail/structuring-and-documenting-in-notion</guid><category><![CDATA[Bootstrapping]]></category><category><![CDATA[documentation]]></category><category><![CDATA[notion]]></category><category><![CDATA[Build In Public]]></category><category><![CDATA[Productivity]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Sat, 20 Aug 2022 11:46:00 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1642132652859-3ef5a1048fd1?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDR8fG5vdGlvbnxlbnwwfHx8fDE2Njg2MTEyNjk&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-a-structured-home-for-our-thoughts-and-data">A structured home for our thoughts and data</h3>
<p>Having just found and defined our vision and framework, we needed a place to put down all our thoughts, decisions, workflows and ideas.</p>
<p>Being already familiar with it from personal use and at the company we are employed at, we started with <a target="_blank" href="https://www.notion.so/">Notion</a>. The free version for teams and collaborative allows for 1k blocks.<br />We were lucky and Notion forgot how to count for the first weeks of our usage, so we could exceed that limit, which we did in a matter of days.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">The limitation does not exist for personal workspaces for a single person. Upgrading to a workspace with collaboration features by sharing it with others is possible at any time.</div>
</div>

<p>Very quickly we collected ideas for names and domains, actual business ideas, to-do lists and boards as well as our vision and workflows.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590828963156615168">https://twitter.com/coders_fail/status/1590828963156615168</a></div>
<p> </p>
<p>Notion's ability to display entries in a database in multiple different ways (list, table, board, calendar and timeline) as well as allow for different filters and sorting settings on each view, helped us keep track of everything.</p>
<p>Even better, the new display of integer fields as progress and percentages as well as the formula property, helped us immensely whilst rating our business ideas. We could calculate an average, sort them by that value and filter out entries that are currently not relevant.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590828966491090944">https://twitter.com/coders_fail/status/1590828966491090944</a></div>
<p> </p>
<h3 id="heading-startup-credits">Startup Credits</h3>
<p>Notion is great but can be too expensive for people just starting and aiming to keep their cost down as much and long as possible.<br />Notion helps out with this by providing a startup credit program to which anyone with a website can apply. It doesn't even have to be set up in English.</p>
<p>They grant $1k in credits as a maximum, but lower amounts are possible as well.</p>
<p>To learn more about Notions Startup credit program and apply, visit the dedicated landing page: <a target="_blank" href="https://www.notion.so/startups">https://www.notion.so/startups</a></p>
<h3 id="heading-workarounds-tips-and-hints">Workarounds, tips and hints</h3>
<p>If you are still missing a website or valuable content, there are other ways around the limitations.</p>
<p>When working with a team, create a central account that you all use together to avoid the limits placed on collaborative workspaces. To associate tasks with members of your team, create a separate "team" database and work with relations.</p>
<p>This has the additional advantage of allowing to reference users who are not yet onboarded to Notion and external partners that will never be in Notion as well as retroactively noting down team members who are not part of the Notion team anymore.</p>
]]></content:encoded></item><item><title><![CDATA[Defining our vision and framework]]></title><description><![CDATA[Reflecting on the approach
In our time during the About You Pangea Festival 2022, we came up with our vision for:

co-creation

our projects and startup

the way of working and approaching ideas

the contents of our ideas


https://twitter.com/coders...]]></description><link>https://writings.coders.fail/defining-our-vision-and-framework</link><guid isPermaLink="true">https://writings.coders.fail/defining-our-vision-and-framework</guid><category><![CDATA[Bootstrapping]]></category><category><![CDATA[Indie Maker]]></category><category><![CDATA[Build In Public]]></category><category><![CDATA[Startups]]></category><category><![CDATA[failure]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Mon, 15 Aug 2022 14:59:00 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1453563391321-df71955e9289?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDd8fHZpc2lvbnxlbnwwfHx8fDE2Njg2MTExODY&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-reflecting-on-the-approach">Reflecting on the approach</h3>
<p>In our time during the <a target="_blank" href="https://www.aboutyoupangea-festival.de/">About You Pangea Festival</a> <a target="_blank" href="https://www.youtube.com/watch?v=qpz56IPtnZE">2022</a>, we came up with our vision for:</p>
<ul>
<li><p>co-creation</p>
</li>
<li><p>our projects and startup</p>
</li>
<li><p>the way of working and approaching ideas</p>
</li>
<li><p>the contents of our ideas</p>
</li>
</ul>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590820994327121920">https://twitter.com/coders_fail/status/1590820994327121920</a></div>
<p> </p>
<p>Instead of starting with one idea, as many do, it was more important to us how we were going to work and what our day-to-day would ideally look like. Especially since we both had some experiences with freelance work and bootstrapping startups that didn't work out the way we wanted them to.<br />So a different approach was needed to succeed someday.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590821012786270208">https://twitter.com/coders_fail/status/1590821012786270208</a></div>
<p> </p>
<p>The way to success would be lined with lessons learned, disappointments, and failures, that was clear to us. So we decided to embrace the lessons it would provide and make it a point to fail rapidly, repeatedly, openly, publicly, honestly, and confidently.<br />And then learn from our results, identify our mistakes, correct our approach, iterate, and improve.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590826627910754304">https://twitter.com/coders_fail/status/1590826627910754304</a></div>
<p> </p>
<p>Each of the failures would allow us to create content about it, allowing others to learn along with us and get to their goal faster. The decision to #buildinpublic was easily made and would force us to get more comfortable with failure culture, kick-start personal growth and hold each other accountable with open communication.</p>
<p>To do so, we needed our name and presentation to reflect and make people quickly understand. We went through quite a few iterations. Very quickly, we fell in love with the idea of having 2 domains: 1 with the <code>.fail</code> TLD and one with <code>.win</code></p>
<p>The main ones with <code>win</code>/<code>fail</code> TLDs in the running were:</p>
<ol>
<li><p><code>coders</code></p>
</li>
<li><p><code>decode</code></p>
</li>
<li><p><code>next</code></p>
</li>
</ol>
<ul>
<li><p><code>replay</code> / <code>incremental</code> / <code>iterative</code></p>
</li>
<li><p><code>simple</code> / <code>mvp</code> / <code>nevermind</code> / <code>poc</code> / <code>bootstrapped</code> / <code>value</code></p>
</li>
<li><p><code>endless</code> / <code>constant</code> / <code>many</code></p>
</li>
<li><p><code>loud</code> / <code>noisy</code></p>
</li>
<li><p><code>humble</code> / <code>confident</code> / <code>bold</code> / <code>graceful</code></p>
</li>
<li><p><code>planned</code> / <code>certain</code> / <code>upcoming</code> / <code>calculated</code></p>
</li>
</ul>
<p>But also others like: <code>fuckup</code> / <code>instant</code> / <code>quickly</code> <code>.build</code></p>
<p>In the end, we decided on the name that we both could associate with, where both TLDs were still available, and where Google keywords would not be highly competitive.</p>
<h3 id="heading-our-vision-framework">Our vision framework</h3>
<p>The rough outlines of our approach ended up being the following:</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">⏲</div>
<div data-node-type="callout-text">Limit the time we spend on an idea andamp; launch it fast.</div>
</div>

<p>In the past, we kept changing and improving the concept of an idea over and over, kept working on it for a long time, and never really launched and validated it.</p>
<blockquote>
<p>People will start using it when I get it to that perfect point and feature set.</p>
</blockquote>
<p>So we limited ourselves to having a rough version 1 ready after 2 weeks. Just spend after-work hours and weekends on it.<br />Preferably, we would spend that time together in one location to improve our communication and keep our focus and motivation.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">📣</div>
<div data-node-type="callout-text">Polish andamp; market the idea for no more than 2 additional weeks.</div>
</div>

<p>Getting the idea to a launch state with working out the last kinks, after successfully building the core, would take a bit more time. So we gave ourselves 2 additional weeks to do so, get people excited for it, and prepare the monetization.</p>
<p>This time could be very well spent apart and wouldn't require us to be in the same location. Giving us a bit more freedom and focus on the task at hand.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💰</div>
<div data-node-type="callout-text">Monetize immediately andamp; aim to earn the first buck after a month.</div>
</div>

<p>After the conclusion of the month, the idea needs to be fully launched and include a monetization feature. Ideally, we would already have the first purchase at that time, giving us an idea if people would like to pay for it.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590826631383613440">https://twitter.com/coders_fail/status/1590826631383613440</a></div>
<p> </p>
<p>With this approach, each idea would not take more than a month to get launched, allowing us to rapidly iterate on things we would like to improve on.</p>
]]></content:encoded></item><item><title><![CDATA[Starting our journey]]></title><description><![CDATA[In July of 2022, we (Marius and Joda) joined our team @ yay.digital and 2Bros Group on a company workation on Ibiza. For one week we enjoyed some much-needed sun and water, direct human connection as well as communication and exchange after over 2 ye...]]></description><link>https://writings.coders.fail/starting-our-journey</link><guid isPermaLink="true">https://writings.coders.fail/starting-our-journey</guid><category><![CDATA[Indie Maker]]></category><category><![CDATA[Startups]]></category><category><![CDATA[Build In Public]]></category><category><![CDATA[Bootstrapping]]></category><category><![CDATA[failure]]></category><dc:creator><![CDATA[Joda Stößer]]></dc:creator><pubDate>Fri, 12 Aug 2022 12:51:00 GMT</pubDate><enclosure url="https://images.unsplash.com/photo-1489641024260-20e5cb3ee4aa?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDF8fGpvdXJuZXl8ZW58MHx8fHwxNjY4NjEzODAy&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In July of 2022, we (Marius and Joda) joined our team @ <a target="_blank" href="https://yay.digital">yay.digital</a> and <a target="_blank" href="https://2bros-group.com">2Bros Group</a> on a company workation on Ibiza. For one week we enjoyed some much-needed sun and water, direct human connection as well as communication and exchange after over 2 years of home office.</p>
<p>Being passionate about the work we do at our company and web tech and development, we discussed some future ideas with our colleagues to advance the stack of the company, maybe fill the vacation fund or start completely new ideas.</p>
<p>Starting to talk about it on our boat trip, we continued to discuss ideas, paths forward and how to approach it throughout the way back in airports, planes and trains.</p>
<p>The next time, both of us met up to advance our ideas and develop our approach was at the <a target="_blank" href="https://www.aboutyoupangea-festival.de/">About You Pangea Festival</a> <a target="_blank" href="https://www.youtube.com/watch?v=qpz56IPtnZE">2022</a>. It gave us some distance from the rut of our daily lives and gave us a space to freely think about new ideas.<br />Both of us had worked freelance before with varying success and satisfaction and wanted to improve upon it.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590820994327121920">https://twitter.com/coders_fail/status/1590820994327121920</a></div>
<p> </p>
<blockquote>
<p>Our Tweet about meeting up at the About You Pangea 2022 festival for brainstorming</p>
</blockquote>
<p>By meeting up beforehand, staying 4 days at the festival and having another day after, we could spend some real time together. It gave us enough time to switch it up between brainstorming sessions, swimming, eating, drinking, dancing and chilling.<br />A lot of different influences from music, artists, cultural events, sports and just people in general allowed us to switch it up to kick-start our creativity.</p>
<p>Our desire to start bootstrapping startups together was not born of a singular business idea nor a dissatisfaction with our jobs or the work we did. But from a drive to grow as people, learn new skills, a belief to thrive as freelancers and entrepreneurs, inspired by other #buildinpublic bootstrappers. Realizing, that getting paid by the hour doesn't provide a lot of opportunity to scale it and very few companies allow one to contribute to better processes to allow for internal optimization and automation, never mind profiting from it yourself. Mostly the latter.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://twitter.com/coders_fail/status/1590821012786270208">https://twitter.com/coders_fail/status/1590821012786270208</a></div>
<p> </p>
<blockquote>
<p>Our tweets about our activities and brainstorming at the About You Pangea 2022 festival</p>
</blockquote>
<p>Being interested in working on bigger projects, open-source, non-profits and selflessly improving the world for everyone without getting paid, we longed for a passive income that would allow us to invest the necessary time.</p>
<p>It became clear to us, that we needed an approach to building, launching, validating, marketing and monetizing projects and startups in a way that would get us to the goal the fastest.<br />The immediate goal would be to get to 2k € MRR, 1k € for each of us, giving us a certain amount of freedom to reduce our working hours in typical jobs and focus more of our time on creating the next one or expanding an existing one.</p>
<p>They needed to be very low-maintenance and automatically scalable until the time when monthly revenue would allow us to spend time on them regularly.</p>
<hr />
<p>To find other people talking about #buildinpublic check:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://buildinpublic.com/">https://buildinpublic.com/</a></div>
<p> </p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/buildinpublic">https://twitter.com/buildinpublic</a></p>
</li>
<li><p><a target="_blank" href="https://twitter.com/search?q=%23buildinpublic">https://twitter.com/search?q=%23buildinpublic</a></p>
</li>
</ul>
]]></content:encoded></item></channel></rss>