diff --git a/architectural_smells.csv b/architectural_smells.csv new file mode 100644 index 00000000..a410274f --- /dev/null +++ b/architectural_smells.csv @@ -0,0 +1,14 @@ +"Primary Service / Module","Code File Path (if applicable)","Code Line(s)","Labeling" +"bookstore-commons module","bookstore-commons/pom.xml","L25-L140","Shared Platform Library - the commons jar wires in validation, JPA, Web MVC, H2, test, Eureka, Consul, Hystrix, OpenFeign, OAuth2, JWT, Swagger, Lombok, and Dozer so every consumer inherits the full runtime stack even when it only needs a utility class, locking services to a monolithic dependency bundle." +"bookstore-feign library","bookstore-feign/pom.xml","L23-L123","Shared Platform Library - the Feign helper adds Spring MVC, JPA, H2, tests, Eureka, Hystrix (twice), OpenFeign, OAuth2, Security, JWT, Swagger, and Lombok to expose a few client interfaces, forcing each service that wants one downstream client to accept the entire platform footprint." +"bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/OrderController.java","L30-L64","Unversioned API Surface - every REST endpoint (/order, /orders, /previewOrder) is rooted at the service base path without a version prefix, so any breaking change to payloads or semantics immediately breaks all consumers with no opt-in migration path." +"bookstore-account-service","bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/UserController.java","L39-L99","Unversioned API Surface - administrative and self-service operations all live under /user, /users, and /userInfo without /v1 (or similar), preventing the team from versioning the endpoints independently for back-office and retail clients." +"bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java","L63-L198","Unstable Dependency - order creation performs synchronous RPC calls to the billing and payment services for every checkout (billingFeignClient.getAddressById, paymentFeignClient.doPayment), so any latency spike or API change in those dependencies blocks or fails the transaction end-to-end." +"bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java","L77-L198","Greedy Service - createOrder fetches addresses, assembles order aggregates, calculates taxes and shipping, triggers payment capture, persists billing and shipping snapshots, and clears the cart, concentrating multiple business capabilities inside one class instead of delegating to focused domain services." +"bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java","L77-L156","Orchestrator Bottleneck - the order workflow choreographs each remote call (billing lookup, payment authorization) in sequence with no asynchronous handoff, retries, or circuit breaking beyond Hystrix defaults, making the order service a tight coupling point for the entire purchase saga." +"bookstore-api-gateway-service","bookstore-api-gateway-service/src/main/resources/application.yml","L26-L42","Hub-like Gateway - Zuul centralises routing for billing, catalog, account, order, and payment domains under a single /api prefix, so a gateway outage or misconfiguration brings down every customer-facing capability." +"bookstore-account-service & bookstore-order-service","bookstore-account-service/src/main/resources/application.yml; bookstore-order-service/src/main/resources/application.yml","Account:L60-L115; Order:L68-L112","Shared Database Schema - both services point at the same bookstore_db schema in local/docker profiles, so a Flyway migration or data repair in one bounded context risks corrupting the other's data set and breaks domain isolation." +"bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/web/CreateOrderResponse.java; bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/dao/OrderItem.java","Response:L25-L39; Item:L23-L52","Broken Abstraction - REST responses return JPA entities (OrderItem, OrderBillingAddress, OrderShippingAddress) directly, leaking persistence annotations and bidirectional associations to API clients who now depend on internal schema details." +"bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/dao/Cart.java; bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/dao/CartItem.java","Cart:L47-L61; CartItem:L54-L63","Bidirectional Aggregate Coupling - Cart maintains a mutable list of CartItem entities while each CartItem holds a back-reference to its parent and mutates it in lifecycle callbacks, introducing tight coupling that complicates reuse, serialization, and transactional boundaries." +"docker-compose deployment","docker-compose.yml","L36-L142","Gateway Bypass Risk - the compose file publishes every service port (4001-8001) alongside the Zuul gateway, letting clients call internal services directly and bypass cross-cutting policies (auth, throttling) intended to live at the edge." +"bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/CartItemServiceImpl.java; bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/web/GetProductResponse.java","CartItemSvc:L41-L107; ProductDTO:L16-L23","Service Intimacy - the cart service pulls full product records over Feign and persists remote fields like price, productName, and availableItemCount into its own entities, baking catalog-domain concepts into the order service and creating hidden data ownership coupling." diff --git a/architectural_smells.md b/architectural_smells.md new file mode 100644 index 00000000..bb0bb03a --- /dev/null +++ b/architectural_smells.md @@ -0,0 +1,17 @@ +# Architectural Smells Inventory + +| Primary Service / Module | Code File Path (if applicable) | Code Line(s) | Labeling | +| --- | --- | --- | --- | +| bookstore-commons module | `bookstore-commons/pom.xml` | L25-L140 | Shared Platform Library - the commons jar wires in validation, JPA, Web MVC, H2, test, Eureka, Consul, Hystrix, OpenFeign, OAuth2, JWT, Swagger, Lombok, and Dozer so every consumer inherits the full runtime stack even when it only needs a utility class, locking services to a monolithic dependency bundle. | +| bookstore-feign library | `bookstore-feign/pom.xml` | L23-L123 | Shared Platform Library - the Feign helper adds Spring MVC, JPA, H2, tests, Eureka, Hystrix (twice), OpenFeign, OAuth2, Security, JWT, Swagger, and Lombok to expose a few client interfaces, forcing each service that wants one downstream client to accept the entire platform footprint. | +| bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/OrderController.java` | L30-L64 | Unversioned API Surface - every REST endpoint (`/order`, `/orders`, `/previewOrder`) is rooted at the service base path without a version prefix, so any breaking change to payloads or semantics immediately breaks all consumers with no opt-in migration path. | +| bookstore-account-service | `bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/UserController.java` | L39-L99 | Unversioned API Surface - administrative and self-service operations all live under `/user`, `/users`, and `/userInfo` without `/v1` (or similar), preventing the team from versioning the endpoints independently for back-office and retail clients. | +| bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java` | L63-L198 | Unstable Dependency - order creation performs synchronous RPC calls to the billing and payment services for every checkout (`billingFeignClient.getAddressById`, `paymentFeignClient.doPayment`), so any latency spike or API change in those dependencies blocks or fails the transaction end-to-end. | +| bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java` | L77-L198 | Greedy Service - `createOrder` fetches addresses, assembles order aggregates, calculates taxes and shipping, triggers payment capture, persists billing and shipping snapshots, and clears the cart, concentrating multiple business capabilities inside one class instead of delegating to focused domain services. | +| bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java` | L77-L156 | Orchestrator Bottleneck - the order workflow choreographs each remote call (billing lookup, payment authorization) in sequence with no asynchronous handoff, retries, or circuit breaking beyond Hystrix defaults, making the order service a tight coupling point for the entire purchase saga. | +| bookstore-api-gateway-service | `bookstore-api-gateway-service/src/main/resources/application.yml` | L26-L42 | Hub-like Gateway - Zuul centralises routing for billing, catalog, account, order, and payment domains under a single `/api` prefix, so a gateway outage or misconfiguration brings down every customer-facing capability. | +| bookstore-account-service & bookstore-order-service | `bookstore-account-service/src/main/resources/application.yml`; `bookstore-order-service/src/main/resources/application.yml` | Account:L60-L115; Order:L68-L112 | Shared Database Schema - both services point at the same `bookstore_db` schema in local/docker profiles, so a Flyway migration or data repair in one bounded context risks corrupting the other's data set and breaks domain isolation. | +| bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/web/CreateOrderResponse.java`; `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/dao/OrderItem.java` | Response:L25-L39; Item:L23-L52 | Broken Abstraction - REST responses return JPA entities (`OrderItem`, `OrderBillingAddress`, `OrderShippingAddress`) directly, leaking persistence annotations and bidirectional associations to API clients who now depend on internal schema details. | +| bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/dao/Cart.java`; `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/repository/dao/CartItem.java` | Cart:L47-L61; CartItem:L54-L63 | Bidirectional Aggregate Coupling - `Cart` maintains a mutable list of `CartItem` entities while each `CartItem` holds a back-reference to its parent and mutates it in lifecycle callbacks, introducing tight coupling that complicates reuse, serialization, and transactional boundaries. | +| docker-compose deployment | `docker-compose.yml` | L36-L142 | Gateway Bypass Risk - the compose file publishes every service port (`4001-8001`) alongside the Zuul gateway, letting clients call internal services directly and bypass cross-cutting policies (auth, throttling) intended to live at the edge. | +| bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/CartItemServiceImpl.java`; `bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/web/GetProductResponse.java` | CartItemSvc:L41-L107; ProductDTO:L16-L23 | Service Intimacy - the cart service pulls full product records over Feign and persists remote fields like `price`, `productName`, and `availableItemCount` into its own entities, baking catalog-domain concepts into the order service and creating hidden data ownership coupling. | diff --git a/final_arch_smells.csv b/final_arch_smells.csv new file mode 100644 index 00000000..35b3dc31 --- /dev/null +++ b/final_arch_smells.csv @@ -0,0 +1,25 @@ +Smell,Primary Service / Module,Code File Path (if applicable),Code Line(s),labeling justification in details +"Architectural Smell","bookstore-application-parent","pom.xml","L20-L104","The parent Maven POM declares every microservice module alongside shared logging, tracing, Swagger, and Dozer dependencies, making the supposed microservices compile as a single multi-module build where each service inherits the same stack and cannot evolve independently." +"Insufficient Modularization","bookstore-commons","bookstore-commons/pom.xml","L23-L138","The commons jar drags in JPA, Web MVC, H2, testing, two Hystrix starters, Eureka, Consul, OAuth2, JWT, Swagger, Lombok, and Dozer just to share utility code, forcing consumers to accept an oversized runtime footprint instead of isolated helpers." +"Insufficient Modularization","bookstore-feign","bookstore-feign/pom.xml","L23-L123","The dedicated Feign client library repeats the entire Spring Boot web/data stack plus Hystrix, security, OAuth2, Swagger, Lombok, and test tooling simply to publish interface stubs, coupling every service that needs an HTTP client to a platform bundle." +"Unversioned API","bookstore-order-service","bookstore-order-service/.../controller/OrderController.java","L30-L63","All order endpoints (/order, /orders, /previewOrder) sit at root paths without a version prefix, so any contract change immediately breaks consumers with no way to opt into a new version." +"Unversioned API","bookstore-billing-service","bookstore-billing-service/.../controller/AddressController.java","L30-L58","The billing controller exposes /address CRUD routes directly, leaving no URI versioning or compatibility buffer for clients consuming stored addresses." +"Unstable Dependency","bookstore-order-service","bookstore-order-service/.../service/impl/OrderServiceImpl.java","L63-L197","OrderServiceImpl performs synchronous Feign calls to billing and payment services for every checkout, so latency or failures in those downstream systems block order creation end-to-end." +"Unstable Dependency","bookstore-order-service","bookstore-order-service/.../service/impl/CartItemServiceImpl.java","L55-L86","The cart item workflow eagerly fetches product data over the catalog Feign client before persisting, making order cart updates contingent on catalog availability." +"Greedy Service","bookstore-order-service","bookstore-order-service/.../service/impl/OrderServiceImpl.java","L77-L197","The same service method fetches addresses, assembles aggregates, calculates tax and shipping, triggers payment capture, persists billing/shipping snapshots, and clears the cart, concentrating multiple bounded contexts in one class." +"Shared Persistence","bookstore-account-service","bookstore-account-service/src/main/resources/application.yml","L58-L115","Account profiles for H2, local MySQL, and Docker all target the shared bookstore_db schema, so account data migrations collide with other services using the same database." +"Shared Persistence","bookstore-order-service","bookstore-order-service/src/main/resources/application.yml","L54-L112","Order service datasource profiles reuse the same bookstore_db JDBC URL and credentials, eliminating database per service isolation." +"Shared Persistence","bookstore-billing-service","bookstore-billing-service/src/main/resources/application.yml","L56-L114","Billing service configurations also point at bookstore_db, confirming three separate bounded contexts persist into the same schema." +"Hub-like Dependency","bookstore-api-gateway-service","bookstore-api-gateway-service/src/main/resources/application.yml","L21-L46","Zuul routes for billing, catalog, account, order, and payment all terminate at the same gateway prefix with eager Ribbon loading, so one gateway outage fans out across every downstream capability." +"Hub-like Dependency","bookstore-order-service","bookstore-order-service/.../service/impl/OrderServiceImpl.java","L63-L197","Order orchestration depends on repositories plus billing and payment clients in the same method, making the order service a hub that other domains must stay aligned with." +"Unnecessary Abstraction","bookstore-feign","bookstore-feign/.../feign/AccountFeignClient.java","L16-L23","The Feign client duplicates the account service routes with method overloads on the same /user path, adding an extra indirection layer without hiding transport details or reducing coupling." +"Unnecessary Abstraction","bookstore-feign","bookstore-feign/.../feign/CatalogFeignClient.java; bookstore-feign/.../feign/BillingFeignClient.java","Catalog:L15-L16; Billing:L14-L15","These Feign interfaces simply mirror downstream REST signatures, yet the shared library also bundles full web/JPA dependencies, so the abstraction adds little value while enlarging every service." +"Broken Modularization","bookstore-order-service","bookstore-order-service/.../web/CreateOrderResponse.java","L25-L39","The REST response type exposes JPA entities like OrderItem, OrderBillingAddress, and OrderShippingAddress, leaking persistence annotations and bidirectional associations to API clients." +"Broken Modularization","bookstore-order-service","bookstore-order-service/.../service/impl/OrderServiceImpl.java","L113-L193","The service copies persistence entities directly into response DTOs and saves billing/shipping records mid-request, binding transport contracts to internal entity structure." +"Cyclic Dependency","bookstore-order-service","bookstore-order-service/.../repository/dao/Cart.java; bookstore-order-service/.../repository/dao/CartItem.java","Cart:L47-L60; CartItem:L54-L63","Cart holds a mutable list of CartItem entities while each CartItem keeps a back-reference and manually severs the relationship in lifecycle callbacks, creating a bidirectional entity cycle." +"ESB Usage","bookstore-api-gateway-service","bookstore-api-gateway-service/src/main/resources/application.yml","L21-L58","The Zuul gateway centralizes routing, timeout, and Hystrix thread isolation policies for every downstream service, effectively acting as an enterprise service bus that mediates all traffic and cross-cutting concerns." +"ESB Usage","bookstore-feign","bookstore-feign/pom.xml; bookstore-feign/.../feign/*.java","Pom:L23-L123; Clients:L13-L23","Consolidating every cross-service client and resilience dependency into a single shared library recreates an integration bus, funneling inter-service communication through one deployable artifact." +"No API Gateway","docker-compose deployment","docker-compose.yml","L36-L142","Docker compose publishes each microservice container on host ports (4001-8001) alongside Zuul, allowing clients to bypass the gateway entirely despite the intended edge routing." +"No API Gateway","bookstore-frontend-react-app","bookstore-frontend-react-app/src/constants/appConstants.js","L1-L3","The SPA hardcodes gateway credentials and URL, so distributing the client leaks secrets and encourages direct calls that can sidestep centralized ingress controls." +"Service Imitation","bookstore-order-service","bookstore-order-service/.../service/impl/CartItemServiceImpl.java","L55-L86","The cart service copies catalog data (productName, price, availableItemCount) into its own entities, duplicating catalog responsibilities instead of referencing them." +"Service Imitation","bookstore-payment-service","bookstore-payment-service/.../service/impl/PaymentsServiceImpl.java; bookstore-payment-service/.../service/impl/PaymentMethodServiceImpl.java","Payments:L42-L70; PaymentMethods:L63-L177","Payment services proxy Stripe APIs almost verbatim—creating intents, customers, and payment methods with no additional domain rules—so the microservice imitates an upstream provider rather than encapsulating unique business logic." diff --git a/final_arch_smells.md b/final_arch_smells.md new file mode 100644 index 00000000..53575397 --- /dev/null +++ b/final_arch_smells.md @@ -0,0 +1,28 @@ +# Final Architectural Smells Inventory + +| Smell | Primary Service / Module | Code File Path (if applicable) | Code Line(s) | Labeling justification in details | +| --- | --- | --- | --- | --- | +| Architectural Smell | bookstore-application-parent | `pom.xml` | L20-L104 | The parent Maven POM declares every microservice module alongside shared logging, tracing, Swagger, and Dozer dependencies, making the supposed microservices compile as a single multi-module build where each service inherits the same stack and cannot evolve independently. | +| Insufficient Modularization | bookstore-commons | `bookstore-commons/pom.xml` | L23-L138 | The commons jar drags in JPA, Web MVC, H2, testing, two Hystrix starters, Eureka, Consul, OAuth2, JWT, Swagger, Lombok, and Dozer just to share utility code, forcing consumers to accept an oversized runtime footprint instead of isolated helpers. | +| Insufficient Modularization | bookstore-feign | `bookstore-feign/pom.xml` | L23-L123 | The dedicated Feign client library repeats the entire Spring Boot web/data stack plus Hystrix, security, OAuth2, Swagger, Lombok, and test tooling simply to publish interface stubs, coupling every service that needs an HTTP client to a platform bundle. | +| Unversioned API | bookstore-order-service | `bookstore-order-service/.../controller/OrderController.java` | L30-L63 | All order endpoints (`/order`, `/orders`, `/previewOrder`) sit at root paths without a version prefix, so any contract change immediately breaks consumers with no way to opt into a new version. | +| Unversioned API | bookstore-billing-service | `bookstore-billing-service/.../controller/AddressController.java` | L30-L58 | The billing controller exposes `/address` CRUD routes directly, leaving no URI versioning or compatibility buffer for clients consuming stored addresses. | +| Unstable Dependency | bookstore-order-service | `bookstore-order-service/.../service/impl/OrderServiceImpl.java` | L63-L197 | `OrderServiceImpl` performs synchronous Feign calls to billing and payment services for every checkout, so latency or failures in those downstream systems block order creation end-to-end. | +| Unstable Dependency | bookstore-order-service | `bookstore-order-service/.../service/impl/CartItemServiceImpl.java` | L55-L86 | The cart item workflow eagerly fetches product data over the catalog Feign client before persisting, making order cart updates contingent on catalog availability. | +| Greedy Service | bookstore-order-service | `bookstore-order-service/.../service/impl/OrderServiceImpl.java` | L77-L197 | The same service method fetches addresses, assembles aggregates, calculates tax and shipping, triggers payment capture, persists billing/shipping snapshots, and clears the cart, concentrating multiple bounded contexts in one class. | +| Shared Persistence | bookstore-account-service | `bookstore-account-service/src/main/resources/application.yml` | L58-L115 | Account profiles for H2, local MySQL, and Docker all target the shared `bookstore_db` schema, so account data migrations collide with other services using the same database. | +| Shared Persistence | bookstore-order-service | `bookstore-order-service/src/main/resources/application.yml` | L54-L112 | Order service datasource profiles reuse the same `bookstore_db` JDBC URL and credentials, eliminating database per service isolation. | +| Shared Persistence | bookstore-billing-service | `bookstore-billing-service/src/main/resources/application.yml` | L56-L114 | Billing service configurations also point at `bookstore_db`, confirming three separate bounded contexts persist into the same schema. | +| Hub-like Dependency | bookstore-api-gateway-service | `bookstore-api-gateway-service/src/main/resources/application.yml` | L21-L46 | Zuul routes for billing, catalog, account, order, and payment all terminate at the same gateway prefix with eager Ribbon loading, so one gateway outage fans out across every downstream capability. | +| Hub-like Dependency | bookstore-order-service | `bookstore-order-service/.../service/impl/OrderServiceImpl.java` | L63-L197 | Order orchestration depends on repositories plus billing and payment clients in the same method, making the order service a hub that other domains must stay aligned with. | +| Unnecessary Abstraction | bookstore-feign | `bookstore-feign/.../feign/AccountFeignClient.java` | L16-L23 | The Feign client duplicates the account service routes with method overloads on the same `/user` path, adding an extra indirection layer without hiding transport details or reducing coupling. | +| Unnecessary Abstraction | bookstore-feign | `bookstore-feign/.../feign/CatalogFeignClient.java`; `bookstore-feign/.../feign/BillingFeignClient.java` | Catalog:L15-L16; Billing:L14-L15 | These Feign interfaces simply mirror downstream REST signatures, yet the shared library also bundles full web/JPA dependencies, so the abstraction adds little value while enlarging every service. | +| Broken Modularization | bookstore-order-service | `bookstore-order-service/.../web/CreateOrderResponse.java` | L25-L39 | The REST response type exposes JPA entities like `OrderItem`, `OrderBillingAddress`, and `OrderShippingAddress`, leaking persistence annotations and bidirectional associations to API clients. | +| Broken Modularization | bookstore-order-service | `bookstore-order-service/.../service/impl/OrderServiceImpl.java` | L113-L193 | The service copies persistence entities directly into response DTOs and saves billing/shipping records mid-request, binding transport contracts to internal entity structure. | +| Cyclic Dependency | bookstore-order-service | `bookstore-order-service/.../repository/dao/Cart.java`; `bookstore-order-service/.../repository/dao/CartItem.java` | Cart:L47-L60; CartItem:L54-L63 | `Cart` holds a mutable list of `CartItem` entities while each `CartItem` keeps a back-reference and manually severs the relationship in lifecycle callbacks, creating a bidirectional entity cycle. | +| ESB Usage | bookstore-api-gateway-service | `bookstore-api-gateway-service/src/main/resources/application.yml` | L21-L58 | The Zuul gateway centralizes routing, timeout, and Hystrix thread isolation policies for every downstream service, effectively acting as an enterprise service bus that mediates all traffic and cross-cutting concerns. | +| ESB Usage | bookstore-feign | `bookstore-feign/pom.xml`; `bookstore-feign/.../feign/*.java` | Pom:L23-L123; Clients:L13-L23 | Consolidating every cross-service client and resilience dependency into a single shared library recreates an integration bus, funneling inter-service communication through one deployable artifact. | +| No API Gateway | docker-compose deployment | `docker-compose.yml` | L36-L142 | Docker compose publishes each microservice container on host ports (`4001-8001`) alongside Zuul, allowing clients to bypass the gateway entirely despite the intended edge routing. | +| No API Gateway | bookstore-frontend-react-app | `bookstore-frontend-react-app/src/constants/appConstants.js` | L1-L3 | The SPA hardcodes gateway credentials and URL, so distributing the client leaks secrets and encourages direct calls that can sidestep centralized ingress controls. | +| Service Imitation | bookstore-order-service | `bookstore-order-service/.../service/impl/CartItemServiceImpl.java` | L55-L86 | The cart service copies catalog data (`productName`, `price`, `availableItemCount`) into its own entities, duplicating catalog responsibilities instead of referencing them. | +| Service Imitation | bookstore-payment-service | `bookstore-payment-service/.../service/impl/PaymentsServiceImpl.java`; `bookstore-payment-service/.../service/impl/PaymentMethodServiceImpl.java` | Payments:L42-L70; PaymentMethods:L63-L177 | Payment services proxy Stripe APIs almost verbatim—creating intents, customers, and payment methods with no additional domain rules—so the microservice imitates an upstream provider rather than encapsulating unique business logic. | diff --git a/final_final_ground_truth.csv b/final_final_ground_truth.csv new file mode 100644 index 00000000..d4cf4221 --- /dev/null +++ b/final_final_ground_truth.csv @@ -0,0 +1,13 @@ +Smell,Primary Service / Module,Code File Path (if applicable),Code Line(s),Labeling justification in details +"Shared Persistence","Account, Billing, Catalog, Order, Payment services","bookstore-account-service/src/main/resources/application.yml; bookstore-billing-service/src/main/resources/application.yml; bookstore-order-service/src/main/resources/application.yml; bookstore-catalog-service/src/main/resources/application.yml; bookstore-payment-service/src/main/resources/application.yml","Account:L72-L116; Billing:L70-L114; Order:L70-L112; Catalog:L70-L112; Payment:L73-L117","All five domain services are configured to point at the same bookstore_db schema and credentials, so they update a single physical database instead of owning isolated persistence, creating tight coupling and deployment contention across bounded contexts." +"Insufficient Modularization","bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/CartController.java; bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/CartItemController.java","Cart:L25-L43; CartItem:L27-L43","The order service exposes cart lifecycle and cart-item mutation endpoints alongside checkout APIs, blending shopping cart management into the order context rather than isolating it as its own service or module." +"Greedy Service","bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java","L63-L198; L201-L356","Order creation orchestrates address hydration, payment capture, tax and shipping calculations, and cart clearing within one class, making the service coordinate responsibilities from billing, payment, and catalog domains instead of delegating them to dedicated services." +"Unstable Dependency","bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java; bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/CartItemServiceImpl.java","Order:L63-L227; CartItem:L32-L107","Checkout and cart mutations synchronously invoke the billing, payment, and catalog services over Feign for every request; any latency or contract change in those downstream APIs immediately breaks core order operations." +"Unversioned API","bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/OrderController.java","L30-L64","The order endpoints are published directly at /order, /orders, and /previewOrder without a version prefix, preventing the team from evolving new versions alongside the original routes." +"Unversioned API","bookstore-payment-service","bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/controller/PaymentsController.java; bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/controller/PaymentMethodController.java","Payments:L26-L29; PaymentMethod:L29-L44","Payment capture and payment-method management share unversioned root paths such as /pay and /paymentMethod, so consumers cannot opt into explicit API versions when backward-incompatible changes are required." +"Unversioned API","bookstore-billing-service","bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/controller/AddressController.java","L30-L58","Address CRUD endpoints are all rooted at /address without any version segment, leaving no HTTP namespace to introduce breaking revisions." +"Unversioned API","bookstore-catalog-service","bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/controller/ProductController.java","L41-L117","Product management and listing routes live directly under /product and /products and therefore expose only a single implicit version of the catalog API." +"Unversioned API","bookstore-account-service","bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/UserController.java","L34-L63","User creation, lookup, and update handlers serve /user and /users without versioning, forcing clients to update in lockstep with any contract changes." +"Broken Modularity","bookstore-commons","bookstore-commons/pom.xml; bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/security/GlobalResourceServerConfig.java","pom:L23-L140; GlobalResourceServerConfig:L34-L63","The shared commons library bundles full web, JPA, discovery, and security stacks together with a global OAuth resource server configuration, so every microservice must import and execute centralized security behavior rather than owning its own modular boundaries." +"Unnecessary Abstraction","bookstore-feign","bookstore-feign/pom.xml; bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/feign/PaymentFeignClient.java","pom:L23-L123; PaymentFeignClient:L14-L21","A standalone feign module wraps simple REST calls yet drags in Spring Web, JPA, security, Swagger, and Hystrix dependencies, meaning services import an oversized abstraction layer that mirrors downstream signatures without reducing coupling." +"Service Intermix","bookstore-account-service","bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/config/AuthorizationServerConfig.java; bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/UserController.java","AuthorizationServerConfig:L41-L135; UserController:L34-L63","The account service simultaneously operates as the OAuth authorization server (issuing tokens, managing clients, signing keys) and as the user-profile CRUD API, combining identity infrastructure concerns with customer data management in a single deployable unit." diff --git a/final_final_ground_truth.md b/final_final_ground_truth.md new file mode 100644 index 00000000..45bfa619 --- /dev/null +++ b/final_final_ground_truth.md @@ -0,0 +1,16 @@ +# Architectural Smells (Final Ground Truth) + +| Smell | Primary Service / Module | Code File Path (if applicable) | Code Line(s) | Labeling justification in details | +| --- | --- | --- | --- | --- | +| Shared Persistence | Account, Billing, Catalog, Order, Payment services | `bookstore-account-service/src/main/resources/application.yml`; `bookstore-billing-service/src/main/resources/application.yml`; `bookstore-order-service/src/main/resources/application.yml`; `bookstore-catalog-service/src/main/resources/application.yml`; `bookstore-payment-service/src/main/resources/application.yml` | Account:L72-L116; Billing:L70-L114; Order:L70-L112; Catalog:L70-L112; Payment:L73-L117 | All five domain services are configured to point at the same `bookstore_db` schema and credentials, so they update a single physical database instead of owning isolated persistence, creating tight coupling and deployment contention across bounded contexts. | +| Insufficient Modularization | bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/CartController.java`; `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/CartItemController.java` | Cart:L25-L43; CartItem:L27-L43 | The order service exposes cart lifecycle and cart-item mutation endpoints alongside checkout APIs, blending shopping cart management into the order context rather than isolating it as its own service or module. | +| Greedy Service | bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java` | L63-L198; L201-L356 | Order creation orchestrates address hydration, payment capture, tax and shipping calculations, and cart clearing within one class, making the service coordinate responsibilities from billing, payment, and catalog domains instead of delegating them to dedicated services. | +| Unstable Dependency | bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java`; `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/CartItemServiceImpl.java` | Order:L63-L227; CartItem:L32-L107 | Checkout and cart mutations synchronously invoke the billing, payment, and catalog services over Feign for every request; any latency or contract change in those downstream APIs immediately breaks core order operations. | +| Unversioned API | bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/OrderController.java` | L30-L64 | The order endpoints are published directly at `/order`, `/orders`, and `/previewOrder` without a version prefix, preventing the team from evolving new versions alongside the original routes. | +| Unversioned API | bookstore-payment-service | `bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/controller/PaymentsController.java`; `bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/controller/PaymentMethodController.java` | Payments:L26-L29; PaymentMethod:L29-L44 | Payment capture and payment-method management share unversioned root paths such as `/pay` and `/paymentMethod`, so consumers cannot opt into explicit API versions when backward-incompatible changes are required. | +| Unversioned API | bookstore-billing-service | `bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/controller/AddressController.java` | L30-L58 | Address CRUD endpoints are all rooted at `/address` without any version segment, leaving no HTTP namespace to introduce breaking revisions. | +| Unversioned API | bookstore-catalog-service | `bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/controller/ProductController.java` | L41-L117 | Product management and listing routes live directly under `/product` and `/products` and therefore expose only a single implicit version of the catalog API. | +| Unversioned API | bookstore-account-service | `bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/UserController.java` | L34-L63 | User creation, lookup, and update handlers serve `/user` and `/users` without versioning, forcing clients to update in lockstep with any contract changes. | +| Broken Modularity | bookstore-commons | `bookstore-commons/pom.xml`; `bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/security/GlobalResourceServerConfig.java` | pom:L23-L140; GlobalResourceServerConfig:L34-L63 | The shared commons library bundles full web, JPA, discovery, and security stacks together with a global OAuth resource server configuration, so every microservice must import and execute centralized security behavior rather than owning its own modular boundaries. | +| Unnecessary Abstraction | bookstore-feign | `bookstore-feign/pom.xml`; `bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/feign/PaymentFeignClient.java` | pom:L23-L123; PaymentFeignClient:L14-L21 | A standalone feign module wraps simple REST calls yet drags in Spring Web, JPA, security, Swagger, and Hystrix dependencies, meaning services import an oversized abstraction layer that mirrors downstream signatures without reducing coupling. | +| Service Intermix | bookstore-account-service | `bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/config/AuthorizationServerConfig.java`; `bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/UserController.java` | AuthorizationServerConfig:L41-L135; UserController:L34-L63 | The account service simultaneously operates as the OAuth authorization server (issuing tokens, managing clients, signing keys) and as the user-profile CRUD API, combining identity infrastructure concerns with customer data management in a single deployable unit. | diff --git a/final_final_v2.csv b/final_final_v2.csv new file mode 100644 index 00000000..347c7145 --- /dev/null +++ b/final_final_v2.csv @@ -0,0 +1,12 @@ +Smell,Primary Service / Module,Code File Path (if applicable),Code Line(s),Labeling justification in details +"Shared Persistency","Account, Billing, Catalog, Order, Payment services","bookstore-account-service/src/main/resources/application.yml; bookstore-billing-service/src/main/resources/application.yml; bookstore-order-service/src/main/resources/application.yml; bookstore-catalog-service/src/main/resources/application.yml; bookstore-payment-service/src/main/resources/application.yml","Account:L52-L116; Billing:L50-L114; Order:L40-L112; Catalog:L50-L112; Payment:L50-L117","Every domain service profile points to the same bookstore_db schema across H2, local MySQL, and docker MySQL URLs, so each microservice reads and writes a shared physical database instead of owning its own persistence boundary." +"Insufficient Modularization","bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/CartController.java; bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/CartItemController.java","CartController:L1-L43; CartItemController:L1-L45","The order service exposes cart lifecycle and cart-item mutation endpoints alongside checkout APIs, coupling shopping-cart management tightly to the order bounded context instead of isolating it into a dedicated service or module." +"Greedy Service","bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java","L60-L357","The order service’s implementation coordinates authentication, cart traversal, address lookups, tax/shipping calculations, payment capture, and cart cleanup in one transaction script, aggregating billing, catalog, and payment concerns inside a single class rather than delegating them to specialized services." +"Unstable Dependency","bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java; bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/CartItemServiceImpl.java","OrderServiceImpl:L63-L356; CartItemServiceImpl:L28-L109","Core order flows synchronously invoke the billing, payment, catalog, and account services through Feign on every request without circuit-breaker protection, so any latency or contract change in those downstream APIs immediately breaks order creation and cart mutation paths." +"Unversioned API","bookstore-order-service","bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/OrderController.java","L25-L58","Order endpoints are published directly at /order, /orders, and /previewOrder without a version prefix, preventing the team from evolving newer versions alongside the original routes." +"Unversioned API","bookstore-payment-service","bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/controller/PaymentsController.java; bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/controller/PaymentMethodController.java","PaymentsController:L26-L29; PaymentMethodController:L29-L44","Payment capture and payment-method management live at /pay and /paymentMethod roots with no versioning strategy, so clients must upgrade in lockstep with any breaking change." +"Unversioned API","bookstore-billing-service","bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/controller/AddressController.java","L30-L58","Address CRUD handlers all sit directly under /address, leaving no HTTP namespace to introduce backward-incompatible revisions." +"Unversioned API","bookstore-catalog-service","bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/controller/ProductController.java","L41-L117","Product creation, lookup, update, deletion, and listing operate on /product and /products endpoints without version identifiers, exposing a single implicit API version." +"Unversioned API","bookstore-account-service","bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/UserController.java","L39-L99","User creation, lookup, and profile management routes respond at /user, /users, and /userInfo, forcing consumers to absorb breaking changes because no versioned paths exist." +"Broken Modularization","bookstore-commons","bookstore-commons/pom.xml; bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/security/GlobalResourceServerConfig.java","pom:L1-L154; GlobalResourceServerConfig:L1-L122","The shared commons library bundles full Spring Web, JPA, discovery, security, Swagger, and OAuth resource-server wiring, so importing the utility jar drags centralized security behavior into every service instead of keeping boundaries modular." +"Unnecessary Abstraction","bookstore-feign","bookstore-feign/pom.xml; bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/feign/PaymentFeignClient.java","pom:L1-L137; PaymentFeignClient:L1-L21","A separate Feign module wraps straightforward payment endpoints yet depends on full Spring Boot web, JPA, security, Swagger, and Hystrix stacks, so services import an oversized abstraction layer that mirrors downstream contracts without reducing coupling." diff --git a/final_final_v2.md b/final_final_v2.md new file mode 100644 index 00000000..4097939d --- /dev/null +++ b/final_final_v2.md @@ -0,0 +1,15 @@ +# Architectural Smells (Final Final Ground Truth v2) + +| Smell | Primary Service / Module | Code File Path (if applicable) | Code Line(s) | Labeling justification in details | +| --- | --- | --- | --- | --- | +| Shared Persistency | Account, Billing, Catalog, Order, Payment services | `bookstore-account-service/src/main/resources/application.yml`; `bookstore-billing-service/src/main/resources/application.yml`; `bookstore-order-service/src/main/resources/application.yml`; `bookstore-catalog-service/src/main/resources/application.yml`; `bookstore-payment-service/src/main/resources/application.yml` | Account:L52-L116; Billing:L50-L114; Order:L40-L112; Catalog:L50-L112; Payment:L50-L117 | Every domain service profile points to the same `bookstore_db` schema across H2, local MySQL, and docker MySQL URLs, so each microservice reads and writes a shared physical database instead of owning its own persistence boundary. | +| Insufficient Modularization | bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/CartController.java`; `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/CartItemController.java` | CartController:L1-L43; CartItemController:L1-L45 | The order service exposes cart lifecycle and cart-item mutation endpoints alongside checkout APIs, coupling shopping-cart management tightly to the order bounded context instead of isolating it into a dedicated service or module. | +| Greedy Service | bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java` | L60-L357 | The order service’s implementation coordinates authentication, cart traversal, address lookups, tax/shipping calculations, payment capture, and cart cleanup in one transaction script, aggregating billing, catalog, and payment concerns inside a single class rather than delegating them to specialized services. | +| Unstable Dependency | bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/OrderServiceImpl.java`; `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/service/impl/CartItemServiceImpl.java` | OrderServiceImpl:L63-L356; CartItemServiceImpl:L28-L109 | Core order flows synchronously invoke the billing, payment, catalog, and account services through Feign on every request without circuit-breaker protection, so any latency or contract change in those downstream APIs immediately breaks order creation and cart mutation paths. | +| Unversioned API | bookstore-order-service | `bookstore-order-service/src/main/java/com/devd/spring/bookstoreorderservice/controller/OrderController.java` | L25-L58 | Order endpoints are published directly at `/order`, `/orders`, and `/previewOrder` without a version prefix, preventing the team from evolving newer versions alongside the original routes. | +| Unversioned API | bookstore-payment-service | `bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/controller/PaymentsController.java`; `bookstore-payment-service/src/main/java/com/devd/spring/bookstorepaymentservice/controller/PaymentMethodController.java` | PaymentsController:L26-L29; PaymentMethodController:L29-L44 | Payment capture and payment-method management live at `/pay` and `/paymentMethod` roots with no versioning strategy, so clients must upgrade in lockstep with any breaking change. | +| Unversioned API | bookstore-billing-service | `bookstore-billing-service/src/main/java/com/devd/spring/bookstorebillingservice/controller/AddressController.java` | L30-L58 | Address CRUD handlers all sit directly under `/address`, leaving no HTTP namespace to introduce backward-incompatible revisions. | +| Unversioned API | bookstore-catalog-service | `bookstore-catalog-service/src/main/java/com/devd/spring/bookstorecatalogservice/controller/ProductController.java` | L41-L117 | Product creation, lookup, update, deletion, and listing operate on `/product` and `/products` endpoints without version identifiers, exposing a single implicit API version. | +| Unversioned API | bookstore-account-service | `bookstore-account-service/src/main/java/com/devd/spring/bookstoreaccountservice/controller/UserController.java` | L39-L99 | User creation, lookup, and profile management routes respond at `/user`, `/users`, and `/userInfo`, forcing consumers to absorb breaking changes because no versioned paths exist. | +| Broken Modularization | bookstore-commons | `bookstore-commons/pom.xml`; `bookstore-commons/src/main/java/com/devd/spring/bookstorecommons/security/GlobalResourceServerConfig.java` | pom:L1-L154; GlobalResourceServerConfig:L1-L122 | The shared commons library bundles full Spring Web, JPA, discovery, security, Swagger, and OAuth resource-server wiring, so importing the utility jar drags centralized security behavior into every service instead of keeping boundaries modular. | +| Unnecessary Abstraction | bookstore-feign | `bookstore-feign/pom.xml`; `bookstore-feign/src/main/java/com/devd/spring/bookstorecommons/feign/PaymentFeignClient.java` | pom:L1-L137; PaymentFeignClient:L1-L21 | A separate Feign module wraps straightforward payment endpoints yet depends on full Spring Boot web, JPA, security, Swagger, and Hystrix stacks, so services import an oversized abstraction layer that mirrors downstream contracts without reducing coupling. |