From 52624b6adf856fe3b9caefc543e961b191e16a26 Mon Sep 17 00:00:00 2001 From: Umesh Date: Sun, 20 Sep 2026 02:42:06 +0530 Subject: [PATCH 1/4] ci: introduce unified CI Quality Gate with intelligent path filtering --- .github/workflows/ci.yml | 98 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a6746c6..726417c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,8 +12,37 @@ env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true jobs: + changes: + name: Detect Changed Paths + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + code: ${{ steps.filter.outputs.code }} + steps: + - name: Checkout Code + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Detect Changed Paths + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: filter + with: + filters: | + code: + - '**/*.go' + - 'go.mod' + - 'go.sum' + - 'Makefile' + - 'scripts/**' + - '.github/workflows/ci.yml' + - '.github/workflows/release.yml' + - '.golangci.yml' + lint: name: GolangCI-Lint + needs: [changes] + if: github.event_name == 'push' || needs.changes.outputs.code == 'true' runs-on: ubuntu-latest steps: - name: Checkout Code @@ -42,6 +71,8 @@ jobs: test: name: Test & Race (${{ matrix.go-version }}) + needs: [changes] + if: github.event_name == 'push' || needs.changes.outputs.code == 'true' runs-on: ubuntu-latest strategy: matrix: @@ -80,6 +111,8 @@ jobs: integration: name: PostgreSQL Integration Tests + needs: [changes] + if: github.event_name == 'push' || needs.changes.outputs.code == 'true' runs-on: ubuntu-latest services: postgres: @@ -115,6 +148,8 @@ jobs: security: name: Supply Chain & Vulnerability Scanner + needs: [changes] + if: github.event_name == 'push' || needs.changes.outputs.code == 'true' runs-on: ubuntu-latest steps: - name: Checkout Code @@ -162,3 +197,66 @@ jobs: - name: Verify Statement Coverage Gate run: ./scripts/check_coverage.sh + + ci-gate: + name: CI Quality Gate + runs-on: ubuntu-latest + if: always() + needs: + - changes + - docs-match-tree + - lint + - test + - integration + - security + steps: + - name: Evaluate CI Quality Gate + run: | + echo "========================================================" + echo "๐Ÿ Evaluating CI Quality Gate" + echo " Event: ${{ github.event_name }}" + echo " Code changes detected: ${{ needs.changes.outputs.code }}" + echo "========================================================" + + if [ "${{ needs.changes.result }}" != "success" ]; then + echo "โŒ Path detection failed with: ${{ needs.changes.result }}" >&2 + exit 1 + fi + + if [ "${{ needs.docs-match-tree.result }}" != "success" ]; then + echo "โŒ Documentation & Version Gate failed with: ${{ needs.docs-match-tree.result }}" >&2 + exit 1 + fi + + SHOULD_VERIFY_CODE="${{ github.event_name == 'push' || needs.changes.outputs.code == 'true' }}" + if [ "$SHOULD_VERIFY_CODE" = "true" ]; then + echo "๐Ÿ” Verifying code test suites..." + FAILED=0 + + check_job() { + local name="$1" + local result="$2" + if [ "$result" != "success" ]; then + echo "โŒ $name failed with result: $result" >&2 + FAILED=1 + else + echo "โœ… $name: success" + fi + } + + check_job "GolangCI-Lint" "${{ needs.lint.result }}" + check_job "Test & Race" "${{ needs.test.result }}" + check_job "PostgreSQL Integration" "${{ needs.integration.result }}" + check_job "Supply Chain Scanner" "${{ needs.security.result }}" + + if [ "$FAILED" -ne 0 ]; then + echo "โŒ CI Quality Gate failed due to errors in code test suite." >&2 + exit 1 + fi + else + echo "๐Ÿ“„ Docs-only change detected. Heavy test suites (lint, test, race, integration, security) safely skipped." + fi + + echo "========================================================" + echo "โœ… All CI Quality Gates successfully satisfied!" + echo "========================================================" From 5348889c0899c9f1e937a55a7baf7b4b52e2f8f6 Mon Sep 17 00:00:00 2001 From: Umesh Date: Mon, 21 Sep 2026 02:19:48 +0530 Subject: [PATCH 2/4] refactor: discontinue deprecated india package in favor of go-fintech-india MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove deprecated backward-compatibility india faรงade package - Migrate examples/invoice_service to import go-fintech-india directly - Update README and docs portal for 5 core enterprise packages and companion architecture - Reconcile test statement coverage to 89.4% and pass all truth gates --- .github/badges/coverage.json | 4 +- CHANGELOG.md | 9 + README.md | 163 ++-- docs/index.html | 335 ++++--- examples/invoice_service/README.md | 8 +- .../invoice_service/invoice_service_test.go | 24 +- examples/invoice_service/service.go | 115 ++- india/README.md | 78 -- india/aadhaar.go | 75 -- india/aging.go | 40 - india/aging_test.go | 76 -- india/currency.go | 40 - india/doc.go | 7 - india/fy.go | 92 -- india/gstin.go | 92 -- india/ifsc.go | 64 -- india/india_test.go | 892 ------------------ india/money.go | 214 ----- india/pan.go | 82 -- india/phone.go | 61 -- scripts/check_version.sh | 4 +- scripts/verify_changelog_symbols.sh | 9 + 22 files changed, 371 insertions(+), 2113 deletions(-) delete mode 100644 india/README.md delete mode 100644 india/aadhaar.go delete mode 100644 india/aging.go delete mode 100644 india/aging_test.go delete mode 100644 india/currency.go delete mode 100644 india/doc.go delete mode 100644 india/fy.go delete mode 100644 india/gstin.go delete mode 100644 india/ifsc.go delete mode 100644 india/india_test.go delete mode 100644 india/money.go delete mode 100644 india/pan.go delete mode 100644 india/phone.go diff --git a/.github/badges/coverage.json b/.github/badges/coverage.json index 1005c3b..d3c6a55 100644 --- a/.github/badges/coverage.json +++ b/.github/badges/coverage.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, "label": "coverage", - "message": "90.5%", - "color": "brightgreen" + "message": "89.4%", + "color": "yellow" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 45a2d63..2fef04a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.4.0] - 2026-09-20 + +### Removed +- india: Discontinued deprecated backward-compatibility faรงade. Canonical statutory Indian primitives (GSTIN, PAN, Aadhaar Verhoeff D5, IFSC, Money) should be imported directly from `github.com/umesh0492/go-fintech-india`. + +### Changed +- examples/invoice_service: Migrated reference billing pipeline to import `github.com/umesh0492/go-fintech-india` directly. +- docs: Refactored documentation portal, architecture diagrams, and README to showcase the 5 core enterprise application infrastructure packages (outbox, pdf, notifications, audit, export) and direct companion composition with `go-fintech-india`. + ## [0.3.2] - 2026-09-18 ### Changed diff --git a/README.md b/README.md index b0992e2..2fb7b2c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # go-app-kit -> Current main-line published release: `v0.3.2`. The lightweight `v0.3.0` tag points to an earlier commit and remains an immutable, separate artifact. See [Release Baseline](docs/RELEASE_BASELINE.md) before selecting a release or publishing a reconciliation. +> Current main-line published release: `v0.4.0`. The lightweight `v0.3.0` tag points to an earlier commit and remains an immutable, separate artifact. See [Release Baseline](docs/RELEASE_BASELINE.md) before selecting a release or publishing a reconciliation. [![CI](https://github.com/Abeta-dev/go-app-kit/actions/workflows/ci.yml/badge.svg)](https://github.com/Abeta-dev/go-app-kit/actions/workflows/ci.yml) [![Code Quality: golangci-lint](https://img.shields.io/badge/code%20quality-golangci--lint-brightgreen?logo=go)](https://golangci-lint.run/) @@ -10,7 +10,7 @@ **Production-grade enterprise application and domain accelerator kit for Go.** -While [`go-libs`](https://github.com/Abeta-dev/go-libs) provides low-level, zero-dependency microservice systems engineering (resilience, concurrency pools, rate limiting, SRE golden signals), **`go-app-kit`** delivers high-velocity business capabilities: **Indian localized fintech helpers (GSTIN, PAN, IFSC, Aadhaar), transactional outbox with PostgreSQL DDL, multi-channel notifications, PDF document generation with GST invoice templates, partitioned compliance audit logging, and streaming data exports**. +While [`go-libs`](https://github.com/Abeta-dev/go-libs) provides low-level, zero-dependency microservice systems engineering (resilience, concurrency pools, rate limiting, SRE golden signals), **`go-app-kit`** delivers 5 core enterprise application infrastructure packages: **transactional outbox with PostgreSQL DDL, PDF document generation with GST invoice templates, multi-channel notifications, partitioned compliance audit logging, and streaming data exports** (composing seamlessly with statutory companion [`go-fintech-india`](https://github.com/Abeta-dev/go-fintech-india)). --- @@ -20,21 +20,20 @@ While [`go-libs`](https://github.com/Abeta-dev/go-libs) provides low-level, zero โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ Enterprise Microservices โ”‚ โ”‚ (Invoicing, Orders, Fintech, B2B SaaS) โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ imports - โ–ผ -โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” -โ”‚ github.com/umesh0492/go-app-kit โ”‚ -โ”‚ โ”‚ -โ”‚ โ”œโ”€โ”€ india/ GSTIN (mod-36), PAN, IFSC, Aadhaar (Verhoeff D5), INR โ”‚ -โ”‚ โ”œโ”€โ”€ pdf/ HTML-to-PDF compilation & embedded GST Invoice template โ”‚ -โ”‚ โ”œโ”€โ”€ notifications/ Multi-channel broker (Email, Slack, Webhook HMAC-SHA256)โ”‚ -โ”‚ โ”œโ”€โ”€ outbox/ Postgres Transactional Outbox (SKIP LOCKED + backoff) โ”‚ -โ”‚ โ”œโ”€โ”€ audit/ Partitioned compliance audit trails & JSON state diffs โ”‚ -โ”‚ โ””โ”€โ”€ export/ Low-memory streaming CSV exporter with Excel UTF-8 BOM โ”‚ -โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ - โ”‚ builds upon - โ–ผ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ imports โ”‚ imports + โ–ผ โ–ผ +โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” +โ”‚ github.com/umesh0492/go-app-kit โ”‚ โ”‚ github.com/umesh0492/ โ”‚ +โ”‚ โ”‚ โ”‚ go-fintech-india (Companion) โ”‚ +โ”‚ โ”œโ”€โ”€ outbox/ PostgreSQL Outbox โ”‚ โ”‚ โ”‚ +โ”‚ โ”œโ”€โ”€ pdf/ HTML-to-PDF / GST โ”‚ โ”‚ โ”œโ”€โ”€ GSTIN (mod-36), PAN, IFSC โ”‚ +โ”‚ โ”œโ”€โ”€ notifications/ Multi-channel โ”‚ โ”‚ โ”œโ”€โ”€ Aadhaar (Verhoeff D5) โ”‚ +โ”‚ โ”œโ”€โ”€ audit/ Compliance Trails โ”‚ โ”‚ โ”œโ”€โ”€ Money (exact paise math) โ”‚ +โ”‚ โ””โ”€โ”€ export/ Streaming CSV/BOM โ”‚ โ”‚ โ””โ”€โ”€ FY & AP/AR Aging โ”‚ +โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ + โ”‚ builds upon + โ–ผ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ github.com/umesh0492/go-libs โ”‚ โ”‚ โ”‚ @@ -53,7 +52,7 @@ While [`go-libs`](https://github.com/Abeta-dev/go-libs) provides low-level, zero ### Standalone Import When consuming `go-app-kit` in your microservice: ```bash -go get github.com/umesh0492/go-app-kit@v0.3.2 +go get github.com/umesh0492/go-app-kit@v0.4.0 ``` ### Multi-Module Local Development (`go.work`) @@ -67,7 +66,7 @@ go work init ./go-app-kit ./go-libs With `go.work` in place, any changes in `go-libs` are immediately reflected in `go-app-kit` during compilation, testing, and debugging. ### Standard Distribution -`go-app-kit` contains no local `replace` directives. Published builds resolve `github.com/umesh0492/go-libs@v0.2.1` and `github.com/umesh0492/go-fintech-india@v0.2.3` from the Go proxy. The repository's immutable release and isolated-consumer verification are documented in [Release Baseline](docs/RELEASE_BASELINE.md). +`go-app-kit` contains no local `replace` directives. Published builds resolve `github.com/umesh0492/go-libs@v0.3.0` and `github.com/umesh0492/go-fintech-india@v0.2.3` from the Go proxy. The repository's immutable release and isolated-consumer verification are documented in [Release Baseline](docs/RELEASE_BASELINE.md). ### Concurrency Architecture & Dependency on `go-libs/workerpool` `go-app-kit`'s asynchronous background execution in `notifications` (async multi-channel fan-out) and `audit` (asynchronous audit log ingestion) imports [`go-libs/workerpool`](https://github.com/Abeta-dev/go-libs/tree/main/workerpool) directly. It leverages bounded concurrency, graceful draining, panic resilience, and Prometheus saturation metrics without maintaining any duplicated forks. @@ -76,32 +75,33 @@ With `go.work` in place, any changes in `go-libs` are immediately reflected in ` ## Package Modules -### 1. `india` - Localized Fintech & Enterprise Compliance Helpers -Zero external dependencies. Implements statutory Indian validation algorithms and formatting: -- **GSTIN** (`ValidateGSTIN`, `ParseGSTIN`, `CalculateGSTINCheckDigit`): 15-character Goods and Services Tax Identification Number validation with official mod-36 check digit calculation and 38 state/UT registries. -- **PAN** (`ValidatePAN`, `ParsePAN`): 10-character Permanent Account Number validation with 4th-character entity mapping (Company, Individual, LLP, HUF, Trust, Government Agency). -- **IFSC** (`ValidateIFSC`, `GetBankCode`, `GetBranchCode`): 11-character RBI Financial System Code validation and branch code extraction. -- **Aadhaar** (`ValidateAadhaar`, `MaskAadhaar`, `FormatAadhaar`): 12-digit UIDAI validation using the official **Verhoeff Dihedral $D_5$ algorithm** with privacy masking (`XXXX-XXXX-1234`). -- **Phone** (`ValidatePhone`, `FormatE164`, `FormatNational`): Indian mobile number validation (`+91`, `91`, or `0` prefix) and standard E.164 normalization. -- **Fintech Money Type** (`india.Money`, `NewMoney`, `NewMoneyFromRupees`, `NewMoneyFromFloat`): Exact integer paise-based arithmetic (`Add`, `Sub`, `Mul`, `MulBasisPoints`, `Percentage`, `Split`), eliminating floating-point rounding errors with JSON and SQL serialization. -- **Currency & Words** (`FormatINRPaise`, `AmountToWordsINR`): Indian number system formatting (`12,34,567.89`) and recursive words converter supporting arbitrary Crores. -- **Financial Year** (`GetFinancialYear`, `CurrentFinancialYear`): Indian fiscal calendar calculation (April 1 to March 31) with fiscal quarters (Q1โ€“Q4). -- **AP/AR Aging Buckets** (`AgingBucket`, `DaysOverdue`): Standard statutory accounts payable/receivable overdue aging (Current, 1-30, 31-60, 61-90, 90+). +### 1. `outbox` - PostgreSQL Transactional Outbox Engine +Guarantees at-least-once message delivery without dual-write race conditions: -```go -import "github.com/umesh0492/go-app-kit/india" +> [!IMPORTANT] +> **Store Interface & Reference Implementation**: `NewPGStore(db DBOperator, opts ...StoreOption) Store` is the production-ready reference implementation for PostgreSQL DDL (`ddl/001_outbox_events.sql` and `ddl/002_outbox_concurrency_index.sql`), implementing SKIP LOCKED worker leasing, lease-token fencing, and retry backoff. +> +> This package defines the Store interface; production use requires implementing Store against your schema; see outbox_integration_test.go as the reference for correct SKIP LOCKED + fencing semantics. + +- **DDL** (`001_outbox_events.sql` & `002_outbox_concurrency_index.sql`): Production PostgreSQL schema with composite index `idx_outbox_poll ON outbox_events (status, next_retry_at, created_at)` for high-throughput, contention-free polling, `lease_token UUID` fencing, and `idx_outbox_aggregate ON outbox_events (aggregate_type, aggregate_id, created_at DESC)` for entity history lookups. +- **PostgreSQL Exclusivity**: Operates exclusively with PostgreSQL via `github.com/jackc/pgx/v5` parameterized queries (`$1, $2, ...`). *(Note: No MySQL dialect support is implemented or supported at runtime).* +- **Relay Poller** (`NewRelay`): Queries ready events using `SELECT ... FOR UPDATE SKIP LOCKED` and atomic lease renewal (`WithLeaseDuration`) with fencing tokens to allow multiple service replicas to poll concurrently without duplicate dispatches or lease clobbering. +- **Dead-Lettering & Backoff**: Full-jitter exponential backoff and configurable max retries transitioning unresolvable poison pills or exhausted retries to `DEAD_LETTER`. -// Exact fintech Money arithmetic -taxable := india.NewMoneyFromFloat(15000.50) -cgst := taxable.Percentage(9.0) // 9% GST -total := taxable.Add(cgst).Add(cgst) -fmt.Println(total.Format()) // "17,700.59" +```go +import "github.com/umesh0492/go-app-kit/outbox" -// Validate GSTIN with official mod-36 checksum -err := india.ValidateGSTIN("27AAPFU0939F1ZV") +// Transactionally write domain event inside database transaction +evt, _ := outbox.NewEvent("Invoice", "INV-100", "InvoiceIssued", invoicePayload) +err := outboxStore.Insert(ctx, tx, *evt) -// Validate Aadhaar using Verhoeff D5 dihedral algorithm -isValid := india.IsValidAadhaar("234567890128") +// Autonomous background relay +relay, _ := outbox.NewRelay(outbox.RelayConfig{ + Store: outboxStore, + Publisher: kafkaPublisher, + PollInterval: 1 * time.Second, +}) +go relay.Start(ctx) ``` --- @@ -154,38 +154,7 @@ err := broker.SendAsync(ctx, notifications.Message{ --- -### 4. `outbox` - PostgreSQL Transactional Outbox Engine -Guarantees at-least-once message delivery without dual-write race conditions: - -> [!IMPORTANT] -> **Store Interface & Reference Implementation**: `NewPGStore(db DBOperator, opts ...StoreOption) Store` is the production-ready reference implementation for PostgreSQL DDL (`ddl/001_outbox_events.sql` and `ddl/002_outbox_concurrency_index.sql`), implementing SKIP LOCKED worker leasing, lease-token fencing, and retry backoff. -> -> This package defines the Store interface; production use requires implementing Store against your schema; see outbox_integration_test.go as the reference for correct SKIP LOCKED + fencing semantics. - -- **DDL** (`001_outbox_events.sql` & `002_outbox_concurrency_index.sql`): Production PostgreSQL schema with composite index `idx_outbox_poll ON outbox_events (status, next_retry_at, created_at)` for high-throughput, contention-free polling, `lease_token UUID` fencing, and `idx_outbox_aggregate ON outbox_events (aggregate_type, aggregate_id, created_at DESC)` for entity history lookups. -- **PostgreSQL Exclusivity**: Operates exclusively with PostgreSQL via `github.com/jackc/pgx/v5` parameterized queries (`$1, $2, ...`). *(Note: No MySQL dialect support is implemented or supported at runtime).* -- **Relay Poller** (`NewRelay`): Queries ready events using `SELECT ... FOR UPDATE SKIP LOCKED` and atomic lease renewal (`WithLeaseDuration`) with fencing tokens to allow multiple service replicas to poll concurrently without duplicate dispatches or lease clobbering. -- **Dead-Lettering & Backoff**: Full-jitter exponential backoff and configurable max retries transitioning unresolvable poison pills or exhausted retries to `DEAD_LETTER`. - -```go -import "github.com/umesh0492/go-app-kit/outbox" - -// Transactionally write domain event inside database transaction -evt, _ := outbox.NewEvent("Invoice", "INV-100", "InvoiceIssued", invoicePayload) -err := outboxStore.Insert(ctx, tx, *evt) - -// Autonomous background relay -relay, _ := outbox.NewRelay(outbox.RelayConfig{ - Store: outboxStore, - Publisher: kafkaPublisher, - PollInterval: 1 * time.Second, -}) -go relay.Start(ctx) -``` - ---- - -### 5. `audit` - Audit Trail & State Diffing +### 4. `audit` - Audit Trail & State Diffing Structured audit logging with relational persistence and change tracking: - **DDL** (`001_audit_logs.sql`): Partitioned by range on `created_at` with trigger-enforced append-only constraints (`trg_prevent_audit_log_modification`). - **State Diffing** (`ComputeDiff`): Computes field-level property changes (`Old` vs `New`) between before and after JSON states. @@ -201,18 +170,21 @@ recorder.RecordAsync(event) --- -### 6. `export` - Streaming Data Exporter +### 5. `export` - Streaming Data Exporter High-throughput, low-memory CSV streaming: - Stream directly to `io.Writer` or `http.ResponseWriter` without buffering complete datasets in memory. - Prepend UTF-8 BOM (`\xEF\xBB\xBF`) for seamless Microsoft Excel rendering. - Configurable delimiters (`,`, `;`, `\t`), CRLF endings, and row batch flushing. ```go -import "github.com/umesh0492/go-app-kit/export" +import ( + fintech "github.com/umesh0492/go-fintech-india" + "github.com/umesh0492/go-app-kit/export" +) columns := []export.Column[InvoiceRow]{ {Header: "Invoice ID", Extractor: func(i InvoiceRow) string { return i.ID }}, - {Header: "Amount (INR)", Extractor: func(i InvoiceRow) string { return india.FormatINRPaise(i.AmountPaise) }}, + {Header: "Amount (INR)", Extractor: func(i InvoiceRow) string { return fintech.FormatINRPaise(i.AmountPaise) }}, {Header: "GSTIN", Extractor: func(i InvoiceRow) string { return i.BuyerGSTIN }}, } @@ -225,11 +197,41 @@ streamer.Flush() --- +### Companion Architecture: Indian Statutory Compliance (go-fintech-india) + +For pure domain statutory checks, zero-allocation paise arithmetic, and Indian banking/tax validation, developers should import [`github.com/umesh0492/go-fintech-india`](https://github.com/Abeta-dev/go-fintech-india) directly as a companion library: + +```go +import ( + "fmt" + fintech "github.com/umesh0492/go-fintech-india" +) + +// 1. Exact Paise Integer Arithmetic (Zero floating-point inaccuracies) +taxable := fintech.NewMoneyFromFloat(15000.50) // 1500050 paise +cgst := fintech.NewMoney(taxable.Paise() * 9 / 100) // 9% CGST +sgst := fintech.NewMoney(taxable.Paise() * 9 / 100) // 9% SGST +total := taxable.Add(cgst).Add(sgst) +fmt.Println(total.String()) // "17,700.59" + +// 2. Statutory GSTIN Mod-36 Checksum Validation +if err := fintech.ValidateGSTIN("27AAPFU0939F1ZV"); err != nil { + fmt.Printf("Invalid GSTIN: %v\n", err) +} + +// 3. Aadhaar UIDAI Verhoeff D5 Dihedral Checksum & Masking +if fintech.IsValidAadhaar("234567890128") { + fmt.Printf("Masked: %s\n", fintech.MaskAadhaar("234567890128")) +} +``` + +--- + ## When, Where, and Why to Use | Problem | Recommended Module | Why Use It | | :--- | :--- | :--- | -| **Indian Tax & Banking Compliance** | `go-app-kit/india` | Zero dependencies; verifies GST mod-36 checksum, Aadhaar Verhoeff $D_5$, PAN legal entities, and IFSC codes. | +| **Indian Tax & Banking Compliance** | [`go-fintech-india`](https://github.com/Abeta-dev/go-fintech-india) *(Companion)* | Zero dependencies; pure domain statutory primitives for GSTIN mod-36, Aadhaar Verhoeff $D_5$, PAN legal entities, IFSC codes, and integer paise math. | | **B2B Billing Documents** | `go-app-kit/pdf` | Pre-bundled GST tax invoice & payment receipt templates; in-memory byte rendering with customizable layout. | | **Cross-Service Dual-Write Safety** | `go-app-kit/outbox` | Atomically commits domain state and events in the same Postgres TX; `SKIP LOCKED` scales poller across $N$ instances. | | **Multi-Channel User Alerts** | `go-app-kit/notifications` | Unified broker routing to SMTP, Slack, and HMAC-signed webhooks; non-blocking delivery via `workerpool`. | @@ -253,18 +255,17 @@ go test -v ./... Coverage across packages in `go-app-kit` is measured using Go's statement-level coverage tool (`go test -coverprofile=coverage.out ./...`): -> **Overall Repository Statement Coverage: 90.5%** (Zero data races across `-race`) +> **Overall Repository Statement Coverage: 89.4%** (Zero data races across `-race`) | Package | Purpose | Statement Coverage | |---|---|---| -| `india` | Statutory Indian validations (GSTIN mod-36, PAN, IFSC, Aadhaar Verhoeff D5, INR Money, Aging) | **95.5%** | | `export` | Low-memory streaming CSV exporter with Excel UTF-8 BOM & formula injection protection | **93.8%** | | `notifications` | Multi-channel notification broker (SMTP Email, Slack, Webhook HMAC-SHA256 & versioning) | **92.3%** | | `outbox` | PostgreSQL transactional outbox engine with row-level locked poller & lease fencing | **90.0%** | | `audit` | Partitioned PostgreSQL audit logging with automated JSON diffing & append-only triggers | **89.5%** | | `pdf` | In-memory HTML-to-PDF compilation & embedded GST invoice templates | **80.7%** | -| `examples/invoice_service` | Reference microservice with end-to-end integration test & exact paise math | **82.9%** | -| **Total Statement Coverage** | **Cumulative across all packages** | **90.5%** | +| `examples/invoice_service` | Reference microservice with end-to-end integration test & exact paise math | **84.1%** | +| **Total Statement Coverage** | **Cumulative across all packages** | **89.4%** | --- diff --git a/docs/index.html b/docs/index.html index 39f1adc..5c4b634 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1096,7 +1096,7 @@ go-app-kit - v0.3.2 + v0.4.0