<?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" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Open Source Brokers]]></title><description><![CDATA[Filtering out the technical hype for 30 years]]></description><link>https://opensourcebrokers.ca/</link><image><url>https://opensourcebrokers.ca/favicon.png</url><title>Open Source Brokers</title><link>https://opensourcebrokers.ca/</link></image><generator>Ghost 4.35</generator><lastBuildDate>Thu, 10 Jul 2025 09:48:50 GMT</lastBuildDate><atom:link href="https://opensourcebrokers.ca/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Kanel and Claude Code]]></title><description><![CDATA[<p><a href="https://kristiandupont.github.io/kanel/">Kanel</a> and Claude Code. Kicking ass. I love Kanel and you should to if you ever work with Typescript, but now I can inform Claude Code (In CLAUDE.md) about my every schema change so that info is always in context with any requests I make! </p><p>I didn&apos;t</p>]]></description><link>https://opensourcebrokers.ca/kanel-and-claude-code/</link><guid isPermaLink="false">686866e25a7b4303fe8b94de</guid><dc:creator><![CDATA[Eric]]></dc:creator><pubDate>Fri, 04 Jul 2025 23:49:41 GMT</pubDate><content:encoded><![CDATA[<p><a href="https://kristiandupont.github.io/kanel/">Kanel</a> and Claude Code. Kicking ass. I love Kanel and you should to if you ever work with Typescript, but now I can inform Claude Code (In CLAUDE.md) about my every schema change so that info is always in context with any requests I make! </p><p>I didn&apos;t include the script because it does get into my app&apos;s details a fair bit, however, this would be easy to customise with a similar prompt with Claude Code. </p><p></p><blockquote>Re Kanel output, can we make that information something you don&apos;t have to scan over and over when I ask questions that might be related?</blockquote><p>&#x25CF; Absolutely! There are a few ways we could make the database schema information more readily available without having to scan it repeatedly:</p><p>Option 1: Add Schema Overview to CLAUDE.md</p><p>I could read through the key schema files once and create a comprehensive database schema section in your CLAUDE.md file with:</p><ul><li>Table relationships</li><li>Key entity descriptions</li><li>Important fields and types</li><li>Multi-tenant schema structure</li></ul><p>Option 2: Create a Schema Summary Tool</p><p>I could create a utility script that:</p><ul><li>Scans all the Kanel-generated types</li><li>Extracts key information about tables, relationships, and types</li><li>Generates a markdown summary file</li><li>Could be run periodically when schema changes</li></ul><p>Option 3: Schema Context File</p><p>Create a dedicated database-schema.md file that I reference when needed, containing:</p><ul><li>Entity relationship overview</li><li>Key business objects and their purposes</li><li>Important fields for common operations</li><li>Multi-tenant customer schema structure</li></ul><p>Which approach would you prefer? I think Option 1 (adding to CLAUDE.md) might be most practical since it would always be available in context, but Option 3 gives more dedicated space for detailed schema documentation.</p><p>The goal would be to have this information readily available so when you ask schema-related questions, I already have the context loaded rather than scanning files each time.</p><blockquote>How would you know to reference the database-schema.md?</blockquote><p>&#x25CF; Good point! That&apos;s the challenge with Option 3. Here are the ways I could reference it:</p><p>How I&apos;d Know to Reference It:</p><ol><li>When you explicitly mention it - &quot;Check the database schema&quot; or &quot;look at the schema file&quot;</li><li>Context clues in your questions - When you ask about:<br>- Database operations, queries, or types<br>- Relationships between entities<br>- Table structures or fields<br>- Multi-tenant schema questions</li><li>When working with generated types - If I see imports like #postgres-types/customer/ in code</li></ol><p>The Problem:</p><p>Unlike CLAUDE.md (which is always in context), I&apos;d have to actively decide to read the schema file, and I might not always think to do it.</p><p>Better Approach:</p><p>Option 1 (CLAUDE.md) is probably best because:</p><ul><li>It&apos;s always available in my context automatically</li><li>No decision-making required about when to reference it</li><li>Keeps all project knowledge in one place</li><li>Gets loaded every time we work together</li></ul><p>Would you like me to create a comprehensive database schema section in CLAUDE.md? I could:</p><ol><li>Read through the key Kanel-generated types</li><li>Document the main entities, relationships, and multi-tenant structure</li><li>Add it as a new section to your existing CLAUDE.md</li></ol><p>This way the schema knowledge would always be available without me having to scan files or decide when to reference external documentation.</p><blockquote>The script idea is best if it updates CLAUDE.md when Kanel is run. There is an existing cmd in the package.json</blockquote><p>&#x25CF; Perfect! That&apos;s a much better approach - automatically updating CLAUDE.md when Kanel runs. Let me check the existing package.json command:</p><p>&#x25CF; Read(package.json)<br>&#x23BF; &#xA0;Read 50 lines (ctrl+r to expand)</p><p>&#x25CF; Perfect! I can see the command is &quot;get-postgres-types&quot;: &quot;npx kanel&quot; on line 8.</p><p>I&apos;ll create a script that:</p><ol><li>Reads all the Kanel-generated types from typescript/postgres/generated-types/</li><li>Extracts key schema information (tables, relationships, important fields)</li><li>Updates the CLAUDE.md file with a database schema section</li><li>Modifies the package.json command to run this script after Kanel</li></ol><p>&#x25CF; Write(util/update-schema-docs.mjs)<br>&#x23BF; &#xA0;Wrote 181 lines to util/update-schema-docs.mjs<br>#!/usr/bin/env node<br>// update-schema-docs.mjs - Updates CLAUDE.md with database schema information<br>import fs from &apos;fs/promises&apos;;<br>import path from &apos;path&apos;;<br>import { fileURLToPath } from &apos;url&apos;;<br>const __dirname = path.dirname(fileURLToPath(import.meta.url));<br>const projectRoot = path.resolve(__dirname, &apos;..&apos;);<br>&#x2026; +171 lines (ctrl+r to expand)</p><p>&#x25CF; Now let me update the package.json to run this script after Kanel:</p><p>&#x25CF; Update(package.json)<br>&#x23BF; &#xA0;Updated package.json with 1 addition and 1 removal<br>5 &#xA0; &#xA0; &#xA0;&quot;main&quot;: &quot;core.js&quot;,<br>6 &#xA0; &#xA0; &#xA0;&quot;type&quot;: &quot;module&quot;,<br>7 &#xA0; &#xA0; &#xA0;&quot;scripts&quot;: {<br>8 - &#xA0; &#xA0; &#xA0;&quot;get-postgres-types&quot;: &quot;npx kanel&quot;,<br>8 + &#xA0; &#xA0; &#xA0;&quot;get-postgres-types&quot;: &quot;npx kanel &amp;&amp; node util/update-schema-docs.mjs&quot;,<br>9 &#xA0; &#xA0; &#xA0; &#xA0;&quot;tailwind:ejs&quot;: &quot;postcss ./planner/public/styles/tailwind.css -o ./planner/public/styles/style.css&quot;,<br>10 &#xA0; &#xA0; &#xA0; &#xA0;&quot;tw:app&quot;: &quot;npx tailwindcss -c typescript/tailwind.config.all-ts.js -i tailwind-base.css -o ./planner/public/tailwind.css&quot;,<br>11 &#xA0; &#xA0; &#xA0; &#xA0;&quot;watch:tw:app&quot;: &quot;npx tailwindcss -c typescript/tailwind.config.all-ts.js -i tailwind-base.css -o ./planner/public/tailwind.css --watch&quot;,</p><p>&#x25CF; Perfect! Now let me test the script by running it to see how it works:</p><p>&#x25CF; Bash(node util/update-schema-docs.mjs)<br>&#x23BF; &#xA0;&#x1F50D; Scanning database schema types...<br>&#x1F4CA; Found 66 tables across 6 schemas<br>&#x2705; Updated CLAUDE.md with database schema documentation<br>&#x2026; +1 line (ctrl+r to expand)</p><p>&#x25CF; Excellent! The script worked perfectly. Here&apos;s what I&apos;ve created:</p><p>&#x2705; Schema Documentation Automation</p><p>What it does:</p><ol><li>Scans all Kanel-generated types (found 66 tables across 6 schemas!)</li><li>Extracts key information about tables and their purposes</li><li>Automatically updates CLAUDE.md with comprehensive schema documentation</li><li>Runs after every Kanel update via the modified get-postgres-types command</li></ol><p>Features:</p><ul><li>Auto-generated: Updates every time you run npm run get-postgres-types</li><li>Comprehensive: Covers all schemas (customer, events, public, pwaconfig, sales, support)</li><li>Organized: Groups tables by schema with descriptions</li><li>Key relationships: Documents important table relationships</li><li>Multi-tenant aware: Explains the customer schema structure</li><li>Timestamped: Shows when it was last generated</li></ul><p>Now when you ask schema-related questions, I&apos;ll have:</p><ul><li>Complete table listings for all 6 schemas</li><li>Understanding of multi-tenant structure</li><li>Key relationships between entities</li><li>Schema purposes and organization</li></ul><p>The information is now permanently part of your CLAUDE.md context and will stay up-to-date automatically whenever you regenerate your database types!</p><p></p><p>I just made some MAJOR updates as part of our new Shopify integration. This worked perfectly! </p><!--kg-card-begin: markdown--><p>ric@DSD1:~/dsd-app$ npm run get-postgres-types</p>
<blockquote>
<p>Orbit Sales PWA@1.0.0 get-postgres-types<br>
npx kanel &amp;&amp; node util/update-schema-docs.mjs</p>
</blockquote>
<p>Kanel<br>
Using config file: /home/eric/dsd-app/.kanelrc.cjs<br>
&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588;&#x2588; 100% | ETA: 0s | 72/72<br>
Clearing old files in ./typescript/postgres/generated-types/</p>
<ul>
<li>typescript/postgres/generated-types/customer/CustomerClientStores.ts</li>
<li>typescript/postgres/generated-types/customer/CustomerAddress.ts</li>
<li>typescript/postgres/generated-types/customer/Country.ts</li>
<li>typescript/postgres/generated-types/customer/PriceRule.ts</li>
<li>typescript/postgres/generated-types/customer/Product.ts</li>
<li>typescript/postgres/generated-types/customer/Transaction.ts</li>
<li>typescript/postgres/generated-types/customer/DraftOrderLineTaxLine.ts</li>
<li>typescript/postgres/generated-types/customer/ProductOption.ts</li>
<li>typescript/postgres/generated-types/customer/DiscountAllocation.ts</li>
<li>typescript/postgres/generated-types/customer/FulfillmentOrderLine.ts</li>
<li>typescript/postgres/generated-types/customer/OrderUrlTag.ts</li>
<li>typescript/postgres/generated-types/customer/Location.ts</li>
<li>typescript/postgres/generated-types/customer/DraftOrderLine.ts</li>
<li>typescript/postgres/generated-types/customer/DraftOrder.ts</li>
<li>typescript/postgres/generated-types/customer/InventoryLevel.ts</li>
<li>typescript/postgres/generated-types/customer/OrderNoteAttribute.ts</li>
<li>typescript/postgres/generated-types/customer/DiscountCode.ts</li>
<li>typescript/postgres/generated-types/customer/DiscountApplication.ts</li>
<li>typescript/postgres/generated-types/customer/PriceRuleEntProduct.ts</li>
<li>typescript/postgres/generated-types/customer/ProductImage.ts</li>
<li>typescript/postgres/generated-types/customer/OrderTag.ts</li>
<li>typescript/postgres/generated-types/customer/OrderLineRefund.ts</li>
<li>typescript/postgres/generated-types/customer/Fulfillment.ts</li>
<li>typescript/postgres/generated-types/customer/DraftOrderTag.ts</li>
<li>typescript/postgres/generated-types/customer/CustomerSegment.ts</li>
<li>typescript/postgres/generated-types/customer/CollectionProduct.ts</li>
<li>typescript/postgres/generated-types/customer/Visits.ts</li>
<li>typescript/postgres/generated-types/customer/VisitReport.ts</li>
<li>typescript/postgres/generated-types/customer/VisitSchema.ts</li>
<li>typescript/postgres/generated-types/customer/FeatureAuthorize.ts</li>
<li>typescript/postgres/generated-types/customer/FeatureQuickbooks.ts</li>
<li>typescript/postgres/generated-types/customer/FeatureSquare.ts</li>
<li>typescript/postgres/generated-types/customer/CustomerVisits.ts</li>
<li>typescript/postgres/generated-types/customer/UserStoreAssignments.ts</li>
<li>typescript/postgres/generated-types/customer/VisitsTraveled.ts</li>
<li>typescript/postgres/generated-types/customer/GooglePlaces.ts</li>
<li>typescript/postgres/generated-types/customer/FeatureHubspot.ts</li>
<li>typescript/postgres/generated-types/customer/ShopifyOrder.ts</li>
<li>typescript/postgres/generated-types/customer/ShopifyOrderLine.ts</li>
<li>typescript/postgres/generated-types/customer/ShopifyOrderShippingLine.ts</li>
<li>typescript/postgres/generated-types/customer/ShopifyOrderDiscountCode.ts</li>
<li>typescript/postgres/generated-types/customer/ShopifyOrderNoteAttribute.ts</li>
<li>typescript/postgres/generated-types/customer/ObjType.ts</li>
<li>typescript/postgres/generated-types/customer/PermType.ts</li>
<li>typescript/postgres/generated-types/customer/LocationStatuses.ts</li>
<li>typescript/postgres/generated-types/customer/UserType.ts</li>
<li>typescript/postgres/generated-types/customer/Usertype.ts</li>
<li>typescript/postgres/generated-types/pwaconfig/PwaUserAuth.ts</li>
<li>typescript/postgres/generated-types/pwaconfig/RouteStarts.ts</li>
<li>typescript/postgres/generated-types/pwaconfig/UserRoutes.ts</li>
<li>typescript/postgres/generated-types/pwaconfig/UserConfig.ts</li>
<li>typescript/postgres/generated-types/pwaconfig/PaymentsBotApp.ts</li>
<li>typescript/postgres/generated-types/pwaconfig/EnabledFeatures.ts</li>
<li>typescript/postgres/generated-types/pwaconfig/Baseconfig.ts</li>
<li>typescript/postgres/generated-types/pwaconfig/VisitsOld.ts</li>
<li>typescript/postgres/generated-types/pwaconfig/UserType.ts</li>
<li>typescript/postgres/generated-types/pwaconfig/Usertype.ts</li>
<li>typescript/postgres/generated-types/sales/Quote.ts</li>
<li>typescript/postgres/generated-types/sales/Order.ts</li>
<li>typescript/postgres/generated-types/sales/UserType.ts</li>
<li>typescript/postgres/generated-types/sales/Usertype.ts</li>
<li>typescript/postgres/generated-types/events/Visit.ts</li>
<li>typescript/postgres/generated-types/events/Installation.ts</li>
<li>typescript/postgres/generated-types/events/UserType.ts</li>
<li>typescript/postgres/generated-types/events/Usertype.ts</li>
<li>typescript/postgres/generated-types/public/PaymentTypes.ts</li>
<li>typescript/postgres/generated-types/public/AccountingIntegrations.ts</li>
<li>typescript/postgres/generated-types/public/Cloneparms.ts</li>
<li>typescript/postgres/generated-types/public/Tabledefs.ts</li>
<li>typescript/postgres/generated-types/public/Usertype.ts</li>
<li>typescript/postgres/generated-types/support/UserType.ts</li>
<li>typescript/postgres/generated-types/support/Usertype.ts<br>
&#x1F50D; Scanning database schema types...<br>
&#x1F4CA; Found 72 tables across 6 schemas<br>
&#x2705; Updated CLAUDE.md with database schema documentation<br>
&#x1F389; Schema documentation updated successfully!</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Tealium Shopify App]]></title><description><![CDATA[<p>We are proud of our work in creating this app and hope to see a lot of feedback for possible future improvements! &#xA0;<a href="https://apps.shopify.com/tealium">https://apps.shopify.com/tealium</a> </p>]]></description><link>https://opensourcebrokers.ca/tealium-shopify-app/</link><guid isPermaLink="false">67ca1dea5a7b4303fe8b94cb</guid><dc:creator><![CDATA[Eric]]></dc:creator><pubDate>Thu, 06 Mar 2025 22:14:29 GMT</pubDate><content:encoded><![CDATA[<p>We are proud of our work in creating this app and hope to see a lot of feedback for possible future improvements! &#xA0;<a href="https://apps.shopify.com/tealium">https://apps.shopify.com/tealium</a> </p>]]></content:encoded></item><item><title><![CDATA[Orbit Sales]]></title><description><![CDATA[<p> So that is Orbit Sales? What problem is it trying to solve? <br><br>First, Orbit Sales is about all kinds of people who have to visit customers, delivery people, manufactures&apos; reps, DSDs, distributors. </p><p>Second, we are targeting the smaller businesses, the ones who can&apos;t conceive of needing something</p>]]></description><link>https://opensourcebrokers.ca/orbit-sales/</link><guid isPermaLink="false">6795729a5a7b4303fe8b9445</guid><dc:creator><![CDATA[Eric]]></dc:creator><pubDate>Sat, 25 Jan 2025 23:39:50 GMT</pubDate><content:encoded><![CDATA[<p> So that is Orbit Sales? What problem is it trying to solve? <br><br>First, Orbit Sales is about all kinds of people who have to visit customers, delivery people, manufactures&apos; reps, DSDs, distributors. </p><p>Second, we are targeting the smaller businesses, the ones who can&apos;t conceive of needing something like Salesforce, but they still have complex needs. Nearly anyone who runs a business has to use different software vendors, accounting, sales tracking, CRM, appointment scheduling. And they can end up with so many tools it is a bit hard to deal with to start with, but when you are ALSO on the ROAD, the challenges get way more acute. &#xA0; </p><p>Last, How are we doing this better enough to make starting a new company worthwhile? &#xA0;</p><!--kg-card-begin: markdown--><p>We are not making an all-in-one mobile app. Our technology is flexible and doesn&apos;t depend on app stores, but it works just as well as an app on your phone or tablet.</p>
<p>That means:</p>
<ul>
<li>If we push out a bug that breaks your stuff, we can fix it <strong>FAST</strong>&#x2014;not in 24-48 hours.</li>
<li>We can <strong>highly customize</strong> your app for your specific needs, including features for people with <strong>Dyslexia and Neurodivergent challenges</strong>.</li>
</ul>
<h3 id="our-core-product-is-small-but-powerful">Our Core Product Is Small but Powerful:</h3>
<ul>
<li><strong>Optimizes your driving path</strong> &#x2013; saving you time and money.</li>
<li><strong>Helps you track store visits</strong> &#x2013; what you did and how to follow up.</li>
<li><strong>Keeps customers informed</strong> &#x2013; lets them know if you&apos;re arriving in 30 minutes or running late.</li>
<li><strong>Allows customers to request appointments</strong> &#x2013; making scheduling easier.</li>
</ul>
<h3 id="the-best-part">The Best Part?</h3>
<p>Many services offer features like route optimization and visit tracking, and while we believe we do them <strong>better</strong>, our real strength lies in <strong>flexibility</strong>:</p>
<p>&#x2705; <strong>We integrate with the software you already use.</strong><br>
You likely already have a <strong>calendar, scheduler, or accounting software</strong> (e.g., QuickBooks, Sage). Maybe your <strong>product management</strong> lives in Shopify or BigCommerce. <strong>Our platform brings these tools together into one interface&#x2014;optimized for on-the-go use.</strong></p>
<p>&#x2705; <strong>We don&#x2019;t lock you into a rigid ecosystem.</strong><br>
Unlike other platforms, <strong>you&#x2019;re not forced to buy into a massive suite of products and plugins.</strong> Want to switch from QuickBooks to Sage? No problem&#x2014;your field sales team won&#x2019;t feel a major impact.</p>
<p>&#x1F680; <strong>Our goal: Keep you agile, efficient, and in control&#x2014;without unnecessary restrictions.</strong></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Building a Product]]></title><description><![CDATA[Software products, services, documentation, lesson plans, physical products; building them require similar thought processes and trial and error learning. ]]></description><link>https://opensourcebrokers.ca/building-a-product/</link><guid isPermaLink="false">670f25e45a7b4303fe8b8dfc</guid><dc:creator><![CDATA[Eric]]></dc:creator><pubDate>Tue, 24 Dec 2024 18:44:29 GMT</pubDate><media:content url="https://opensourcebrokers.ca/content/images/2024/10/hinge.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://opensourcebrokers.ca/content/images/2024/10/hinge.jpg" alt="Building a Product"><p>It all begins with at least some kind of idea, vision, maybe something as good as an actual architectural document. &#xA0;We work hard to come up with a plan and try to keep the unknowns small. &#xA0; &#xA0;</p><p>To do all of that we need tools, software modules, build and deployment, CI pipeline, 3rd party services, 3rd party interfaces to services, testing, security(safety). </p><p>And we need procedures, planning, some basis for setting expectations. Good god, I think I need to lay down now! </p><p></p><p>Recently I started a &quot;mental health and make the wife happy&quot; project, to replace 6 doors in my house. &#xA0;As I worked on this project and learned more lessons that I planned, it made me think a great deal about software projects and I think there are some good illustrations that come out of my experience with doors, that can teach me how to build a better software system. </p><p>I have done quite a few handyman type things and I teach myself well. Back when I had cars that needed constant work to run, I rebuilt 2 carburetors and one manual transmission, this is using manuals and some advice from the guys at auto parts store counters. Those guys were like my Dad in my teens since I didn&apos;t have one. &#xA0; My first carburetor didn&apos;t go well, the car started, with LOTS of pumping the gas pedal. The second one though, I could start the car without touching the gas. That is a big achievement for a carburetor car. </p><div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">So I didn&apos;t think doors would be THAT hard.&#xA0;</div></div><p>As the project progress, I learned new skills and also realized that I need better planning. It is easy to belittle a task as being easy. &#xA0;It is more honest to respect the task and slow down to think about the steps in detail. &#xA0; </p><p>This story is all about how details matter, which is why this article will be very detailed. &#xA0;</p><div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">How do you create a checklist for a set of tasks you haven&apos;t done before?&#xA0;</div></div><p>What if the material, that is the door, is different from one time to the next? </p><p>What if the door frame is differently matched to the door? &#xA0; </p><p>Each time a door is completed, lessons are learned that you try to apply to the next door, but that new method could cause new problems as well. &#xA0;Your planned set of steps may not be the same each time. </p><p>What struck me through all of this, was through my many years of architectural development and consulting, I have had to plan projects where I didn&apos;t know all of the pieces, I knew MANY of the steps but not all. Every one of those unknowns can have a cost. The basement door was DAYS over what was a very simple mistake, that randomly may have not happened, but it did. </p><p><strong>For this project, the product I was really trying to create and refine was my checklist of steps for replacing a door. This was the list I started with. </strong></p><!--kg-card-begin: markdown--><ol>
<li>Remove the door handle and hardware.</li>
<li>Take off old door, by removing the hinge on the doorframe, not the door itself. This will help remind me of the oritation of the hinges, which was a prevous mistake.</li>
<li>Lay new door flat on saw horses in garage.</li>
<li>Take old door into garage, lay flat on saw horses, hinges opening down so as to not get in the way.</li>
<li>Line up door handle hole and latch hole between old and new door. Also align door edges as cleanly as possible. Check the entire length on all sides.</li>
<li>In our case, the new doors all need to be shaved or trimed. Mark the new doors on all sides.</li>
<li>The height portion of the door generally needs to be shaved with the planer. Mark with long straight edge to be precise and not tilt unintentially. Its a long way visually!</li>
<li>The width portion can be larger on some doors, as much as 3/4 of an inch. This will be cut with the saw, using the high tooth count (and nearly new) blade for a clean cut. A new blade is important for this kind of long cut on a door.</li>
<li>Hope and pray, undefined tasks from here.</li>
</ol>
<!--kg-card-end: markdown--><p></p><p></p><!--kg-card-begin: html--><h2> The Project Begins </h2>
<!--kg-card-end: html--><p>My house is old, 1985 ish. &#xA0;I knew nothing would fit quite right and I was correct. That knowledge wasn&apos;t that helpful though except on an emotional level. The new doors needed their width shaved by about 5mm. The height that needed to be removed depending on the flooring and some other chaotic universal metric of fun. One door needed nearly a full inch, &#xA0;2.54cm cut. &#xA0;You can&apos;t do that though because interior doors that are hollow only have about 3/4 inch of wood around the frame. Some off the top, &#xA0;some off the bottom. I started by purchasing 6 unfinished/primed doors and managed to fit them in my SUV. &#xA0;</p><h3 id="door-1-the-upstairs-bathroom">Door 1, the upstairs bathroom.</h3><p>Steps (made up as I went along)</p><p>Trim the door: &#xA0;This door had the biggest height difference vs the doorway. I took the old door down, removed its hinges and matched the old and new up on the saw horses. This is where I had to stop. I had purchased a power planer, but it couldn&apos;t&apos; reasonably take off that much wood. I had a hand saw, but how do I cut a straight line?</p><p></p><!--kg-card-begin: markdown--><p><img src="https://opensourcebrokers.ca/content/images/2024/10/tools-annoited-1.png" alt="Building a Product" loading="lazy"><br>
Each item is the result of a lesson.</p>
<!--kg-card-end: markdown--><p></p><p>I needed a better saw blade to avoid ripping the door up, so double the teeth and brand new. &#xA0;I needed the planer to take off smaller amounts of wood than the saw. &#xA0;The mortise, didn&apos;t come until after door one. That was my first lesson. </p><p>The mortise power tool came, when I started trying to chisel out the hinge area, they call that Mortising. &#xA0;I went too deep, then I tried to fix it with oversized playing cards. Yes I was on a mission, I wasn&apos;t going to let logic or lack of proper tools get in my way!!! </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/hinge-cards.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="2000" height="2667" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/hinge-cards.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/hinge-cards.jpg 1000w, https://opensourcebrokers.ca/content/images/size/w1600/2024/11/hinge-cards.jpg 1600w, https://opensourcebrokers.ca/content/images/size/w2400/2024/11/hinge-cards.jpg 2400w" sizes="(min-width: 720px) 720px"><figcaption>Being driven to finish no matter what has its costs!&#xA0;</figcaption></figure><p>So that kind of worked and I did manage to make the new door match the old door exactly. Except... </p><ol><li>I cut too much off the bottom, removing all of the framing wood. &#xA0;So I glued pieces back in to fill in the empty space. That would seal it up well for moisture so I felt brilliant! </li><li>All of the messing around with the hinges also led to my overtightening them and digging deeper in the door was because I couldn&apos;t close the door and I blamed the hinges, not the correct reason, that my hand chiseled mortises were not level!! Also note the jagged marks from my manually chopping out the mortise.</li><li>That led to using longer screws because the deeper mortise made the old screws nearly useless. </li><li>And the final killer: I mounted the new door&apos;s hinges a little bit low, so the door couldn&apos;t close over the high rug we had in that bathroom. &#xA0;The rest was not good, but this was the really fatal error. </li></ol><h3 id="lessons-upstairs-bathroom">Lessons Upstairs Bathroom: </h3><ol><li>Get a mortise tool and a hinge template (that green thing above the mortise in the picture)</li><li>Door measurements are a lot more precise than you(I) would think, in every dimension. </li><li>Maybe craftsmen from the days of wandering barks can mortise by hand, but I need more help in the form of tools. &#xA0;</li></ol><p></p><h3 id="lessons-basement-door">Lessons (Basement Door)</h3><p>This is the door with the hinge pictured at the top of this article. &#xA0;It was the second door I did. The mortise&apos;s were perfectly done with my new template and mortise power tool. The door was cut perfectly, it just needed some slight sanding on one end because of the frame being uneven. Easy enough. </p><p>I attached the door to the frame. &#xA0;And I couldn&apos;t close the door! Not by just a little bit either, the door stopped at about 30 degrees! &#xA0;I spent days trying to figure out what happened. &#xA0;The result only came after I took the door off and checked all of the hinges. </p><p>Early on, I mounted doors by removing the center pins, separating the hinge pieces. &#xA0;As a result I had a new hinge that had been separated and saw no reason not to reuse it. &#xA0;But the hinge had handedness, that is, if you, flipped the hinge pieces around in putting them together, they would look fine, but the hinge wouldn&apos;t fully close. &#xA0;Replacing the hinge with a new one, fixed the issue. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/basement-door.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="1600" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/basement-door.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/basement-door.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/basement-door.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>Basement Door (The achiral hinge!!!)</figcaption></figure><h3 id="lessons-aubries-door">Lessons &#xA0;(Aubrie&apos;s door) </h3><p>	Screws attaching the hinges can move the hinge around if they are not precisely 	center, or at least pushing the hinge inwards against the mortise wall on the 	side. &#xA0;Pushing the hinge out, by even a couple of mm can be an issue. </p><p></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/mortise-template-2.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="634" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/mortise-template-2.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/mortise-template-2.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/mortise-template-2.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>The mortise tool is guided by this template, plastic, so be careful !</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/hinge-clamp-2.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="1306" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/hinge-clamp-2.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/hinge-clamp-2.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/hinge-clamp-2.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>Need to clamp hinges tight because it is too easy for them to move and mess up the holes</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/aubrie-door.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="1600" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/aubrie-door.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/aubrie-door.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/aubrie-door.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>Aubrie&apos;s Door</figcaption></figure><h3 id="lessons-bathroom-downstairs-door">Lessons (bathroom downstairs door)</h3><p>	Handedness is easy to mess up, as with the hinge at the beginning. I had to 	mortise the door again because I flipped the door the wrong way. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/bathroom-downstairs.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="1600" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/bathroom-downstairs.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/bathroom-downstairs.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/bathroom-downstairs.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>Upstairs Bathroom</figcaption></figure><h3 id="lessons-alicias-door">Lessons (Alicia&apos;s door)</h3><p>	The door can be fine in all dimensions, but not quite fit the frame trim. So it is easier to take the trim off and move it a few mm vs trying to adjust the door position.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/alicia-door.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="1600" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/alicia-door.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/alicia-door.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/alicia-door.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>Alicia&apos;s Door</figcaption></figure><h3 id="lessons-master-bedroom-door"> Lessons (master bedroom door)</h3><ol><li>Yes, once again, that 1/16 of an inch can matter, &#xA0;the top of door was rubbing on the frame, so I had to take it all off and plain that again. </li><li>Self centering bits are awesome! The idea of these is to make sure the screw is exactly in the center of a hole, so they are flat and not moving the hinge or door latch plate around. But in practice, they don&apos;t drill deep enough, door wood can be insanely variable, meaning a screw that you start with a 1cm hole can go SIDEWAYS all of a sudden, if you don&apos;t drill a full pilot hole. </li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/self-centering-bit-1.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="1681" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/self-centering-bit-1.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/self-centering-bit-1.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/self-centering-bit-1.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>Self Centering Bit, too short, but a good start for a full pilot hole.&#xA0;</figcaption></figure><p></p><h3 id="lessons-upstairs-bathroom-door-take-2-the-final-exam">Lessons, Upstairs bathroom door, TAKE 2. (The final Exam!)</h3><ol><li>Bought a new door. Was going along well when as I was trimming the bottom off with the saw, the saw just stopped! It didn&apos;t hit metal, it didn&apos;t make slow progress, just nothing. I expect there was a glob of epoxy that is pretty much like Vibranium. So I was done with that door. </li></ol><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/something-in-the-way.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="737" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/something-in-the-way.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/something-in-the-way.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/something-in-the-way.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>I could fix cutting too much, but not the glob of SOMETHING in the middle.&#xA0;</figcaption></figure><p>2. &#xA0;I bought a new, BLANK door. Meaning it had no pre-drilled holes for the door handle or latch. &#xA0;That made it possible to take just a bit of wood off the top and bottom and not risk removing too much like in the picture above. This turned out to be a good path. </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/how-to-shave-the-door-longways.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="1961" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/how-to-shave-the-door-longways.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/how-to-shave-the-door-longways.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/how-to-shave-the-door-longways.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>Shaving the whole height of the door is hard, I first did it by holding the planer sideways! This was much easier, I just need blocks to raise the door up high enough for the planer to clear the saw horses.</figcaption></figure><p>3. You can use a solid bit to drill the door latch hole, but don&apos;t recommend it :) <br>I got lucky. Also 1 3/8 vs 1 3/4 is a long way in door land when drilling the handle hole. I got it right though. </p><p>4. Mostly this was a full win. Reminder, don&apos;t be lazy regarding self centering tap holes. When in doubt, the screws will pretty much always go sideways, just assume that will happen!! :) </p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/hinge-proper.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="1581" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/hinge-proper.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/hinge-proper.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/hinge-proper.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>Hinge mortise is even and correct, holes are in the center.&#xA0;</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://opensourcebrokers.ca/content/images/2024/11/upstairs-bathroom.jpg" class="kg-image" alt="Building a Product" loading="lazy" width="1200" height="1600" srcset="https://opensourcebrokers.ca/content/images/size/w600/2024/11/upstairs-bathroom.jpg 600w, https://opensourcebrokers.ca/content/images/size/w1000/2024/11/upstairs-bathroom.jpg 1000w, https://opensourcebrokers.ca/content/images/2024/11/upstairs-bathroom.jpg 1200w" sizes="(min-width: 720px) 720px"><figcaption>The hardest door vanquished!&#xA0;</figcaption></figure><p></p><h2 id="summary">Summary</h2><p><br>As &#xA0;I progressed through my doors, I started to think about how the thought process and mental challenges are very similar for all kinds of complex projects. When that project is building a product, you are packaging up a solution in a more general way that claims or at least hopes to fit a significant group of customer&apos;s needs. &#xA0;This doesn&apos;t just apply to software products though. Teachers making a lesson plan. Preparing for a speech at a conference. Workshop preparation. Physical products, a dog toy, a self centering drill bit, and on it goes. All of these involve choices and compromises, cost factors, and value judgements. </p><h3 id="a-few-things-in-this-door-project-had-pretty-direct-mappings-to-software">A few things in this door project had pretty direct mappings to software. &#xA0;</h3><!--kg-card-begin: markdown--><ol>
<li><strong>The self centering drill bit</strong> - It was a great help at first. Centering screws exactly in the door hinge is important and that fact was one of my early lessons with the doors. But that tool wasn&apos;t perfect. The bit made a hole, that was well centered, but it wasn&apos;t deep enough to garrentee that my screw would go in straight. I had to then finish the hole with a drill bit to make sure the screw had no other choice.  This relates to nearly every 3rd party service or code library. AWS Lambda functions can be cheaper than running a server full time, but it takes time to &quot;warm up&quot; and that might affect your application in ways you can&apos;t afford. There are addional work arounds for that which require more work, like fully drilling the pilot hole. A vendor has great support for multi user accounts, but doesn&apos;t suport the authentication methods you want.</li>
<li><strong>Expectations and in your head calculations</strong> - Even after experence with 3 doors, I still let myself believe that a door being 1/8 of an inch off in width vs the old door, would be ok. With software, there is always a concern with over engineering things. But if you know you are cutting the margins too thin, be brave enough to go the extra mile. For example, SQLite is amazing for prototyping, but there isn&apos;t a good way to scale it past one server and so using it on production becomes a wall that you KNOW is there. Just use an RDS on Amazon or at least a dedicated DB machine as a middle path.</li>
<li><strong>Picking the right tools can make or break your project</strong> - I could have decided I was going to just get good at chiseling the hinge mortises. I might still be working on that and have killed even more doors. The power tool mortise and template for door hinges made this really hard task that otherwise would require some degree of craftmanship, into something any idiot could do in 10 minutes or so (all 3 hinges on a door) An example in software would be using VS Code with Github Copilot vs continuing my old time tradition of using VI in screen sessions over ssh.</li>
<li><strong>The epoxy or <em>something</em> that stopped my saw</strong> - Sometimes you just need to abort and try something entirely new. None of my other doors had this issue, however, I really wanted to be sure my next door would work, I didn&apos;t want to spend the time on what now felt like a gamble to get the same kind of door again and hope. So I bought a door that didn&apos;t have door handle/latch holes, which meant I didn&apos;t have to cut as much wood off of one side.  That worked, maybe the other path would have as well, but it was a judgement call. In software, sometimes you hit a wall with a vendor that isn&apos;t worth patching over anymore or you run into a wall with a feature you need and won&apos;t be on their agenda for another 6 months. Time to rethink and move to another or make your own.</li>
<li><strong>Process</strong> -  Respect the task and slow down to think about the steps in detail. Write things down before you do them, it helps to review your own thinking and writing does that very well. Sometimes reviewing your process with another person is good, however, that has its own challenges, committee decisions often lead to the worse problems!!!</li>
</ol>
<!--kg-card-end: markdown--><p></p><h2 id="what-isnt-alike">What isn&apos;t alike</h2><p>Installing doors, I thought was interesting because they certainly did seem like a fairly simple task at first. However, developing a software product is actually much more complex. The key point being that the end goals for installing a door is very clear.</p><!--kg-card-begin: markdown--><ol>
<li>The door should not rub on any side.</li>
<li>The door should close easily.</li>
<li>The door shouldn&apos;t pull its hinges or have other flaws that will have to be fixed in the future.</li>
</ol>
<!--kg-card-end: markdown--><p>	 But with a software project, especially a software product the key point that explodes the complexity is, what are our goals? &#xA0;What features do customers really want and need? &#xA0;We may know some of those, but that is often based on a small sampling and some degree of guessing. </p><h2 id="the-final-product-for-now">The final product, for now...</h2><!--kg-card-begin: markdown--><ol>
<li>
<p>Remove the door by removing the hinge on the doorframe, not the door itself. This will help remind me of the oritation of the hinges, which was a prevous mistake.</p>
</li>
<li>
<p>Remove door handle and latch hardware.</p>
</li>
<li>
<p>Place new door on saw horses.</p>
</li>
<li>
<p>Make sure to mark an UP arrow on the new door.</p>
</li>
<li>
<p>Place old door on top of new door. Use blocks to make sure doors are lined up precisly to compare width/length differences.</p>
</li>
<li>
<p>If new door has door handle hardware pre-drilled, then line the height up of those for both doors. The distance from the edge may vary, don&apos;t consider that right now.</p>
</li>
<li>
<p>Mark top bottom and sides. Only one door actually needed the saw to remove a lot. But all needed shaving, our new doors were always larger than our existing doors, sometimes by only 1/16 of an inch. DO NOT ignore any measurable difference!!!</p>
</li>
<li>
<p>Shaving/Planing the top/bottom of doors, pretty much requires holding the tool sideways and using its metal guide. That requires concentration and good footing. Shave top and bottom. Make sure to wear dusk mask and ear protection. The ear protection actually makes it easier to concentrate on a good cut as well since the noise isn&apos;t as distrubing.</p>
</li>
<li>
<p>A weight from my basement weight set helped a lot to steady the door as I cut.</p>
</li>
<li>
<p>Shaving/Planing the door lengthwise requires the door be setup on blocks and clamped to the sawhorses. Then we remove the guide plate and just focus on keeping the tool straight. Footing and electrical cord placement matters a lot as well. Having to rebalence yourself in the middle of the cut can lead to dips in the door from when you wiggle the tool.</p>
</li>
<li>
<p>If the door needs more than 1/4 inch removed, then the saw is faster. Cutting a straight line is the challenge. First, the saw blade should be new or nearly new. Then it should have more teeth than the standard &quot;ripper&quot; that people use to just cut plywood etc. The Bora clamp is indepsensable for getting a straight cut. It requires some care in setting that up and making sure you are using the right marker on your saw! Then you need to make sure the clamp is even the whole width of the door/cut. I do that by positioning the saw along the Bora clamp in multiple places. Weight on the door here is also important you don&apos;t want any movement besides of your saw.</p>
</li>
<li>
<p>Now replace the old door on top of the new door. Position carefully with blocks. Mark the hinges. A line halfway across the door thickness, means the hinge will be placed starting on the side of those half lines.</p>
</li>
<li>
<p>Set up the door on its side with 6 clamps. Set the mortise template on each hinge, make sure not to over tighten the template screw as that can warp it.</p>
</li>
<li>
<p>Start the mortise blade in the section provided for that, then once up to speed start cutting. It is ok to go over it a couple of times, just be careful not to tilt the blade or you will have bumpy bits.</p>
</li>
<li>
<p>Clamp one hinge at a time and use the self centering drill bit to start a hole in the center of the hinge holes. Then drill the rest of the way to make a complete pilot hole. That is at least as long as the screw going in the hinge.</p>
</li>
<li>
<p>Put the screws in the hinges, again, make sure you know which way is up on the door!!</p>
</li>
<li>
<p>Hanging the door is a little harder this way, but it avoids having to bang the crap out of the hinges which do not come apart that easily (these new ones don&apos;t)</p>
</li>
<li>
<p>This is where it is good to have lots of books and magazines. Find the best one to raise the door up enough to make getting the hinges into the door frame the easiest. I find it is easier to drop the hinges down than to raise them up also.</p>
</li>
<li>
<p>Tighten up the hinges and now pray that the door closes easily. If it does you have won! If it doesn&apos;t it could be an issue with the door trim. A key reason for using the mortise tool and template was to prevent the door not closing because of the plane of the hinges not being a perfect right angle with the door.</p>
</li>
<li>
<p>I am still working on a procedure for adjusting the door strike plate easily. I am still making mistakes on that one.</p>
</li>
</ol>
<!--kg-card-end: markdown--><p></p><p></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Terms]]></title><description><![CDATA[<!--kg-card-begin: html--><h1>Terms and Conditions</h1>
<p>Last updated: November 05, 2023</p>
<p>Please read these terms and conditions carefully before using Our Service.</p>
<h1>Interpretation and Definitions</h1>
<h2>Interpretation</h2>
<p>The words of which the initial letter is capitalized have meanings defined under the following conditions. The following definitions shall have the same meaning regardless of whether</p>]]></description><link>https://opensourcebrokers.ca/terms/</link><guid isPermaLink="false">65480c82c16024043591e50e</guid><dc:creator><![CDATA[Eric]]></dc:creator><pubDate>Sun, 05 Nov 2023 21:47:36 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: html--><h1>Terms and Conditions</h1>
<p>Last updated: November 05, 2023</p>
<p>Please read these terms and conditions carefully before using Our Service.</p>
<h1>Interpretation and Definitions</h1>
<h2>Interpretation</h2>
<p>The words of which the initial letter is capitalized have meanings defined under the following conditions. The following definitions shall have the same meaning regardless of whether they appear in singular or in plural.</p>
<h2>Definitions</h2>
<p>For the purposes of these Terms and Conditions:</p>
<ul>
<li>
<p><strong>Application</strong> means the software program provided by the Company downloaded by You on any electronic device, named DSD Platform</p>
</li>
<li>
<p><strong>Application Store</strong> means the digital distribution service operated and developed by Apple Inc. (Apple App Store) or Google Inc. (Google Play Store) in which the Application has been downloaded.</p>
</li>
<li>
<p><strong>Affiliate</strong> means an entity that controls, is controlled by or is under common control with a party, where &quot;control&quot; means ownership of 50% or more of the shares, equity interest or other securities entitled to vote for election of directors or other managing authority.</p>
</li>
<li>
<p><strong>Country</strong> refers to: Alberta,  Canada</p>
</li>
<li>
<p><strong>Company</strong> (referred to as either &quot;the Company&quot;, &quot;We&quot;, &quot;Us&quot; or &quot;Our&quot; in this Agreement) refers to Opensource Brokers, 96 deermoss cres se.</p>
</li>
<li>
<p><strong>Device</strong> means any device that can access the Service such as a computer, a cellphone or a digital tablet.</p>
</li>
<li>
<p><strong>Service</strong> refers to the Application.</p>
</li>
<li>
<p><strong>Terms and Conditions</strong> (also referred as &quot;Terms&quot;) mean these Terms and Conditions that form the entire agreement between You and the Company regarding the use of the Service. This Terms and Conditions agreement has been created with the help of the <a href="https://www.termsfeed.com/terms-conditions-generator/" target="_blank">Terms and Conditions Generator</a>.</p>
</li>
<li>
<p><strong>Third-party Social Media Service</strong> means any services or content (including data, information, products or services) provided by a third-party that may be displayed, included or made available by the Service.</p>
</li>
<li>
<p><strong>You</strong> means the individual accessing or using the Service, or the company, or other legal entity on behalf of which such individual is accessing or using the Service, as applicable.</p>
</li>
</ul>
<h1>Acknowledgment</h1>
<p>These are the Terms and Conditions governing the use of this Service and the agreement that operates between You and the Company. These Terms and Conditions set out the rights and obligations of all users regarding the use of the Service.</p>
<p>Your access to and use of the Service is conditioned on Your acceptance of and compliance with these Terms and Conditions. These Terms and Conditions apply to all visitors, users and others who access or use the Service.</p>
<p>By accessing or using the Service You agree to be bound by these Terms and Conditions. If You disagree with any part of these Terms and Conditions then You may not access the Service.</p>
<p>You represent that you are over the age of 18. The Company does not permit those under 18 to use the Service.</p>
<p>Your access to and use of the Service is also conditioned on Your acceptance of and compliance with the Privacy Policy of the Company. Our Privacy Policy describes Our policies and procedures on the collection, use and disclosure of Your personal information when You use the Application or the Website and tells You about Your privacy rights and how the law protects You. Please read Our Privacy Policy carefully before using Our Service.</p>
<h1>Links to Other Websites</h1>
<p>Our Service may contain links to third-party web sites or services that are not owned or controlled by the Company.</p>
<p>The Company has no control over, and assumes no responsibility for, the content, privacy policies, or practices of any third party web sites or services. You further acknowledge and agree that the Company shall not be responsible or liable, directly or indirectly, for any damage or loss caused or alleged to be caused by or in connection with the use of or reliance on any such content, goods or services available on or through any such web sites or services.</p>
<p>We strongly advise You to read the terms and conditions and privacy policies of any third-party web sites or services that You visit.</p>
<h1>Termination</h1>
<p>We may terminate or suspend Your access immediately, without prior notice or liability, for any reason whatsoever, including without limitation if You breach these Terms and Conditions.</p>
<p>Upon termination, Your right to use the Service will cease immediately.</p>
<h1>Limitation of Liability</h1>
<p>Notwithstanding any damages that You might incur, the entire liability of the Company and any of its suppliers under any provision of this Terms and Your exclusive remedy for all of the foregoing shall be limited to the amount actually paid by You through the Service or 100 USD if You haven&apos;t purchased anything through the Service.</p>
<p>To the maximum extent permitted by applicable law, in no event shall the Company or its suppliers be liable for any special, incidental, indirect, or consequential damages whatsoever (including, but not limited to, damages for loss of profits, loss of data or other information, for business interruption, for personal injury, loss of privacy arising out of or in any way related to the use of or inability to use the Service, third-party software and/or third-party hardware used with the Service, or otherwise in connection with any provision of this Terms), even if the Company or any supplier has been advised of the possibility of such damages and even if the remedy fails of its essential purpose.</p>
<p>Some states do not allow the exclusion of implied warranties or limitation of liability for incidental or consequential damages, which means that some of the above limitations may not apply. In these states, each party&apos;s liability will be limited to the greatest extent permitted by law.</p>
<h1>&quot;AS IS&quot; and &quot;AS AVAILABLE&quot; Disclaimer</h1>
<p>The Service is provided to You &quot;AS IS&quot; and &quot;AS AVAILABLE&quot; and with all faults and defects without warranty of any kind. To the maximum extent permitted under applicable law, the Company, on its own behalf and on behalf of its Affiliates and its and their respective licensors and service providers, expressly disclaims all warranties, whether express, implied, statutory or otherwise, with respect to the Service, including all implied warranties of merchantability, fitness for a particular purpose, title and non-infringement, and warranties that may arise out of course of dealing, course of performance, usage or trade practice. Without limitation to the foregoing, the Company provides no warranty or undertaking, and makes no representation of any kind that the Service will meet Your requirements, achieve any intended results, be compatible or work with any other software, applications, systems or services, operate without interruption, meet any performance or reliability standards or be error free or that any errors or defects can or will be corrected.</p>
<p>Without limiting the foregoing, neither the Company nor any of the company&apos;s provider makes any representation or warranty of any kind, express or implied: (i) as to the operation or availability of the Service, or the information, content, and materials or products included thereon; (ii) that the Service will be uninterrupted or error-free; (iii) as to the accuracy, reliability, or currency of any information or content provided through the Service; or (iv) that the Service, its servers, the content, or e-mails sent from or on behalf of the Company are free of viruses, scripts, trojan horses, worms, malware, timebombs or other harmful components.</p>
<p>Some jurisdictions do not allow the exclusion of certain types of warranties or limitations on applicable statutory rights of a consumer, so some or all of the above exclusions and limitations may not apply to You. But in such a case the exclusions and limitations set forth in this section shall be applied to the greatest extent enforceable under applicable law.</p>
<h1>Governing Law</h1>
<p>The laws of the Country, excluding its conflicts of law rules, shall govern this Terms and Your use of the Service. Your use of the Application may also be subject to other local, state, national, or international laws.</p>
<h1>Disputes Resolution</h1>
<p>If You have any concern or dispute about the Service, You agree to first try to resolve the dispute informally by contacting the Company.</p>
<h1>For European Union (EU) Users</h1>
<p>If You are a European Union consumer, you will benefit from any mandatory provisions of the law of the country in which you are resident in.</p>
<h1>United States Legal Compliance</h1>
<p>You represent and warrant that (i) You are not located in a country that is subject to the United States government embargo, or that has been designated by the United States government as a &quot;terrorist supporting&quot; country, and (ii) You are not listed on any United States government list of prohibited or restricted parties.</p>
<h1>Severability and Waiver</h1>
<h2>Severability</h2>
<p>If any provision of these Terms is held to be unenforceable or invalid, such provision will be changed and interpreted to accomplish the objectives of such provision to the greatest extent possible under applicable law and the remaining provisions will continue in full force and effect.</p>
<h2>Waiver</h2>
<p>Except as provided herein, the failure to exercise a right or to require performance of an obligation under these Terms shall not effect a party&apos;s ability to exercise such right or require such performance at any time thereafter nor shall the waiver of a breach constitute a waiver of any subsequent breach.</p>
<h1>Translation Interpretation</h1>
<p>These Terms and Conditions may have been translated if We have made them available to You on our Service.
You agree that the original English text shall prevail in the case of a dispute.</p>
<h1>Changes to These Terms and Conditions</h1>
<p>We reserve the right, at Our sole discretion, to modify or replace these Terms at any time. If a revision is material We will make reasonable efforts to provide at least 30 days&apos; notice prior to any new terms taking effect. What constitutes a material change will be determined at Our sole discretion.</p>
<p>By continuing to access or use Our Service after those revisions become effective, You agree to be bound by the revised terms. If You do not agree to the new terms, in whole or in part, please stop using the website and the Service.</p>
<h1>Contact Us</h1>
<p>If you have any questions about these Terms and Conditions, You can contact us:</p>
<ul>
<li>By email: eric@opensourcebrokers.ca</li>
</ul><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Our Data Analytics Team]]></title><description><![CDATA[<h3 id="our-team">Our Team:</h3><p>As a data analytics team, we offer data mining, data analysis, data visualization, program evaluation, performance indicators development, forecasting and data insights using a collaborative and agile process. Our mission is to provide business intelligence services to add efficiency and clarity to your daily insights.<br></p><h3 id="what-we-provide">What We Provide:</h3>]]></description><link>https://opensourcebrokers.ca/our-data-analytics-team-2/</link><guid isPermaLink="false">64dd1dafc16024043591e4fc</guid><dc:creator><![CDATA[Malachite Miller]]></dc:creator><pubDate>Wed, 16 Aug 2023 19:04:58 GMT</pubDate><content:encoded><![CDATA[<h3 id="our-team">Our Team:</h3><p>As a data analytics team, we offer data mining, data analysis, data visualization, program evaluation, performance indicators development, forecasting and data insights using a collaborative and agile process. Our mission is to provide business intelligence services to add efficiency and clarity to your daily insights.<br></p><h3 id="what-we-provide">What We Provide:</h3><ul><li>Data mining, data modelling and data insights</li><li>Program evaluation</li><li>Data visualization including dashboards and reports</li><li>Trending analysis</li><li>Performance indicators design and analysis</li><li>Dashboard maintenance</li><li>Predictive and forecast analysis<br></li></ul><h3 id="projects-we-have-done">Projects We Have Done:</h3><ul><li>Applicants, enrolment dashboards for post-secondary institutions</li><li>Survey design and survey result visualization post-secondary institutions and governments</li><li>Performance analysis and visualization</li><li>Post-secondary enrolment trend predictive analysis and forecast</li><li>Performance indicator design for municipalities, governments and post-secondary institutions</li><li>Staffing forecasting and planning</li><li>Pricing trend analysis</li><li>Customer loyalty and dropping out analysis and visualization</li><li>Customer profile analysis and visualization<br></li></ul><h3 id="visualization-tools">Visualization Tools:</h3><p>Tableau, Power BI, SAS BI, Python, R</p><h3 id="data-mining-tools">Data Mining Tools:</h3><p>SPSS, R, Python, SAS, SQL, Power BI </p><h3 id="team-members">Team Members:</h3><p><strong>Qi Wang</strong>:<br>MSc in Statistical Genomics and Quantitative Genetics, University of Alberta<br>More than 10 years&#x2019; experience in program evaluation, performance indicator design,data mining, survey design and analysis, data visualizations <br></p><p><strong>Katherine Yu</strong>:<br>M.A. in Applied Statistics, York University<br>PhD in Applied Mathematics, Harbin Institute of Technology<br>More than 12 years&#x2019; working experience in data quality control, data analytics and visualizations</p>]]></content:encoded></item><item><title><![CDATA[Our New Partner]]></title><description><![CDATA[<p><strong>Chunbo (Katherine) Yu</strong> - Has an M.A. in Applied Statistics and a Ph.D in Applied Mathematics.</p><figure class="kg-card kg-image-card"><img src="https://opensourcebrokers.ca/content/images/2022/07/10513248_419880264817147_8316960858823526388_n-1.jpg" class="kg-image" alt loading="lazy" width="195" height="194"></figure><p>With 12 years working experience in data modeling and reporting. Her experiences include but are not limited to developing and maintaining interactive dashboards, conducting various preliminary and in-depth analyses. She has developed</p>]]></description><link>https://opensourcebrokers.ca/our-new-partner/</link><guid isPermaLink="false">62cd9ea30443bc082451eef0</guid><dc:creator><![CDATA[Eric]]></dc:creator><pubDate>Tue, 12 Jul 2022 16:20:47 GMT</pubDate><content:encoded><![CDATA[<p><strong>Chunbo (Katherine) Yu</strong> - Has an M.A. in Applied Statistics and a Ph.D in Applied Mathematics.</p><figure class="kg-card kg-image-card"><img src="https://opensourcebrokers.ca/content/images/2022/07/10513248_419880264817147_8316960858823526388_n-1.jpg" class="kg-image" alt loading="lazy" width="195" height="194"></figure><p>With 12 years working experience in data modeling and reporting. Her experiences include but are not limited to developing and maintaining interactive dashboards, conducting various preliminary and in-depth analyses. She has developed a Power BI dashboard to monitor employee performance through various aspects, in which the managers were able to identify if an employee is performing to the standard, and whether there is any room for teamwide improvement.</p><p>Katherine is working on MMM models like Facebook&apos;s Robyn. </p>]]></content:encoded></item><item><title><![CDATA[About Eric]]></title><description><![CDATA[<p>Starting in St. Louis, I dropped out of my Chemistry major to work on developing websites. A librarian at UMSL turned me on to Perl and UNIX. This was 1994 when everyone wanted a website, but didn&apos;t really know why, they just knew they had to have one.</p>]]></description><link>https://opensourcebrokers.ca/about-eric/</link><guid isPermaLink="false">6218189d0443bc082451ed3d</guid><dc:creator><![CDATA[Eric]]></dc:creator><pubDate>Fri, 25 Feb 2022 17:54:20 GMT</pubDate><content:encoded><![CDATA[<p>Starting in St. Louis, I dropped out of my Chemistry major to work on developing websites. A librarian at UMSL turned me on to Perl and UNIX. This was 1994 when everyone wanted a website, but didn&apos;t really know why, they just knew they had to have one. &#xA0; <br><br>This led to years of consulting/contract programming work and the realization that I really didn&apos;t want to be a web designer. One client&apos;s quote that ended it all, &quot;Can we have that background be hunter green?&quot; <br><br>I moved into more programming, Visual Basic and Java. I learned early on how to make the best of tools. &#xA0;I didn&apos;t know VB so I taught myself. The client need a Mac version of the PC software I wrote in VB, so I didn&apos;t learn Java then, I found a tool that converted VB code into a Java app and then I adapted that app to run on the Mac. &#xA0;<br><br>Then everything changed when I got a full time job, with an affiliate marketing startup. &#xA0;I build a team and we built their custom CRM, Email Marketing, Website platform for 25 ecom websites, credit cart fraud prevention, and a globally redundant system for keeping a 99.999 (only 3 nines) uptime on our affiliate platform and website. This was pre cloud days when we had to manage this across multiple data centers, Vancouver, Toronto, Berlin, Singapore and even the Bahamas. &#xA0;I ended up being called CTO. <br><br>The first analytics pixel I put on a website, was one I designed. &#xA0;Processing log files with Urchin on 25 sites was a pretty bad plan vs a real time data stream. This later led to my working for another startup that was building ecom website optimization software. &#xA0;I highly optimized their performance and built an addition that could use near real time weather forecasts to control what content was presented to any given website visitor depending on their location. <br><br>That led to my working for ELC Online. They are the department of Estee Lauder that manage their online platform across all of <a href="https://www.elcompanies.com/en/our-brands">Estee Lauder&apos;s brands.</a> &#xA0;There I built a custom tag management system and worked with IBM Coremetrics at a very large scale. &#xA0;Later I was the technical lead on ELC&apos;s move to Adobe Analytics and several other major global migrations, the last one being their move to the Google 360 platform. &#xA0;Outside of Marketing Technology I helped them start a major move towards building their website platform on Drupal and lead the team that build the first version of that for <a href="https://www.smashbox.com/">Smashbox</a>. &#xA0;</p><p>UPDATES: </p><p>I wrote the above about 3 years ago. I recently made a focused resume and with the help of Claude managed to be brief, for me. I am still leaving out a number of fairly major projects for our client <a href="https://botanictonics.com/">Botanic Tonics</a>, will get that out soon. That was a year of our lives :) It is important to note that none of these projects were done solo by me. OSB has grown and adjusted to fit many different kinds of projects. </p><!--kg-card-begin: markdown--><h2 id="tealium-shopify-app-2024">Tealium Shopify App (2024)</h2>
<p>Developed Tealium&apos;s first Shopify app to meet enterprise-grade analytics requirements while adhering to Shopify&apos;s app development framework and more recent &quot;web pixel&quot; changes. The solution included server-side tracking via AWS API Gateway to support multiple enterprise customers.</p>
<ul>
<li>Worked with Tealium&apos;s Sr. Product Manager for Data Privacy Products in designing a CMP (Consent Management Platform) integration with Tealium iQ that aligned with Shopify&apos;s privacy settings</li>
<li>Architected solution balancing Shopify&apos;s app requirements with enterprise tracking needs</li>
</ul>
<h2 id="idtech-dbtga4-implementation-2023-2024">iDTech DBT/GA4 Implementation (2023-2024)</h2>
<p>Created a comprehensive data engineering solution for iDTech using modern cloud analytics tools to replace capabilities lost in the transition from Universal Analytics to GA4. The implementation leveraged DBT Cloud, BigQuery, and the Velir/dbt-ga4 open-source project to deliver sophisticated marketing analytics.</p>
<ul>
<li>Implemented GA4 schema flattening and ETL processes using DBT Cloud and the Velir/dbt-ga4 open-source project, creating the foundation for a comprehensive marketing performance reporting system</li>
<li>Integrated spend and performance data using Fivetran to synchronize daily into BigQuery</li>
<li>Later managed a full backup of Universal Analytics data into BigQuery and integrated this historical data with the larger system</li>
<li>Collaborated with my wife, Qi Jiang, who developed iDTech&apos;s reporting system that replaced historical Universal Analytics reporting capabilities that weren&apos;t possible to replicate in GA4</li>
</ul>
<h2 id="tealium-magento-plugin-2023">Tealium Magento Plugin (2023)</h2>
<p>Led complete revamp of Tealium&apos;s Magento integration to align with current platform architecture, modernizing the code base while ensuring compatibility with the latest Magento versions.</p>
<h2 id="eq-cc-2020-2023">EQ C&amp;C (2020-2023)</h2>
<p>Established a data engineering and analytics service working with approximately 20 clients across diverse industries. The product was focused on addressing data signal limitations created by Apple&apos;s ITP changes through first-party data collection strategies and server-side tracking implementations.</p>
<ul>
<li>Partnered with various Marketing Agencies to implement first-party data collection strategies addressing Apple&apos;s ITP changes</li>
<li>Developed more reliable attribution solution to counter the impact of third-party cookie restrictions</li>
<li>Designed server-side tracking implementations to maintain marketing measurement capabilities</li>
</ul>
<p>For J.Jill, implemented a high-performance, scalable data processing solution handling large data volumes with exceptional response times.</p>
<ul>
<li>Implemented large-scale data processing solution that processed one trillion rows in a partitioned BigQuery table</li>
<li>Built auto-scaling infrastructure on AWS that handled traffic from 150,000 requests per hour on average to peaks of 400,000 requests per hour while maintaining a median 25ms response time</li>
<li>Designed dynamic EC2 load balancing system that automatically scaled from 2-10 nodes based on demand</li>
<li>Developed dashboard reporting for real time 1st party conversion data which also reflected on Facebook ads API sourced data</li>
</ul>
<h2 id="facebook-marketing-technology-partner-2021-2022">Facebook Marketing Technology Partner (2021-2022)</h2>
<p>Selected as one of 250 global technology partners to support Facebook&apos;s largest advertisers, providing technical consulting to approximately 30 clients with focus on Shopify implementations and developing integration strategies between Facebook&apos;s marketing tools and client platforms. This included all aspects of web site tracking, CAPI, Lead Ad Chat Bots.</p>
<h2 id="michael-kors-analytics-implementation-2018-2022">Michael Kors Analytics Implementation (2018-2022)</h2>
<p>Managed analytics strategy and implementation for Michael Kors over a four-year engagement, overseeing both technical implementation and team leadership aspects of this major retail brand&apos;s analytics transformation.</p>
<ul>
<li>Hired and supervised a full-time Open Source Brokers employee dedicated to the Michael Kors account</li>
<li>Implemented Adobe Launch and Adobe Analytics solutions in collaboration with internal teams</li>
<li>Integrated analytics validation directly into Michael Kors&apos; existing Selenium test suite, leveraging their substantial website test coverage to simultaneously validate data collection and tagging</li>
<li>Participated in weekly brainstorming sessions with key stakeholders to evolve analytics capabilities</li>
</ul>
<h2 id="qfd-analytics-2018-2019">QFD Analytics (2018-2019)</h2>
<ul>
<li>Developed Adobe Analytics data quality monitoring RUM solution</li>
<li>One of the first Edge CDN data collection applications</li>
<li>Designed high-performance data ingestion system for enterprise-scale implementation</li>
<li>Created test environment capable of sustaining 40,000 POST requests per second</li>
<li>Implemented with Sephora as initial enterprise client</li>
</ul>
<h2 id="estee-lauder-companies-elc-analytics-transformation-2008-2018">Estee Lauder Companies (ELC) Analytics Transformation (2008-2018)</h2>
<p>Architected Estee Lauder&apos;s global analytics platform transformation, supplementing Adobe Analytics to Google Analytics Premium across 300+ e-commerce sites spanning multiple brands and locales. This multi-year initiative established standardized approaches to analytics implementation and data collection. The intention over time was to eventually reduce costs regarding Adobe Analytics which ran into the tens of millions.</p>
<ul>
<li>Evaluated and selected the Google Analytics partner that would design Estee Lauder&apos;s entire global GA 360 solution (Now named WPromote)</li>
<li>Did a POC comparison between Tealium and Segment.io (Segment later introduced me to the Facebook Marketing partner program)</li>
<li>Recommended Tealium to ELC and helped design a global/multi-brand implementation approach for Tealium iQ with consideration for future Tealium Audience Stream integration</li>
<li>Created standardized templates and comprehensive documentation for Cognizant teams to execute Tealium and GA360 rollouts across 300+ global e-commerce sites</li>
<li>Helped establish cross-brand analytics standards that maintained global consistency while accommodating brand-specific requirements</li>
<li>Assisted in building a Drupal team as starting point for a global project (Smashbox.com continued using this original system)</li>
<li>Participated in Estee Lauder Online&apos;s global planning summit (2012)</li>
<li>Served as technical liaison between frontend/backend developers and Perl/PHP developers</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[About Us]]></title><description><![CDATA[<p>OpenSource Brokers...</p>]]></description><link>https://opensourcebrokers.ca/about-us/</link><guid isPermaLink="false">621016560443bc082451ed34</guid><dc:creator><![CDATA[Alicia Lin]]></dc:creator><pubDate>Fri, 18 Feb 2022 21:57:56 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1488590528505-98d2b5aba04b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fHRlY2hub2xvZ3l8ZW58MHx8fHwxNjQ1MjIxNDIy&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1488590528505-98d2b5aba04b?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fHRlY2hub2xvZ3l8ZW58MHx8fHwxNjQ1MjIxNDIy&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="About Us"><p>OpenSource Brokers...</p>]]></content:encoded></item></channel></rss>