159159 # api-bar { font-size : 0.78rem ; color : # aaa ; margin-bottom : 1rem ; }
160160 # api-bar code { background : # f0f0f0 ; padding : 0.1rem 0.4rem ; border-radius : 4px ; }
161161
162+ details .info-panel {
163+ background : # fff ;
164+ border-radius : 8px ;
165+ box-shadow : 0 1px 4px rgba (0 , 0 , 0 , 0.08 );
166+ margin-bottom : 1.5rem ;
167+ overflow : hidden;
168+ }
169+ details .info-panel summary {
170+ padding : 0.9rem 1.5rem ;
171+ cursor : pointer;
172+ font-size : 0.875rem ;
173+ font-weight : 600 ;
174+ color : # 444 ;
175+ text-transform : uppercase;
176+ letter-spacing : 0.05em ;
177+ list-style : none;
178+ display : flex;
179+ align-items : center;
180+ gap : 0.5rem ;
181+ user-select : none;
182+ }
183+ details .info-panel summary ::-webkit-details-marker { display : none; }
184+ details .info-panel summary ::before {
185+ content : "›" ;
186+ font-size : 1rem ;
187+ color : # aaa ;
188+ transition : transform 0.15s ;
189+ display : inline-block;
190+ }
191+ details .info-panel [open ] summary ::before { transform : rotate (90deg ); }
192+ .info-body {
193+ padding : 0 1.5rem 1.5rem ;
194+ display : grid;
195+ grid-template-columns : repeat (auto-fill, minmax (280px , 1fr ));
196+ gap : 1.25rem ;
197+ border-top : 1px solid # f0f0f0 ;
198+ padding-top : 1.25rem ;
199+ }
200+ .info-section h3 { font-size : 0.8rem ; font-weight : 700 ; color : # 1a1a2e ; text-transform : uppercase; letter-spacing : 0.05em ; margin-bottom : 0.5rem ; }
201+ .info-section p , .info-section li { font-size : 0.82rem ; color : # 555 ; line-height : 1.55 ; }
202+ .info-section ul { padding-left : 1.1rem ; }
203+ .info-section li { margin-bottom : 0.2rem ; }
204+ .service-tag {
205+ display : inline-block;
206+ background : # eef2ff ;
207+ color : # 3730a3 ;
208+ border-radius : 4px ;
209+ padding : 0.1rem 0.45rem ;
210+ font-size : 0.72rem ;
211+ font-weight : 600 ;
212+ margin : 0.15rem 0.1rem ;
213+ font-family : monospace;
214+ }
215+
162216 # chaos-banner {
163217 display : none;
164218 background : # fff3cd ;
@@ -184,6 +238,55 @@ <h1>Order Processing Pipeline</h1>
184238< main >
185239 < p id ="api-bar "> API endpoint: < code id ="api-url "> </ code > </ p >
186240
241+ < details class ="info-panel ">
242+ < summary > About this demo</ summary >
243+ < div class ="info-body ">
244+ < div class ="info-section ">
245+ < h3 > What is this?</ h3 >
246+ < p > A fully local serverless order-processing pipeline running on
247+ < strong > LocalStack</ strong > — an AWS emulator that lets you develop
248+ and test cloud applications on your laptop without touching a real AWS account.</ p >
249+ < p style ="margin-top:0.5rem; "> Everything here — Lambda, API Gateway, DynamoDB,
250+ SQS, Step Functions, S3 — runs locally inside a single Docker container.</ p >
251+ </ div >
252+ < div class ="info-section ">
253+ < h3 > Architecture</ h3 >
254+ < ul >
255+ < li > < span class ="service-tag "> API Gateway</ span > exposes < code style ="font-size:0.78rem "> POST /orders</ code > and < code style ="font-size:0.78rem "> GET /orders</ code > </ li >
256+ < li > < span class ="service-tag "> Lambda</ span > < em > order-handler</ em > writes the order to DynamoDB and enqueues it on SQS</ li >
257+ < li > < span class ="service-tag "> SQS</ span > < em > orders-queue</ em > buffers orders; failed messages go to a < em > orders-dlq</ em > </ li >
258+ < li > < span class ="service-tag "> Lambda</ span > < em > order-processor</ em > starts a Step Functions execution per order</ li >
259+ < li > < span class ="service-tag "> Step Functions</ span > orchestrates: Validate → Wait → Payment → Wait → Fulfill (with error catch)</ li >
260+ < li > < span class ="service-tag "> DynamoDB</ span > tracks order status and step timestamps</ li >
261+ < li > < span class ="service-tag "> S3</ span > stores a receipt JSON when an order is fulfilled</ li >
262+ </ ul >
263+ </ div >
264+ < div class ="info-section ">
265+ < h3 > Chaos Engineering</ h3 >
266+ < p > Use < strong > make inject-fault</ strong > to enable a
267+ < code style ="font-size:0.78rem "> ProvisionedThroughputExceededException</ code >
268+ on every DynamoDB < code style ="font-size:0.78rem "> UpdateItem</ code > call.
269+ This simulates a DynamoDB throttling incident:</ p >
270+ < ul >
271+ < li > New orders get stuck in < em > pending</ em > — the processor Lambda throws before starting the state machine</ li >
272+ < li > SQS retries the message 3 times, then routes it to the < strong > DLQ</ strong > </ li >
273+ < li > Run < strong > make remove-fault</ strong > to restore normal operation</ li >
274+ < li > Enable < strong > Auto-resume DLQ</ strong > above to automatically replay stranded messages once the fault is cleared</ li >
275+ </ ul >
276+ </ div >
277+ < div class ="info-section ">
278+ < h3 > Try it out</ h3 >
279+ < ul >
280+ < li > Place an order and watch it move through the pipeline in real time</ li >
281+ < li > Inject a fault, place more orders, observe them pile up in < em > pending</ em > </ li >
282+ < li > Check the chaos banner — it reflects the live fault list from LocalStack</ li >
283+ < li > Remove the fault and tick < em > Auto-resume DLQ</ em > — orders recover automatically</ li >
284+ < li > Expand any row to see per-step timestamps and details</ li >
285+ </ ul >
286+ </ div >
287+ </ div >
288+ </ details >
289+
187290 < div id ="chaos-banner ">
188291 < strong > ⚠ Chaos mode active</ strong > — fault injections are enabled, orders may fail or get stuck.
189292 < div id ="chaos-faults "> </ div >
0 commit comments