원클릭으로
awcms-mini-payment-gateway
Kerjakan bagian mana pun dari modul payment_gateway AWCMS-Mini (Issue
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Kerjakan bagian mana pun dari modul payment_gateway AWCMS-Mini (Issue
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Kelola/konsumsi sistem Module Management AWCMS-Mini (registry, validasi komposisi registry base, tenant lifecycle enable/disable, settings, permission sync/status, navigation, job registry, health/readiness). Gunakan saat menambah field descriptor baru (permissions/navigation/settings/jobs/health) di modul lain, saat menambah modul domain baru langsung di `src/modules/` dan perlu memverifikasi registry base tetap valid (`bun run modules:compose:check`), saat menyelidiki kenapa suatu modul terlihat degraded/orphaned, atau saat mengubah perilaku enable/disable/settings/health module_management sendiri. Sesuai src/modules/module-management/README.md, epic
Pilih dan jalankan profil deployment AWCMS-Mini (development/staging/production/offline-LAN). Gunakan saat menyiapkan deployment baru, memutuskan LAN-first vs registry-based, atau deploy ke Coolify. Sesuai doc 18 dan deployment-profiles.md/deploy-coolify.md.
Kelola sistem log/audit/metrics AWCMS-Mini yang sudah aktif — correlation ID lintas hop, retensi/purge audit log, extension point untuk consumer eksternal (alerting/export/SIEM), dan metrics port (counter/histogram/gauge berkardinalitas rendah untuk request/pool/job/provider). Gunakan saat menambah endpoint baru (correlation ID otomatis), menjadwalkan purge audit log, memasang consumer log/audit di aplikasi turunan, atau menambah/mengonsumsi metrik operasional. Berbeda dari awcms-mini-audit-log (APA yang wajib diaudit) — skill ini tentang BAGAIMANA sistem log/audit/metrics itu sendiri dikelola, sesuai Issue
Kerjakan bagian mana pun dari modul tenant_provisioning AWCMS-Mini (Issue
Triase dan perbaiki temuan CodeQL code scanning AWCMS-Mini (github.com/ahliweb/awcms-mini/security/code-scanning). Gunakan saat diminta "analisis code scanning"/"perbaiki CodeQL", saat sebuah PR gagal check CodeQL, atau saat menemukan alert baru. Mendokumentasikan satu TRUE-positive terkonfirmasi (password sungguhan → digest cepat yang dipersist = oracle cracking offline, plus dua "fix" yang membungkam alert tanpa memperbaiki apa pun) dan lima false-positive nyata (name-heuristic password, incompatible-types typeof/null, URL substring-sanitization di test mock, dua kasus dismiss resmi tanpa reformulasi kode, dan Bun.SQL tagged-template null-cast) plus pola "unused-local-variable di test kadang menandai coverage gap" — supaya tidak diinvestigasi ulang dari nol.
Daftarkan tabel bervolume tinggi ke registry lifecycle AWCMS-Mini (retensi/partisi/arsip/legal hold/purge), atau kerjakan bagian mana pun modul data_lifecycle sendiri. Gunakan saat menambah tabel baru yang tumbuh besar (log, telemetry, outbox, queue, provider attempt) dan butuh kebijakan retensi/purge aman, saat membuat/melepas legal hold, atau saat mengubah engine dry-run/archive/purge/archive-port. Sesuai Issue
| name | awcms-mini-payment-gateway |
| description | Kerjakan bagian mana pun dari modul payment_gateway AWCMS-Mini (Issue |
payment_gateway (src/modules/payment-gateway, Issue #877, epic #868 SaaS
control plane Wave 1, ADR-0022) adalah modul control-plane KEENAM &
TERAKHIR — Official Optional Business Foundation, opt-in per tenant,
default-disabled, tenant-scoped. Ia menyediakan kapabilitas pembayaran
provider-netral: hosted checkout/session, webhook masuk bertandatangan,
event pembayaran ternormalisasi, refund, retry/DLQ, provider health + circuit
breaker, dan reconciliation. Ia BUKAN general ledger / AR-AP / double-entry
accounting / merchant settlement / tax engine, dan tidak pernah menyimpan
kredensial kartu / PAN (ADR-0022 §11).
webhook/[providerAccountId].ts diautentikasi oleh id akun opaque (bind ke
TEPAT SATU tenant) + verifikasi adapter — bukan sesi JWT tenant.initiateCheckout/
requestRefund commit intent + baris outbox DULU; worker
outbox-dispatch memanggil provider tanpa transaksi terbuka, lalu
finalize di transaksi terpisah. Outage provider → retry/backoff + circuit
breaker + DLQ, TAK PERNAH menahan/rollback transaksi sumber.domain/webhook-security.ts +
webhook-intake.ts): (a) HMAC signature timing-safe; (b) timestamp/freshness
window ≤300s; (c) binding provider/account (payload account_ref ==
akun terikat → cegah cross-tenant substitution); (d) payload size; (e)
anti-replay via event-id PERSISTEN di DB (unique
(tenant, account, provider_event_id) — BUKAN in-memory); (f) ordering
(provider_sequence monotonic). Valid signed webhook update payment TEPAT
SEKALI (loser ON CONFLICT = no-op). Gagal/oversized/duplicate/out-of-order/
stale = tolak fail-closed + audit + reconciliation evidence.domain/endpoint-allowlist.ts): endpoint provider +
callback URL allow-listed per akun; validasi host via new URL() +
host equality (BUKAN startsWith prefix — memory
[[linkedin-media-trust-helper-862]]).process.env — row akun menyimpan POINTER
env:VAR_NAME (domain/secret-ref.ts), TAK PERNAH nilai secret. Tidak di
tabel/event/log/audit. Rotasi = env deployment.domain/masking.ts)
— hanya snippet ter-mask (bukan raw body), referensi provider ter-MASK,
safe error class (tak pernah pesan provider mentah).defaultTenantState:"disabled" + gate di
tests/unit/module-governance-default-disabled.test.ts.module-boundary.test.ts): no reverse dep,
awcms_mini_payment_gateway_* hanya modul sendiri, port payment_outcome
neutral. Konsumsi billing #876 (billing_document_state read + recordPayment
Allocation write) HANYA di composition-root (_support.ts/scripts), jangan
di app/domain payment_gateway.FOR UPDATE + UPDATE
ber-predikat status → 409, ON CONFLICT partial-unique,
replayConcurrentIdempotentWinner. Webhook EXACTLY-ONCE (event-id unique).
Job (dispatch/reconcile/expire) pakai LEASE per-(tenant,job_kind).
JANGAN Promise.all atas satu tx.BEFORE UPDATE saja sejak 102 (#932). Sebelumnya
BEFORE UPDATE OR DELETE + raise tanpa syarat = TIDAK ADA role yang bisa
hapus, termasuk pemilik tabel → retensi mustahil, legal hold tak punya
objek. Batas DELETE sekarang ada di GRANT (awcms_mini_app tidak pernah,
awcms_mini_worker ya), pola usage_metering 087. Kalau menambah tabel
bukti append-only baru: pakai BEFORE UPDATE + grant, JANGAN sertakan
OR DELETE.domain/money.ts).request-parsing/request- validation). Event versioned emit dgn KONSTANTA ter-import LANGSUNG dari
event-type-registry, snapshot same-commit.Adapter provider = External Integration off-by-default. Base HANYA ship
sandbox-adapter.ts (fake, untuk test + docs) di infrastructure/adapter- registry.ts. Provider nyata (Midtrans/Xendit/Stripe) opt-in via composition-root
repo ini lewat registerPaymentProviderAdapter, TAK PERNAH hardcoded di base.
LAN/offline (modul disabled) = 100% tanpa provider.
CONSUMES billing_document_state (#876, read-only) untuk validasi invoice payable.
PROVIDES payment_outcome (_shared/ports/payment-outcome-port.ts) —
settled/refunded diteruskan ke subscription_billing.recordPaymentAllocation
(write path #876 sendiri, idempoten, audited), wired di composition-root.
Migrasi 093 (schema) + 094 (permissions) + 102 (retensi bukti, #932);
jobs payment-gateway:dispatch-outbox|reconcile|expire-sweep|purge.
dataLifecycle: 4 descriptor (domain/lifecycle-keys.ts) mode delegated,
jalur hapus TUNGGAL application/retention-purge.ts. Rantai
webhook_inbox <- normalized_events <- processing_attempts di-purge
FK-safe (daun dulu; tiap tingkat HANYA hapus baris tanpa anak yang masih
hidup — umur saja tidak aman, induk selalu lebih tua dari anaknya). Legal
hold di satu mata rantai memblokir SELURUH rantai (fail-closed);
reconciliations independen, di-hold terpisah. Test batas grant WAJIB
assert SQLSTATE 42501 — "sekadar throw" juga dipenuhi 23503 dari FK
anak dan lolos walau grant salah lebar.
Sinyal fleet-wide (#930): application/control-plane-signals.ts —
deadLetterDepth (outbox status='dead') + webhookBacklog (inbox
status='received'), dibaca bun run control-plane:fleet-sweep. DLQ BUKAN
backlog: tiap barisnya kerja provider yang sudah habis retry dan tak akan
pernah dicoba lagi tanpa aksi operator — itu kehilangan permanen, bukan
antrean yang terkuras sendiri.
Lihat src/modules/payment-gateway/README.md untuk detail ERD/tabel/state
machine.