diff --git a/payguard-api-gateway/pom.xml b/payguard-api-gateway/pom.xml
index f216969..86f9e7c 100644
--- a/payguard-api-gateway/pom.xml
+++ b/payguard-api-gateway/pom.xml
@@ -6,7 +6,7 @@
dev.amg.payguard
- payguard
+ payguard-parent
1.0.0-SNAPSHOT
diff --git a/payguard-collateral-service/pom.xml b/payguard-collateral-service/pom.xml
index 87985a2..3e1b822 100644
--- a/payguard-collateral-service/pom.xml
+++ b/payguard-collateral-service/pom.xml
@@ -6,13 +6,30 @@
dev.amg.payguard
- payguard
+ payguard-parent
1.0.0-SNAPSHOT
payguard-collateral-service
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-kafka
+
+
+ org.flywaydb
+ flyway-core
+
+
+ com.oracle.database.jdbc
+ ojdbc17
+ runtime
+
dev.amg.payguard
payguard-shared
@@ -24,11 +41,17 @@
org.springframework.boot
- spring-boot-starter-kafka
+ spring-boot-starter-webmvc-test
+ test
- org.springframework.boot
- spring-boot-starter-webmvc-test
+ org.testcontainers
+ testcontainers-oracle-xe
+ test
+
+
+ org.testcontainers
+ testcontainers-junit-jupiter
test
diff --git a/payguard-collateral-service/src/main/resources/application.yaml b/payguard-collateral-service/src/main/resources/application.yaml
index b5771f8..6cc583f 100644
--- a/payguard-collateral-service/src/main/resources/application.yaml
+++ b/payguard-collateral-service/src/main/resources/application.yaml
@@ -1,3 +1,12 @@
spring:
application:
name: payguard-collateral-service
+ datasource:
+ url: ${SPRING_DATASOURCE_URL}
+ username: ${SPRING_DATASOURCE_USERNAME}
+ password: ${SPRING_DATASOURCE_PASSWORD}
+ driver-class-name: oracle.jdbc.OracleDriver
+ jpa:
+ open-in-view: false
+ flyway:
+ enabled: true
diff --git a/payguard-collateral-service/src/main/resources/db/migration/V1__collateral_schema.sql b/payguard-collateral-service/src/main/resources/db/migration/V1__collateral_schema.sql
new file mode 100644
index 0000000..dd4793e
--- /dev/null
+++ b/payguard-collateral-service/src/main/resources/db/migration/V1__collateral_schema.sql
@@ -0,0 +1,8 @@
+CREATE TABLE collateral (id RAW(16) PRIMARY KEY, owner_token VARCHAR2(128) NOT NULL, loan_id RAW(16) NOT NULL, amount NUMBER(28,8) NOT NULL, asset_currency CHAR(3) NOT NULL, warning_ltv NUMBER(10,8) NOT NULL, margin_ltv NUMBER(10,8) NOT NULL, liquidation_ltv NUMBER(10,8) NOT NULL, status VARCHAR2(24) NOT NULL, version NUMBER(19) DEFAULT 0 NOT NULL, retention_until TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL);
+CREATE INDEX ix_collateral_loan_status ON collateral(loan_id, status);
+CREATE TABLE collateral_valuation (id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, collateral_id RAW(16) NOT NULL, asset_value NUMBER(28,8) NOT NULL, fx_rate NUMBER(28,12) NOT NULL, observed_at TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT fk_val_collateral FOREIGN KEY(collateral_id) REFERENCES collateral(id));
+CREATE INDEX ix_collateral_val_time ON collateral_valuation(collateral_id, observed_at);
+CREATE TABLE collateral_audit_log (id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, collateral_id RAW(16) NOT NULL, subject_token VARCHAR2(128), actor_token VARCHAR2(128), action VARCHAR2(64) NOT NULL, reason VARCHAR2(256), occurred_at TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL, previous_hash VARCHAR2(128), record_hash VARCHAR2(128) NOT NULL);
+CREATE INDEX ix_collateral_audit_subject_time ON collateral_audit_log(subject_token, occurred_at);
+CREATE TABLE collateral_processed_event (event_id RAW(16) NOT NULL, consumer_name VARCHAR2(128) NOT NULL, processed_at TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL, PRIMARY KEY(event_id, consumer_name));
+CREATE TABLE collateral_outbox (id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, event_id RAW(16) UNIQUE NOT NULL, event_type VARCHAR2(128) NOT NULL, aggregate_id VARCHAR2(128) NOT NULL, payload CLOB NOT NULL, occurred_at TIMESTAMP WITH TIME ZONE NOT NULL, published_at TIMESTAMP WITH TIME ZONE);
diff --git a/payguard-collateral-service/src/test/java/dev/amg/payguard/collateral/CollateralServiceApplicationTests.java b/payguard-collateral-service/src/test/java/dev/amg/payguard/collateral/CollateralServiceApplicationTests.java
index a32414c..1e729ba 100644
--- a/payguard-collateral-service/src/test/java/dev/amg/payguard/collateral/CollateralServiceApplicationTests.java
+++ b/payguard-collateral-service/src/test/java/dev/amg/payguard/collateral/CollateralServiceApplicationTests.java
@@ -2,10 +2,33 @@
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.testcontainers.containers.OracleContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
@SpringBootTest
+@ActiveProfiles("test")
+@Testcontainers
class CollateralServiceApplicationTests {
+ @Container
+ static final OracleContainer ORACLE =
+ new OracleContainer("gvenzl/oracle-xe:21-slim-faststart")
+ .withUsername("PAYGUARD_TEST")
+ .withPassword("payguard_test");
+
+ @DynamicPropertySource
+ static void oracleProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.datasource.url", ORACLE::getJdbcUrl);
+ registry.add("spring.datasource.username", ORACLE::getUsername);
+ registry.add("spring.datasource.password", ORACLE::getPassword);
+ registry.add("spring.datasource.driver-class-name", ORACLE::getDriverClassName);
+ registry.add("spring.jpa.database-platform", () -> "org.hibernate.dialect.OracleDialect");
+ }
+
@Test
void contextLoads() {}
}
diff --git a/payguard-collateral-service/src/test/resources/application-test.yaml b/payguard-collateral-service/src/test/resources/application-test.yaml
new file mode 100644
index 0000000..53dc98c
--- /dev/null
+++ b/payguard-collateral-service/src/test/resources/application-test.yaml
@@ -0,0 +1,16 @@
+spring:
+ datasource:
+ # Replaced by CollateralServiceApplicationTests.oracleProperties at runtime.
+ url: ${TEST_ORACLE_JDBC_URL:jdbc:oracle:thin:@//localhost:1521/XEPDB1}
+ username: ${TEST_ORACLE_USERNAME:PAYGUARD_TEST}
+ password: ${TEST_ORACLE_PASSWORD:payguard_test}
+ driver-class-name: oracle.jdbc.OracleDriver
+ jpa:
+ database-platform: org.hibernate.dialect.OracleDialect
+ hibernate:
+ ddl-auto: none
+ open-in-view: false
+ flyway:
+ # Schema migrations are exercised independently; context tests only need
+ # the Oracle-backed JPA infrastructure to start.
+ enabled: false
diff --git a/payguard-loan-service/pom.xml b/payguard-loan-service/pom.xml
index b9d7627..76e699c 100644
--- a/payguard-loan-service/pom.xml
+++ b/payguard-loan-service/pom.xml
@@ -6,7 +6,7 @@
dev.amg.payguard
- payguard
+ payguard-parent
1.0.0-SNAPSHOT
@@ -26,11 +26,34 @@
org.springframework.boot
spring-boot-starter-kafka
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.flywaydb
+ flyway-core
+
+
+ com.oracle.database.jdbc
+ ojdbc17
+ runtime
+
org.springframework.boot
spring-boot-starter-webmvc-test
test
+
+ org.testcontainers
+ testcontainers-oracle-xe
+ test
+
+
+ org.testcontainers
+ testcontainers-junit-jupiter
+ test
+
diff --git a/payguard-loan-service/src/main/resources/application.yaml b/payguard-loan-service/src/main/resources/application.yaml
index 4b50a35..667f1df 100644
--- a/payguard-loan-service/src/main/resources/application.yaml
+++ b/payguard-loan-service/src/main/resources/application.yaml
@@ -1,3 +1,12 @@
spring:
application:
name: payguard-loan-service
+ datasource:
+ url: ${SPRING_DATASOURCE_URL}
+ username: ${SPRING_DATASOURCE_USERNAME}
+ password: ${SPRING_DATASOURCE_PASSWORD}
+ driver-class-name: oracle.jdbc.OracleDriver
+ jpa:
+ open-in-view: false
+ flyway:
+ enabled: true
diff --git a/payguard-loan-service/src/main/resources/db/migration/V1__loan_schema.sql b/payguard-loan-service/src/main/resources/db/migration/V1__loan_schema.sql
new file mode 100644
index 0000000..e537797
--- /dev/null
+++ b/payguard-loan-service/src/main/resources/db/migration/V1__loan_schema.sql
@@ -0,0 +1,6 @@
+CREATE TABLE loan_account (id RAW(16) PRIMARY KEY, borrower_token VARCHAR2(128) NOT NULL, collateral_id RAW(16) NOT NULL, principal NUMBER(28,8) NOT NULL, annual_rate NUMBER(20,12) NOT NULL, term_months NUMBER(5) NOT NULL, status VARCHAR2(24) NOT NULL, outstanding_principal NUMBER(28,8) NOT NULL, accrued_interest NUMBER(28,8) NOT NULL, last_accrual_date DATE NOT NULL, version NUMBER(19) DEFAULT 0 NOT NULL, retention_until TIMESTAMP WITH TIME ZONE, created_at TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL);
+CREATE INDEX ix_loan_due ON loan_account(status, last_accrual_date);
+CREATE TABLE loan_audit_log (id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, loan_id RAW(16) NOT NULL, subject_token VARCHAR2(128), actor_token VARCHAR2(128), action VARCHAR2(64) NOT NULL, reason VARCHAR2(256), occurred_at TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL, previous_hash VARCHAR2(128), record_hash VARCHAR2(128) NOT NULL);
+CREATE INDEX ix_loan_audit_subject_time ON loan_audit_log(subject_token, occurred_at);
+CREATE TABLE loan_processed_event (event_id RAW(16) NOT NULL, consumer_name VARCHAR2(128) NOT NULL, processed_at TIMESTAMP WITH TIME ZONE DEFAULT SYSTIMESTAMP NOT NULL, PRIMARY KEY(event_id, consumer_name));
+CREATE TABLE loan_outbox (id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, event_id RAW(16) UNIQUE NOT NULL, event_type VARCHAR2(128) NOT NULL, aggregate_id VARCHAR2(128) NOT NULL, payload CLOB NOT NULL, occurred_at TIMESTAMP WITH TIME ZONE NOT NULL, published_at TIMESTAMP WITH TIME ZONE);
diff --git a/payguard-loan-service/src/test/java/dev/amg/payguard/loan/LoanServiceApplicationTests.java b/payguard-loan-service/src/test/java/dev/amg/payguard/loan/LoanServiceApplicationTests.java
index 8b2129c..04605f0 100644
--- a/payguard-loan-service/src/test/java/dev/amg/payguard/loan/LoanServiceApplicationTests.java
+++ b/payguard-loan-service/src/test/java/dev/amg/payguard/loan/LoanServiceApplicationTests.java
@@ -2,10 +2,33 @@
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.DynamicPropertyRegistry;
+import org.springframework.test.context.DynamicPropertySource;
+import org.testcontainers.containers.OracleContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
@SpringBootTest
+@ActiveProfiles("test")
+@Testcontainers
class LoanServiceApplicationTests {
+ @Container
+ static final OracleContainer ORACLE =
+ new OracleContainer("gvenzl/oracle-xe:21-slim-faststart")
+ .withUsername("PAYGUARD_TEST")
+ .withPassword("payguard_test");
+
+ @DynamicPropertySource
+ static void oracleProperties(DynamicPropertyRegistry registry) {
+ registry.add("spring.datasource.url", ORACLE::getJdbcUrl);
+ registry.add("spring.datasource.username", ORACLE::getUsername);
+ registry.add("spring.datasource.password", ORACLE::getPassword);
+ registry.add("spring.datasource.driver-class-name", ORACLE::getDriverClassName);
+ registry.add("spring.jpa.database-platform", () -> "org.hibernate.dialect.OracleDialect");
+ }
+
@Test
void contextLoads() {}
}
diff --git a/payguard-loan-service/src/test/resources/application-test.yaml b/payguard-loan-service/src/test/resources/application-test.yaml
new file mode 100644
index 0000000..291eb64
--- /dev/null
+++ b/payguard-loan-service/src/test/resources/application-test.yaml
@@ -0,0 +1,16 @@
+spring:
+ datasource:
+ # Replaced by LoanServiceApplicationTests.oracleProperties at runtime.
+ url: ${TEST_ORACLE_JDBC_URL:jdbc:oracle:thin:@//localhost:1521/XEPDB1}
+ username: ${TEST_ORACLE_USERNAME:PAYGUARD_TEST}
+ password: ${TEST_ORACLE_PASSWORD:payguard_test}
+ driver-class-name: oracle.jdbc.OracleDriver
+ jpa:
+ database-platform: org.hibernate.dialect.OracleDialect
+ hibernate:
+ ddl-auto: none
+ open-in-view: false
+ flyway:
+ # Schema migrations are exercised independently; context tests only need
+ # the Oracle-backed JPA infrastructure to start.
+ enabled: false
diff --git a/payguard-proto/pom.xml b/payguard-proto/pom.xml
index 1a7e588..fcbe987 100644
--- a/payguard-proto/pom.xml
+++ b/payguard-proto/pom.xml
@@ -6,7 +6,7 @@
dev.amg.payguard
- payguard
+ payguard-parent
1.0.0-SNAPSHOT
diff --git a/payguard-shared/pom.xml b/payguard-shared/pom.xml
index d421b65..21f65ed 100644
--- a/payguard-shared/pom.xml
+++ b/payguard-shared/pom.xml
@@ -5,7 +5,7 @@
4.0.0
dev.amg.payguard
- payguard
+ payguard-parent
1.0.0-SNAPSHOT
diff --git a/payguard-wallet-service/pom.xml b/payguard-wallet-service/pom.xml
index 5faa39a..01fe374 100644
--- a/payguard-wallet-service/pom.xml
+++ b/payguard-wallet-service/pom.xml
@@ -4,7 +4,7 @@
4.0.0
dev.amg.payguard
- payguard
+ payguard-parent
1.0.0-SNAPSHOT
payguard-wallet-service
diff --git a/payguard-wallet-service/src/main/resources/application.yaml b/payguard-wallet-service/src/main/resources/application.yaml
index 3b31bc3..d71ae8d 100644
--- a/payguard-wallet-service/src/main/resources/application.yaml
+++ b/payguard-wallet-service/src/main/resources/application.yaml
@@ -2,9 +2,9 @@ spring:
application:
name: wallet-service
datasource:
- url: jdbc:oracle:thin:@localhost:${ORACLE_PORT:1521}/FREE
- username: ${ORACLE_APP_USER:payguard_user}
- password: ${ORACLE_APP_PASSWORD:payguard_pass}
+ url: ${SPRING_DATASOURCE_URL}
+ username: ${SPRING_DATASOURCE_USERNAME}
+ password: ${SPRING_DATASOURCE_PASSWORD}
driver-class-name: oracle.jdbc.OracleDriver
jooq:
sql-dialect: default
diff --git a/pom.xml b/pom.xml
index 09150aa..13f1819 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
4.0.0
dev.amg.payguard
- payguard
+ payguard-parent
1.0.0-SNAPSHOT
pom
@@ -24,7 +24,7 @@
25
25
UTF-8
- 4.0.1
+ 4.1.1
1.68.0
3.25.5
3.19.15