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
Binary file added core/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
94 changes: 94 additions & 0 deletions core/gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

85 changes: 85 additions & 0 deletions core/src/main/java/com/opencontext/common/CommonResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.opencontext.common;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;

import java.time.LocalDateTime;

/**
* Standard API response structure class.
* Handles success and failure responses in a consistent format to simplify client response processing.
*
* This class should only be created through static factory methods,
* preventing direct constructor usage to ensure API response consistency.
*/
@Schema(description = "Standard API response structure")
@Getter
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CommonResponse<T> {

@Schema(description = "Request success status", example = "true")
private final boolean success;

@Schema(description = "Response data (null on failure)")
private final T data;

@Schema(description = "Message to display to user", example = "Request processed successfully.")
private final String message;

@Schema(description = "Error code (null on success)", example = "VALIDATION_FAILED")
private final String errorCode;

@Schema(description = "Response creation timestamp", example = "2025-08-07T12:00:00")
private final LocalDateTime timestamp;

/**
* Private constructor. Only allows instance creation through static factory methods.
*/
private CommonResponse(boolean success, T data, String message, String errorCode, LocalDateTime timestamp) {
this.success = success;
this.data = data;
this.message = message;
this.errorCode = errorCode;
this.timestamp = timestamp;
}

/**
* Static factory method for creating success responses.
*/
public static <T> CommonResponse<T> success(T data) {
return new CommonResponse<>(
true,
data,
"Request processed successfully.",
null,
LocalDateTime.now()
);
}

/**
* Static factory method for creating success responses with custom message.
*/
public static <T> CommonResponse<T> success(T data, String message) {
return new CommonResponse<>(
true,
data,
message,
null,
LocalDateTime.now()
);
}

/**
* Static factory method for creating error responses.
*/
public static <T> CommonResponse<T> error(String message, String errorCode) {
return new CommonResponse<>(
false,
null,
message,
errorCode,
LocalDateTime.now()
);
}
}
85 changes: 85 additions & 0 deletions core/src/main/java/com/opencontext/common/PageResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.opencontext.common;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.domain.Page;

import java.util.List;

/**
* Paginated list response DTO.
* Converts Spring Data Page objects into a client-friendly format.
*/
@Schema(description = "Paginated list response DTO")
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class PageResponse<T> {

@Schema(description = "Data list for current page")
private List<T> content;

@Schema(description = "Current page number (zero-based)", example = "0")
private int page;

@Schema(description = "Number of items per page", example = "10")
private int size;

@Schema(description = "Total number of items", example = "100")
private long totalElements;

@Schema(description = "Total number of pages", example = "10")
private int totalPages;

@Schema(description = "Whether this is the first page", example = "true")
private boolean first;

@Schema(description = "Whether this is the last page", example = "false")
private boolean last;

@Schema(description = "Whether there is a next page", example = "true")
private boolean hasNext;

@Schema(description = "Whether there is a previous page", example = "false")
private boolean hasPrevious;

/**
* Static factory method to convert Page object to PageResponse DTO.
*/
public static <T> PageResponse<T> from(Page<T> page) {
return PageResponse.<T>builder()
.content(page.getContent())
.page(page.getNumber())
.size(page.getSize())
.totalElements(page.getTotalElements())
.totalPages(page.getTotalPages())
.first(page.isFirst())
.last(page.isLast())
.hasNext(page.hasNext())
.hasPrevious(page.hasPrevious())
.build();
}

/**
* Static factory method to convert Page object with custom content to PageResponse DTO.
*/
public static <T> PageResponse<T> from(Page<T> page, List<T> content) {
return PageResponse.<T>builder()
.content(content)
.page(page.getNumber())
.size(page.getSize())
.totalElements(page.getTotalElements())
.totalPages(page.getTotalPages())
.first(page.isFirst())
.last(page.isLast())
.hasNext(page.hasNext())
.hasPrevious(page.hasPrevious())
.build();
}
}

49 changes: 49 additions & 0 deletions core/src/main/java/com/opencontext/config/AsyncConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.opencontext.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

/**
* Asynchronous processing configuration.
* Configuration for executing heavy operations like document ingestion pipeline
* in separate threads.
*/
@Configuration
@EnableAsync
public class AsyncConfig {

/**
* Dedicated thread pool configuration for document ingestion pipeline.
*/
@Bean(name = "ingestionTaskExecutor")
public Executor ingestionTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(2); // Number of concurrent document ingestion tasks
executor.setMaxPoolSize(4); // Maximum number of threads
executor.setQueueCapacity(10); // Queue capacity for waiting tasks
executor.setThreadNamePrefix("ingestion-");
executor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}

/**
* Default thread pool configuration for general asynchronous tasks.
*/
@Bean(name = "taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4);
executor.setMaxPoolSize(8);
executor.setQueueCapacity(20);
executor.setThreadNamePrefix("async-");
executor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}

14 changes: 14 additions & 0 deletions core/src/main/java/com/opencontext/config/JpaAuditingConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.opencontext.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

/**
* JPA Auditing configuration.
* Enables automatic field updates for @CreatedDate, @LastModifiedDate, etc.
* in entities with @EntityListeners(AuditingEntityListener.class).
*/
@Configuration
@EnableJpaAuditing
public class JpaAuditingConfig {
}
28 changes: 28 additions & 0 deletions core/src/main/java/com/opencontext/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.opencontext.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
* Web-related configuration.
* Handles web-related settings such as CORS, interceptors, resource handlers, etc.
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {

/**
* CORS configuration.
* Allows CORS for communication with frontend in development environment.
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOriginPatterns("*") // Allow all origins in development environment
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS","PATCH")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}

Loading