Feature/project fixes and improvements - #2
Merged
Conversation
…teway auth-service JwtTokenProvider was using Base64.decode() while api-gateway used hex decoding for the same JWT_SECRET env var. Tokens issued by auth-service were silently failing validation at the gateway. Fixed by replacing Decoders.BASE64 with hexStringToByteArray() in JwtTokenProvider — same logic the gateway already uses.
…ledEvent Saga compensation was incomplete — reserved stock was never returned when payment or shipment failed, permanently locking inventory. Added PaymentFailedEvent and ShipmentFailedEvent listeners to InventorySagaHandler. Both call cancelReservation() which restores available stock. Errors are caught per-message to avoid blocking the Kafka partition.
kafka:9092 and postgres:5432 were hardcoded, breaking local development outside Docker. Replaced with env-var driven config matching every other service pattern: DB_HOST, DB_PORT, KAFKA_BOOTSTRAP_SERVERS. Also added HikariCP pool config and actuator/prometheus exposure.
Each Dockerfile uses eclipse-temurin:21-jdk-alpine as builder and eclipse-temurin:21-jre-alpine as runtime. Non-root user for security. JVM flags: UseContainerSupport, MaxRAMPercentage=75. Also added .dockerignore to exclude target/, .git, .env from context.
Added Job2 (docker-publish): matrix build of all 15 services in parallel, pushed to ghcr.io on main branch only. Tags: sha-, latest, semver. BuildKit layer caching for fast incremental builds. Added Job3 (security-scan): Trivy SARIF scan on 4 critical services. Job1 (build+test) runs on every push and PR as before.
Added springdoc version to parent pom dependencyManagement.
webmvc-ui added to all 13 servlet services, webflux-ui to api-gateway.
Shared OpenApiConfig in common-library auto-registered via
AutoConfiguration.imports — adds JWT Bearer security scheme to every
service Swagger UI automatically.
Gateway aggregates all service docs at /swagger-ui.html with
/v3/api-docs/{service} proxy routes per service.
… order-service OrderServiceImpl now writes OutboxEvent in the same @transactional as the Order save — eliminating the dual-write race condition where Kafka could fail after DB commit, silently dropping the event. OutboxPublisher polls every 5s, retries up to 5 times, marks FAILED after max retries. Nightly cleanup removes published events older than 7d. @EnableScheduling added to OrderServiceApplication.
JwtTokenProvider now adds jti (UUID) claim to every token. TokenBlacklistService stores jti in Redis with TTL = token remaining lifetime. AuthService.logout() blacklists the access token AND revokes refresh token. AuthController.logout() reads Bearer token from Authorization header. JwtAuthFilter (gateway) does reactive Redis hasKey check — fails open if Redis is down to avoid blocking all traffic.
KafkaConsumerHealthIndicator in common-library auto-registers via AutoConfiguration.imports. Uses @ConditionalOnBean(KafkaAdmin.class) so non-Kafka services (cart, product, user) are unaffected. Exposes /actuator/health/kafka with clusterId, brokerCount, broker list. 3-second timeout prevents blocking the health check thread.
Kafka lag exporter: - kafka-lag-exporter in docker-compose monitors all 7 consumer groups - kafka-lag-exporter.conf polls every 30s, exposes metrics on :8000 - Prometheus scrape job added for kafka-lag-exporter Alertmanager: - alertmanager in docker-compose on port 9093 - alertmanager.yml: SMTP + Slack receivers, routing tree (critical/payment/default) - Inhibition rules suppress warnings when critical fires for same job - Prometheus alerting block wired to alertmanager:9093
Access logging (AccessLogFilter): - GlobalFilter runs on every request (HIGHEST_PRECEDENCE+1) - Logs method, path, status, durationMs, userId, traceId via LogPublisher - ERROR for 5xx, WARN for 4xx, INFO for everything else - Added common-library + spring-kafka deps to api-gateway pom Role-based auth (RoleAuthorizationFilter): - GatewayFilterFactory reads X-User-Role injected by JwtAuthFilter - Returns 403 with JSON if role not in allowed list - Applied: /api/v1/admin/sellers/** and /api/v1/logs/** require ROLE_ADMIN SecurityConfig updated to permit /swagger-ui and /v3/api-docs paths.
Added append-only order_events table. Every status change writes an
immutable OrderEvent row in the same transaction as the Order update.
OrderEvent stores: orderId, correlationId, eventType, previousStatus,
newStatus, triggeredBy, details, occurredAt (immutable).
OrderEventService: append(), getHistory(), getByCorrelationId(),
rebuildCurrentStatus() for audit/reconciliation.
GET /api/v1/orders/{id}/history endpoint returns full audit trail.
OrderStatusEmitter holds ConcurrentHashMap of orderId -> SseEmitter.
subscribe() creates emitter with 5-min timeout and cleanup handlers.
push() sends status-update events; completes stream on terminal states.
GET /api/v1/orders/{id}/status-stream streams status changes as they
happen through the saga — no polling needed by the client.
OrderSagaStateMachineConfig defines all saga transitions explicitly (PENDING→INVENTORY_CHECKING→PAYMENT_PROCESSING→SHIPPED→COMPLETED + failure/compensation paths). OrderSagaOrchestrator drives the state machine per order, loading current state from DB each time (crash-safe). Handles all transitions and compensation in one place with full LogPublisher audit trail. OrderSagaHandler reduced to thin Kafka adapter — delegates all logic to the orchestrator, removing scattered business logic from listeners.
…routes All 18 controllers updated from @RequestMapping('/api/') to '/api/v1/'. All gateway route predicates updated to Path=/api/v1/**. auth-service SecurityConfig permit list and OAuth2 redirect URIs updated. auth-service application.yml OAuth2 callback path updated. SagaFlow Postman collection updated to use /api/v1/ paths.
- analytics: improved EventJsonDeserializer usage in consumer - common-library: LogPublisher minor improvements - order: OrderResponse DTO cleanup - payment: application.yml env-var improvements - product: ProductRepository + ProductService improvements, application.yml updated - shipping: ShippingServiceImpl improvements, application.yml/properties cleaned - user: removed stale UserProfileService (was replaced by newer implementation)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.