Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs.
# https://editorconfig.org

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space

[*.java]
indent_size = 4

[*.{yml,yaml}]
indent_size = 2

[*.xml]
indent_size = 4

[*.json]
indent_size = 2

[*.md]
trim_trailing_whitespace = false
indent_size = 2

[Makefile]
indent_style = tab
36 changes: 36 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Payflow API CI Pipeline

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

permissions:
contents: read

jobs:
build:
name: Build, Quality Audit & Test
runs-on: ubuntu-latest

steps:
- name: Checkout Source Code
uses: actions/checkout@v4

- name: Set up JDK 25
uses: actions/setup-java@v4
with:
java-version: '25'
distribution: 'temurin'

- name: Cache Maven Dependencies
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-

- name: Execute Maven Verification Pipeline (Format, Checkstyle, Build & Test)
run: mvn clean verify -B
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ build/

### VS Code ###
.vscode/

### Internal docs (not committed) ###
internal/
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Changelog

All notable changes to the Payflow API 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).

---

## [Unreleased]

### Added
- Project scaffolding: MIT `LICENSE`, `CHANGELOG.md`, `.editorconfig`.
- Architectural Decision Records log (`docs/ADR.md`) and engineering standards guide (`docs/CONVENTIONS.md`).
- Spotless code formatting plugin (`com.diffplug.spotless:spotless-maven-plugin`) integrated into Maven build.
- Checkstyle static analysis (`checkstyle.xml`) plugin (`maven-checkstyle-plugin`) enforcing coding rules on `validate` phase.
- GitHub Actions CI pipeline (`.github/workflows/ci.yml`) for automated build, linting, formatting, and test execution on Java 25.
- Repository contribution guidelines and branch protection rules (`CONTRIBUTING.md`).
- GitHub status badges in `README.md`.

---

## [0.1.0] - 2026-07-27

### Added
- Baseline Phase 0 implementation.
- Basic User (`/users`) and Transaction (`/transactions`) REST endpoints.
- Spring Data JPA entities (`User`, `Transaction`) and repositories.
- In-memory H2 database persistence for local development builds.
- Initial Spring Boot 4.0.6 project configuration with Java 25.
- System Architecture documentation (`docs/ARCHITECTURE.md`), API Specification (`docs/API_SPECIFICATION.md`), and Phased Roadmap (`docs/ROADMAP.md`).
70 changes: 70 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Contributing to Payflow API

Thank you for participating in the evolution of the Payflow API payment backend!

This guide outlines our development workflow, pull request expectations, quality gates, and repository standards.

---

## 1. Development Workflow

1. **Fork & Clone**: Clone the repository locally.
2. **Branch Naming**: Create a topic branch following our convention:
- `feat/phase-<num>-<short-description>` for new features
- `fix/<short-description>` for bug fixes
- `docs/<short-description>` for documentation updates
3. **Local Build & Quality Check**:
Before opening a PR, ensure code formatting, static analysis, and tests pass:
```bash
mvn spotless:apply
mvn clean verify
```

---

## 2. Code Quality Gates & Automated Checks

Every pull request triggers the **GitHub Actions CI pipeline**, which enforces strict quality gates:

- **Formatting Check (`Spotless`)**: Validates code layout against Eclipse/Java format rules (`mvn spotless:check`).
- **Static Analysis (`Checkstyle`)**: Ensures compliance with naming, import, and structural standards (`mvn checkstyle:check`).
- **Compilation & Test Suite**: Verifies clean compilation on Java 25 and executes all unit and integration tests.

> **Note**: PRs with failing CI checks, unformatted code, or lint violations will not be merged.

---

## 3. Conventional Commit Guidelines

We enforce the [Conventional Commits](https://www.conventionalcommits.org/) specification for clean git history:

- **Format**: `<type>(<scope>): <short summary in imperative mood>`
- **Allowed Types**:
- `feat`: A new feature or endpoint implementation
- `fix`: A bug fix in existing logic
- `docs`: Documentation changes (`README`, architecture guide, specs)
- `style`: Formatting changes that do not affect code logic
- `refactor`: Code reorganization without functional changes
- `test`: Adding or refactoring tests
- `chore`: Updating dependencies, build scripts, or configuration
- **Examples**:
- `feat(domain): replace Double balance with BigDecimal in User entity`
- `fix(locking): sort user UPI IDs alphabetically to prevent deadlock`

---

## 4. Pull Request Requirements

- **Scoped Changes**: Keep PRs small and aligned with a single sub-phase (target: <500 net lines of code).
- **Documentation Parity**: If changing API contracts, business logic, or configuration parameters, update `README.md`, `docs/ARCHITECTURE.md`, and `docs/API_SPECIFICATION.md` within the same PR.
- **Changelog Entry**: Add a concise entry under `[Unreleased]` in `CHANGELOG.md`.

---

## 5. Recommended Repository Branch Protection Rules

For repository maintainers, configure GitHub branch protection for `main`:

- **Require a pull request before merging**.
- **Require status checks to pass before merging**: Select `Build, Quality Audit & Test`.
- **Require linear history** (squash or rebase merging preferred).
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Shashank Chandel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO QUALITY, MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
65 changes: 45 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,69 @@
# Payflow API — Backend Service

Payflow is a highly resilient, transactional payments backend built using **Java 25** and **Spring Boot 4.x**. The project is designed with a pluggable, cloud-flexible architecture optimized for local developer iteration, Kubernetes deployment, and resource-constrained environments (like AWS Free Tier).
<p align="left">
<a href="https://github.com/shashankch/payflow-api/actions/workflows/ci.yml"><img src="https://github.com/shashankch/payflow-api/actions/workflows/ci.yml/badge.svg" alt="Build"></a>
<a href="https://dev.java/"><img src="https://img.shields.io/badge/Java-25-ED8B00?logo=openjdk&logoColor=white" alt="Java 25"></a>
<a href="https://spring.io/projects/spring-boot"><img src="https://img.shields.io/badge/Spring%20Boot-4.0.6-6DB33F?logo=springboot&logoColor=white" alt="Spring Boot"></a>
<a href="https://www.postgresql.org/"><img src="https://img.shields.io/badge/PostgreSQL-17-4169E1?logo=postgresql&logoColor=white" alt="PostgreSQL"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
<a href="CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome"></a>
</p>

Payflow is a highly resilient, transactional payments backend built using **Java 25** and **Spring Boot 4.x**. The project is designed with a pluggable, cloud-flexible architecture optimized for local developer iteration, Kubernetes deployment, and resource-constrained environments (like AWS Free Tier and Oracle Cloud Always Free).

---

## Current Status & Evolution Roadmap

The project is currently evolving through a phased implementation roadmap from a Phase 0 baseline into an enterprise-grade payment system.

- **Phase 0 (Completed)**: Baseline REST API for User & Transaction CRUD with H2 in-memory storage.
- **Phase 1 (In Progress)**: Project hygiene, static analysis (Spotless, Checkstyle), and GitHub Actions CI.
- **Target Phases**: PostgreSQL & Flyway migrations, pessimistic row locking with deadlock avoidance, durable idempotency engine, transactional outbox pattern, JWT security, Resilience4j fault tolerance, Redis caching & Redisson distributed locking, Kafka event streaming, and Gen-AI transaction insights.

See the complete step-by-step evolution in **[Phased Roadmap](docs/ROADMAP.md)**.

---

## Technical Features
## Technical Architecture Highlights

- **ACID Transaction Hardening**: Enforces sequential consistency under race conditions using database-level pessimistic locking (`SELECT FOR UPDATE`).
- **Distributed Locking Coordination**: Integrates **Redis Redlock** (via Redisson) to synchronize distributed triggers, preventing multi-instance concurrency collisions.
- **JPA N+1 Resolution**: Avoids Hibernate lazy loading bottlenecks through explicit **Fetch Joins** and `@EntityGraph` definitions to batch-load related entities.
- **REST API Versioning**: Implements strict URI version control (`/api/v1`) protecting endpoints from breaking database changes.
- **Gen-AI Spending Assistant**: Integrates **Spring AI** and a Generative AI LLM to automatically categorize transactions and generate spend analysis.
- **Distributed Locking Coordination**: Integrates **Redis Redlock** (via Redisson) to synchronize distributed triggers across multi-instance deployments.
- **JPA N+1 Resolution**: Avoids Hibernate lazy loading bottlenecks through explicit **Fetch Joins** and `@EntityGraph` definitions.
- **REST API Versioning**: Implements strict URI version control (`/api/v1`) protecting endpoints from breaking changes.
- **Gen-AI Spending Assistant**: Integrates **Spring AI** (Ollama / Groq / Gemini) to automatically categorize transactions and generate spend analysis.
- **Durable Idempotency Engine**: Enforces exactly-once execution on mutation APIs via SHA-256 request payload hashing and persistent state checking.
- **Transactional Outbox Pattern**: Guarantees atomic consistency between state transitions and event streaming to Kafka without dual-write vulnerabilities.
- **Transactional Outbox Pattern**: Guarantees atomic consistency between state transitions and event streaming without dual-write vulnerabilities.
- **Pluggable Resilience Policies**: Configured via Resilience4j for client-side rate-limiting, exponential backoff retries with jitter, and call timeouts.
- **Telemetry & Observability**: Integrated with Spring Boot Actuator, Prometheus metrics, and Logback MDC-based distributed trace correlation.
- **Telemetry & Observability**: Integrated with Spring Boot Actuator, Prometheus metrics, Logback MDC-based distributed trace correlation, and Grafana dashboards.

---

## Project Documentation Directory

For complete details on the architecture, evolution, and APIs, refer to the following documents:

1. 📘 **[System Architecture Guide](docs/ARCHITECTURE.md)**: Deep technical details on locking, N+1 query resolution, API versioning, AI spends insights, Spring profiles, and observability.
1. 📘 **[System Architecture Guide](docs/ARCHITECTURE.md)**: Deep technical details on topology, locking, idempotency, Spring profiles, and observability.
2. 🗓️ **[Phased Implementation Roadmap](docs/ROADMAP.md)**: Subdivided step-by-step phases (A and B) spanning database migrations, security, event streaming, and deployment.
3. 🌐 **[REST API Specification](docs/API_SPECIFICATION.md)**: Complete request and response payload schemas, versioned endpoints, validations, status codes, and RFC 7807 error formats.
4. 📋 **[Engineering Conventions](docs/CONVENTIONS.md)**: Coding standards, Git commit conventions, PR guidelines, and test naming rules.
5. 📜 **[Architecture Decision Records](docs/ADR.md)**: Log of architectural decisions, context, trade-offs, and consequences.

---

## Spring Profiles Strategy

The application leverages profile isolation to adapt resources to the target environment dynamically:

- **`local` (Default)**: In-memory H2 database, automated hibernate schema updates, and mock environments. Excellent for standalone, dependency-free code exploration.
- **`test`**: Active during JUnit execution, utilizing **Testcontainers** to dynamically boot local Postgres/Kafka container instances for validation.
- **`local` (Default)**: In-memory H2 database, automated hibernate schema updates, and zero-dependency local startup.
- **`test`**: Active during integration tests, utilizing **Testcontainers** to dynamically boot local Postgres/Kafka container instances for validation.
- **`prod`**: Production-grade settings. Database credentials and broker addresses are read from system environment variables. Schema evolution is strictly managed by **Flyway migrations**.
- **`prod-light` (AWS Free Tier Optimization)**: Tailored for a single constrained AWS virtual server (1 GiB RAM). Plugs out heavy Redis/Kafka containers and replaces them with lightweight in-memory fallbacks to prevent Out-Of-Memory (OOM) failures.
- **`prod-light` (Resource Constrained / Free Tier)**: Memory-optimized profile for single constrained virtual servers (1 GiB RAM). Uses lightweight in-memory fallbacks for Redis and Kafka to prevent OOM failures.

---

## Quick Start

### 1. Build and Run Local Tests
Requires JDK 25 and Maven. This will trigger integration tests using Testcontainers (if a Docker daemon is active) or unit tests.
Requires JDK 25 and Maven:
```bash
mvn clean install
mvn test
Expand All @@ -58,11 +79,10 @@ mvn spring-boot:run
- *Credentials*: `user` / `user`

### 3. Local Full-Stack Ecosystem Startup (Docker Compose)
To run a realistic local staging environment containing Postgres, Redis, Kafka KRaft, Prometheus, and Grafana:
To run a local staging environment containing Postgres, Redis, Kafka KRaft, Prometheus, and Grafana:
```bash
docker-compose up --build
```
The Spring Boot instance connects to the docker network using environment variables specified in the compose file.

---

Expand All @@ -75,15 +95,20 @@ kubectl apply -f k8s/
```
- **Liveness Probe**: Routed to `/actuator/health/liveness`
- **Readiness Probe**: Routed to `/actuator/health/readiness`
- **Graceful Shutdown**: Handled via `server.shutdown=graceful` which coordinates with the container orchestration to process in-flight transactions before terminating the pod container.
- **Graceful Shutdown**: Handled via `server.shutdown=graceful` coordinating with container orchestration to process in-flight transactions before pod termination.

### GraalVM Native Compilation
To compile the application to a lightweight, platform-native binary that starts in milliseconds and consumes only ~30-50MB of RAM:
To compile the application to a lightweight, platform-native binary that starts in milliseconds and consumes ~30-50MB of RAM:
```bash
# Compile native binary locally
mvn -Pnative native:compile

# Or build an optimized native OCI image via Buildpacks
mvn -Pnative spring-boot:build-image
```
*Note: GraalVM native compiler tools must be installed locally on the host.*

---

## License

This project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.
55 changes: 55 additions & 0 deletions checkstyle.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">

<module name="Checker">
<property name="charset" value="UTF-8"/>
<property name="severity" value="error"/>
<property name="fileExtensions" value="java, properties, xml"/>

<!-- Excludes all 'target' and build directories -->
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="[/\\]target[/\\]"/>
</module>

<!-- Checks for Size Violations -->
<module name="LineLength">
<property name="fileExtensions" value="java"/>
<property name="max" value="120"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>

<module name="TreeWalker">
<!-- Naming Conventions -->
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
</module>
<module name="TypeName"/>
<module name="MemberName"/>
<module name="ParameterName"/>
<module name="LocalVariableName"/>
<module name="ClassTypeParameterName"/>
<module name="MethodTypeParameterName"/>
<module name="ConstantName"/>

<!-- Imports -->
<module name="AvoidStarImport">
<property name="excludes" value="org.junit.jupiter.api.Assertions.*,org.mockito.Mockito.*,org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*,org.springframework.test.web.servlet.result.MockMvcResultMatchers.*"/>
</module>
<module name="IllegalImport"/>
<module name="RedundantImport"/>
<module name="UnusedImports"/>

<!-- Class Design -->
<module name="OneTopLevelClass"/>
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>

<!-- Coding -->
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
</module>
</module>
Loading
Loading