<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:media="http://search.yahoo.com/mrss/" >

<channel>
	<title>Thien Trinh Duc | Qilin.Cloud</title>
	<atom:link href="https://qilin.cloud/author/t-trinh/feed/" rel="self" type="application/rss+xml" />
	<link>https://qilin.cloud</link>
	<description>Technology Platform for composable e-commerce</description>
	<lastBuildDate>Thu, 26 Mar 2026 11:08:59 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://qilin.cloud/wp-content/uploads/2023/08/cropped-QilinCloud-Logo-32x32.png</url>
	<title>Thien Trinh Duc | Qilin.Cloud</title>
	<link>https://qilin.cloud</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>AI-Native Commerce Ops: Treating Qilin Like a Coworker (Not a Chat Widget)</title>
		<link>https://qilin.cloud/ai-native-commerce-ops-qilin-strategy/</link>
		
		<dc:creator><![CDATA[Thien Trinh Duc]]></dc:creator>
		<pubDate>Sun, 31 May 2026 08:00:00 +0000</pubDate>
				<category><![CDATA[Engineering Deep Dives]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[commerce ops]]></category>
		<category><![CDATA[governance]]></category>
		<category><![CDATA[roadmap]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3778</guid>

					<description><![CDATA[<p>A practical preview of our AI direction: AI as the primary interface for commerce operations—permissioned, auditable, and grounded in real execution data.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/ai-native-commerce-ops-qilin-strategy/">AI-Native Commerce Ops: Treating Qilin Like a Coworker (Not a Chat Widget)</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="et_pb_section et_pb_section_0 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_0">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_0  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_0  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>Most “AI features” today fall into one of two categories:</p>
<ol>
<li><strong>A chat widget taped onto the side of a product</strong></li>
<li><strong>A content generator that writes… more content</strong></li>
</ol>
<p>Useful sometimes. <br />Rarely operational.</p>
<p>Commerce operations are a different beast. They’re messy, time-sensitive, and full of edge cases. If AI is going to matter here, it has to do more than talk.</p>
<p>This May post is a practical preview of our direction:</p>
<p><strong>Qilin.Cloud as an AI-native operations coworker.</strong></p>
<p>Not a mascot. Not a gimmick. Not “AI bolted-on”.</p>
<p>An assistant that can help you <em>run</em> commerce flows.</p></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_1">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_1  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_with_border et_pb_module pac_divi_table_of_contents pac_divi_table_of_contents_0">
				
				
				
				
				
				
				<div class="et_pb_module_inner">
					
        <div class="pac_dtoc_main_container"
        data-allow_collapse_minimize="on"
        data-allow_collapse_minimize_tablet="on"
        data-allow_collapse_minimize_phone="on"
        data-ss="2000"
        data-sah="100"
        data-collapse_when_sticky="off"
        data-collapse_when_sticky_tablet="off"
        data-collapse_when_sticky_phone="off"
        data-skh="off"
        data-mtocai="off"
        data-mtocai_tablet="off"
        data-mtocai_phone="off"
        data-alh="off"
        data-ds="closed"
        data-dst="closed"
        data-dsp="closed">
            <div class="pac_dtoc_title_area click_on click_tablet_on click_phone_on">
                <div role="heading" aria-level="2" id="pac_dtocm_title" class="pac_dtoc_title">Table of Contents</div>
                
                <div class="pac_dtoc_icon_responsive">
                    <div class="pac_dtoc_opened_icon">2</div>
                    <div class="pac_dtoc_closed_icon">3</div>
                </div>
                
            </div>
            <div role="navigation" aria-labelledby="pac_dtocm_title" class="pac_dtoc_body_area inside">
                
                <div class='divi_table_of_contents' role="tree" ><ul class="pac_dtoc_heading_level_1" role="group" ><li class="pac_dtoc_li_heading_level_1" role="treeitem" ><div role="presentation" ><span data-href='#pac_remove_first_heading' data-hl='1'></span><a href='#pac_remove_first_heading' id='pac_remove_first_heading_toc_headding'>FirstHeading</a></div></li><ul class="pac_dtoc_heading_level_2" role="group" ><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#ThenorthstarQilinisanemployeenotatool' data-hl='2'></span><a href='#ThenorthstarQilinisanemployeenotatool' id='ThenorthstarQilinisanemployeenotatool_toc_headding'>The north star: “Qilin is an employee, not a tool”</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whythisisevenpossible' data-hl='2'></span><a href='#Whythisisevenpossible' id='Whythisisevenpossible_toc_headding'>Why this is even possible</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#WhatAInativecouldlooklikerealexamples' data-hl='2'></span><a href='#WhatAInativecouldlooklikerealexamples' id='WhatAInativecouldlooklikerealexamples_toc_headding'>What “AI-native” could look like (real examples)</a></div></li><ul class="pac_dtoc_heading_level_3" role="group" ><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Explainfailuresinbusinesslanguage' data-hl='3'></span><a href='#Explainfailuresinbusinesslanguage' id='Explainfailuresinbusinesslanguage_toc_headding'>Explain failures in business language</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Suggestpipelineimprovementswithevidence' data-hl='3'></span><a href='#Suggestpipelineimprovementswithevidence' id='Suggestpipelineimprovementswithevidence_toc_headding'>Suggest pipeline improvements (with evidence)</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Detectanomaliesbeforehumansnotice' data-hl='3'></span><a href='#Detectanomaliesbeforehumansnotice' id='Detectanomaliesbeforehumansnotice_toc_headding'>Detect anomalies before humans notice</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Thepartpeopleforgettrustandguardrails' data-hl='2'></span><a href='#Thepartpeopleforgettrustandguardrails' id='Thepartpeopleforgettrustandguardrails_toc_headding'>The part people forget: trust and guardrails</a></div></li><ul class="pac_dtoc_heading_level_3" role="group" ><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Permissionsfirst' data-hl='3'></span><a href='#Permissionsfirst' id='Permissionsfirst_toc_headding'>Permissions first</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Auditabilityalways' data-hl='3'></span><a href='#Auditabilityalways' id='Auditabilityalways_toc_headding'>Auditability always</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Noblackboxoperations' data-hl='3'></span><a href='#Noblackboxoperations' id='Noblackboxoperations_toc_headding'>No black box operations</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whythismattersdependingonwhoyouare' data-hl='2'></span><a href='#Whythismattersdependingonwhoyouare' id='Whythismattersdependingonwhoyouare_toc_headding'>Why this matters (depending on who you are)</a></div></li><ul class="pac_dtoc_heading_level_3" role="group" ><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Developers' data-hl='3'></span><a href='#Developers' id='Developers_toc_headding'>Developers</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Agenciesintegrators' data-hl='3'></span><a href='#Agenciesintegrators' id='Agenciesintegrators_toc_headding'>Agencies &amp; integrators</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Merchants' data-hl='3'></span><a href='#Merchants' id='Merchants_toc_headding'>Merchants</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Investors' data-hl='3'></span><a href='#Investors' id='Investors_toc_headding'>Investors</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Agroundedpromise' data-hl='2'></span><a href='#Agroundedpromise' id='Agroundedpromise_toc_headding'>A grounded promise</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_6">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_6  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_6  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>The north star: “Qilin is an employee, not a tool”</span></h2>
						<div class="et_pb_blurb_description"><p>Tools wait for clicks.</p>
<p>Employees:</p>
<ul>
<li>listen for intent</li>
<li>propose actions</li>
<li>execute within permissions</li>
<li>keep watch</li>
<li>and escalate only when needed</li>
</ul>
<p>That’s the experience we’re aiming for.</p>
<p>The portal remains important (visualization and control matter), but the long-term center of gravity becomes:</p>
<blockquote>
<p><em><strong>&gt; “Tell Qilin what outcome you want,” not “find the right menu item.”</strong></em></p>
</blockquote></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_7">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_7  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_7  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Why this is even possible</span></h2>
						<div class="et_pb_blurb_description"><p>Because Qilin.Cloud already has the ingredients that most “AI products” lack:</p>
<ul>
<li><strong>Structured execution data</strong> (Data Flow Tracking)</li>
<li><strong>Reliable status and idempotency</strong> (Transfer Status Engine)</li>
<li><strong>Process-level telemetry</strong> (think process mining data)</li>
<li><strong>A modular pipeline model</strong> (processors and connectors)</li>
<li><strong>Permissions and roles</strong> (so “automation” doesn’t become “chaos”)</li>
</ul>
<p>In other words: the system is observable and controllable enough for AI to act responsibly.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_8  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>What “AI-native” could look like (real examples)</span></h2>
						<div class="et_pb_blurb_description"><p>Here are examples of <em>outcome-based</em> interactions that become possible when AI is tied to the operational model:</p>
<h3>Explain failures in business language</h3>
<blockquote>
<p><em><strong>&gt; “Why did today’s Kaufland updates fail?”</strong></em></p>
</blockquote>
<p>Qilin can translate:</p>
<ul>
<li>which offers failed</li>
<li>which condition caused mismatch (e.g., EAN/condition/storefront)</li>
<li>what to fix in the source data</li>
<li>whether a retry would succeed or just waste time</li>
</ul>
<h3>Suggest pipeline improvements (with evidence)</h3>
<blockquote>
<p><em><strong>&gt; “How can we reduce cost on this pipeline by 20%?”</strong></em></p>
</blockquote>
<p>Qilin can look at execution telemetry and propose:</p>
<ul>
<li>buffer bursts to reduce connector retries</li>
<li>move non-critical enrichments to slower speed</li>
<li>batch outputs where the marketplace allows it</li>
<li>tighten timeouts on known-bad endpoints</li>
</ul>
<h3>Detect anomalies before humans notice</h3>
<blockquote>
<p><em><strong>&gt; “Alert me if stock updates exceed 10 minutes latency.”</strong></em></p>
</blockquote>
<p>That’s not a chat feature. That’s operational guardrails.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_1">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_1  et_pb_toggle_open">
				
				
				
				
				<h5 class="et_pb_toggle_title"></h5>
				<div class="et_pb_toggle_content clearfix">We invite you to share your experiences and lessons learned with Qilin.Cloud’s innovative technology platform for composable e-commerce. Your story can inspire others and help the whole community to improve.

&nbsp;
<h4><strong>Share your Qilin.Cloud Success Story</strong>
<span> </span></h4>
<div class="et_pb_button_module_wrapper et_pb_button_0_wrapper  et_pb_module "><a class="et_pb_button et_pb_button_0 et_pb_bg_layout_light" href="https://qilin.cloud/share-your-story/">Your Journey</a></div></div>
			</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_9  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>The part people forget: trust and guardrails</span></h2>
						<div class="et_pb_blurb_description"><p>AI in commerce ops is useless if it can’t be trusted.</p>
<p>So the AI-native direction has non-negotiables:</p>
<h3>Permissions first</h3>
<p>AI actions must respect:</p>
<ul>
<li>roles</li>
<li>API key scopes</li>
<li>tenant boundaries</li>
<li>approval workflows (where needed)</li>
</ul>
<h3>Auditability always</h3>
<p>If AI changes something, it must leave a trail:</p>
<ul>
<li>what was changed</li>
<li>why it was changed</li>
<li>who authorized it</li>
<li>which data triggered it</li>
</ul>
<h3>No black box operations</h3>
<p>You should be able to ask:</p>
<ul>
<li>“What evidence led to that recommendation?”</li>
<li>“What would happen if we don’t do it?”</li>
<li>“Show me the DFT blocks that support this.”</li>
</ul>
<p>The goal is not “magic”. <br />The goal is <strong>reliable leverage</strong>.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_10  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Why this matters (depending on who you are)</span></h2>
						<div class="et_pb_blurb_description"><h3>Developers</h3>
<p>Less firefighting. More engineering. <br />AI should reduce the time spent chasing ghosts in distributed systems.</p>
<h3>Agencies &amp; integrators</h3>
<p>Faster onboarding and fewer handover headaches. <br />If Qilin can explain the system, your delivery becomes more repeatable.</p>
<h3>Merchants</h3>
<p>Better uptime and fewer penalties. <br />The best incident is the one that never happens.</p>
<h3>Investors</h3>
<p>AI-native operations is a moat when it’s tied to real platform primitives:</p>
<ul>
<li>telemetry</li>
<li>workflows</li>
<li>permissions</li>
<li>automation hooks</li>
</ul>
<p>That combination is hard to copy quickly.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_11  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>A grounded promise</span></h2>
						<div class="et_pb_blurb_description"><p>We’re not claiming “the AI commerce OS is finished.”</p>
<p>We are claiming:</p>
<ul>
<li>the direction is clear</li>
<li>the foundation is being built the right way</li>
<li>and we’ll share progress as it becomes production-grade</li>
</ul>
<p>AI is exciting. <br />But boring reliability is what makes it real.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/ai-native-commerce-ops-qilin-strategy/">AI-Native Commerce Ops: Treating Qilin Like a Coworker (Not a Chat Widget)</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Queue Storage &#038; Buffering: When Real-Time Isn’t the Whole Story</title>
		<link>https://qilin.cloud/queue-storage-buffering-when-real-time-isnt-everything/</link>
		
		<dc:creator><![CDATA[Thien Trinh Duc]]></dc:creator>
		<pubDate>Thu, 31 Jul 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[batching]]></category>
		<category><![CDATA[buffering]]></category>
		<category><![CDATA[cost control]]></category>
		<category><![CDATA[queue]]></category>
		<category><![CDATA[scheduling]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=3700</guid>

					<description><![CDATA[<p>July’s update: Qilin Queue Storage + buffering processors. Collect objects, trigger batches by size or schedule, and ship data in stable chunks that respect connector limits.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/queue-storage-buffering-when-real-time-isnt-everything/">Queue Storage &amp; Buffering: When Real-Time Isn’t the Whole Story</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="et_pb_section et_pb_section_1 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_8">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_8  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_2  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>The oldest trick in commerce operations is also one of the smartest:</p>
<p><strong>Don’t ship boxes one by one when you can ship a pallet.</strong></p>
<p>Real-time is great &#8211; when you need it.</p>
<p>But experienced teams know that many workflows are better when they run in controlled batches:</p>
<ul>
<li>catalog sync overnight</li>
<li>stock updates every 15 minutes</li>
<li>offer updates grouped to reduce API overhead</li>
<li>partner exports once per hour</li>
</ul>
<p>July’s development work has been about making this “batch wisdom” a first-class citizen in Qilin.Cloud via:</p>
<ul>
<li><strong>Qilin Queue Storage (QQS)</strong></li>
<li><strong>Push-to-Queue + Buffer Entry processors</strong></li>
<li><strong>Scheduling that respects real-world limits</strong></li>
</ul></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_9">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_9  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_with_border et_pb_module pac_divi_table_of_contents pac_divi_table_of_contents_1">
				
				
				
				
				
				
				<div class="et_pb_module_inner">
					
        <div class="pac_dtoc_main_container"
        data-allow_collapse_minimize="on"
        data-allow_collapse_minimize_tablet="on"
        data-allow_collapse_minimize_phone="on"
        data-ss="2000"
        data-sah="100"
        data-collapse_when_sticky="off"
        data-collapse_when_sticky_tablet="off"
        data-collapse_when_sticky_phone="off"
        data-skh="off"
        data-mtocai="off"
        data-mtocai_tablet="off"
        data-mtocai_phone="off"
        data-alh="off"
        data-ds="closed"
        data-dst="closed"
        data-dsp="closed">
            <div class="pac_dtoc_title_area click_on click_tablet_on click_phone_on">
                <div role="heading" aria-level="2" id="pac_dtocm_title" class="pac_dtoc_title">Table of Contents</div>
                
                <div class="pac_dtoc_icon_responsive">
                    <div class="pac_dtoc_opened_icon">2</div>
                    <div class="pac_dtoc_closed_icon">3</div>
                </div>
                
            </div>
            <div role="navigation" aria-labelledby="pac_dtocm_title" class="pac_dtoc_body_area inside">
                
                <div class='divi_table_of_contents' role="tree" ><ul class="pac_dtoc_heading_level_1" role="group" ><li class="pac_dtoc_li_heading_level_1" role="treeitem" ><div role="presentation" ><span data-href='#pac_remove_first_heading' data-hl='1'></span><a href='#pac_remove_first_heading' id='pac_remove_first_heading_toc_headding'>FirstHeading</a></div></li><ul class="pac_dtoc_heading_level_2" role="group" ><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#QilinQueueStorageastagingareaforpipelineoutputs' data-hl='2'></span><a href='#QilinQueueStorageastagingareaforpipelineoutputs' id='QilinQueueStorageastagingareaforpipelineoutputs_toc_headding'>Qilin Queue Storage: a staging area for pipeline outputs</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Thedatamodelsimpleonpurpose' data-hl='2'></span><a href='#Thedatamodelsimpleonpurpose' id='Thedatamodelsimpleonpurpose_toc_headding'>The data model (simple, on purpose)</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#PushQilinObjectToQueueStorageProcessorcollectingitems' data-hl='2'></span><a href='#PushQilinObjectToQueueStorageProcessorcollectingitems' id='PushQilinObjectToQueueStorageProcessorcollectingitems_toc_headding'>PushQilinObjectToQueueStorage Processor: collecting items</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#BufferEntryProcessortriggeringthebatch' data-hl='2'></span><a href='#BufferEntryProcessortriggeringthebatch' id='BufferEntryProcessortriggeringthebatch_toc_headding'>Buffer Entry Processor: triggering the batch</a></div></li><ul class="pac_dtoc_heading_level_3" role="group" ><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#1ThresholdbasedRunwhenthequeuecontainsatleastNitems' data-hl='3'></span><a href='#1ThresholdbasedRunwhenthequeuecontainsatleastNitems' id='1ThresholdbasedRunwhenthequeuecontainsatleastNitems_toc_headding'>1) Threshold-basedRun when the queue contains at least N items:</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#2Schedulebased' data-hl='3'></span><a href='#2Schedulebased' id='2Schedulebased_toc_headding'>2) Schedule-based</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whybatchingisaplatformfeaturenotjustanoptimization' data-hl='2'></span><a href='#Whybatchingisaplatformfeaturenotjustanoptimization' id='Whybatchingisaplatformfeaturenotjustanoptimization_toc_headding'>Why batching is a platform feature (not just an optimization)</a></div></li><ul class="pac_dtoc_heading_level_3" role="group" ><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Fordevelopers' data-hl='3'></span><a href='#Fordevelopers' id='Fordevelopers_toc_headding'>For developers</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Formerchantsandagencies' data-hl='3'></span><a href='#Formerchantsandagencies' id='Formerchantsandagencies_toc_headding'>For merchants and agencies</a></div></li><li class="pac_dtoc_li_heading_level_3" role="treeitem" ><div role="presentation" ><span data-href='#Forinvestors' data-hl='3'></span><a href='#Forinvestors' id='Forinvestors_toc_headding'>For investors</a></div></li></ul><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Arealisticexampleofferupdateswithoutratelimitpain' data-hl='2'></span><a href='#Arealisticexampleofferupdateswithoutratelimitpain' id='Arealisticexampleofferupdateswithoutratelimitpain_toc_headding'>A realistic example: offer updates without rate-limit pain</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whatsnext' data-hl='2'></span><a href='#Whatsnext' id='Whatsnext_toc_headding'>What’s next</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Respecttheoldwisdombatchwhenitmakessense' data-hl='2'></span><a href='#Respecttheoldwisdombatchwhenitmakessense' id='Respecttheoldwisdombatchwhenitmakessense_toc_headding'>Respect the old wisdom: batch when it makes sense</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_14">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_14  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_20  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Qilin Queue Storage: a staging area for pipeline outputs</span></h2>
						<div class="et_pb_blurb_description"><p>Think of QQS as a <strong>staging warehouse</strong> inside the platform.</p>
<p>Instead of pushing every object immediately to the next step, you can:</p>
<ol>
<li>collect objects into a queue storage</li>
<li>wait until the queue reaches a condition (size or time)</li>
<li>trigger a downstream pipeline step with a batch</li>
</ol>
<p>This is especially useful when destinations prefer bulk updates &#8211; or punish you with rate limits for chattiness.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_15">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_15  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_21  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>The data model (simple, on purpose)</span></h2>
						<div class="et_pb_blurb_description"><p>At the conceptual level:</p>
<ul>
<li>a <strong>Queue Storage</strong> belongs to a subscription and has a configured duration (how long items live)</li>
<li>a <strong>Queue Item</strong> stores:
<ul>
<li>object type</li>
<li>object ID</li>
<li>object data (serialized)</li>
<li>created timestamp</li>
<li>expiration timestamp</li>
</ul>
</li>
</ul>
<p>This gives you the platform equivalent of “put it in the staging area, and process it later”.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_22  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>PushQilinObjectToQueueStorage Processor: collecting items</span></h2>
						<div class="et_pb_blurb_description"><p>This processor takes the current object in your flow and pushes it into a chosen queue storage.</p>
<p>Example:</p>
<pre>{
  "id": "push_to_queue",
  "type": "Qilin.PushQilinObjectToQueueStorage",
  "config": {
    "queueStorageId": "your-queue-storage-id",
    "objectType": "Offer",
    "domainName": "Offer",
    "domainObjectIdPath": "$.FlowObjectAttributes.entry.objectId"
  }
}
</pre>
<p>You can override the object ID or object type if needed, and you can write different object kinds to different queue storages.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_23  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Buffer Entry Processor: triggering the batch</span></h2>
						<div class="et_pb_blurb_description"><p>Once objects are in the queue, you need a clean way to “release” them downstream.</p>
<p>That’s what Buffer Entry does.</p>
<p>Two common trigger patterns:</p>
<h3>1) Threshold-based<br />Run when the queue contains at least N items:</h3>
<pre>{
  "id": "buffer_entry",
  "type": "Qilin.BufferEntry",
    "config": {
    "queueStorageId": "your-queue-storage-id",
    "minimumItemsToRelease": 150
  }
}
</pre>
<h3>2) Schedule-based</h3>
<p>Run on a schedule (cron expression), releasing what’s available.</p>
<p>This matches classic operational workflows: “every 15 minutes, push what changed.”</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_3">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_3  et_pb_toggle_open">
				
				
				
				
				<h5 class="et_pb_toggle_title"></h5>
				<div class="et_pb_toggle_content clearfix">We invite you to share your experiences and lessons learned with Qilin.Cloud’s innovative technology platform for composable e-commerce. Your story can inspire others and help the whole community to improve.</p>
<p>&nbsp;</p>
<h4><strong>Share your Qilin.Cloud Success Story</strong><br />
<span> </span></h4>
<div class="et_pb_button_module_wrapper et_pb_button_0_wrapper  et_pb_module "><a class="et_pb_button et_pb_button_0 et_pb_bg_layout_light" href="https://qilin.cloud/share-your-story/">Your Journey</a></div></div>
			</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_24  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Why batching is a platform feature (not just an optimization)</span></h2>
						<div class="et_pb_blurb_description"><h3>For developers</h3>
<ul>
<li>fewer connector calls, less overhead</li>
<li>easier throughput control with predictable bursts</li>
<li>reduced retry complexity (retries happen per batch, not per object)</li>
<li>clean separation between “capture changes” and “ship changes”</li>
</ul>
<h3>For merchants and agencies</h3>
<ul>
<li>stable sync behavior under load</li>
<li>predictable operational windows (e.g., nightly exports)</li>
<li>fewer “API limit exceeded” incidents</li>
<li>easier to align platform behavior with business rhythms</li>
</ul>
<h3>For investors</h3>
<p>Queue storage unlocks higher-volume use cases without linear increases in operational cost. That’s leverage.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_25  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>A realistic example: offer updates without rate-limit pain</span></h2>
						<div class="et_pb_blurb_description"><p>Offers (price, stock, handling time) can change frequently.</p>
<p>Instead of pushing every micro-change instantly:</p>
<ul>
<li>collect offer updates in QQS</li>
<li>release them in batches every 10–15 minutes</li>
<li>ship a predictable batch to the connector</li>
</ul>
<p>This keeps data fresh enough for commerce… without turning your connector into a chatty stress test.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_26  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>What’s next</span></h2>
						<div class="et_pb_blurb_description"><p>Once you can batch, the next step is:</p>
<p><strong>smarter branching and routing</strong>.</p>
<p>August will introduce more around conditional execution and switch-case routing &#8211; so pipelines can decide what to do with a batch based on content, not just schedule.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_27  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Respect the old wisdom: batch when it makes sense</span></h2>
						<div class="et_pb_blurb_description"><p>Real-time is exciting.</p>
<p>Batching is profitable.</p>
<p>Qilin.Cloud is building both &#8211; so you can choose the right tool for each workflow, instead of forcing everything into one tempo.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div></p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/queue-storage-buffering-when-real-time-isnt-everything/">Queue Storage &amp; Buffering: When Real-Time Isn’t the Whole Story</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Egression Module: Shipping Commerce Data Without Shipping Excuses</title>
		<link>https://qilin.cloud/egression-module-shipping-commerce-data-without-excuses/</link>
		
		<dc:creator><![CDATA[Thien Trinh Duc]]></dc:creator>
		<pubDate>Mon, 30 Sep 2024 11:26:00 +0000</pubDate>
				<category><![CDATA[Product Updates]]></category>
		<category><![CDATA[commerce data]]></category>
		<category><![CDATA[connectors]]></category>
		<category><![CDATA[egression]]></category>
		<category><![CDATA[event-driven]]></category>
		<category><![CDATA[reliability]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=2756</guid>

					<description><![CDATA[<p>The post <a rel="nofollow" href="https://qilin.cloud/egression-module-shipping-commerce-data-without-excuses/">The Egression Module: Shipping Commerce Data Without Shipping Excuses</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="et_pb_section et_pb_section_2 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_16">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_16  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_4  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>You’ve probably done this the “<em>classic</em>” way before: a cron job exports data, a script pushes it somewhere, and everyone crosses their fingers that categories arrive before products and nothing hits a rate limit at 02:00 AM.</p>
<p>It works… right up until it doesn’t.</p>
<p>Modern commerce isn’t a single storefront anymore. It’s a constellation of channels, each with its own quirks, dependencies, and “please don’t call us more than X times per second” constraints. That’s why September’s engineering focus has been on one of the least glamorous—but most important—parts of the platform:</p>
<p><strong>Getting data out reliably.</strong></p>
<p>Welcome to the <strong>Egression Module</strong>: the part of Qilin.Cloud that turns “here’s what changed” into “it arrived, in the right order, with retries, without chaos”.</p></div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_17">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_17  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_with_border et_pb_module pac_divi_table_of_contents pac_divi_table_of_contents_2">
				
				
				
				
				
				
				<div class="et_pb_module_inner">
					
        <div class="pac_dtoc_main_container"
        data-allow_collapse_minimize="on"
        data-allow_collapse_minimize_tablet="on"
        data-allow_collapse_minimize_phone="on"
        data-ss="2000"
        data-sah="100"
        data-collapse_when_sticky="off"
        data-collapse_when_sticky_tablet="off"
        data-collapse_when_sticky_phone="off"
        data-skh="off"
        data-mtocai="off"
        data-mtocai_tablet="off"
        data-mtocai_phone="off"
        data-alh="off"
        data-ds="closed"
        data-dst="closed"
        data-dsp="closed">
            <div class="pac_dtoc_title_area click_on click_tablet_on click_phone_on">
                <div role="heading" aria-level="2" id="pac_dtocm_title" class="pac_dtoc_title">Table of Contents</div>
                
                <div class="pac_dtoc_icon_responsive">
                    <div class="pac_dtoc_opened_icon">2</div>
                    <div class="pac_dtoc_closed_icon">3</div>
                </div>
                
            </div>
            <div role="navigation" aria-labelledby="pac_dtocm_title" class="pac_dtoc_body_area inside">
                
                <div class='divi_table_of_contents' role="tree" ><ul class="pac_dtoc_heading_level_1" role="group" ><li class="pac_dtoc_li_heading_level_1" role="treeitem" ><div role="presentation" ><span data-href='#pac_remove_first_heading' data-hl='1'></span><a href='#pac_remove_first_heading' id='pac_remove_first_heading_toc_headding'>FirstHeading</a></div></li><ul class="pac_dtoc_heading_level_2" role="group" ><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#TheEgressionModuleinplainEnglish' data-hl='2'></span><a href='#TheEgressionModuleinplainEnglish' id='TheEgressionModuleinplainEnglish_toc_headding'>The Egression Module in plain English</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whyjobsbeatpayloaddumps' data-hl='2'></span><a href='#Whyjobsbeatpayloaddumps' id='Whyjobsbeatpayloaddumps_toc_headding'>Why “jobs” beat “payload dumps”</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Underthehoodconveyorbeltspartitionsandratelimits' data-hl='2'></span><a href='#Underthehoodconveyorbeltspartitionsandratelimits' id='Underthehoodconveyorbeltspartitionsandratelimits_toc_headding'>Under the hood: conveyor belts, partitions, and rate limits</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Thedeliveryloopfromjobtoconnectorcall' data-hl='2'></span><a href='#Thedeliveryloopfromjobtoconnectorcall' id='Thedeliveryloopfromjobtoconnectorcall_toc_headding'>The delivery loop: from job to connector call</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#RealworldexampleCatalogsyncwithoutthemidnightpanic' data-hl='2'></span><a href='#RealworldexampleCatalogsyncwithoutthemidnightpanic' id='RealworldexampleCatalogsyncwithoutthemidnightpanic_toc_headding'>Real-world example: “Catalog sync without the midnight panic”</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Fordevelopers' data-hl='2'></span><a href='#Fordevelopers' id='Fordevelopers_toc_headding'>For developers</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Formerchantsagenciesandinvestors' data-hl='2'></span><a href='#Formerchantsagenciesandinvestors' id='Formerchantsagenciesandinvestors_toc_headding'>For merchants, agencies, and investors</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Whatsnext' data-hl='2'></span><a href='#Whatsnext' id='Whatsnext_toc_headding'>What’s next</a></div></li><li class="pac_dtoc_li_heading_level_2" role="treeitem" ><div role="presentation" ><span data-href='#Readytoputittowork' data-hl='2'></span><a href='#Readytoputittowork' id='Readytoputittowork_toc_headding'>Ready to put it to work?</a></div></li></ul></div>
            </div>
        </div>
        
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_22">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_22  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_37  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>The Egression Module in plain English</span></h2>
						<div class="et_pb_blurb_description"><p>Think of the Egression Module like a <strong>logistics hub</strong>.</p>
<p>Upstream systems (your ERP, PIM, shop system, marketplace feeds, NiFi flows, custom processors) don’t ship parcels directly to every destination. They hand over <strong>jobs</strong> to a hub.</p>
<p>The hub then answers five practical questions for every job:</p>
<ul>
<li><strong>Whose package is this?</strong> (subscription)</li>
<li><strong>Where did it come from?</strong> (source)</li>
<li><strong>Where should it go?</strong> (target channel / connector endpoint)</li>
<li><strong>When should it go?</strong> (now, or scheduled later)</li>
<li><strong>What is it?</strong> (object type + object IDs + action like create/update/delete)</li>
</ul>
<p>That’s the foundation for doing commerce integrations the way seasoned teams have always wanted to do them: <strong>predictable, traceable, and recoverable</strong>.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div><div class="et_pb_row et_pb_row_23">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_23  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_blurb et_pb_blurb_38  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Why “jobs” beat “payload dumps”</span></h2>
						<div class="et_pb_blurb_description"><p>Old-school integrations love to ship massive payloads and hope the destination sorts it out.</p>
<p>But e-commerce data has <strong>dependencies</strong>:</p>
<ul>
<li>Categories and brands often need to exist before products reference them.</li>
<li>Offers might depend on products.</li>
<li>Orders might require customer and shipping context.</li>
</ul>
<p>So instead of blindly dumping big blobs, Qilin.Cloud models the “work to do” explicitly as <strong>jobs</strong>, and lets the platform orchestrate ordering and parallelism safely.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_39  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Under the hood: conveyor belts, partitions, and rate limits</span></h2>
						<div class="et_pb_blurb_description"><p>A logistics hub needs conveyor belts.</p>
<p>In Qilin.Cloud, the Event Processor pulls jobs from storage and processes them:</p>
<ul>
<li><strong>Sequentially</strong> when ordering matters (same partition key).</li>
<li><strong>In parallel</strong> when independence allows it (different partition keys).</li>
</ul>
<p>A <strong>partition key</strong> is basically: “these jobs must stay in order together”.</p>
<p>Example: all product updates for the same storefront could share a partition key, while different storefronts run concurrently.</p>
<p>Then comes the real-world pain point: <strong>connector rate limits</strong>.</p>
<p>Before sending a job to an output connector, the processor checks whether that connector is currently over its allowed throughput. If it is, the job gets delayed and rescheduled. No heroics, no drama, no accidental DDoS.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_40  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>The delivery loop: from job to connector call</span></h2>
						<div class="et_pb_blurb_description"><p>At a high level, the delivery loop looks like this:</p>
<ol>
<li>Upstream sends an HTTP request to create jobs (object type, object IDs, subscription, action).</li>
<li> Jobs are stored and then pushed into the Event Processor’s workflow.</li>
<li> The Event Processor resolves:<br />&#8211; the object payload via Metadata APIs,<br />&#8211; the correct connector endpoint based on the target channel,<br />&#8211; the authentication method configured for that subscription + channel.</li>
<li> The processor calls the output connector with:<br />&#8211; the action (create/update/delete),<br />&#8211; the object bodies,<br />&#8211; the authentication context.</li>
<li> The job is marked <em>success</em> or <em>failed</em>.<br />&#8211; On failure, it can be <strong>rescheduled</strong> automatically based on response codes and retry rules.</li>
</ol>
<p>This is the unsexy part of a platform that makes the sexy part possible: <strong>shipping data without shipping excuses</strong>.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_accordion et_pb_accordion_5">
				
				
				
				
				<div class="et_pb_toggle et_pb_module et_pb_accordion_item et_pb_accordion_item_5  et_pb_toggle_open">
				
				
				
				
				<h5 class="et_pb_toggle_title"></h5>
				<div class="et_pb_toggle_content clearfix">We invite you to share your experiences and lessons learned with Qilin.Cloud’s innovative technology platform for composable e-commerce. Your story can inspire others and help the whole community to improve.</p>
<p>&nbsp;</p>
<h4><strong>Share your Qilin.Cloud Success Story</strong><br />
<span> </span></h4>
<div class="et_pb_button_module_wrapper et_pb_button_0_wrapper  et_pb_module "><a class="et_pb_button et_pb_button_0 et_pb_bg_layout_light" href="https://qilin.cloud/share-your-story/">Your Journey</a></div></div>
			</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_41  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Real-world example: “Catalog sync without the midnight panic”</span></h2>
						<div class="et_pb_blurb_description"><p>Scenario: a merchant is launching a new collection across multiple channels.</p>
<p>They push a batch of:</p>
<ul>
<li>Categories</li>
<li>Manufacturers / brands</li>
<li>Products</li>
<li>Offers</li>
</ul>
<p>The Egression Module can process these with controlled ordering:</p>
<ul>
<li>Belt 1: Categories and brands first</li>
<li>Belt 2: Products next</li>
<li>Belt 3: Offers once products exist</li>
</ul>
<p>And it can do it across multiple destinations in parallel—without mixing up ordering where it matters.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_42  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>For developers</span></h2>
						<div class="et_pb_blurb_description"><p>If you build integrations for a living, the Egression Module should feel like coming home:</p>
<ul>
<li><strong>Explicit orchestration</strong> beats implicit side effects.</li>
<li><strong>Partitioning</strong> gives you concurrency <strong>and</strong> determinism.</li>
<li><strong>Rate-limit aware scheduling</strong> prevents the classic “works in staging, melts in production” story.</li>
<li><strong>Retry as a first-class concept</strong> means fewer custom “retry-daemon” scripts.</li>
</ul>
<p>In short: the platform does the boring parts so you can do the clever parts.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_43  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>For merchants, agencies, and investors</span></h2>
						<div class="et_pb_blurb_description"><ul>
<li><strong>Merchants:</strong> fewer partial syncs, fewer “why is it missing?” mysteries.</li>
<li><strong>Agencies:</strong> predictable delivery semantics mean faster implementations and fewer late-night support calls.</li>
<li><strong>Investors:</strong> reliable egression is compounding platform value—it enables more connectors, more volume, and lower operational cost as usage grows.</li>
</ul></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_44  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>What’s next</span></h2>
						<div class="et_pb_blurb_description"><p>Now that delivery is getting sharper, the next step is controlling <em>what</em> should be delivered—without having to write custom code for every rule. Next month’s topic will dive into <strong>Filter Predicates</strong>: routing logic you can version, audit, and reuse across pipelines.</p></div>
					</div>
				</div>
			</div><div class="et_pb_module et_pb_blurb et_pb_blurb_45  et_pb_text_align_left  et_pb_blurb_position_top et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_blurb_content">
					
					<div class="et_pb_blurb_container">
						<h2 class="et_pb_module_header"><span>Ready to put it to work?</span></h2>
						<div class="et_pb_blurb_description"><p>If you’ve ever had to rebuild the same “delivery engine” in three different client projects… you already know why this matters.</p>
<p>Qilin.Cloud is where that hard-earned integration wisdom becomes reusable infrastructure.</p></div>
					</div>
				</div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div></p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/egression-module-shipping-commerce-data-without-excuses/">The Egression Module: Shipping Commerce Data Without Shipping Excuses</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Principles &#038; Best Practices for Rest API</title>
		<link>https://qilin.cloud/principles-and-best-practices-for-rest-api/</link>
					<comments>https://qilin.cloud/principles-and-best-practices-for-rest-api/#respond</comments>
		
		<dc:creator><![CDATA[Thien Trinh Duc]]></dc:creator>
		<pubDate>Fri, 07 Apr 2023 07:58:17 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=694</guid>

					<description><![CDATA[<p>This best practice article is for developers who want to create RESTful web services that provide high reliability and consistency across multiple service suites. When these guidelines are followed, the services are positioned for rapid, widespread, public adoption by internal and external customers.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/principles-and-best-practices-for-rest-api/">Principles &#038; Best Practices for Rest API</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><div class="et_pb_section et_pb_section_3 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_24">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_24  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_6  et_pb_text_align_left et_pb_bg_layout_dark">
				
				
				
				
				<div class="et_pb_text_inner"><p id="2eb1">This best-practices article intends for developers interested in creating RESTful Web services that provide high <b>reliability</b> and consistency across multiple service suites; following these guidelines; services are positioned for rapid, widespread, public adoption by internal and external clients.</p>
<p id="af77">Here is the complete diagram to easily understand REST API’s principles, methods, and best practices.</p>
<p><!-- /divi:paragraph --></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_0">
				
				
				
				
				<a href="https://qilin.cloud/wp-content/uploads/2023/08/blog2-1.png" class="et_pb_lightbox_image" title=""><span class="et_pb_image_wrap "><img fetchpriority="high" decoding="async" width="2048" height="1639" src="https://qilin.cloud/wp-content/uploads/2023/08/blog2-1.png" alt="blog2 1" title="blog2-1" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog2-1.png 2048w, https://qilin.cloud/wp-content/uploads/2023/08/blog2-1-1280x1024.png 1280w, https://qilin.cloud/wp-content/uploads/2023/08/blog2-1-980x784.png 980w, https://qilin.cloud/wp-content/uploads/2023/08/blog2-1-480x384.png 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) and (max-width: 1280px) 1280px, (min-width: 1281px) 2048px, 100vw" class="wp-image-699"></span></a>
			</div><div class="et_pb_module et_pb_text et_pb_text_7  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><span>Now, Let’s begin with elaborating on each box by starting with its principles.</span></p>
<h2><strong></strong></h2>
<h2 id="434f"><strong>The 10 Principles / Constraints</strong></h2>
<p>&nbsp;</p>
<ol>
<li><strong>Client-Server</strong>: Separation of concerns is the principle behind the client-server constraints. By separating the user interface concerns from the data storage concerns, we improve the portability of the user interface across multiple platforms and improve scalability by simplifying the server components.
</li>
<li><strong>Stateless</strong>: communication must be stateless, as in the client-stateless-server (CSS) style. Each request from the client to the server must contain all of the information necessary to understand the request. The session state is therefore kept entirely on the client.</li>
<li><strong>Cacheable</strong>: To improve network efficiency, we add cache constraints to form the client-cache-stateless-server style. Cache constraints require that the data respond to a request with the implicit or explicit label as cacheable or non-cacheable. If a response is cacheable, then a client cache is given the right to reuse that response data for later, equivalent requests.
</li>
<li><strong>Layered System</strong>: A client cannot ordinarily tell whether it is connected directly to the end server or an intermediary along the way. Intermediary servers may improve system scalability by enabling load-balancing and by providing shared caches. Layers may also enforce security policies.
</li>
<li><strong>Code-on-Demand</strong>: REST allows client functionality to extend by downloading and executing code in the form of applets or scripts. Simplifies clients by reducing the number of features required to be pre-implemented. It allows features to download after deployment improving system extensibility.
</li>
<li><strong>Uniform Interface</strong>: By applying the software engineering principle of generality to the component interface, the overall system architecture becomes simplified, and the visibility of interactions is improved. Implementations decouple from the services they provide, which encourages independent evolvability. REST defines by four interface constraints: identification of resources, manipulation of resources through representations, self-descriptive messages, and Hypermedia as the engine of the application state.
</li>
<li><strong>Self-descriptive Messages</strong>: Each message includes enough information to describe how to process the message.
</li>
<li><strong>Resource-Based</strong>: Individual resources are identified in requests using URIs as resource identifiers. The resources themselves are conceptually separate from the representations that return to the client.
</li>
<li><strong>Manipulation of Resources Through Representations</strong>: When a client represents a resource, including any metadata attached, it has enough information to modify or delete the resource on the server, provided it has permission to do so.
</li>
<li><strong>Hypermedia as the Engine of Application State (HATEOAS)</strong>: Clients deliver state via body contents, query-string parameters, request headers, and the requested URI (the resource name). Services provide the state to clients via body content, response codes, and response headers.</li>
</ol></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_8  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2></h2>
<h2 id="development-styles">Best Practices</h2>
<p>&nbsp;</p>
<p><span>Now, Let’s change the gear to understand REST’s essential best practice, which every engineer should know.</span></p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_1">
				
				
				
				
				<a href="https://qilin.cloud/wp-content/uploads/2023/08/blog2-2.jpg" class="et_pb_lightbox_image" title=""><span class="et_pb_image_wrap "><img decoding="async" width="1165" height="654" src="https://qilin.cloud/wp-content/uploads/2023/08/blog2-2.jpg" alt="blog2 2" title="blog2-2" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog2-2.jpg 1165w, https://qilin.cloud/wp-content/uploads/2023/08/blog2-2-980x550.jpg 980w, https://qilin.cloud/wp-content/uploads/2023/08/blog2-2-480x269.jpg 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1165px, 100vw" class="wp-image-701"></span></a>
			</div><div class="et_pb_module et_pb_text et_pb_text_9  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><ol>
<li><strong>Keep it Simple and Fine-Grained</strong>: Create APIs that mimic your system’s underlying application domain or database architecture of your system. Eventually, you’ll want aggregate services — services that utilize multiple underlying resources to reduce chattiness.
</li>
<li><strong>Filtering &amp; Ordering</strong>: For large data sets, limiting the amount of data returned is vital from a bandwidth standpoint. Additionally, we may want to specify the fields or properties of a resource to be included in the response, thereby limiting the amount of data that comes back. We eventually want to query for specific values and sort the returned data.
</li>
<li><strong>Versioning</strong>: There are many ways to break a contract and negatively impact your clients in API development. If you are uncertain of the consequences of your change, it is better to play it safe and consider Versioning. There are several factors to consider when deciding if a new version is appropriate or if a modification of an existing representation is sufficient and acceptable. Since maintaining many versions becomes cumbersome, complex, error-prone, and costly, you should support no more than two versions for any given resource.
</li>
<li><strong>Cache</strong>: Caching enhances scalability by enabling layers in the system to eliminate remote calls to retrieve requested data. Services improve cache-ability by setting headers on responses such as <code>Cache-Control</code>, <code>Expires</code>, <code>Pragma</code>, <code>Last-Modified</code>, etc
</li>
<li><strong>Pagination</strong>: One of the principles of REST is connectedness — via hypermedia links. At the same time, services are still helpful without them. APIs become more self-descriptive when links return in the response. For collections returned in a response that supports Pagination, ‘first’, ‘last’, ‘next’, and ‘prev’ links at a minimum are beneficial.
</li>
<li><strong>Resource-Naming</strong>: An API is intuitive and easy to use when resources are named well. Done poorly, that same API can feel klutzy and be challenging to use and understand. RESTful APIs are for consumers. The name and structure of URIs should convey meaning to those consumers. It’s often difficult to know what the data boundaries should be, but with the understanding of your data, you most likely are equipped to take a stab and what makes sense to return as a representation to your clients. Design for your clients, not for your data.<br />
– <strong>Pluralization</strong>: The commonly-accepted practice is always to use plurals in node names to keep your API URIs consistent across all HTTP methods. The reasoning is that `customers` are a collection within the service suite and the ID (e.g., 33245) refers to one of those customers in the collection.</p>
</li>
<li><strong>Monitoring</strong>: Make sure to add all kinds of monitoring to improve the quality or performance of your API. Data points can be Response Time (P50, p90, P99), Status Codes (5XX, 4XX, etc.), Network Bandwidth, and many more.
</li>
<li><strong>Security</strong>:<br />
– <strong>Authorization / Authentication</strong>: Authorization for services is no different than authorization for any application. Ask this question, “Does this principal have the requested permission on the given resource?”<br />
– <strong>CORS</strong>: Implementing CORS on a server is as simple as sending an additional HTTP header in the response, such as <code>Access-Control-Allow-Origin</code>, <code>Access-Control-Allow-Credentials</code>, etc<br />
– <strong>TLS</strong>: All authentication should use SSL. OAuth2 requires the authorization server and access token credentials to use TLS.<br />
– <strong>Idempotence</strong>: an operation that will produce the same results if executed once or multiple times. It may have a different meaning depending on the context in which it applies. In the case of methods or subroutine calls with side effects, for instance, it means that the modified state remains the same after the first call.<br />
– <strong>Input Validation</strong>: Validate all input on the server. Accept “known” good input and reject bad input, Protect against SQL and NoSQL injection, Restrict the message size to the exact length of the field, Services should only display generic error messages and many more.<br />
– <strong>Rate limiting:</strong> is a strategy for limiting network traffic. It puts a cap on how often someone can repeat an action within a certain timeframe — for instance, trying to log in to an account.<br />
– <strong>Logging</strong>: Make sure you do not accidentally log any Personally identifiable <strong>information</strong> (PII).</li>
</ol></div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div></p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/principles-and-best-practices-for-rest-api/">Principles &#038; Best Practices for Rest API</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qilin.cloud/principles-and-best-practices-for-rest-api/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Use architecture decision records to document your project</title>
		<link>https://qilin.cloud/use-architecture-decision-records-to-document-your-project/</link>
					<comments>https://qilin.cloud/use-architecture-decision-records-to-document-your-project/#comments</comments>
		
		<dc:creator><![CDATA[Thien Trinh Duc]]></dc:creator>
		<pubDate>Thu, 16 Mar 2023 13:11:44 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">https://qilin.cloud/?p=707</guid>

					<description><![CDATA[<p>Documenting architectural decisions helps a project succeed by helping current and future contributors understand the reasons for doing things a certain way.</p>
<p>The post <a rel="nofollow" href="https://qilin.cloud/use-architecture-decision-records-to-document-your-project/">Use architecture decision records to document your project</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div class="et_pb_section et_pb_section_4 et_section_regular" >
				
				
				
				
				
				
				<div class="et_pb_row et_pb_row_25">
				<div class="et_pb_column et_pb_column_4_4 et_pb_column_25  et_pb_css_mix_blend_mode_passthrough et-last-child">
				
				
				
				
				<div class="et_pb_module et_pb_text et_pb_text_10  et_pb_text_align_left et_pb_bg_layout_dark">
				
				
				
				
				<div class="et_pb_text_inner"><h2 id="2eb1"><span>Documenting architectural decisions helps a project succeed by helping current and future contributors understand the reasons for doing things a certain way.</span></h2>
<p><!-- /divi:paragraph --></p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_11  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>When they are working on a new feature, project leaders—whether open or closed source—need to decide how to implement it. Agile projects often make decisions on the fly, unlike the old waterfall world, where a long requirement-engineering phase precedes the development process. Often enough, the <em>why</em> and <em>how</em> of the feature are kept in the decision-making developer&#8217;s brain. Newcomers to the project then are left to wonder why certain things are done in a certain way, making it hard for them to figure out and contribute, as the necessary knowledge is not readily available.</p>
<p>Michael Nygard identified this issue back in 2011 in his article<span> </span><a href="https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions" target="_blank" rel="noopener">Documenting architecture decisions</a>, where he presents the concept of architecture decision records (ADRs).</p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_2">
				
				
				
				
				<span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="1232" height="760" src="https://qilin.cloud/wp-content/uploads/2023/08/blog3-1.png" alt="blog3 1" title="blog3-1" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog3-1.png 1232w, https://qilin.cloud/wp-content/uploads/2023/08/blog3-1-980x605.png 980w, https://qilin.cloud/wp-content/uploads/2023/08/blog3-1-480x296.png 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1232px, 100vw" class="wp-image-712"></span>
			</div><div class="et_pb_module et_pb_text et_pb_text_12  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><p>The need for such records increases for larger or more distributed projects, especially those where no single architect is available or where new contributors are being onboarded. The time was ripe for such a format when Nygard wrote his article, and seven years later, IT consultancy Thoughtworks put ADRs into the Adopt category of its <a href="https://www.thoughtworks.com/radar/techniques/lightweight-architecture-decision-records" target="_blank" rel="noopener">technology radar</a>.<strong><em></em></strong></p>
<p>As the name ADR suggests, you use these records for making larger architectural decisions. They don&#8217;t serve as a glorified change log or replace (good) commit messages.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_13  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2>Components of an ADR</h2>
<p><span>This image shows the general components of an ADR:</span></p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_3">
				
				
				
				
				<a href="https://qilin.cloud/wp-content/uploads/2023/08/blog3-2.png" class="et_pb_lightbox_image" title=""><span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="1232" height="1051" src="https://qilin.cloud/wp-content/uploads/2023/08/blog3-2.png" alt="blog3 2" title="blog3-2" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog3-2.png 1232w, https://qilin.cloud/wp-content/uploads/2023/08/blog3-2-980x836.png 980w, https://qilin.cloud/wp-content/uploads/2023/08/blog3-2-480x409.png 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1232px, 100vw" class="wp-image-713"></span></a>
			</div><div class="et_pb_module et_pb_text et_pb_text_14  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><ul>
<li><strong>Number/Date:</strong><span> </span>A unique increasing number and date that usually follows the <em>ADR-nnnn</em> pattern to help sort them from old to new</li>
<li><strong>Title:</strong><span> </span>Indicates the content</li>
<li><strong>Context (Why):</strong><span> </span>Describes the current situation and <em>why</em> you made this decision or thought it necessary—some variations explicitly break out an &#8220;alternatives covered&#8221; section to ensure all considerations get recorded</li>
<li><strong>Decision (What/How):</strong><span> </span>Describes the <em>what</em> and <em>how</em> of the feature</li>
<li><strong>Status:</strong><span> </span>Describes the status; note that ADRs can be superseded later by newer ADRs</li>
<li><strong>Consequences:</strong><span> </span>Describes the effect of the decision, listing positive and negative aspects</li>
</ul>
<p>While decision records contain the &#8220;technical&#8221; decisions, they should also list non-functional ones. They can also include the decision to use an ADR in the first place or the license chosen. You can find an example of this in the<span> </span><a href="https://github.com/operate-first/blueprint/tree/main/adr" target="_blank" rel="noopener">Operate First</a> project&#8217;s repository.</p></div>
			</div><div class="et_pb_module et_pb_text et_pb_text_15  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2></h2>
<h2>ADR formats</h2>
<p>The previous section describes the basic format of an ADR. Over time, many ADR formats and templates have evolved. The<span> </span><a href="https://adr.github.io/" target="_blank" rel="noopener">ADR repository on GitHub</a><span> </span>lists some of them and some templates. Common to all is using a (lightweight) markup language like AsciiDoc.</p>
<p>Much more important than the concrete format you choose is where you put the records. It is best to put them next to the source code in your project in a dedicated ADR folder in the documentation. Of course, that isn&#8217;t possible for projects with multiple repositories. There, the best option is to use the main repository and link it into the README of the dependent projects.</p></div>
			</div><div class="et_pb_module et_pb_image et_pb_image_4">
				
				
				
				
				<span class="et_pb_image_wrap "><img loading="lazy" decoding="async" width="1232" height="206" src="https://qilin.cloud/wp-content/uploads/2023/08/blog3-3.png" alt="blog3 3" title="blog3-3" srcset="https://qilin.cloud/wp-content/uploads/2023/08/blog3-3.png 1232w, https://qilin.cloud/wp-content/uploads/2023/08/blog3-3-980x164.png 980w, https://qilin.cloud/wp-content/uploads/2023/08/blog3-3-480x80.png 480w" sizes="(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1232px, 100vw" class="wp-image-714"></span>
			</div><div class="et_pb_module et_pb_text et_pb_text_16  et_pb_text_align_left et_pb_bg_layout_light">
				
				
				
				
				<div class="et_pb_text_inner"><h2>Wrap up</h2>
<p>You can use ADRs during the ODF feedback loop: Put a draft of the decision with documentation of constraints, goals, and such into a pull request, and then update this alongside the feedback rounds. Once you make your decision, you can merge the pull request into the main repository.</p>
<p>For more information, read:</p>
<ul>
<li><a href="https://opensource.com/article/20/3/documentation?extIdCarryOver=true&amp;sc_cid=701f2000001Css0AAC" target="_blank" rel="noopener">How to write effective documentation for your open source project</a></li>
<li><a href="https://github.com/operate-first/blueprint" target="_blank" rel="noopener">Operate First Blueprint</a></li>
</ul></div>
			</div>
			</div>
				
				
				
				
			</div>
				
				
			</div>
<p>The post <a rel="nofollow" href="https://qilin.cloud/use-architecture-decision-records-to-document-your-project/">Use architecture decision records to document your project</a> appeared first on <a rel="nofollow" href="https://qilin.cloud">Qilin.Cloud</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qilin.cloud/use-architecture-decision-records-to-document-your-project/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
