บทที่ 22 · Part 5 — Enterprise Fintech Architecture

Product and Context Map

ทบทวน Wallet, Checkout, Billing และ Payment Integration เป็น ownership/contracts map พร้อม trace journey ข้าม contexts

Product and Context Map

เมื่อเรียน pattern แยกบท เราอาจได้ modules ที่ดีเฉพาะตัวแต่ contract ระหว่าง Wallet, Checkout และ Billing ยังคลุมเครือ Context Map รอบสุดท้ายต้องระบุ ownership, language, Published Language, failure responsibility และห้าม direct table/vendor-model sharing จากนั้น trace business journey เพื่อพิสูจน์ว่ากล่องทำงานร่วมกันได้

จบบทนี้คุณจะ

สร้าง enterprise Context Map ของ Wallet, Checkout, Billing และ Payment Integration แยก Product/Context/module/service ระบุ commands, events, queries และ translation พร้อม review journey Wallet top-up ตั้งแต่ intent ถึง ledger effect/reconciliation

[!IMPORTANT] วิธีอ่านหลักฐานในบทนี้ คำที่เป็น Definition/Pattern มีแหล่งต้นทางอยู่ใกล้ claim ส่วน decision table, starting structure, checklist และ lab เป็น Heuristic/Trade-off หรือ Course Convention สำหรับฝึกตัดสินใจ ไม่ใช่มาตรฐานสากล เว้นแต่บทจะระบุแหล่งและขอบเขตไว้ชัดเจน

กลับมาทบทวน Boundary ที่ยังเป็นสมมติฐาน

แผนที่ต่อไปเป็น case-study hypothesis ไม่ใช่ universal Fintech architecture:

  • Checkout Context owns Checkout Session และ Payment Attempt ที่ merchant/customer เห็น
  • Payment Connectivity Context/Module owns provider credentials, protocol translation, routing execution และ normalized provider observations ตาม strategy
  • Wallet Context owns Wallet Account, posting/ledger rules และ balance availability
  • Billing contexts แยก Subscriptions, Metering, Invoicing, Receivables, Receipts ตาม discovery
  • Identity capability establishes principals/protocols แต่ไม่ owns business authorization
  • Web Portal/BFF เป็น channel/query composition โดย default

คำว่า Context/Module ต้องติดป้าย หาก Payment Connectivity ยังเป็น adapter package ใน Checkout service อย่าเรียก context เพื่อให้ diagram สมมาตร

Registry ของ Context

สร้าง record ต่อ boundary:

Name and status: observed | proposed | unknown
Ubiquitous Language:
Owned decisions/invariants:
Authoritative data:
Team and business owner:
Exposed commands:
Published events:
Supported queries:
Translations / ACL:
Operational failure owner:
Explicit non-responsibilities:

ตัวอย่าง Wallet:

Owns: posting eligibility, unique top-up credit, Wallet entry, available-balance decision
Consumes: CreditWallet command with verified business reference
Publishes: WalletCreditedV1, WalletCreditRejectedV1
Does not own: provider status, Checkout Session, Portal display cache
Data: authoritative MySQL ledger/posting records; derived balance/read views

คำว่า ledger ในระบบจริงต้องมี accounting/audit requirements ที่ยืนยันแล้ว Case นี้ใช้เพียง Wallet posting ownership ไม่สรุปว่า ledger ทุกระบบต้องเป็น double-entry/append-only

Published Language และการแปล

Contract ข้าม context ต้อง stable เท่าที่ consumer ต้องใช้:

type CreditWallet struct {
	OperationID string
	WalletID    string
	AmountMinor int64
	Currency    string
	EvidenceRef string
}

Wallet ไม่ควรรับ Stripe PaymentIntent หรือ Checkout database row Checkout/Payment adapter แปล provider outcome เป็น evidence ที่ contract รับรองและส่ง intent/fact ตาม relationship

Integration event ควรมี schema version, event ID, producer, occurred time, correlation และ semantic payload ผู้ผลิตมี migration/deprecation policy ผู้บริโภคไม่ query table ผู้ผลิต เพื่อเติม field แบบลับ ๆ

Context Map หลังการทบทวน

เส้นจาก Identity ไม่แปลว่า identity service approve commands แต่ Portal/application ใช้ evidence สร้าง Principal แล้ว owning context ทำ authorization

ไล่เส้นทาง Wallet Top-up

StepOwnerContractDurable/idempotent evidence
Start top-upCheckoutRequestTopUpoperation ID unique
Charge providerConnectivity adapterChargeRequestmapped vendor key/ref
Normalize resultCheckout/payment applicationChargeOutcomestate/version
Request creditCheckout → WalletCreditWalletoutbox event/command ID
Post valueWalletowned posting operationwallet + operation unique
Confirm journeyWallet → CheckoutWalletCreditedinbox/correlation
Repair gapsReconciliation ownercompare/query contractscase/evidence/audit

Failure owner ต้องชัด หาก provider success แต่ Wallet rejects currency mismatch Checkout ไม่ควร retry blind Reconciliation/operator workflow ต้องเห็นทั้ง references และ reason

Context contract ไม่อนุญาตให้ caller ข้าม invariant

CreditWallet เป็น request ไม่ใช่สิทธิ์เขียน ledger Wallet ต้อง validate reference, currency, idempotency และ policy จาก authoritative state เอง ห้ามให้ Checkout เขียน Wallet table หรือส่ง balance ใหม่มาแทน decision

กำกับดูแลโดยไม่สร้าง Central Model

Enterprise governance ควรกำหนด:

  • contract catalog และ owners
  • schema compatibility/deprecation
  • identity/tenant propagation rules
  • monetary type conventions ที่ boundary
  • observability/correlation มาตรฐาน
  • forbidden direct data/vendor dependencies
  • exception ADR พร้อม expiry

ไม่ควรสร้าง canonical enterprise object ที่รวม Customer/Payment/Invoice ทุก field Published Languages ควรเฉพาะ relationship และมี translator

แบบฝึกปฏิบัติ: ทบทวน Context Map

สร้าง Context Map พร้อม registry และ trace top-up end-to-end จากนั้นให้ reviewers ต่างบทบาทถาม:

  • Domain expert: language/invariant ถูก owner หรือไม่
  • Security: principal/tenant/audit ข้ามเส้นอย่างไร
  • Data: authoritative/derived/freshness อยู่ไหน
  • Operations: unknown/crash/reconciliation owner ใคร
  • Team: contract version และ deploy coordination เป็นอย่างไร

ให้บันทึกทุก contested boundary เป็น proposed/unknown พร้อม experiment ไม่บังคับ consensus ด้วย diagram

รายการตรวจสอบ

  • Product/Context/module/service มี label ถูกระดับ
  • Boundary มี language/invariant/data/team owner
  • เส้นทุกเส้นเป็น command/event/query พร้อม semantics
  • Vendor model หยุดที่ ACL
  • ไม่มี direct table write ข้าม context
  • Principal evidence ไม่ถูกใช้แทน business authorization
  • Journey มี idempotency/reconciliation evidence ทุก money effect
  • Unknown boundaries มี experiment และ review date

สรุปบทนี้

Context Map เป็นข้อตกลงเรื่อง meaning, ownership และ integration ไม่ใช่ service inventory แผนที่ที่ดี trace journey ได้และบอกผู้รับผิดชอบเมื่อ partial failure Product names เป็นจุดเริ่ม ส่วน commands/events/queries กับ translation ทำให้ boundary นำไปใช้จริง

อ่านเพิ่มเติม