<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Deep Tech Guide]]></title><description><![CDATA[Deep Tech Guide]]></description><link>https://deeptechguide.blog</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 02:55:53 GMT</lastBuildDate><atom:link href="https://deeptechguide.blog/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Online Movie Ticket Booking Platform
Solution Architecture]]></title><description><![CDATA[Online Movie Ticket Booking Platform (Backend)

This post focuses on backend system design only (no UI). It covers architecture, service boundaries, booking correctness, scalability, observability, deployment, and API contracts for one read + one wri...]]></description><link>https://deeptechguide.blog/online-movie-ticket-booking-platform-solution-architecture</link><guid isPermaLink="true">https://deeptechguide.blog/online-movie-ticket-booking-platform-solution-architecture</guid><category><![CDATA[bookmyshow]]></category><category><![CDATA[hld]]></category><category><![CDATA[System Design]]></category><dc:creator><![CDATA[Sushil Chandra]]></dc:creator><pubDate>Thu, 29 Jan 2026 08:50:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/q8P8YoR6erg/upload/93b439b81d4a524fefe482f2e4e6030d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-online-movie-ticket-booking-platform-backend">Online Movie Ticket Booking Platform (Backend)</h1>

This post focuses on <strong>backend system design only</strong> (no UI). It covers architecture, service boundaries, booking correctness, scalability, observability, deployment, and API contracts for one read + one write scenario.


<hr />
<h2 id="heading-1-system-overview">1. System Overview</h2>
<h3 id="heading-11-problem-statement">1.1 Problem Statement</h3>
<p>The objective is to design and implement a scalable, highly available <strong>Online Movie Ticket Booking Platform</strong> that enables seamless collaboration between theatre partners and end customers, while supporting:</p>
<ul>
<li>High-volume concurrent bookings  </li>
<li>Multiple cities and languages  </li>
<li>Secure payment processing  </li>
</ul>
<p>The platform must:</p>
<ul>
<li>Allow theatre partners to onboard, manage theatres, screens, seat layouts, and show schedules.</li>
<li>Enable customers to browse movies, theatres, and show timings across cities and dates.</li>
<li>Support real-time seat availability, ticket booking, payments, and notifications.</li>
<li>Scale reliably during peak demand (e.g., movie releases, weekends).</li>
<li>Ensure data consistency, prevent double booking, and meet stringent non-functional requirements such as <strong>99.99% availability</strong>, security, and compliance.</li>
</ul>
<p>The solution is expected to be <strong>service-oriented, cloud-native, and production-grade</strong>, focusing on backend services only.</p>
<hr />
<h3 id="heading-12-key-stakeholders">1.2 Key Stakeholders</h3>
<ul>
<li><p><strong>Customers (B2C)</strong><br />Browse movies and showtimes, select seats, make payments, and receive booking confirmations.</p>
</li>
<li><p><strong>Theatre Partners (B2B)</strong><br />Onboard theatres, define screens and seat maps, create/update shows, and manage availability.</p>
</li>
<li><p><strong>Platform Operations Team</strong><br />Monitor system health, handle deployments, manage configurations, and ensure SLA compliance.</p>
</li>
<li><p><strong>External Systems</strong><br />Payment gateways, notification providers (SMS/Email/WhatsApp), and analytics platforms.</p>
</li>
</ul>
<hr />
<h3 id="heading-13-core-functional-capabilities">1.3 Core Functional Capabilities</h3>
<h4 id="heading-theatre-amp-partner-management">Theatre &amp; Partner Management</h4>
<ul>
<li>Partner onboarding and authentication  </li>
<li>Theatre, screen, and seat-map configuration  </li>
<li>Show creation, updates, and cancellations  </li>
</ul>
<h4 id="heading-movie-discovery-amp-browsing">Movie Discovery &amp; Browsing</h4>
<ul>
<li>Browse movies by city, language, genre, and date  </li>
<li>View theatres currently running a selected movie  </li>
<li>Retrieve show timings and seat availability  </li>
</ul>
<h4 id="heading-ticket-booking-amp-payments">Ticket Booking &amp; Payments</h4>
<ul>
<li>Seat selection with real-time availability  </li>
<li>Temporary seat locking to avoid double booking  </li>
<li>Secure payment initiation and confirmation  </li>
<li>Booking confirmation and ticket issuance  </li>
</ul>
<h4 id="heading-offers-amp-pricing">Offers &amp; Pricing</h4>
<ul>
<li>Rule-based promotional offers (e.g., third ticket at 50% discount)  </li>
<li>Flexible pricing strategies configurable per city or theatre  </li>
</ul>
<h4 id="heading-notifications">Notifications</h4>
<ul>
<li>Booking confirmations, cancellations, and refunds  </li>
<li>Asynchronous notification delivery via messaging systems  </li>
</ul>
<hr />
<h3 id="heading-14-key-non-functional-requirements">1.4 Key Non-Functional Requirements</h3>
<ul>
<li><p><strong>High Availability:</strong><br />Achieve <strong>99.99% uptime</strong>, especially during peak booking windows.</p>
</li>
<li><p><strong>Scalability:</strong><br />Horizontal scalability for spikes in read traffic (browsing) and write traffic (bookings).</p>
</li>
<li><p><strong>Consistency &amp; Concurrency Control:</strong><br />Strong consistency for seat booking to prevent overselling and race conditions.</p>
</li>
<li><p><strong>Performance:</strong><br />Low-latency responses for browsing and booking flows.</p>
</li>
<li><p><strong>Security &amp; Compliance:</strong><br />Protection against OWASP Top 10, secure handling of PII, and compliant payment processing.</p>
</li>
<li><p><strong>Extensibility:</strong><br />Easy onboarding of new cities, theatres, languages, and future features like recommendations or dynamic pricing.</p>
</li>
</ul>
<hr />
<h3 id="heading-15-in-scope-and-out-of-scope">1.5 In-Scope and Out-of-Scope</h3>
<h4 id="heading-in-scope">In Scope</h4>
<ul>
<li>Backend service design and implementation  </li>
<li>API design for <strong>one read scenario</strong> (browse shows)  </li>
<li>API design for <strong>one write scenario</strong> (ticket booking)  </li>
<li>Database schema design  </li>
<li>Concurrency, transactions, and failure handling  </li>
<li>High-level architecture and deployment strategy  </li>
</ul>
<h4 id="heading-out-of-scope">Out of Scope</h4>
<ul>
<li>UI / frontend implementation  </li>
<li>Recommendation engines or advanced AI models  </li>
<li>Detailed financial settlement with theatre partners  </li>
<li>Manual customer support workflows  </li>
</ul>
<hr />
<h3 id="heading-16-solution-approach-summary">1.6 Solution Approach Summary</h3>
<p>The proposed solution adopts a <strong>microservices-based architecture</strong> with clear separation of concerns across catalog, search, booking, payment, and notification domains.</p>
<p>It leverages <strong>event-driven communication</strong>, <strong>caching</strong>, and <strong>search indexing</strong> to achieve scalability and resilience, while ensuring strong transactional guarantees for seat booking and payments.</p>
<hr />
<h2 id="heading-2-architecture-diagram">2. Architecture Diagram</h2>
<h3 id="heading-21-high-level-architecture">2.1 High-Level Architecture</h3>
<p>The platform is designed as a cloud-native microservices system optimized for:</p>
<ul>
<li><strong>Read-heavy browsing</strong> (movie discovery, theatres, show timings) using <strong>Search + Cache</strong></li>
<li><strong>Write-critical booking</strong> (seat selection → lock → payment → confirmation) using <strong>strong consistency + idempotency</strong></li>
<li><strong>High availability (99.99%)</strong> via stateless services, horizontal scaling, and multi-AZ persistence</li>
<li><strong>Loose coupling</strong> via an event-driven backbone for non-blocking workflows like notifications, analytics, and booking transitions</li>
</ul>

If you want, you can embed a diagram here (Mermaid, Excalidraw export, or an image). In MDX, you can also import a React diagram component.


<hr />
<h3 id="heading-22-component-responsibilities">2.2 Component Responsibilities</h3>
<h4 id="heading-api-gateway">API Gateway</h4>
<ul>
<li>Central entry point for customers and partners  </li>
<li>Authentication/authorization, request validation, rate limiting, WAF rules, routing  </li>
<li>Supports versioned APIs and throttling during peak traffic  </li>
</ul>
<h4 id="heading-browse-path-read-optimized">Browse Path (Read Optimized)</h4>
<p>Search Service + Cache handle most browse traffic:</p>
<ul>
<li>Search service provides low-latency browse APIs (movie → city → theatres → shows)</li>
<li>Uses OpenSearch/Elasticsearch index populated via events from Catalog/Show services</li>
<li>Redis caches hot keys (popular movies, cities, show listings) to reduce DB load</li>
</ul>
<h4 id="heading-booking-path-write-consistency-critical">Booking Path (Write / Consistency Critical)</h4>
<p>Booking Service owns:</p>
<ul>
<li>Seat selection validation and seat lock with TTL</li>
<li>Booking state machine: <code>INITIATED → SEATS_LOCKED → PAYMENT_PENDING → CONFIRMED / FAILED / EXPIRED</code></li>
<li>Double-booking prevention via:<ul>
<li>Redis seat locks (fast TTL-based locking) and/or</li>
<li>DB-level constraints/transactions during confirmation (final authority)</li>
</ul>
</li>
</ul>
<h4 id="heading-payment-processing">Payment Processing</h4>
<p>Payment Service integrates with external gateways:</p>
<ul>
<li>Creates payment intent for a booking (idempotent)</li>
<li>Handles gateway webhooks (signature verification)</li>
<li>Publishes payment events (<code>payment.succeeded</code>, <code>payment.failed</code>) to Kafka</li>
</ul>
<h4 id="heading-offers-amp-pricing-1">Offers &amp; Pricing</h4>
<p>Offer/Pricing Service:</p>
<ul>
<li>Centralized discount rules (e.g., “3rd ticket 50%”)</li>
<li>Pluggable rule execution (Strategy pattern)</li>
<li>Ensures consistent pricing during booking creation/confirmation</li>
</ul>
<h4 id="heading-notifications-1">Notifications</h4>
<p>Notification Service:</p>
<ul>
<li>Asynchronous confirmation/cancellation messages triggered by booking/payment events</li>
<li>Multi-channel (SMS/Email/WhatsApp) with retries and DLQ</li>
</ul>
<hr />
<h3 id="heading-23-key-data-and-event-flows">2.3 Key Data and Event Flows</h3>
<h4 id="heading-read-scenario-browse-shows-fast-scalable">Read Scenario: Browse Shows (Fast, Scalable)</h4>
<ol>
<li>Client calls Search APIs via Gateway (e.g., movie + city + date)</li>
<li>Search service fetches from OpenSearch + Redis cache</li>
<li>If needed, resolves freshness via show updates consumed from Kafka</li>
<li>Returns theatre list + show timings + availability summary</li>
</ol>
<p>Design goal: keep browsing highly available even under heavy load.</p>
<h4 id="heading-write-scenario-book-tickets-correctness-first">Write Scenario: Book Tickets (Correctness First)</h4>
<ol>
<li>Client requests booking with <code>showId + seatIds</code></li>
<li>Booking service locks seats (Redis TTL), creates booking (<code>PAYMENT_PENDING</code>)</li>
<li>Pricing calculated via Offer/Pricing service</li>
<li>Client initiates payment → Payment service creates payment intent</li>
<li>Gateway webhook triggers payment status update</li>
<li>Payment service publishes payment event to Kafka</li>
<li>Booking service consumes event and finalizes booking (<code>CONFIRMED</code>) or releases locks (<code>FAILED</code>)</li>
</ol>
<p>Design goal: no double-booking, idempotent retries, consistent final state.</p>
<hr />
<h3 id="heading-24-architecture-decisions-why-this-works">2.4 Architecture Decisions (Why This Works)</h3>
<ul>
<li><strong>Read/Write separation:</strong> browsing uses Search + Cache; booking uses strong consistency  </li>
<li><strong>Event-driven workflows:</strong> decouple booking, payment, notifications, indexing  </li>
<li><strong>Idempotency everywhere:</strong> protects against retries/timeouts in booking/payment  </li>
<li><strong>Horizontal scalability:</strong> stateless services scale behind load balancers  </li>
<li><strong>High availability:</strong> multi-AZ, retries/backoff, circuit breakers, graceful degradation  </li>
</ul>
<hr />
<h2 id="heading-3-component-descriptions">3. Component Descriptions</h2>
<p>This section describes major components, responsibilities, data ownership, key APIs, and interactions.</p>
<h3 id="heading-31-core-application-services">3.1 Core Application Services</h3>
<h4 id="heading-311-api-gateway">3.1.1 API Gateway</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Single entry point for external client and partner requests</td></tr>
<tr>
<td>Responsibilities</td><td>AuthN/AuthZ, rate limiting, request validation, WAF rules, API versioning</td></tr>
<tr>
<td>Data Store</td><td>None (stateless)</td></tr>
<tr>
<td>Key Interactions</td><td>Routes requests to backend microservices</td></tr>
<tr>
<td>Availability Strategy</td><td>Stateless, horizontally scalable behind load balancer</td></tr>
</tbody>
</table>
</div><h4 id="heading-312-catalog-service">3.1.2 Catalog Service</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Manages static and semi-static metadata</td></tr>
<tr>
<td>Responsibilities</td><td>Movies, genres, languages, cities, availability metadata</td></tr>
<tr>
<td>Data Store</td><td>Document or relational DB (MongoDB / PostgreSQL)</td></tr>
<tr>
<td>Key APIs</td><td>Get movies by city/language, retrieve movie metadata</td></tr>
<tr>
<td>Events</td><td>Publishes catalog update events</td></tr>
<tr>
<td>Scaling Considerations</td><td>Read-heavy; aggressively cached</td></tr>
</tbody>
</table>
</div><h4 id="heading-313-theatre-amp-partner-service">3.1.3 Theatre &amp; Partner Service</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Manages theatre partners and infrastructure</td></tr>
<tr>
<td>Responsibilities</td><td>Partner onboarding, theatre creation, screen setup, seat layout configuration</td></tr>
<tr>
<td>Data Store</td><td>Relational database</td></tr>
<tr>
<td>Key APIs</td><td>Create/update theatre, screens, seat maps</td></tr>
<tr>
<td>Security</td><td>Partner-role based access control</td></tr>
<tr>
<td>Events</td><td>Theatre and seat layout change events</td></tr>
</tbody>
</table>
</div><h4 id="heading-314-show-service">3.1.4 Show Service</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Manages movie show scheduling</td></tr>
<tr>
<td>Responsibilities</td><td>Create/update/cancel shows; maintain show status</td></tr>
<tr>
<td>Data Store</td><td>Relational database</td></tr>
<tr>
<td>Key APIs</td><td>Create show, fetch shows by theatre/movie/date</td></tr>
<tr>
<td>Events</td><td>Show published/updated events for indexing</td></tr>
<tr>
<td>Consistency Model</td><td>Strong consistency per show</td></tr>
</tbody>
</table>
</div><h4 id="heading-315-search-service">3.1.5 Search Service</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Fast, browse-optimized read APIs</td></tr>
<tr>
<td>Responsibilities</td><td>Movie → city → theatre → show discovery</td></tr>
<tr>
<td>Data Store</td><td>OpenSearch / Elasticsearch</td></tr>
<tr>
<td>Key APIs</td><td>Browse shows, theatres by filters</td></tr>
<tr>
<td>Data Source</td><td>Event-driven updates from Catalog and Show services</td></tr>
<tr>
<td>Performance</td><td>Millisecond-level latency for high traffic</td></tr>
</tbody>
</table>
</div><h4 id="heading-316-booking-service">3.1.6 Booking Service</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Core transactional service for ticket booking</td></tr>
<tr>
<td>Responsibilities</td><td>Seat locking, booking lifecycle, concurrency control</td></tr>
<tr>
<td>Data Store</td><td>Relational database (strong consistency)</td></tr>
<tr>
<td>Cache</td><td>Redis locks with TTL</td></tr>
<tr>
<td>Key APIs</td><td>Create booking, confirm booking, cancel booking</td></tr>
<tr>
<td>Events</td><td>Booking created/confirmed/failed/expired</td></tr>
<tr>
<td>Design Patterns</td><td>State Machine, Idempotency</td></tr>
</tbody>
</table>
</div><h4 id="heading-317-offer-amp-pricing-service">3.1.7 Offer &amp; Pricing Service</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Centralized pricing and promotions engine</td></tr>
<tr>
<td>Responsibilities</td><td>Discount rules, price calculation</td></tr>
<tr>
<td>Data Store</td><td>Relational/config store</td></tr>
<tr>
<td>Key APIs</td><td>Calculate price</td></tr>
<tr>
<td>Design Patterns</td><td>Strategy pattern</td></tr>
<tr>
<td>Extensibility</td><td>Plug-and-play rule addition</td></tr>
</tbody>
</table>
</div><h4 id="heading-318-payment-service">3.1.8 Payment Service</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Payment orchestration</td></tr>
<tr>
<td>Responsibilities</td><td>Payment intent, webhook processing, status tracking</td></tr>
<tr>
<td>Data Store</td><td>Relational database</td></tr>
<tr>
<td>Key APIs</td><td>Initiate payment, webhook endpoint</td></tr>
<tr>
<td>External Integrations</td><td>Payment gateways</td></tr>
<tr>
<td>Reliability</td><td>Idempotent processing, retries/backoff</td></tr>
</tbody>
</table>
</div><h4 id="heading-319-notification-service">3.1.9 Notification Service</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Asynchronous communication</td></tr>
<tr>
<td>Responsibilities</td><td>Confirmations, cancellations, refunds</td></tr>
<tr>
<td>Data Store</td><td>None / lightweight delivery status store</td></tr>
<tr>
<td>Channels</td><td>SMS, Email, WhatsApp</td></tr>
<tr>
<td>Trigger Mechanism</td><td>Kafka events</td></tr>
<tr>
<td>Fault Handling</td><td>Retry + DLQ</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-32-infrastructure-components">3.2 Infrastructure Components</h3>
<h4 id="heading-321-cache-redis">3.2.1 Cache (Redis)</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Reduce latency and DB load</td></tr>
<tr>
<td>Usage</td><td>Seat locks, hot browse data</td></tr>
<tr>
<td>TTL Strategy</td><td>Short TTL for locks; longer TTL for catalog</td></tr>
<tr>
<td>Availability</td><td>Clustered, multi-AZ</td></tr>
</tbody>
</table>
</div><h4 id="heading-322-message-broker-kafka">3.2.2 Message Broker (Kafka)</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td>Purpose</td><td>Asynchronous communication backbone</td></tr>
<tr>
<td>Usage</td><td>Booking/payment/notification/indexing events</td></tr>
<tr>
<td>Benefits</td><td>Loose coupling, retryability, replay</td></tr>
<tr>
<td>Consumers</td><td>Booking, Payment, Search, Notification services</td></tr>
</tbody>
</table>
</div><h4 id="heading-323-databases">3.2.3 Databases</h4>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Database Type</td><td>Usage</td></tr>
</thead>
<tbody>
<tr>
<td>Relational DB</td><td>Bookings, payments, theatres, shows</td></tr>
<tr>
<td>Document DB</td><td>Catalog metadata (optional)</td></tr>
<tr>
<td>Search Index</td><td>Browse-optimized queries</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-33-component-interaction-summary">3.3 Component Interaction Summary</h3>
<ul>
<li><strong>Browse path:</strong> API Gateway → Search Service → Search Index / Cache  </li>
<li><strong>Booking path:</strong> API Gateway → Booking Service → Offer Service → Payment Service  </li>
<li><strong>Async path:</strong> Core services → Kafka → Search/Notification consumers  </li>
<li><strong>Failure isolation:</strong> booking/payment issues don’t impact browse functionality  </li>
</ul>
<hr />
<h3 id="heading-34-design-rationale">3.4 Design Rationale</h3>
<ul>
<li>Clear service boundaries enable independent scaling and deployments.</li>
<li>Event-driven design improves resilience and extensibility.</li>
<li>Strong transactional guarantees are limited to booking + payment.</li>
<li>Read-optimized components protect the system during traffic spikes.</li>
</ul>
<hr />
<h2 id="heading-4-booking-amp-seat-locking-deep-dive">4. Booking &amp; Seat Locking Deep Dive</h2>
<p>This section explains how correctness and consistency are ensured under high concurrency.</p>
<h3 id="heading-41-core-challenges-addressed">4.1 Core Challenges Addressed</h3>
<ul>
<li>Prevent double booking under concurrent requests  </li>
<li>Handle partial failures (payment outcomes, timeouts)  </li>
<li>Ensure idempotent behavior for retries  </li>
<li>Support high throughput while maintaining correctness  </li>
<li>Auto-recover abandoned bookings  </li>
</ul>
<p>The solution prioritizes <strong>data integrity</strong> for booking and <strong>availability</strong> for browsing.</p>
<hr />
<h3 id="heading-42-booking-lifecycle-state-machine">4.2 Booking Lifecycle (State Machine)</h3>
<p>Each booking follows a deterministic state machine owned by the Booking Service:</p>
<ul>
<li><code>INITIATED</code>
→ <code>SEATS_LOCKED</code>
→ <code>PAYMENT_PENDING</code>
→ <code>CONFIRMED</code>
→ <code>COMPLETED</code></li>
</ul>
<p>Failure / Exit states:</p>
<ul>
<li><code>FAILED</code> – payment failure or validation error  </li>
<li><code>EXPIRED</code> – seat lock TTL expired before payment completion  </li>
<li><code>CANCELLED</code> – user-initiated cancellation  </li>
</ul>
<p>Rules:</p>
<ul>
<li>Monotonic + idempotent transitions  </li>
<li>Only valid transitions allowed (e.g., <code>EXPIRED → CONFIRMED</code> rejected)  </li>
<li>Transitions persisted atomically in the booking DB  </li>
</ul>
<hr />
<h3 id="heading-43-seat-locking-strategy">4.3 Seat Locking Strategy</h3>
<p><strong>Design goal:</strong> prevent two users from booking the same seat, while allowing temporary reservation during payment.</p>
<h4 id="heading-chosen-approach-redis-seat-lock-with-ttl">Chosen Approach: Redis Seat Lock with TTL</h4>
<p>Each seat lock key:</p>
<ul>
<li><code>seatlock:{showId}:{seatId}</code></li>
</ul>
<p>Lock acquisition:</p>
<ul>
<li>Booking Service uses atomic <code>SETNX</code></li>
<li>Lock TTL (example: 5 minutes)</li>
<li>All seats must lock successfully, or booking fails</li>
</ul>
<p>Properties:</p>
<ul>
<li>Atomic (exclusive ownership)  </li>
<li>Time-bound (TTL prevents deadlocks)  </li>
<li>Fast (high concurrency without DB hotspot)  </li>
</ul>
<p>Failure handling:</p>
<ul>
<li>If any seat lock fails:<ul>
<li>Release all acquired locks</li>
<li>Reject with conflict</li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-44-booking-creation-flow">4.4 Booking Creation Flow</h3>
<ol>
<li>Client selects show and seats  </li>
<li>Booking Service validates show status + seatIds  </li>
<li>Acquire Redis seat locks  </li>
<li>Create booking record in <code>SEATS_LOCKED</code>  </li>
<li>Store booking expiry timestamp (lock TTL)  </li>
<li>Calculate pricing via Offer &amp; Pricing  </li>
<li>Transition to <code>PAYMENT_PENDING</code></li>
</ol>
<p>Idempotent via client-provided <code>Idempotency-Key</code>.</p>
<hr />
<h3 id="heading-45-payment-orchestration">4.5 Payment Orchestration</h3>
<h4 id="heading-payment-initiation">Payment initiation</h4>
<ul>
<li>Payment Service creates payment intent with gateway</li>
<li><code>bookingId</code> used as idempotency key</li>
<li>Payment state tracked independently</li>
</ul>
<h4 id="heading-webhook-processing">Webhook processing</h4>
<ul>
<li>Gateway sends signed webhook callbacks</li>
<li>Payment Service verifies signature and publishes:<ul>
<li><code>payment.succeeded</code></li>
<li><code>payment.failed</code></li>
</ul>
</li>
</ul>
<h4 id="heading-booking-finalization">Booking finalization</h4>
<ul>
<li>Booking Service consumes payment events</li>
<li>On success:<ul>
<li>booking → <code>CONFIRMED</code></li>
<li>seat inventory marked sold</li>
<li>seat locks released</li>
</ul>
</li>
<li>On failure:<ul>
<li>booking → <code>FAILED</code></li>
<li>locks released</li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-46-database-consistency-guarantees">4.6 Database Consistency Guarantees</h3>
<p><strong>Final authority:</strong> relational database.</p>
<p>Constraints:</p>
<ul>
<li>Unique constraint on <code>(show_id, seat_id)</code> for sold seats  </li>
<li>Transactional updates during confirmation  </li>
<li>Defensive checks during finalization  </li>
</ul>
<p>Dual-layer approach (Redis + DB) gives strong consistency + throughput.</p>
<hr />
<h3 id="heading-47-handling-expired-bookings">4.7 Handling Expired Bookings</h3>
<p>Scheduled job:</p>
<ul>
<li>Detect expired bookings</li>
<li>Transition to <code>EXPIRED</code></li>
<li>Release remaining locks</li>
<li>Publish <code>booking.expired</code></li>
</ul>
<p>Covers abandoned payments, client crashes, timeouts.</p>
<hr />
<h3 id="heading-48-idempotency-amp-retry-handling">4.8 Idempotency &amp; Retry Handling</h3>
<p>Retries happen due to timeouts, duplicates, webhook replays.</p>
<p>Implementation:</p>
<ul>
<li>All write APIs accept <code>Idempotency-Key</code></li>
<li>Booking/payment deduped</li>
<li>Webhooks: exactly-once logically, at-least-once physically</li>
</ul>
<hr />
<h3 id="heading-49-failure-scenarios-amp-recovery">4.9 Failure Scenarios &amp; Recovery</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Scenario</td><td>Handling</td></tr>
</thead>
<tbody>
<tr>
<td>Payment gateway timeout</td><td>Booking stays pending until webhook or expiry</td></tr>
<tr>
<td>Duplicate payment callback</td><td>Idempotent event handling</td></tr>
<tr>
<td>Booking service crash</td><td>Redis TTL releases locks</td></tr>
<tr>
<td>Notification failure</td><td>Retried async</td></tr>
<tr>
<td>Partial system outage</td><td>Browsing remains available</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-410-why-this-design-works">4.10 Why This Design Works</h3>
<ul>
<li>Strong correctness guarantees  </li>
<li>High concurrency without DB hot-spotting  </li>
<li>Self-healing via TTL + background jobs  </li>
<li>Clear ownership of state transitions  </li>
<li>Scales linearly with traffic  </li>
</ul>
<hr />
<h2 id="heading-5-technology-stack">5. Technology Stack</h2>
<h3 id="heading-51-application-amp-service-layer">5.1 Application &amp; Service Layer</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Technology</td><td>Purpose</td><td>Rationale</td></tr>
</thead>
<tbody>
<tr>
<td>Java 17+</td><td>Backend services</td><td>Mature ecosystem, strong concurrency, reliability</td></tr>
<tr>
<td>Spring Boot</td><td>Microservices framework</td><td>Production-ready defaults, observability/security</td></tr>
<tr>
<td>Spring Web / REST</td><td>API development</td><td>Standard REST integration</td></tr>
<tr>
<td>Spring Security</td><td>AuthN/AuthZ</td><td>OAuth2/JWT, role-based access</td></tr>
<tr>
<td>Spring State Machine (optional)</td><td>Booking lifecycle</td><td>Enforced state transitions</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-52-api-amp-integration-layer">5.2 API &amp; Integration Layer</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Technology</td><td>Purpose</td><td>Rationale</td></tr>
</thead>
<tbody>
<tr>
<td>REST (OpenAPI/Swagger)</td><td>Service contracts</td><td>Clear documentation, contract-first</td></tr>
<tr>
<td>JSON</td><td>Data format</td><td>Lightweight, widely supported</td></tr>
<tr>
<td>Webhooks</td><td>Payment callbacks</td><td>Async, reliable confirmations</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-53-data-storage-layer">5.3 Data Storage Layer</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Data Type</td><td>Technology</td><td>Usage</td></tr>
</thead>
<tbody>
<tr>
<td>Transactional</td><td>PostgreSQL / MySQL</td><td>Bookings, payments, shows, seat inventory</td></tr>
<tr>
<td>Catalog</td><td>MongoDB / PostgreSQL</td><td>Movies, cities, languages, genres</td></tr>
<tr>
<td>Search</td><td>OpenSearch / Elasticsearch</td><td>Browse-optimized queries</td></tr>
<tr>
<td>Cache / Locks</td><td>Redis</td><td>Seat locks, hot caching</td></tr>
</tbody>
</table>
</div><p><strong>Rationale</strong></p>
<ul>
<li>Relational DB for ACID booking/payment</li>
<li>Search index for low-latency browsing</li>
<li>Redis for fast TTL locks and reduced contention</li>
</ul>
<hr />
<h3 id="heading-54-messaging-amp-event-streaming">5.4 Messaging &amp; Event Streaming</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Technology</td><td>Purpose</td><td>Rationale</td></tr>
</thead>
<tbody>
<tr>
<td>Apache Kafka</td><td>Event streaming</td><td>High throughput, durable, replayable</td></tr>
<tr>
<td>Schema Registry (optional)</td><td>Event contracts</td><td>Backward/forward compatibility</td></tr>
<tr>
<td>DLQs</td><td>Failure handling</td><td>Safe retries and diagnostics</td></tr>
</tbody>
</table>
</div><p>Events for:</p>
<ul>
<li>Booking state changes</li>
<li>Payment outcomes</li>
<li>Show/catalog updates</li>
<li>Notification triggers</li>
<li>Search indexing updates</li>
</ul>
<hr />
<h3 id="heading-55-security-amp-compliance">5.5 Security &amp; Compliance</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Technology</td><td>Purpose</td><td>Rationale</td></tr>
</thead>
<tbody>
<tr>
<td>OAuth2 / JWT</td><td>Authentication</td><td>Stateless and secure</td></tr>
<tr>
<td>Gateway WAF</td><td>Threat protection</td><td>OWASP mitigation</td></tr>
<tr>
<td>TLS (HTTPS)</td><td>In-transit security</td><td>End-to-end encryption</td></tr>
<tr>
<td>Secrets Manager / Vault</td><td>Secret storage</td><td>No secrets in code</td></tr>
<tr>
<td>Encryption at Rest</td><td>PII protection</td><td>Compliance needs</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-56-observability-amp-monitoring">5.6 Observability &amp; Monitoring</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Technology</td><td>Purpose</td><td>Rationale</td></tr>
</thead>
<tbody>
<tr>
<td>OpenTelemetry</td><td>Tracing</td><td>End-to-end visibility</td></tr>
<tr>
<td>Prometheus</td><td>Metrics</td><td>Golden signals</td></tr>
<tr>
<td>Grafana</td><td>Dashboards</td><td>Live visibility</td></tr>
<tr>
<td>ELK / Loki</td><td>Logs</td><td>Faster debugging + audits</td></tr>
<tr>
<td>Alertmanager</td><td>Alerts</td><td>SLA/SLO enforcement</td></tr>
</tbody>
</table>
</div><p>Key metrics:</p>
<ul>
<li>API latency/error rates</li>
<li>Seat lock contention</li>
<li>Booking success/failure</li>
<li>Payment success rate</li>
<li>Booking expiry %</li>
</ul>
<hr />
<h3 id="heading-57-deployment-amp-platform">5.7 Deployment &amp; Platform</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Technology</td><td>Purpose</td><td>Rationale</td></tr>
</thead>
<tbody>
<tr>
<td>Docker</td><td>Containers</td><td>Consistent environments</td></tr>
<tr>
<td>Kubernetes (EKS)</td><td>Orchestration</td><td>Auto-scaling, self-healing</td></tr>
<tr>
<td>CI/CD</td><td>Automation</td><td>Safer, faster releases</td></tr>
<tr>
<td>Blue-Green / Canary</td><td>Release strategy</td><td>Zero downtime</td></tr>
<tr>
<td>Multi-AZ</td><td>HA</td><td>Fault tolerance</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-58-cloud-infrastructure">5.8 Cloud Infrastructure</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Component</td><td>Technology</td><td>Usage</td></tr>
</thead>
<tbody>
<tr>
<td>Compute</td><td>AWS EKS / EC2</td><td>Service runtime</td></tr>
<tr>
<td>Database</td><td>AWS RDS / Aurora</td><td>Multi-AZ relational</td></tr>
<tr>
<td>Cache</td><td>ElastiCache (Redis)</td><td>HA caching/locks</td></tr>
<tr>
<td>Search</td><td>AWS OpenSearch</td><td>Distributed search</td></tr>
<tr>
<td>Messaging</td><td>MSK / Managed Kafka</td><td>Event streaming</td></tr>
<tr>
<td>Load Balancer</td><td>ALB / NLB</td><td>Traffic distribution</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-59-ai-amp-intelligent-capabilities-suggested">5.9 AI &amp; Intelligent Capabilities (Suggested)</h3>
<ul>
<li>Search relevance: typo tolerance, fuzzy matching  </li>
<li>Customer support: FAQ / booking-status bot  </li>
<li>Risk signals: fraud/anomaly detection  </li>
<li>Ops insights: demand forecasting, capacity planning  </li>
</ul>
<p>AI is pluggable and does not impact booking consistency.</p>
<hr />
<h3 id="heading-510-key-technology-drivers-summary">5.10 Key Technology Drivers Summary</h3>
<ul>
<li>Correctness first: ACID DB + controlled concurrency  </li>
<li>Scale on demand: stateless + cache + search  </li>
<li>Resilience: event-driven + graceful degradation  </li>
<li>Security by design: OWASP-compliant, encrypted, auditable  </li>
<li>Future-ready: modular services, extensible pricing + AI  </li>
</ul>
<hr />
<h2 id="heading-6-scalability-amp-9999-availability">6. Scalability &amp; 99.99% Availability</h2>
<h3 id="heading-61-availability-target-amp-design-philosophy">6.1 Availability Target &amp; Design Philosophy</h3>
<p><strong>99.99% uptime</strong> → less than <strong>4.4 minutes downtime/month</strong>.</p>
<p>Principles:</p>
<ul>
<li>Stateless services</li>
<li>Failure isolation (browse vs booking)</li>
<li>Graceful degradation</li>
<li>Automated recovery</li>
</ul>
<p>Correctness is prioritized for booking; availability for browsing.</p>
<hr />
<h3 id="heading-62-horizontal-scalability-strategy">6.2 Horizontal Scalability Strategy</h3>
<ul>
<li>Stateless microservices behind load balancers</li>
<li>Kubernetes HPA based on CPU, latency, and custom metrics</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Workload</td><td>Scaling Strategy</td></tr>
</thead>
<tbody>
<tr>
<td>Browsing</td><td>Scale Search + Cache aggressively</td></tr>
<tr>
<td>Booking</td><td>Scale Booking carefully to avoid lock contention</td></tr>
<tr>
<td>Payments</td><td>Scale independently based on gateway latency</td></tr>
<tr>
<td>Notifications</td><td>Fully async and elastic</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-63-read-heavy-workload-optimization">6.3 Read-Heavy Workload Optimization</h3>
<p>Techniques:</p>
<ul>
<li>Search index for denormalized reads</li>
<li>Redis hot caching</li>
<li>Event-driven index updates</li>
<li>TTL eviction to balance freshness</li>
</ul>
<p>Result:</p>
<ul>
<li>Browse APIs stay up even if transactional services degrade</li>
<li>Sub-second latency during spikes</li>
</ul>
<hr />
<h3 id="heading-64-write-path-scalability-booking">6.4 Write Path Scalability (Booking)</h3>
<p>Challenges:</p>
<ul>
<li>Contention on popular shows</li>
<li>Strict correctness</li>
</ul>
<p>Solutions:</p>
<ul>
<li>Redis locks to minimize DB contention</li>
<li>Shard booking data by city or showId</li>
<li>Short-lived TTL locks</li>
<li>Backoff retries to avoid thundering herd</li>
</ul>
<p>Trade-off: write throughput is intentionally constrained to preserve correctness.</p>
<hr />
<h3 id="heading-65-database-high-availability">6.5 Database High Availability</h3>
<p>Relational DB:</p>
<ul>
<li>Multi-AZ failover</li>
<li>Read replicas for reporting</li>
<li>Partitioning by city/time</li>
</ul>
<p>Cache:</p>
<ul>
<li>Redis cluster with replicas + failover</li>
<li>TTL recovery</li>
</ul>
<p>Search:</p>
<ul>
<li>Multi-node cluster</li>
<li>Shard replication and rebalancing</li>
</ul>
<hr />
<h3 id="heading-66-event-driven-resilience">6.6 Event-Driven Resilience</h3>
<p>Kafka provides:</p>
<ul>
<li>At-least-once delivery</li>
<li>Idempotent consumers</li>
<li>DLQs for poison messages</li>
</ul>
<p>Ensures:</p>
<ul>
<li>Booking confirmation doesn’t block notifications</li>
<li>Payment processing survives transient failures</li>
</ul>
<hr />
<h3 id="heading-67-fault-tolerance-amp-graceful-degradation">6.7 Fault Tolerance &amp; Graceful Degradation</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Failure Scenario</td><td>System Behavior</td></tr>
</thead>
<tbody>
<tr>
<td>Search down</td><td>Fallback to cache</td></tr>
<tr>
<td>Payment slow</td><td>Booking pending until webhook</td></tr>
<tr>
<td>Notification failure</td><td>Async retries</td></tr>
<tr>
<td>Booking down</td><td>Browsing unaffected</td></tr>
<tr>
<td>Cache failure</td><td>Fall back to DB</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-68-disaster-recovery-amp-multi-az-strategy">6.8 Disaster Recovery &amp; Multi-AZ Strategy</h3>
<ul>
<li>Services across multiple AZs</li>
<li>Load balancers spread traffic</li>
<li>Automated pod restarts/rescheduling</li>
<li>DB failover in minutes</li>
</ul>
<p>Targets:</p>
<ul>
<li><strong>RTO:</strong> &lt; 5 minutes  </li>
<li><strong>RPO:</strong> near-zero for bookings/payments  </li>
</ul>
<hr />
<h3 id="heading-69-observability-driven-reliability">6.9 Observability-Driven Reliability</h3>
<p>Focus:</p>
<ul>
<li>Golden signals: latency, traffic, errors, saturation</li>
<li>Booking metrics: lock success/failure, payment rate, expiry rate</li>
</ul>
<p>Alerts:</p>
<ul>
<li>SLA breach risk</li>
<li>Error spikes</li>
<li>Capacity thresholds</li>
</ul>
<hr />
<h3 id="heading-610-why-this-meets-9999">6.10 Why This Meets 99.99%</h3>
<ul>
<li>No single point of failure</li>
<li>Read/write isolation prevents cascading outages</li>
<li>Stateless compute + auto-scaling</li>
<li>Strong transactional boundaries only where needed</li>
<li>Event-driven retries/recovery</li>
</ul>
<hr />
<h2 id="heading-7-monitoring-amp-observability">7. Monitoring &amp; Observability</h2>
<h3 id="heading-71-monitoring-objectives">7.1 Monitoring Objectives</h3>
<ul>
<li>Ensure 99.99% SLA compliance</li>
<li>Detect issues before customer impact</li>
<li>Deep visibility into booking + payment correctness</li>
<li>Faster RCA</li>
<li>Capacity planning and forecasting</li>
</ul>
<p>Monitoring is a first-class production feature.</p>
<hr />
<h3 id="heading-72-observability-pillars">7.2 Observability Pillars</h3>
<ol>
<li><strong>Metrics</strong> (numbers)  </li>
<li><strong>Logs</strong> (structured debugging + audit)  </li>
<li><strong>Traces</strong> (end-to-end flow visibility)  </li>
</ol>
<hr />
<h3 id="heading-73-metrics-monitoring">7.3 Metrics Monitoring</h3>
<p>Infrastructure:</p>
<ul>
<li>CPU/memory/disk/network</li>
<li>Pod restarts, node health</li>
<li>HPA activity</li>
</ul>
<p>Golden signals:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Signal</td><td>Examples</td></tr>
</thead>
<tbody>
<tr>
<td>Latency</td><td>p95/p99 response times</td></tr>
<tr>
<td>Traffic</td><td>RPS per service</td></tr>
<tr>
<td>Errors</td><td>HTTP 4xx/5xx</td></tr>
<tr>
<td>Saturation</td><td>thread/connection pool exhaustion</td></tr>
</tbody>
</table>
</div><p>Booking metrics:</p>
<ul>
<li>Seat lock success vs failure</li>
<li>Booking creation and confirmation rate</li>
<li>Booking expiry %</li>
<li>Double-booking prevention triggers</li>
</ul>
<p>Payment metrics:</p>
<ul>
<li>Payment initiation success</li>
<li>Gateway latency</li>
<li>Webhook success/failure</li>
<li>Payment-to-booking conversion</li>
</ul>
<hr />
<h3 id="heading-74-logging-strategy">7.4 Logging Strategy</h3>
<ul>
<li>Structured JSON logs</li>
<li>Centralized aggregation</li>
</ul>
<p>Types:</p>
<ul>
<li>Application logs</li>
<li>Audit logs (state transitions, payment events)</li>
<li>Security logs (auth failures)</li>
</ul>
<p>Principles:</p>
<ul>
<li>Correlation IDs everywhere</li>
<li>Mask PII/payment data</li>
<li>Retention aligned with compliance</li>
</ul>
<hr />
<h3 id="heading-75-distributed-tracing">7.5 Distributed Tracing</h3>
<p>Coverage:</p>
<ul>
<li>Browse → search → cache → response</li>
<li>Booking → lock → pricing → payment</li>
<li>Webhook → confirmation → notification</li>
</ul>
<p>Benefits:</p>
<ul>
<li>Find latency bottlenecks</li>
<li>Detect dependency failures</li>
<li>Speed up RCA</li>
</ul>
<hr />
<h3 id="heading-76-alerting-amp-incident-response">7.6 Alerting &amp; Incident Response</h3>
<p>Alerts are actionable:</p>
<ul>
<li>SLA near-breach</li>
<li>Error spikes</li>
<li>Payment gateway down</li>
<li>Seat lock contention anomalies</li>
<li>Resource saturation</li>
</ul>
<p>Response:</p>
<ul>
<li>On-call routing</li>
<li>Runbooks</li>
<li>Automated recovery (restart/scale)</li>
</ul>
<hr />
<h3 id="heading-77-sla-amp-slo-tracking">7.7 SLA &amp; SLO Tracking</h3>
<p>SLIs:</p>
<ul>
<li>API availability</li>
<li>Booking success rate</li>
<li>Payment completion rate</li>
</ul>
<p>SLOs:</p>
<ul>
<li>≥ 99.99% availability</li>
<li>p99 latency thresholds</li>
<li>acceptable booking failure %</li>
</ul>
<p>Error budgets:</p>
<ul>
<li>guide release velocity vs stability</li>
<li>freeze/rollback on exhaustion</li>
</ul>
<hr />
<h3 id="heading-78-capacity-planning-amp-trend-analysis">7.8 Capacity Planning &amp; Trend Analysis</h3>
<p>Use monitoring data for:</p>
<ul>
<li>peak forecasting (releases/weekends)</li>
<li>scaling validation</li>
<li>performance regression detection</li>
<li>cost optimization</li>
</ul>
<hr />
<h3 id="heading-79-why-this-works">7.9 Why This Works</h3>
<ul>
<li>Combines technical + business metrics</li>
<li>Proactive detection</li>
<li>Fast troubleshooting</li>
<li>SLA visibility always</li>
<li>Scales with platform growth</li>
</ul>
<hr />
<h2 id="heading-8-deployment-amp-release-strategy">8. Deployment &amp; Release Strategy</h2>
<h3 id="heading-81-deployment-environments">8.1 Deployment Environments</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Environment</td><td>Purpose</td></tr>
</thead>
<tbody>
<tr>
<td>Development</td><td>Local feature development</td></tr>
<tr>
<td>QA / Integration</td><td>Functional + integration tests</td></tr>
<tr>
<td>Staging / Pre-Prod</td><td>Production-like validation</td></tr>
<tr>
<td>Production</td><td>Live traffic</td></tr>
</tbody>
</table>
</div><p>Each environment is isolated (infra/config/data boundaries).</p>
<hr />
<h3 id="heading-82-cicd-pipeline">8.2 CI/CD Pipeline</h3>
<p>CI:</p>
<ul>
<li>Build + unit tests</li>
<li>Static analysis + security scans</li>
<li>Container image build</li>
<li>Versioned artifacts stored in registry</li>
</ul>
<p>CD:</p>
<ul>
<li>Auto deploy to lower envs</li>
<li>Manual approval to prod</li>
<li>Config injection per env</li>
<li>Immutable image promotion</li>
</ul>
<hr />
<h3 id="heading-83-containerization-amp-orchestration">8.3 Containerization &amp; Orchestration</h3>
<p>Docker:</p>
<ul>
<li>Each microservice packaged as image</li>
</ul>
<p>Kubernetes (EKS):</p>
<ul>
<li>Rolling updates</li>
<li>Liveness/readiness probes</li>
<li>Auto-scaling</li>
</ul>
<hr />
<h3 id="heading-84-release-strategies">8.4 Release Strategies</h3>
<ul>
<li><p><strong>Blue-Green</strong></p>
<ul>
<li>Two identical environments</li>
<li>Switch traffic after validation</li>
<li>Instant rollback</li>
</ul>
</li>
<li><p><strong>Canary</strong></p>
<ul>
<li>Small % traffic first</li>
<li>Gradual ramp using health metrics</li>
<li>Auto rollback on error thresholds</li>
</ul>
</li>
<li><p><strong>Feature Flags</strong></p>
<ul>
<li>Toggle offers/pricing without redeploy</li>
<li>City/theatre rollouts</li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-85-zero-downtime-guarantee">8.5 Zero-Downtime Guarantee</h3>
<p>Achieved via:</p>
<ul>
<li>Stateless services behind LBs</li>
<li>Rolling/canary</li>
<li>Backward-compatible API/schema changes</li>
<li>Safe DB migrations with versioning tools</li>
</ul>
<hr />
<h3 id="heading-86-database-migration-strategy">8.6 Database Migration Strategy</h3>
<ul>
<li>Managed via migration tools</li>
<li>Prefer backward-compatible migrations</li>
<li>Multi-step for breaking changes:<ol>
<li>Expand schema</li>
<li>Deploy app changes</li>
<li>Contract old fields</li>
</ol>
</li>
<li>Maintain rollback scripts</li>
</ul>
<hr />
<h3 id="heading-87-multi-region-amp-multi-az">8.7 Multi-Region &amp; Multi-AZ</h3>
<p>AZ strategy:</p>
<ul>
<li>Services spread across AZs</li>
<li>LBs distribute traffic</li>
</ul>
<p>DR:</p>
<ul>
<li>DB failover</li>
<li>Backup/restore drills</li>
<li><strong>RTO &lt; 5 minutes</strong>, <strong>RPO near zero</strong></li>
</ul>
<hr />
<h3 id="heading-88-configuration-amp-secrets">8.8 Configuration &amp; Secrets</h3>
<ul>
<li>Centralized config</li>
<li>Env-specific externalized settings</li>
<li>Secrets in vault/secrets manager</li>
<li>No secrets in code or images</li>
</ul>
<hr />
<h3 id="heading-89-rollback-amp-recovery">8.9 Rollback &amp; Recovery</h3>
<p>Triggers:</p>
<ul>
<li>SLA breach</li>
<li>Error spikes</li>
<li>Payment/booking failures</li>
</ul>
<p>Methods:</p>
<ul>
<li>Traffic switch (blue-green)</li>
<li>Abort canary</li>
<li>Disable feature flags</li>
</ul>
<p>Fast + reversible + automated.</p>
<hr />
<h3 id="heading-810-why-this-works">8.10 Why This Works</h3>
<ul>
<li>Frequent safe releases</li>
<li>Minimal customer impact</li>
<li>Controlled experimentation</li>
<li>Operational stability</li>
<li>Scales with growth</li>
</ul>
<hr />
<pre><code class="lang-mdx">## 9. API Contracts (Read &amp; Write)

This section defines the backend API contracts for **one Read scenario** (browse theatres &amp; show timings for a selected movie in a city on a given date) and **one Write scenario** (book tickets by selecting theatre/timing/seats). APIs are **RESTful**, **versioned**, and designed for **idempotency**, **concurrency safety**, and clear **error handling**.

---

### 9.1 API Standards (Common)

#### Base
- **Base URL:** `/api/v1`  
- **Content-Type:** `application/json`  
- **Auth:** `Authorization: Bearer &lt;JWT&gt;`

#### Idempotency (Write APIs)
- **Header:** `Idempotency-Key: &lt;uuid&gt;`
- Re-sending the same request with the same key returns the same logical outcome (same booking/payment intent).

#### Correlation
- **Header:** `X-Correlation-Id: &lt;uuid&gt;` (optional; server generates if absent)
- Returned in response headers for traceability.

#### Standard Error Format
```json
{
  "error": {
    "code": "SEAT_LOCK_FAILED",
    "message": "One or more seats are no longer available.",
    "details": {
      "showId": "sh_123",
      "unavailableSeatIds": ["A10", "A11"]
    },
    "correlationId": "c0b7f2d0-6c8d-4e6f-9c5f-3ff2f2f0f9b1"
  }
}
</code></pre>
<h4 id="heading-common-error-codes">Common Error Codes</h4>
<ul>
<li><code>VALIDATION_ERROR</code>, <code>UNAUTHORIZED</code>, <code>FORBIDDEN</code>, <code>NOT_FOUND</code></li>
<li><code>SEAT_LOCK_FAILED</code>, <code>BOOKING_EXPIRED</code>, <code>PAYMENT_PENDING</code>, <code>PAYMENT_FAILED</code></li>
<li><code>RATE_LIMITED</code>, <code>INTERNAL_ERROR</code></li>
</ul>
<hr />
<h3 id="heading-92-read-scenario-apis-browse">9.2 Read Scenario APIs (Browse)</h3>
<h4 id="heading-921-browse-theatres-running-a-movie-in-a-city-with-show-timings-for-a-date">9.2.1 Browse theatres running a movie in a city (with show timings for a date)</h4>
<p><strong>Endpoint</strong></p>
<ul>
<li><code>GET /api/v1/cities/{cityId}/movies/{movieId}/shows?date=YYYY-MM-DD&amp;language=&lt;optional&gt;&amp;format=&lt;optional&gt;</code></li>
</ul>
<p><strong>Description</strong>
Returns theatres currently running the selected movie in the given city on the specified date, along with show timings and a lightweight availability summary.</p>
<p><strong>Path Params</strong></p>
<ul>
<li><code>cityId</code> (required): City identifier (e.g., <code>blr</code>)</li>
<li><code>movieId</code> (required): Movie identifier (e.g., <code>mv_901</code>)</li>
</ul>
<p><strong>Query Params</strong></p>
<ul>
<li><code>date</code> (required): <code>YYYY-MM-DD</code></li>
<li><code>language</code> (optional): e.g., <code>en</code>, <code>hi</code>, <code>te</code></li>
<li><code>format</code> (optional): e.g., <code>2D</code>, <code>3D</code>, <code>IMAX</code></li>
</ul>
<p><strong>Response 200 (Example)</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"cityId"</span>: <span class="hljs-string">"blr"</span>,
  <span class="hljs-attr">"movie"</span>: {
    <span class="hljs-attr">"movieId"</span>: <span class="hljs-string">"mv_901"</span>,
    <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Example Movie"</span>,
    <span class="hljs-attr">"language"</span>: <span class="hljs-string">"en"</span>,
    <span class="hljs-attr">"genres"</span>: [<span class="hljs-string">"Thriller"</span>, <span class="hljs-string">"Drama"</span>],
    <span class="hljs-attr">"durationMins"</span>: <span class="hljs-number">128</span>
  },
  <span class="hljs-attr">"date"</span>: <span class="hljs-string">"2026-02-01"</span>,
  <span class="hljs-attr">"theatres"</span>: [
    {
      <span class="hljs-attr">"theatreId"</span>: <span class="hljs-string">"th_101"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"PVR Orion"</span>,
      <span class="hljs-attr">"area"</span>: <span class="hljs-string">"Malleshwaram"</span>,
      <span class="hljs-attr">"shows"</span>: [
        {
          <span class="hljs-attr">"showId"</span>: <span class="hljs-string">"sh_5001"</span>,
          <span class="hljs-attr">"screenName"</span>: <span class="hljs-string">"Screen 3"</span>,
          <span class="hljs-attr">"startTime"</span>: <span class="hljs-string">"2026-02-01T18:30:00+05:30"</span>,
          <span class="hljs-attr">"format"</span>: <span class="hljs-string">"2D"</span>,
          <span class="hljs-attr">"priceFrom"</span>: <span class="hljs-number">180</span>,
          <span class="hljs-attr">"availability"</span>: {
            <span class="hljs-attr">"availableSeats"</span>: <span class="hljs-number">72</span>,
            <span class="hljs-attr">"status"</span>: <span class="hljs-string">"AVAILABLE"</span>
          }
        },
        {
          <span class="hljs-attr">"showId"</span>: <span class="hljs-string">"sh_5002"</span>,
          <span class="hljs-attr">"screenName"</span>: <span class="hljs-string">"Screen 3"</span>,
          <span class="hljs-attr">"startTime"</span>: <span class="hljs-string">"2026-02-01T21:45:00+05:30"</span>,
          <span class="hljs-attr">"format"</span>: <span class="hljs-string">"2D"</span>,
          <span class="hljs-attr">"priceFrom"</span>: <span class="hljs-number">220</span>,
          <span class="hljs-attr">"availability"</span>: {
            <span class="hljs-attr">"availableSeats"</span>: <span class="hljs-number">12</span>,
            <span class="hljs-attr">"status"</span>: <span class="hljs-string">"FAST_FILLING"</span>
          }
        }
      ]
    }
  ]
}
</code></pre>
<p><strong>Errors</strong></p>
<ul>
<li><code>400 VALIDATION_ERROR</code> (invalid date format)</li>
<li><code>404 NOT_FOUND</code> (city/movie not found)</li>
<li><code>429 RATE_LIMITED</code></li>
</ul>
<hr />
<h4 id="heading-922-get-seat-map-real-time-availability-for-a-show">9.2.2 Get seat map + real-time availability for a show</h4>
<p><strong>Endpoint</strong></p>
<ul>
<li><code>GET /api/v1/shows/{showId}/seats</code></li>
</ul>
<p><strong>Description</strong>
Returns seat layout and availability at the time of request. Availability is derived from:</p>
<ul>
<li><strong>sold seats</strong> (DB truth)</li>
<li><strong>locked seats</strong> (Redis locks, TTL)</li>
</ul>
<p><strong>Path Params</strong></p>
<ul>
<li><code>showId</code> (required): Show identifier (e.g., <code>sh_5001</code>)</li>
</ul>
<p><strong>Response 200 (Example)</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"showId"</span>: <span class="hljs-string">"sh_5001"</span>,
  <span class="hljs-attr">"theatreId"</span>: <span class="hljs-string">"th_101"</span>,
  <span class="hljs-attr">"screenName"</span>: <span class="hljs-string">"Screen 3"</span>,
  <span class="hljs-attr">"startTime"</span>: <span class="hljs-string">"2026-02-01T18:30:00+05:30"</span>,
  <span class="hljs-attr">"seatMap"</span>: {
    <span class="hljs-attr">"rows"</span>: [
      {
        <span class="hljs-attr">"rowLabel"</span>: <span class="hljs-string">"A"</span>,
        <span class="hljs-attr">"seats"</span>: [
          { <span class="hljs-attr">"seatId"</span>: <span class="hljs-string">"A1"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"REGULAR"</span>, <span class="hljs-attr">"price"</span>: <span class="hljs-number">180</span>, <span class="hljs-attr">"status"</span>: <span class="hljs-string">"AVAILABLE"</span> },
          { <span class="hljs-attr">"seatId"</span>: <span class="hljs-string">"A2"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"REGULAR"</span>, <span class="hljs-attr">"price"</span>: <span class="hljs-number">180</span>, <span class="hljs-attr">"status"</span>: <span class="hljs-string">"LOCKED"</span>, <span class="hljs-attr">"lockExpiresAt"</span>: <span class="hljs-string">"2026-02-01T18:05:00+05:30"</span> },
          { <span class="hljs-attr">"seatId"</span>: <span class="hljs-string">"A3"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"REGULAR"</span>, <span class="hljs-attr">"price"</span>: <span class="hljs-number">180</span>, <span class="hljs-attr">"status"</span>: <span class="hljs-string">"SOLD"</span> }
        ]
      }
    ]
  }
}
</code></pre>
<p><strong>Errors</strong></p>
<ul>
<li><code>404 NOT_FOUND</code> (show not found)</li>
<li><code>429 RATE_LIMITED</code></li>
</ul>
<details>
  <summary><strong>Notes on seat status</strong></summary>

<em> <code>AVAILABLE</code>: Not sold and not locked
</em> <code>LOCKED</code>: Temporarily reserved by another booking; includes <code>lockExpiresAt</code> when available
* <code>SOLD</code>: Finalized purchase (DB truth)

</details>

<hr />
<h3 id="heading-93-write-scenario-apis-booking">9.3 Write Scenario APIs (Booking)</h3>
<h4 id="heading-931-create-booking-lock-seats-seat-reservation">9.3.1 Create booking + lock seats (Seat Reservation)</h4>
<p><strong>Endpoint</strong></p>
<ul>
<li><code>POST /api/v1/bookings</code></li>
</ul>
<p><strong>Headers</strong></p>
<ul>
<li><code>Authorization: Bearer &lt;JWT&gt;</code></li>
<li><code>Idempotency-Key: &lt;uuid&gt;</code></li>
<li><code>X-Correlation-Id: &lt;uuid&gt;</code> (optional)</li>
</ul>
<p><strong>Request Body</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"userId"</span>: <span class="hljs-string">"u_2001"</span>,
  <span class="hljs-attr">"showId"</span>: <span class="hljs-string">"sh_5001"</span>,
  <span class="hljs-attr">"seatIds"</span>: [<span class="hljs-string">"A10"</span>, <span class="hljs-string">"A11"</span>],
  <span class="hljs-attr">"couponCode"</span>: <span class="hljs-string">"THIRD50"</span>,
  <span class="hljs-attr">"client"</span>: {
    <span class="hljs-attr">"platform"</span>: <span class="hljs-string">"WEB"</span>,
    <span class="hljs-attr">"appVersion"</span>: <span class="hljs-string">"1.0.0"</span>
  }
}
</code></pre>
<p><strong>Behavior</strong></p>
<ul>
<li>Validates <code>showId</code> is active and <code>seatIds</code> are valid</li>
<li>Attempts to lock all requested seats with TTL (e.g., 5 minutes)</li>
<li>Calculates price via Offer &amp; Pricing Service</li>
<li>Creates booking in <code>PAYMENT_PENDING</code> (or <code>SEATS_LOCKED</code> then transitions internally)</li>
</ul>
<p><strong>Response 201 (Example)</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"bookingId"</span>: <span class="hljs-string">"bk_90001"</span>,
  <span class="hljs-attr">"status"</span>: <span class="hljs-string">"PAYMENT_PENDING"</span>,
  <span class="hljs-attr">"expiresAt"</span>: <span class="hljs-string">"2026-02-01T18:10:00+05:30"</span>,
  <span class="hljs-attr">"show"</span>: {
    <span class="hljs-attr">"showId"</span>: <span class="hljs-string">"sh_5001"</span>,
    <span class="hljs-attr">"theatreId"</span>: <span class="hljs-string">"th_101"</span>,
    <span class="hljs-attr">"startTime"</span>: <span class="hljs-string">"2026-02-01T18:30:00+05:30"</span>
  },
  <span class="hljs-attr">"seats"</span>: [<span class="hljs-string">"A10"</span>, <span class="hljs-string">"A11"</span>],
  <span class="hljs-attr">"pricing"</span>: {
    <span class="hljs-attr">"currency"</span>: <span class="hljs-string">"INR"</span>,
    <span class="hljs-attr">"subtotal"</span>: <span class="hljs-number">360</span>,
    <span class="hljs-attr">"discount"</span>: <span class="hljs-number">90</span>,
    <span class="hljs-attr">"fees"</span>: <span class="hljs-number">20</span>,
    <span class="hljs-attr">"tax"</span>: <span class="hljs-number">12</span>,
    <span class="hljs-attr">"total"</span>: <span class="hljs-number">302</span>,
    <span class="hljs-attr">"appliedOffers"</span>: [
      { <span class="hljs-attr">"code"</span>: <span class="hljs-string">"THIRD50"</span>, <span class="hljs-attr">"description"</span>: <span class="hljs-string">"50% off on eligible ticket"</span> }
    ]
  }
}
</code></pre>
<p><strong>Errors</strong></p>
<ul>
<li><code>400 VALIDATION_ERROR</code> (invalid seatIds, show not bookable)</li>
<li><code>404 NOT_FOUND</code> (show not found)</li>
<li><code>409 SEAT_LOCK_FAILED</code> (one/more seats unavailable/locked)</li>
<li><code>410 BOOKING_EXPIRED</code> (idempotency replay edge-case referencing expired booking)</li>
<li><code>429 RATE_LIMITED</code></li>
</ul>
<hr />
<h4 id="heading-932-initiate-payment-for-a-booking-create-payment-intent">9.3.2 Initiate payment for a booking (Create Payment Intent)</h4>
<p><strong>Endpoint</strong></p>
<ul>
<li><code>POST /api/v1/bookings/{bookingId}/payments</code></li>
</ul>
<p><strong>Headers</strong></p>
<ul>
<li><code>Authorization: Bearer &lt;JWT&gt;</code></li>
<li><code>Idempotency-Key: &lt;uuid&gt;</code></li>
<li><code>X-Correlation-Id: &lt;uuid&gt;</code> (optional)</li>
</ul>
<p><strong>Request Body</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"provider"</span>: <span class="hljs-string">"RAZORPAY"</span>,
  <span class="hljs-attr">"returnUrl"</span>: <span class="hljs-string">"https://app.example.com/payment/return"</span>
}
</code></pre>
<p><strong>Response 201 (Example)</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"paymentId"</span>: <span class="hljs-string">"pay_771"</span>,
  <span class="hljs-attr">"bookingId"</span>: <span class="hljs-string">"bk_90001"</span>,
  <span class="hljs-attr">"status"</span>: <span class="hljs-string">"INITIATED"</span>,
  <span class="hljs-attr">"amount"</span>: <span class="hljs-number">302</span>,
  <span class="hljs-attr">"currency"</span>: <span class="hljs-string">"INR"</span>,
  <span class="hljs-attr">"provider"</span>: <span class="hljs-string">"RAZORPAY"</span>,
  <span class="hljs-attr">"providerPayload"</span>: {
    <span class="hljs-attr">"paymentIntentId"</span>: <span class="hljs-string">"pi_abc123"</span>,
    <span class="hljs-attr">"redirectUrl"</span>: <span class="hljs-string">"https://gateway.example.com/pay/pi_abc123"</span>
  }
}
</code></pre>
<p><strong>Errors</strong></p>
<ul>
<li><code>404 NOT_FOUND</code> (booking not found)</li>
<li><code>409 PAYMENT_PENDING</code> (payment already initiated)</li>
<li><code>410 BOOKING_EXPIRED</code> (seat lock expired)</li>
<li><code>422</code> (booking not in payable state)</li>
</ul>
<details>
  <summary><strong>State validation rules (payable)</strong></summary>

A booking is payable only if:

<em> status is <code>PAYMENT_PENDING</code>
</em> and current time is <strong>before</strong> <code>expiresAt</code>

</details>

<hr />
<h4 id="heading-933-payment-webhook-provider-platform">9.3.3 Payment webhook (Provider → Platform)</h4>
<p>This endpoint is called by the payment gateway and <strong>not</strong> by the client.</p>
<p><strong>Endpoint</strong></p>
<ul>
<li><code>POST /api/v1/payments/webhooks/{provider}</code></li>
</ul>
<p><strong>Security</strong></p>
<ul>
<li>Signature validation (provider-specific headers)</li>
<li>Optional IP allowlist</li>
<li>Idempotent handling based on <code>eventId</code> / provider event identifier</li>
</ul>
<p><strong>Webhook Payload (Example)</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"eventId"</span>: <span class="hljs-string">"evt_99001"</span>,
  <span class="hljs-attr">"paymentIntentId"</span>: <span class="hljs-string">"pi_abc123"</span>,
  <span class="hljs-attr">"status"</span>: <span class="hljs-string">"SUCCEEDED"</span>,
  <span class="hljs-attr">"amount"</span>: <span class="hljs-number">302</span>,
  <span class="hljs-attr">"currency"</span>: <span class="hljs-string">"INR"</span>,
  <span class="hljs-attr">"bookingReference"</span>: <span class="hljs-string">"bk_90001"</span>,
  <span class="hljs-attr">"timestamp"</span>: <span class="hljs-string">"2026-02-01T18:06:30+05:30"</span>
}
</code></pre>
<p><strong>Webhook Response</strong></p>
<ul>
<li><code>200 OK</code> if processed (or already processed)</li>
<li><code>400</code> if signature invalid</li>
</ul>
<p><strong>Downstream Effect</strong></p>
<ul>
<li>Payment Service publishes <code>payment.succeeded</code> / <code>payment.failed</code> event</li>
<li>Booking Service consumes event and finalizes booking</li>
</ul>
<hr />
<h4 id="heading-934-get-booking-status-client-polling-fallback">9.3.4 Get booking status (Client polling fallback)</h4>
<p><strong>Endpoint</strong></p>
<ul>
<li><code>GET /api/v1/bookings/{bookingId}</code></li>
</ul>
<p><strong>Response 200 (Example)</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"bookingId"</span>: <span class="hljs-string">"bk_90001"</span>,
  <span class="hljs-attr">"status"</span>: <span class="hljs-string">"CONFIRMED"</span>,
  <span class="hljs-attr">"confirmedAt"</span>: <span class="hljs-string">"2026-02-01T18:06:45+05:30"</span>,
  <span class="hljs-attr">"ticket"</span>: {
    <span class="hljs-attr">"ticketId"</span>: <span class="hljs-string">"tkt_50001"</span>,
    <span class="hljs-attr">"qrCodeData"</span>: <span class="hljs-string">"BASE64_OR_TOKEN"</span>,
    <span class="hljs-attr">"seatIds"</span>: [<span class="hljs-string">"A10"</span>, <span class="hljs-string">"A11"</span>]
  }
}
</code></pre>
<p><strong>Errors</strong></p>
<ul>
<li><code>404 NOT_FOUND</code></li>
<li><code>403 FORBIDDEN</code> (booking does not belong to user)</li>
</ul>
<hr />
<h4 id="heading-935-cancel-booking-optional-but-production-realistic">9.3.5 Cancel booking (Optional but production-realistic)</h4>
<p><strong>Endpoint</strong></p>
<ul>
<li><code>POST /api/v1/bookings/{bookingId}/cancel</code></li>
</ul>
<p><strong>Behavior</strong></p>
<ul>
<li>If <code>PAYMENT_PENDING</code> and lock valid → cancel + release locks</li>
<li>If already <code>CONFIRMED</code> → initiate refund workflow (if supported)</li>
</ul>
<p><strong>Response 200 (Example)</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"bookingId"</span>: <span class="hljs-string">"bk_90001"</span>,
  <span class="hljs-attr">"status"</span>: <span class="hljs-string">"CANCELLED"</span>,
  <span class="hljs-attr">"refund"</span>: {
    <span class="hljs-attr">"status"</span>: <span class="hljs-string">"INITIATED"</span>,
    <span class="hljs-attr">"amount"</span>: <span class="hljs-number">302</span>
  }
}
</code></pre>
<hr />
<h3 id="heading-94-status-codes-summary">9.4 Status Codes Summary</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>API</td><td>Success Codes</td><td>Common Failure Codes</td></tr>
</thead>
<tbody>
<tr>
<td>Browse shows</td><td>200</td><td>400, 404, 429</td></tr>
<tr>
<td>Seat map</td><td>200</td><td>404, 429</td></tr>
<tr>
<td>Create booking</td><td>201</td><td>400, 404, 409, 410, 429</td></tr>
<tr>
<td>Initiate payment</td><td>201</td><td>404, 409, 410, 422</td></tr>
<tr>
<td>Webhook</td><td>200</td><td>400</td></tr>
<tr>
<td>Get booking</td><td>200</td><td>403, 404</td></tr>
</tbody>
</table>
</div>]]></content:encoded></item><item><title><![CDATA[DataStage Job Context]]></title><description><![CDATA[Ask: I was assigned to build a sample job in IBM DataStage where it takes a text file from NAS path and validates the data in the text file and if the validations are passed, the data will get transformed, written in a new txt file and placed in the ...]]></description><link>https://deeptechguide.blog/datastage-job-context</link><guid isPermaLink="true">https://deeptechguide.blog/datastage-job-context</guid><category><![CDATA[IBM DataStage]]></category><dc:creator><![CDATA[Sushil Chandra]]></dc:creator><pubDate>Thu, 29 Jan 2026 08:38:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/0mXw-dvuLok/upload/b7661c0ae4d68ff5894beea4f3e5227d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Ask: I was assigned to build a sample job in IBM DataStage where it takes a text file from NAS path and validates the data in the text file and if the validations are passed, the data will get transformed, written in a new txt file and placed in the same NAS path and if the validations are failed for even a particular record in the text file, the failed records will get written in a new error text file and an email will be sent to the concerned team. This failure scenario can happen when an empty text file is uploaded. Please guide me in detail about how to create this job in DataStage. This task is given to verify my knowledge on DataStage. I want this job to be created like a real-time production-grade and if possible a BFSI scenario which doesn’t involve transactions. Also I want a high-level visual appealing professional workflow diagram developed for this job</p>
<p>Below is a <strong>real production-style DataStage design</strong> that exactly matches your ask:</p>
<ul>
<li>Read a <strong>text file from a NAS path</strong></li>
<li><strong>Validate every record</strong></li>
<li>If <strong>all validations pass</strong> → transform + write a “good” output file back to NAS</li>
<li>If <strong>even 1 record fails</strong> → write failed records to an <strong>error file</strong> + <strong>send email</strong></li>
<li>Special case: <strong>empty file uploaded</strong> → treat as failure + email</li>
</ul>
<p>I’ll frame it as a <strong>BFSI non-transaction scenario</strong>: <em>Customer Master / KYC enrichment batch</em> (no payments, no transactions).</p>
<hr />
<h2 id="heading-bfsi-scenario-non-transaction-you-can-say-in-interview">BFSI scenario (non-transaction) you can say in interview</h2>
<p><strong>Input file:</strong> <code>CUSTOMER_KYC_UPDATES_YYYYMMDD.txt</code> dropped to NAS by an upstream system.</p>
<p>Each row contains customer updates used for analytics / compliance reporting:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Field</td><td>Example</td><td>Validation idea</td></tr>
</thead>
<tbody>
<tr>
<td>customer_id</td><td>1029384756</td><td>mandatory, numeric, length</td></tr>
<tr>
<td>pan</td><td>ABCDE1234F</td><td>mandatory, PAN pattern</td></tr>
<tr>
<td>dob</td><td>1996-09-16</td><td>valid date, not future, age &gt;= 18</td></tr>
<tr>
<td>mobile</td><td>9876543210</td><td>10 digits</td></tr>
<tr>
<td>email</td><td><a target="_blank" href="mailto:a@b.com">a@b.com</a></td><td>contains <code>@</code> + domain</td></tr>
<tr>
<td>risk_category</td><td>LOW/MED/HIGH</td><td>allowed values</td></tr>
<tr>
<td>pincode</td><td>560001</td><td>6 digits</td></tr>
</tbody>
</table>
</div><p><strong>Transformations (examples):</strong></p>
<ul>
<li>normalize mobile, uppercase PAN</li>
<li>derive <code>age</code></li>
<li>mask PAN for output (<code>ABCDE****F</code>)</li>
<li>standardize risk_category</li>
</ul>
<hr />
<h2 id="heading-production-grade-architecture-in-datastage">Production-grade architecture in DataStage</h2>
<p>You’ll build <strong>one Sequence job</strong> (orchestrator) + <strong>one Parallel job</strong> (ETL).</p>
<h3 id="heading-1-sequence-job-orchestrator">1) Sequence job (Orchestrator)</h3>
<p>Name example: <code>SEQ_CUST_KYC_FILE_PROCESS</code></p>
<p><strong>Purpose:</strong></p>
<ul>
<li>Detect file arrival + empty file</li>
<li>Run parallel ETL job</li>
<li>Based on result (fail count or empty file), send email</li>
<li>Archive/rename input file safely</li>
</ul>
<p><strong>Key activities inside the Sequence</strong></p>
<ol>
<li><p><strong>Start → Set Variables</strong></p>
<ul>
<li>Compute <code>RUN_TS</code>, <code>RUN_ID</code>, file names (good/error), archive name</li>
</ul>
</li>
<li><p><strong>Check File Exists</strong></p>
<ul>
<li>Use <em>Execute Command stage</em> with UNIX: <code>test -f &lt;inputfile&gt;</code></li>
</ul>
</li>
<li><p><strong>Check Empty File</strong></p>
<ul>
<li>Use UNIX: <code>test -s &lt;inputfile&gt;</code></li>
<li>If empty → go to <em>Send Email</em> + create an error marker file (optional)</li>
</ul>
</li>
<li><p><strong>Run Parallel Job</strong></p>
<ul>
<li><code>JOB_CUST_KYC_VALIDATE_TRANSFORM</code></li>
</ul>
</li>
<li><p><strong>Decision: any rejects?</strong></p>
<ul>
<li>Based on returned reject count / status</li>
<li>If rejects &gt; 0 → send email (and keep reject file)</li>
</ul>
</li>
<li><p><strong>Archive Input File</strong></p>
<ul>
<li>Move to <code>/nas/archive/</code> with timestamp suffix</li>
</ul>
</li>
<li><strong>End</strong></li>
</ol>
<h3 id="heading-email-sending-options-production-friendly">Email sending options (production-friendly)</h3>
<ul>
<li><strong>Execute Command stage</strong> using <code>mailx</code> or <code>sendmail</code> (most common on UNIX)</li>
<li>If your org uses enterprise email: call a <strong>shell script</strong> that hits SMTP relay / API.</li>
</ul>
<hr />
<h2 id="heading-2-parallel-job-etl">2) Parallel job (ETL)</h2>
<p>Name example: <code>JOB_CUST_KYC_VALIDATE_TRANSFORM</code></p>
<h3 id="heading-stages-typical">Stages (typical)</h3>
<ol>
<li><p><strong>Sequential File (Read)</strong></p>
<ul>
<li>Reads input from NAS</li>
<li>Define schema (fixed-width or delimited)</li>
</ul>
</li>
<li><p><strong>Transformer (Validate + Transform)</strong></p>
<ul>
<li><p>Outputs to two links:</p>
<ul>
<li><code>VALID_OUT</code></li>
<li><code>REJECT_OUT</code></li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Sequential File (Write Good Output)</strong></p>
<ul>
<li>Writes transformed valid rows to output file on NAS</li>
</ul>
</li>
<li><p><strong>Sequential File (Write Error Output)</strong></p>
<ul>
<li>Writes rejected rows with rejection reason to error file</li>
</ul>
</li>
<li><p><strong>Row counts / audit</strong></p>
<ul>
<li>Capture total/valid/reject counts (for sequence + logs)</li>
</ul>
</li>
</ol>
<hr />
<h1 id="heading-how-to-implement-the-key-requirements-step-by-step">How to implement the key requirements (step-by-step)</h1>
<h2 id="heading-a-parameterize-everything-must-for-production-grade">A) Parameterize everything (must for “production-grade”)</h2>
<p>Create a <strong>Parameter Set</strong> (recommended) or job parameters:</p>
<ul>
<li><code>p_in_dir</code> = <code>/nas/in/customer/</code></li>
<li><code>p_in_filename</code> = <code>#CUSTOMER_KYC_UPDATES#</code> (or full name)</li>
<li><code>p_out_dir</code> = <code>/nas/out/customer/</code></li>
<li><code>p_err_dir</code> = <code>/nas/out/customer/error/</code></li>
<li><code>p_archive_dir</code> = <code>/nas/archive/customer/</code></li>
<li><code>p_mail_to</code> = <code>kyc-ops@bank.com</code></li>
<li><code>p_mail_cc</code> (optional)</li>
<li><code>p_env</code> = <code>DEV/UAT/PROD</code></li>
</ul>
<p>In Sequence, derive dynamic names:</p>
<ul>
<li><code>good_file = CUST_KYC_CLEAN_${RUN_TS}.txt</code></li>
<li><code>err_file  = CUST_KYC_REJECT_${RUN_TS}.txt</code></li>
</ul>
<hr />
<h2 id="heading-b-empty-file-handling-this-is-where-many-fail-interviews">B) Empty file handling (this is where many fail interviews)</h2>
<p>In <strong>Sequence</strong>, do it <em>before</em> running the parallel job:</p>
<p><strong>Execute Command stage command:</strong></p>
<ul>
<li>Existence check:
<code>test -f "${p_in_dir}/${p_in_filename}"</code></li>
<li>Non-empty check:
<code>test -s "${p_in_dir}/${p_in_filename}"</code></li>
</ul>
<p><strong>If empty:</strong></p>
<ul>
<li>Send email: “Empty file received”</li>
<li><p>Optionally write a 1-line error file like:</p>
<ul>
<li><code>EMPTY_FILE|&lt;filename&gt;|&lt;timestamp&gt;</code></li>
</ul>
</li>
<li>Archive the empty file (still archive it, to avoid reprocessing)</li>
</ul>
<p>This is exactly the “real world” behavior BFSI teams expect.</p>
<hr />
<h2 id="heading-c-record-level-validation-and-reject-reason">C) Record-level validation and “reject reason”</h2>
<p>In your <strong>Transformer</strong>, create a column like:</p>
<ul>
<li><code>reject_reason</code> (string)</li>
</ul>
<p>Example rules (simple but solid):</p>
<ul>
<li><code>customer_id</code> null or non-numeric</li>
<li>PAN not matching <code>[A-Z]{5}[0-9]{4}[A-Z]</code></li>
<li>DOB invalid / future / age &lt; 18</li>
<li>mobile not 10 digits</li>
<li>risk_category not in (<code>LOW</code>,<code>MED</code>,<code>HIGH</code>)</li>
<li>pincode not 6 digits</li>
</ul>
<p><strong>Pattern in Transformer (recommended):</strong></p>
<ol>
<li><p>Create boolean flags per rule:</p>
<ul>
<li><code>is_pan_valid</code></li>
<li><code>is_dob_valid</code></li>
<li>etc.</li>
</ul>
</li>
<li>Create <code>is_record_valid = is_pan_valid AND is_dob_valid AND ...</code></li>
<li><p>Build <code>reject_reason</code> by concatenating failures:</p>
<ul>
<li>e.g., <code>"PAN_INVALID|DOB_INVALID|MOBILE_INVALID"</code></li>
</ul>
</li>
</ol>
<p><strong>Output link constraints:</strong></p>
<ul>
<li><code>VALID_OUT</code> constraint: <code>is_record_valid</code></li>
<li><code>REJECT_OUT</code> constraint: <code>NOT(is_record_valid)</code></li>
</ul>
<p>This gives you <strong>record-level rejects</strong> without killing the whole job.</p>
<hr />
<h2 id="heading-d-if-even-one-record-fails-send-email">D) “If even one record fails → send email”</h2>
<p>You still write the clean output file for valid records (as you described), <strong>but</strong> you must trigger an email if rejects exist.</p>
<p>How to get reject count back to Sequence (practical options):</p>
<h3 id="heading-option-1-most-common-use-job-user-status">Option 1 (most common): use job <strong>User Status</strong></h3>
<p>At end of the Parallel job:</p>
<ul>
<li>add an Aggregator/Counter logic to compute reject_count</li>
<li><p>in a final Transformer or a routine, set:</p>
<ul>
<li><code>DSSetUserStatus("REJECT_COUNT=" : String(reject_count) : ";TOTAL=" : String(total_count))</code></li>
</ul>
</li>
</ul>
<p>Then in Sequence:</p>
<ul>
<li>read the job user status string and parse reject_count</li>
<li>Decision stage: if <code>reject_count &gt; 0</code> → send email</li>
</ul>
<h3 id="heading-option-2-write-a-small-control-file">Option 2: write a small “control file”</h3>
<p>Parallel job writes:</p>
<ul>
<li><code>/nas/out/customer/control/CUST_KYC_CTRL_${RUN_TS}.txt</code>
with:</li>
<li><code>TOTAL=1000</code></li>
<li><code>VALID=980</code></li>
<li><code>REJECT=20</code></li>
</ul>
<p>Sequence reads that file (or just greps it) and decides.</p>
<p>If you want to look “extra production-grade” in interview, pick <strong>Option 2</strong> (it’s audit-friendly).</p>
<hr />
<h2 id="heading-e-email-content-what-ops-teams-like">E) Email content (what ops teams like)</h2>
<p>Include:</p>
<ul>
<li>environment</li>
<li>file name</li>
<li>counts</li>
<li>path to reject file</li>
<li>sample reject reasons (top 5)</li>
</ul>
<p>Example subject:</p>
<ul>
<li><code>[UAT][CUST_KYC] File validation failed: 20 rejects - CUSTOMER_KYC_UPDATES_20260128.txt</code></li>
</ul>
<hr />
<h2 id="heading-f-operational-hardening-small-things-that-impress">F) Operational hardening (small things that impress)</h2>
<ul>
<li><strong>Archive input file</strong> only after processing</li>
<li>Use <strong>timestamped output files</strong> to avoid overwrite</li>
<li>Write <strong>reject file even if 1 record fails</strong></li>
<li><p>Add a <strong>header/trailer check</strong> if your file has it (common in banks)</p>
<ul>
<li>trailer might include record count; validate it</li>
</ul>
</li>
<li>Add a <strong>job retry</strong> logic in sequence (optional)</li>
<li>Add <strong>standard log messages</strong> + counts</li>
</ul>
<hr />
<h1 id="heading-professional-workflow-diagram-high-level">Professional workflow diagram (high-level)</h1>
<p>You can paste this into any Mermaid renderer (or even Confluence/GitHub) and it looks clean.</p>
<pre><code class="lang-mermaid">flowchart TB
  A([Start]) --&gt; B[Set RUN_TS, build filenames, set params]
  B --&gt; C{Input file exists?}
  C -- No --&gt; E1[Send Email: File not found] --&gt; Z([End])

  C -- Yes --&gt; D{File empty? (size=0)}
  D -- Yes --&gt; E2[Write error marker (optional)] --&gt; E3[Send Email: Empty file received] --&gt; H[Archive input file] --&gt; Z

  D -- No --&gt; F[Run Parallel Job: Validate + Transform]
  F --&gt; G{Reject count &gt; 0?}
  G -- Yes --&gt; I[Write reject file already created by job] --&gt; J[Send Email: Validation failed + attach paths] --&gt; H --&gt; Z
  G -- No --&gt; K[Good output file written] --&gt; H --&gt; Z
</code></pre>
<hr />
<h1 id="heading-parallel-job-internal-flow-diagram-what-the-etl-job-looks-like">Parallel job internal flow diagram (what the ETL job looks like)</h1>
<pre><code class="lang-mermaid">flowchart LR
  R[Sequential File - Read Input] --&gt; T[Transformer - Validate &amp; Transform]
  T --&gt;|VALID_OUT| W1[Sequential File - Write Good Output]
  T --&gt;|REJECT_OUT| W2[Sequential File - Write Reject Output (with reason)]
  T --&gt; C[Row Count/Audit] --&gt; S[Set UserStatus or Write Control File]
</code></pre>
<hr />
<h2 id="heading-what-to-tell-your-evaluator-the-i-know-datastage-talking-points">What to tell your evaluator (the “I know DataStage” talking points)</h2>
<ul>
<li>“I used a <strong>Sequence</strong> to orchestrate file checks, routing, email notifications, and archival.”</li>
<li>“I handled the <strong>empty file</strong> case <em>before</em> running ETL to avoid false job success.”</li>
<li>“In the parallel job, I split data into <strong>valid</strong> and <strong>reject</strong> flows with <strong>link constraints</strong>, and captured <strong>reject_reason</strong> for each failed row.”</li>
<li>“I made it production-grade via <strong>parameterization</strong>, <strong>timestamped outputs</strong>, <strong>audit counts</strong>, and <strong>deterministic archiving</strong>.”</li>
</ul>
<hr />
<p>flowchart TB
  A([Start]) --&gt; B[Set RUN_TS, build filenames, set params]
  B --&gt; C{Input file exists?}
  C -- No --&gt; E1[Send Email: File not found] --&gt; Z([End])</p>
<p>  C -- Yes --&gt; D{File empty? (size=0)}
  D -- Yes --&gt; E2[Write error marker (optional)] --&gt; E3[Send Email: Empty file received] --&gt; H[Archive input file] --&gt; Z</p>
<p>  D -- No --&gt; F[Run Parallel Job: Validate + Transform]
  F --&gt; G{Reject count &gt; 0?}
  G -- Yes --&gt; I[Write reject file already created by job] --&gt; J[Send Email: Validation failed + attach paths] --&gt; H --&gt; Z
  G -- No --&gt; K[Good output file written] --&gt; H --&gt; Z</p>
<p>flowchart LR
  R[Sequential File - Read Input] --&gt; T[Transformer - Validate &amp; Transform]
  T --&gt;|VALID_OUT| W1[Sequential File - Write Good Output]
  T --&gt;|REJECT_OUT| W2[Sequential File - Write Reject Output (with reason)]
  T --&gt; C[Row Count/Audit] --&gt; S[Set UserStatus or Write Control File]</p>
]]></content:encoded></item><item><title><![CDATA[Deloitte Interview Experience for Senior Consultant — Microservices JAVA (5+ years)]]></title><description><![CDATA[I have recently given interview for Senior Developer Role at Deloitte USI and below are the questions I was asked.

What is the Facade Design Pattern and where would you use it in a real-world application?

What is the Singleton Design Pattern?

What...]]></description><link>https://deeptechguide.blog/deloitte-interview-experience-for-senior-consultant-microservices-java-5-years</link><guid isPermaLink="true">https://deeptechguide.blog/deloitte-interview-experience-for-senior-consultant-microservices-java-5-years</guid><category><![CDATA[Java]]></category><category><![CDATA[Deloitte]]></category><category><![CDATA[interview questions]]></category><category><![CDATA[interview preparations]]></category><category><![CDATA[Interview experience]]></category><dc:creator><![CDATA[Sushil Chandra]]></dc:creator><pubDate>Sun, 18 Jan 2026 12:29:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/npxXWgQ33ZQ/upload/8322858070a6518180a8c7fbe4aa2bc0.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I have recently given interview for Senior Developer Role at Deloitte USI and below are the questions I was asked.</p>
<ol>
<li><p>What is the <strong>Facade Design Pattern</strong> and where would you use it in a real-world application?</p>
</li>
<li><p>What is the <strong>Singleton Design Pattern?</strong></p>
</li>
<li><p>What are <strong>eager and lazy initializations</strong> in Singleton?</p>
</li>
<li><p>How to make <strong>Singleton</strong> thread-safe?</p>
</li>
<li><p>What is <strong>Double-Checked Locking</strong> in Singleton?</p>
</li>
<li><p>How would you <strong>secure your APIs</strong> in a Spring Boot application?</p>
</li>
<li><p>What is the difference between <code>@Primary</code> <strong>and</strong> <code>@Qualifier</code> annotations in Spring?</p>
</li>
<li><p>What is the difference between <code>@Mock</code> <strong>and</strong> <code>@MockBean</code>?</p>
</li>
<li><p>What are the <strong>important annotations associated with JUnit</strong>?</p>
</li>
<li><p>What is the difference between <strong>ClassNotFoundException</strong> and <strong>NoClassDefFoundError</strong>?</p>
</li>
<li><p>How do you <strong>check the health of your application and individual instances</strong> in Spring Boot?</p>
</li>
<li><p>How do you maintain <strong>data consistency in a distributed transaction</strong> across microservices?</p>
</li>
<li><p>What is <strong>Resilience4j</strong>, and why is it needed in microservices?</p>
</li>
<li><p>What is a <strong>Circuit Breaker</strong>, and what are its states?</p>
</li>
<li><p>How do you <strong>configure a Circuit Breaker using Resilience4j</strong>?</p>
</li>
<li><p>What is <strong>Eureka Server</strong>, and how does it work internally?</p>
</li>
<li><p>How does <strong>service discovery</strong> work in a microservices architecture?</p>
</li>
<li><p>Features of <strong>Java 17.</strong></p>
</li>
<li><p>What are <strong>Generics</strong> in Java?</p>
</li>
<li><p>What is <strong>Type Erasure</strong> in Java?</p>
</li>
<li><p>What are Java Streams?</p>
</li>
<li><p>Intermediate vs Terminal operations in Streams.</p>
</li>
<li><p>Parallel vs Sequential streams</p>
</li>
<li><p>What is a <strong>Functional Interface</strong>, and why is it important?</p>
</li>
<li><p>Internal working of <strong>HashMap</strong></p>
</li>
<li><p>If you want to use an <strong>Employee object as a key in HashMap</strong>, what changes are required?</p>
</li>
<li><p>What is <strong>CompletableFuture</strong>? How is it different from <strong>Future</strong>?</p>
</li>
<li><p>What is <strong>Kubernetes</strong>, and why is it used?</p>
</li>
<li><p>How do you <strong>monitor logs of individual instances</strong> in a distributed system?</p>
</li>
<li><p>What is the difference between <strong>Synchronous and Asynchronous communication</strong>?</p>
</li>
<li><p>Which is faster: <strong>method overloading or method overriding</strong>? Why?</p>
</li>
<li><p>Given an integer array of length at least 3, determine whether it is a <strong>valid mountain array</strong>. An array is a mountain array if:</p>
</li>
</ol>
<ul>
<li><p>It strictly increases up to a single peak.</p>
</li>
<li><p>Then strictly decreases after the peak.</p>
</li>
<li><p>The peak is not the first or last element.</p>
</li>
</ul>
<p><strong>Code Solution:</strong></p>
<pre><code class="lang-java">
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DeloitteInterview</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{

        System.out.println(isMountainArray(<span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[]{<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">8</span>, <span class="hljs-number">5</span>, <span class="hljs-number">2</span>})); <span class="hljs-comment">// true</span>

        System.out.println(isMountainArray(<span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[]{<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>}));       <span class="hljs-comment">// false</span>

        System.out.println(isMountainArray(<span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[]{<span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>}));       <span class="hljs-comment">// false</span>

        System.out.println(isMountainArray(<span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[]{<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">2</span>, <span class="hljs-number">1</span>}));    <span class="hljs-comment">// false</span>

        System.out.println(isMountainArray(<span class="hljs-keyword">new</span> <span class="hljs-keyword">int</span>[]{<span class="hljs-number">1</span>, <span class="hljs-number">3</span>, <span class="hljs-number">2</span>, <span class="hljs-number">4</span>, <span class="hljs-number">1</span>})); <span class="hljs-comment">// false</span>

    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isMountainArray</span><span class="hljs-params">(<span class="hljs-keyword">int</span>[] arr)</span> </span>{
        <span class="hljs-keyword">int</span> n = arr.length;

        <span class="hljs-keyword">if</span> (n &lt; <span class="hljs-number">3</span>) <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;

        <span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>;

        <span class="hljs-keyword">while</span> (i + <span class="hljs-number">1</span> &lt; n &amp;&amp; arr[i] &lt; arr[i + <span class="hljs-number">1</span>]) {
            i++;
        }

        <span class="hljs-keyword">if</span> (i == <span class="hljs-number">0</span> || i == n - <span class="hljs-number">1</span>) <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;

        <span class="hljs-keyword">while</span> (i + <span class="hljs-number">1</span> &lt; n &amp;&amp; arr[i] &gt; arr[i + <span class="hljs-number">1</span>]) {
            i++;
        }

        <span class="hljs-keyword">return</span> i == n - <span class="hljs-number">1</span>;

    }

}
</code></pre>
]]></content:encoded></item></channel></rss>