diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b9093b6..9567aee 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,8 +2,22 @@ name: CI
on:
push:
branches: [develop]
+ paths-ignore:
+ - '**.md'
+ - 'docs/**'
+ - 'tutorials/**'
+ - 'examples/**/README.md'
+ - 'LICENSE'
+ - '.gitignore'
pull_request:
branches: [develop, main]
+ paths-ignore:
+ - '**.md'
+ - 'docs/**'
+ - 'tutorials/**'
+ - 'examples/**/README.md'
+ - 'LICENSE'
+ - '.gitignore'
workflow_dispatch:
inputs:
triggered-by:
@@ -13,10 +27,5 @@ on:
jobs:
build:
uses: fireflyframework/.github/.github/workflows/java-ci.yml@main
- permissions:
- packages: read
- contents: read
- actions: write
with:
java-version: '25'
- secrets: inherit
diff --git a/README.md b/README.md
index 779a0fe..5e52cfc 100644
--- a/README.md
+++ b/README.md
@@ -1,388 +1,98 @@
-# Firefly R2DBC Common Library
+# Firefly Framework - R2DBC
[](https://github.com/fireflyframework/fireflyframework-r2dbc/actions/workflows/ci.yml)
+[](LICENSE)
+[](https://openjdk.org)
+[](https://spring.io/projects/spring-boot)
-A comprehensive reactive database connectivity library for the Firefly platform, providing advanced filtering, pagination, and transaction management capabilities for Spring Data R2DBC applications.
+> Reactive database access module with R2DBC, pagination, filtering, and Swagger integration for Spring Boot applications.
-## Overview
-
-The fireflyframework-r2dbc library is a core component of the Firefly platform that provides powerful utilities for working with reactive database connections using Spring Data R2DBC. It simplifies common database operations with a focus on:
-
-- **Reactive Programming**: Built on Project Reactor for non-blocking database operations
-- **Advanced Filtering**: Flexible and type-safe filtering capabilities
-- **Pagination**: Standardized pagination with sorting support
-- **Transaction Management**: Simplified R2DBC transaction handling
-- **PostgreSQL Support**: Optimized for PostgreSQL databases
-- **OpenAPI Integration**: Automatic API documentation for filter and pagination models
-
-## Features
+---
-### Reactive Filtering
+## Table of Contents
-The library provides a powerful filtering system that supports:
+- [Overview](#overview)
+- [Features](#features)
+- [Requirements](#requirements)
+- [Installation](#installation)
+- [Quick Start](#quick-start)
+- [Configuration](#configuration)
+- [Documentation](#documentation)
+- [Contributing](#contributing)
+- [License](#license)
-- **String Filtering**: Case-sensitive or case-insensitive LIKE queries
-- **Numeric/Boolean Filtering**: Exact match filtering for numeric and boolean values
-- **ID Field Handling**: Special handling for ID fields with @FilterableId annotation support
-- **Range Filtering**: Between, greater-than, and less-than operations for numeric and date fields
-- **Collection/Array Filtering**: Support for filtering on collection and array fields
-- **Null/Not-Null Filtering**: Explicit filtering for NULL or NOT NULL values
-- **Performance Optimization**: Field reflection caching for better performance
+## Overview
-### Pagination
+Firefly Framework R2DBC provides reactive database connectivity using Spring Data R2DBC with PostgreSQL. It includes auto-configuration for R2DBC connections, transaction management, and a set of utility classes for pagination and dynamic filtering.
-Standardized pagination support with:
+The module also bundles Swagger/OpenAPI configuration for documenting reactive API endpoints, and provides reusable filter utilities that enable dynamic query construction based on request parameters.
-- **Page Size and Number**: Control the number of results per page
-- **Sorting**: Sort by any field with ascending or descending direction
-- **Total Count**: Automatic calculation of total results
-- **Consistent Response Format**: Standardized response structure
+This module is typically used by domain and data-layer microservices that require non-blocking database access.
-### Transaction Management
+## Features
-Simplified transaction management for R2DBC operations.
+- Spring Data R2DBC auto-configuration with PostgreSQL
+- Reactive transaction management via `R2dbcTransactionConfig`
+- `PaginationRequest` / `PaginationResponse` utilities for standardized pagination
+- `FilterRequest` and `FilterUtils` for dynamic query filtering
+- `RangeFilter` for range-based query parameters
+- `@FilterableId` annotation support via `FilterParameterCustomizer`
+- Swagger/OpenAPI configuration for WebFlux endpoints
+- Spring Boot auto-configuration via `AutoConfiguration.imports`
-### OpenAPI Documentation
+## Requirements
-Automatic generation of OpenAPI documentation for filter and pagination models. The library includes a `FilterParameterCustomizer` that enhances Swagger/OpenAPI documentation with detailed query parameters for all filtering capabilities.
+- Java 21+
+- Spring Boot 3.x
+- Maven 3.9+
+- PostgreSQL database
## Installation
-### Maven
-
-Add the following dependency to your `pom.xml`:
-
```xml
org.fireflyframework
fireflyframework-r2dbc
- 1.0.0-SNAPSHOT
+ 26.01.01
```
-### Repository Configuration
-
-Ensure you have access to the GitHub Packages repository:
-
-```xml
-
-
- github
- GitHub Packages
- https://maven.pkg.github.org/fireflyframework-oss/fireflyframework-r2dbc
-
-
-```
-
-## Usage
-
-### Basic Configuration
-
-The library auto-configures itself when included in a Spring Boot application. Make sure your application has the necessary R2DBC connection properties:
-
-```yaml
-spring:
- r2dbc:
- url: r2dbc:postgresql://localhost:5432/your_database
- username: your_username
- password: your_password
-```
-
-### Creating a Filter
-
-1. Create an entity class:
-
-```java
-@Data
-@Table("users")
-public class User {
- @Id
- private Long id;
-
- private String name;
- private String email;
- private Boolean active;
- private LocalDateTime createdDate;
-}
-```
-
-2. Create a filter class for your entity:
+## Quick Start
```java
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class UserFilter {
- // Use @FilterableId to make ID fields filterable
- @FilterableId
- private Long id;
+import org.fireflyframework.core.queries.PaginationRequest;
+import org.fireflyframework.core.queries.PaginationResponse;
- private String name;
- private String email;
- private Boolean active;
-}
-```
-
-3. Create a controller endpoint that uses the filtering utilities:
-
-```java
@RestController
-@RequestMapping("/api/users")
-public class UserController {
- private final UserRepository userRepository;
- private final UserMapper userMapper;
-
- @PostMapping("/filter")
- public Mono> filterUsers(@RequestBody FilterRequest request) {
- // Create a filter for the User entity
- GenericFilter filter =
- FilterUtils.createFilter(User.class, userMapper::toDto);
+public class ProductController {
- // Apply the filter and return paginated results
- return filter.filter(request);
+ @GetMapping("/products")
+ public Mono> list(PaginationRequest pagination) {
+ return productService.findAll(pagination);
}
}
```
-### Filter Request Examples
-
-#### Basic Filtering
-
-```java
-// Create a filter request with basic filters
-FilterRequest request = FilterRequest.builder()
- .filters(new UserFilter(null, "John", "john@example.com", true))
- .pagination(new PaginationRequest(0, 10, "name", "ASC"))
- .build();
-```
-
-#### Range Filtering
-
-```java
-// Create a filter request with range filters
-FilterRequest request = FilterRequest.builder()
- .filters(new UserFilter("John", null, true))
- .rangeFilters(RangeFilter.builder()
- .ranges(Map.of(
- "createdDate", new RangeFilter.Range<>(
- LocalDateTime.now().minusDays(30),
- LocalDateTime.now()
- ),
- "balance", new RangeFilter.Range<>(
- 1000.0,
- 5000.0
- )
- ))
- .build())
- .pagination(new PaginationRequest(0, 10, "name", "ASC"))
- .build();
-```
-
-#### Case-Insensitive String Filtering
-
-```java
-// Create a filter request with case-insensitive string filtering
-FilterRequest request = FilterRequest.builder()
- .filters(new UserFilter("john", null, true))
- .options(FilterUtils.FilterOptions.builder()
- .caseInsensitiveStrings(true)
- .build())
- .pagination(new PaginationRequest(0, 10, "name", "ASC"))
- .build();
-```
-
-#### Collection/Array Filtering
-
-```java
-// Create a filter with collection values
-UserFilter filter = new UserFilter();
-filter.setRoles(Arrays.asList("ADMIN", "MANAGER"));
-filter.setTags(new String[]{"important", "urgent"});
-
-FilterRequest request = FilterRequest.builder()
- .filters(filter)
- .pagination(new PaginationRequest(0, 10, "name", "ASC"))
- .build();
-```
-
-#### Null/Not Null Filtering
+## Configuration
-```java
-// Create a filter to find users with null email
-UserFilter filter = new UserFilter();
-filter.setEmail(FilterRequest.NULL_VALUE);
-
-// Create a filter to find users with non-null phone
-UserFilter anotherFilter = new UserFilter();
-anotherFilter.setPhone(FilterRequest.NOT_NULL_VALUE);
-
-FilterRequest request = FilterRequest.builder()
- .filters(filter)
- .pagination(new PaginationRequest(0, 10, "name", "ASC"))
- .build();
-```
-
-#### Combining Multiple Filter Types
-
-```java
-// Create a complex filter combining different filter types
-UserFilter filter = new UserFilter();
-filter.setName("john");
-filter.setActive(true);
-filter.setRoles(Arrays.asList("ADMIN", "MANAGER"));
-filter.setEmail(FilterRequest.NOT_NULL_VALUE);
-
-Map> ranges = new HashMap<>();
-ranges.put("createdDate", new RangeFilter.Range<>(
- LocalDateTime.now().minusDays(30),
- LocalDateTime.now()
-));
-ranges.put("lastLoginDate", new RangeFilter.Range<>(
- LocalDateTime.now().minusDays(7),
- null // Only specify lower bound
-));
-
-FilterRequest request = FilterRequest.builder()
- .filters(filter)
- .rangeFilters(RangeFilter.builder().ranges(ranges).build())
- .options(FilterUtils.FilterOptions.builder()
- .caseInsensitiveStrings(true)
- .includeInheritedFields(true)
- .build())
- .pagination(new PaginationRequest(0, 10, "name", "ASC"))
- .build();
-```
-
-### Pagination Example
-
-```java
-// Create a pagination request
-PaginationRequest paginationRequest = new PaginationRequest();
-paginationRequest.setPageNumber(0);
-paginationRequest.setPageSize(20);
-paginationRequest.setSortBy("lastName");
-paginationRequest.setSortDirection("ASC");
-
-// Use PaginationUtils to paginate a query
-Mono> result = PaginationUtils.paginateQuery(
- paginationRequest,
- userMapper::toDto,
- pageable -> userRepository.findAll(pageable),
- () -> userRepository.count()
-);
-```
-
-## OpenAPI Documentation
-
-The library includes comprehensive Swagger/OpenAPI support for all filter and pagination models. When used in a Spring Boot application with SpringDoc OpenAPI, the models and query parameters will be automatically documented.
-
-### Setup
-
-To enable Swagger UI, add the following dependency to your project:
-
-```xml
-
- org.springdoc
- springdoc-openapi-starter-webflux-ui
- ${springdoc.version}
-
-```
-
-### Automatic Query Parameter Documentation
-
-The `FilterParameterCustomizer` class automatically enhances your OpenAPI documentation with detailed query parameters for all filtering capabilities:
-
-- **Pagination Parameters**: `pagination.pageNumber`, `pagination.pageSize`, `pagination.sortBy`, `pagination.sortDirection`
-- **Filter Parameters**: `filters.` for each field in your filter class
-- **Range Filter Parameters**: `rangeFilters.ranges[].from` and `rangeFilters.ranges[].to` for numeric and date fields
-- **Filter Options**: `options.caseInsensitiveStrings`, `options.includeInheritedFields`
-
-### Example
-
-When you annotate your controller method with `@ParameterObject` or `@ModelAttribute`:
-
-```java
-@GetMapping("/filter")
-public Mono> filterUsers(
- @ParameterObject FilterRequest request) {
- // Implementation
-}
-```
-
-The OpenAPI documentation will automatically include all the filter parameters:
-
-```
-GET /api/users/filter?
- pagination.pageNumber=0&
- pagination.pageSize=10&
- filters.name=John&
- rangeFilters.ranges[createdDate].from=2023-01-01T00:00:00&
- options.caseInsensitiveStrings=true
-```
-
-## Troubleshooting
-
-### Common Issues and Solutions
-
-#### No Results When Filtering
-
-**Issue**: Filter is applied but no results are returned when you expect matches.
-
-**Possible causes and solutions**:
-- **Case sensitivity**: String filters are case-sensitive by default. Use the `caseInsensitiveStrings` option if you need case-insensitive matching.
-- **ID fields**: ID fields are excluded from filtering by default unless annotated with `@FilterableId`.
-- **Null values**: Regular filters skip null values. Use `FilterRequest.NULL_VALUE` to explicitly filter for null values.
-
-#### Performance Issues
-
-**Issue**: Filtering operations are slow, especially with large datasets.
-
-**Possible solutions**:
-- Ensure database indexes are created for commonly filtered fields
-- Use pagination with reasonable page sizes
-- Consider using range filters instead of collection filters for large datasets
-- The library uses field reflection caching to improve performance, but complex filter objects might still impact performance
-
-#### Error: "R2dbcEntityTemplate not initialized"
-
-**Issue**: `IllegalStateException: R2dbcEntityTemplate not initialized` when using FilterUtils.
-
-**Solution**: Call `FilterUtils.initializeTemplate(entityTemplate)` in your application configuration before using any filtering functionality.
-
-```java
-@Configuration
-public class AppConfig {
- @Autowired
- private R2dbcEntityTemplate entityTemplate;
-
- @PostConstruct
- public void init() {
- FilterUtils.initializeTemplate(entityTemplate);
- }
-}
+```yaml
+spring:
+ r2dbc:
+ url: r2dbc:postgresql://localhost:5432/mydb
+ username: user
+ password: secret
```
-#### Issues with Inherited Fields
+## Documentation
-**Issue**: Fields from parent classes are not included in filtering.
+No additional documentation available for this project.
-**Solution**: Use the `includeInheritedFields` option to include fields from parent classes.
+## Contributing
-```java
-FilterRequest request = FilterRequest.builder()
- .filters(filter)
- .options(FilterUtils.FilterOptions.builder()
- .includeInheritedFields(true)
- .build())
- .build();
-```
+Contributions are welcome. Please read the [CONTRIBUTING.md](CONTRIBUTING.md) guide for details on our code of conduct, development process, and how to submit pull requests.
-## Contributing
+## License
-Contributions to the fireflyframework-r2dbc library are welcome. Please follow these steps:
+Copyright 2024-2026 Firefly Software Solutions Inc.
-1. Fork the repository
-2. Create a feature branch (`git checkout -b feature/your-feature`)
-3. Commit your changes (`git commit -am 'Add some feature'`)
-4. Push to the branch (`git push origin feature/your-feature`)
-5. Create a new Pull Request
+Licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.