├── services ├── promoter-ui │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── app │ │ │ ├── app.component.scss │ │ │ ├── concerts │ │ │ │ ├── create-concert │ │ │ │ │ ├── create-concert.component.scss │ │ │ │ │ ├── create-concert.component.spec.ts │ │ │ │ │ └── create-concert.component.html │ │ │ │ ├── list-concerts │ │ │ │ │ ├── list-concerts.component.scss │ │ │ │ │ ├── list-concerts.component.spec.ts │ │ │ │ │ └── list-concerts.component.ts │ │ │ │ └── http-client │ │ │ │ │ ├── create-concert-result-dto.model.ts │ │ │ │ │ ├── concert-dto.model.ts │ │ │ │ │ └── concert-http-client.service.ts │ │ │ ├── shared │ │ │ │ ├── interfaces │ │ │ │ │ └── menu-item.interface.ts │ │ │ │ ├── snack-bar.service.ts │ │ │ │ └── models │ │ │ │ │ └── menu-item.model.ts │ │ │ ├── app.server-uris.ts │ │ │ ├── app.mainmenu-items.ts │ │ │ ├── app-routing.module.ts │ │ │ ├── main-sidemenu-item │ │ │ │ ├── main-sidemenu-item.component.scss │ │ │ │ ├── main-sidemenu-item.component.spec.ts │ │ │ │ ├── main-sidemenu-item.component.html │ │ │ │ └── main-sidemenu-item.component.ts │ │ │ ├── app.component.ts │ │ │ ├── app.component.spec.ts │ │ │ └── app.component.html │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── styles.scss │ │ ├── e2e │ │ │ ├── tsconfig.e2e.json │ │ │ ├── test │ │ │ │ ├── shared │ │ │ │ │ └── browser-tools.ts │ │ │ │ └── concerts │ │ │ │ │ ├── concert.e2e-spec.ts │ │ │ │ │ └── concert-operations.ts │ │ │ └── conf.js │ │ ├── main.ts │ │ ├── index.html │ │ └── test.ts │ ├── .editorconfig │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ ├── proxy.conf.json │ ├── .browserslistrc │ ├── .gitignore │ ├── tsconfig.json │ ├── README.md │ ├── package.json │ └── karma.conf.js ├── Pricing │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ ├── config │ │ │ │ │ ├── application-db.yml │ │ │ │ │ ├── application.yml │ │ │ │ │ └── application-kafka.yml │ │ │ │ └── logback.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── bottega │ │ │ │ └── pricing │ │ │ │ ├── price │ │ │ │ ├── domain │ │ │ │ │ ├── FactorType.java │ │ │ │ │ ├── PriceFactorFactory.java │ │ │ │ │ ├── PriceId.java │ │ │ │ │ ├── FactorId.java │ │ │ │ │ ├── FactorPolicy.java │ │ │ │ │ ├── PricingEventFactory.java │ │ │ │ │ ├── PercentageFactor.java │ │ │ │ │ ├── PriceFactor.java │ │ │ │ │ └── ItemPrice.java │ │ │ │ ├── api │ │ │ │ │ └── rest │ │ │ │ │ │ ├── PercentageFactorRequestDto.java │ │ │ │ │ │ ├── PriceRestController.java │ │ │ │ │ │ └── PriceWithFactorsDto.java │ │ │ │ └── infra │ │ │ │ │ └── repo │ │ │ │ │ └── ItemPriceRepo.java │ │ │ │ ├── PricingApplication.java │ │ │ │ ├── priceRead │ │ │ │ └── api │ │ │ │ │ └── app │ │ │ │ │ └── PriceUpdateService.java │ │ │ │ ├── initialPrice │ │ │ │ ├── InitPriceCalculator.java │ │ │ │ └── InitialPriceService.java │ │ │ │ ├── config │ │ │ │ └── KafkaConsumerConfig.java │ │ │ │ └── infra │ │ │ │ └── KafkaEventPublisher.java │ │ ├── test │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── bottega │ │ │ │ │ └── pricing │ │ │ │ │ ├── fixtures │ │ │ │ │ ├── PriceReadFixtures.java │ │ │ │ │ ├── LogicTestBase.java │ │ │ │ │ ├── TestBuilders.java │ │ │ │ │ ├── InitPriceChangeEventPublisher.java │ │ │ │ │ ├── PriceJsonAssert.java │ │ │ │ │ ├── PriceChangeEventAssert.java │ │ │ │ │ ├── InitPriceFixtures.java │ │ │ │ │ └── SharedFixtures.java │ │ │ │ │ ├── price │ │ │ │ │ ├── fixtures │ │ │ │ │ │ ├── InMemoryItemPriceRepo.java │ │ │ │ │ │ ├── PricingHttpClient.java │ │ │ │ │ │ ├── PriceFactorAssert.java │ │ │ │ │ │ └── ItemPriceBuilder.java │ │ │ │ │ ├── domain │ │ │ │ │ │ └── ItemPrice_applyFactor_unitTest.java │ │ │ │ │ ├── api │ │ │ │ │ │ └── rest │ │ │ │ │ │ │ └── PriceRestController_applyPercentageFactor_restApiTest.java │ │ │ │ │ └── infra │ │ │ │ │ │ └── repo │ │ │ │ │ │ └── ItemPriceRepo_saveAll_depTest.java │ │ │ │ │ ├── initialPrice │ │ │ │ │ └── api │ │ │ │ │ │ └── event │ │ │ │ │ │ ├── InitialPriceEventListener_settleInitialPrice_eventApiTest.java │ │ │ │ │ │ └── InitialPriceEventListener_settleInitialPrice_eventContractApiTest.java │ │ │ │ │ └── infra │ │ │ │ │ └── TestKafkaEventListener.java │ │ │ └── resources │ │ │ │ └── config │ │ │ │ └── application-test.yml │ │ └── contractTest │ │ │ ├── java │ │ │ └── com │ │ │ │ └── bottega │ │ │ │ └── pricing │ │ │ │ └── fixtures │ │ │ │ ├── CdcFrameworkTestBase.java │ │ │ │ ├── PromoterPercentageDiscountBase.java │ │ │ │ ├── MessagingPriceChangeBase.java │ │ │ │ └── RestAssuredConfig.java │ │ │ └── resources │ │ │ └── contracts │ │ │ ├── messaging │ │ │ └── priceChange │ │ │ │ ├── settleBasePricePublishesPriceChange.groovy │ │ │ │ └── applyDiscountPublishesPriceChange.groovy │ │ │ └── promoter │ │ │ └── percentageDiscount │ │ │ └── applyPercentageDiscount.groovy │ ├── gradle │ │ ├── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── test-suites.gradle │ │ └── spring-cloud-contract.gradle │ └── .gitignore └── Promoter │ ├── src │ ├── main │ │ ├── resources │ │ │ └── config │ │ │ │ ├── application-db.yml │ │ │ │ ├── application.yml │ │ │ │ └── application-kafka.yml │ │ └── java │ │ │ └── com │ │ │ └── bottega │ │ │ └── promoter │ │ │ ├── concert │ │ │ ├── api │ │ │ │ ├── rest │ │ │ │ │ ├── DiscountConcertRequestDto.java │ │ │ │ │ ├── CreateConcertRequestDto.java │ │ │ │ │ └── DiscountedPriceResponseDto.java │ │ │ │ └── app │ │ │ │ │ └── ConcertErrorCode.java │ │ │ ├── PriceFactor.java │ │ │ ├── infra │ │ │ │ └── repo │ │ │ │ │ ├── TagRepo.java │ │ │ │ │ ├── CategoryRepo.java │ │ │ │ │ └── ConcertRepo.java │ │ │ ├── Price.java │ │ │ └── domain │ │ │ │ ├── TagId.java │ │ │ │ ├── CategoryId.java │ │ │ │ ├── ConcertId.java │ │ │ │ ├── Tag.java │ │ │ │ ├── PromoterEventFactory.java │ │ │ │ ├── CategoryService.java │ │ │ │ ├── TagService.java │ │ │ │ ├── Category.java │ │ │ │ ├── ConcertFactory.java │ │ │ │ └── ConcertDate.java │ │ │ ├── infra │ │ │ ├── client │ │ │ │ └── pricing │ │ │ │ │ ├── PercentagePriceFactorRequestDto.java │ │ │ │ │ ├── PricingClient.java │ │ │ │ │ └── PriceResponseDto.java │ │ │ └── KafkaEventPublisher.java │ │ │ ├── agreements │ │ │ ├── PromoterAgreement.java │ │ │ ├── PromoterId.java │ │ │ └── PromoterService.java │ │ │ ├── PromoterApplication.java │ │ │ ├── concertRead │ │ │ ├── ConcertDto.java │ │ │ ├── ConcertFinderRepo.java │ │ │ ├── ConcertReadService.java │ │ │ └── ConcertReadRestController.java │ │ │ └── config │ │ │ └── KafkaConsumerConfig.java │ ├── test │ │ ├── resources │ │ │ ├── requests.http │ │ │ └── config │ │ │ │ └── application-test.yml │ │ └── java │ │ │ └── com │ │ │ └── bottega │ │ │ └── promoter │ │ │ ├── fixtures │ │ │ ├── LogicTestBase.java │ │ │ ├── PromoterFixtures.java │ │ │ ├── PromoterAgreementBuilder.java │ │ │ ├── SccFrameworkTestBase.java │ │ │ ├── SpecificationBase.groovy │ │ │ ├── FakePricingClient.java │ │ │ ├── ConcertReadFixtures.java │ │ │ ├── SharedFixtures.java │ │ │ ├── PactFrameworkTestBase.java │ │ │ └── TestBuilders.java │ │ │ ├── concert │ │ │ ├── fixtures │ │ │ │ ├── InMemoryTagRepo.java │ │ │ │ ├── InMemoryConcertRepo.java │ │ │ │ ├── InMemoryCategoryRepo.java │ │ │ │ ├── asserts │ │ │ │ │ └── PriceAssert.java │ │ │ │ ├── ConcertLogicTestBase.java │ │ │ │ ├── ConcertDateAssertSpock.groovy │ │ │ │ └── TitleAssertSpock.groovy │ │ │ └── api │ │ │ │ ├── rest │ │ │ │ └── ConcertRestController_discountConcert_restApiTest.java │ │ │ │ └── app │ │ │ │ └── ConcertService_createConcert_springCompTest.java │ │ │ ├── config │ │ │ ├── ExceptionThrowingController.java │ │ │ └── ErrorExceptionMapper_convertToResponse_apiTest.java │ │ │ ├── concertRead │ │ │ ├── fixtures │ │ │ │ └── InMemoryConcertFinderRepo.java │ │ │ ├── ConcertReadService_findConcerts_compTest.java │ │ │ └── ConcertReadRestController_findConcerts_restApiTest.java │ │ │ └── infra │ │ │ ├── KafkaEventPublisher_publish_depTest.java │ │ │ ├── client │ │ │ └── pricing │ │ │ │ └── PricingClient_applyDiscount_pactDepTest.java │ │ │ └── TestKafkaEventListener.java │ └── contractTest │ │ ├── java │ │ └── com │ │ │ └── bottega │ │ │ └── promoter │ │ │ └── fixtures │ │ │ ├── PromoterUIBase.java │ │ │ ├── CdcFrameworkTestBase.java │ │ │ └── MessagingConcertCreatedBase.java │ │ └── resources │ │ └── contracts │ │ ├── messaging │ │ └── concertCreated │ │ │ └── publishesConcertCreated.groovy │ │ └── promoterUI │ │ └── createConcert.groovy │ ├── gradle │ ├── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── test-suites.gradle │ └── spring-cloud-contract.gradle │ ├── api-stubs │ ├── stub-runner │ │ └── stub-runner-boot-3.1.2.jar │ └── run-contract-stubs.sh │ └── .gitignore ├── docs └── TicketsArchitecture.jpg ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── libs └── SharedLib │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── bottega │ │ │ │ └── sharedlib │ │ │ │ ├── event │ │ │ │ ├── EventVersion.java │ │ │ │ ├── EventPublisher.java │ │ │ │ ├── EventType.java │ │ │ │ ├── payload │ │ │ │ │ ├── PriceChangeEventPayload.java │ │ │ │ │ └── ConcertCreatedEventPayload.java │ │ │ │ ├── Event.java │ │ │ │ └── EventPayload.java │ │ │ │ ├── repo │ │ │ │ ├── BaseEntity.java │ │ │ │ ├── MoneyDbEntity.java │ │ │ │ └── AggregateId.java │ │ │ │ ├── vo │ │ │ │ ├── error │ │ │ │ │ ├── ErrorCode.java │ │ │ │ │ ├── GenericErrorCode.java │ │ │ │ │ ├── ErrorException.java │ │ │ │ │ ├── ErrorType.java │ │ │ │ │ └── ErrorExceptionMapper.java │ │ │ │ └── Money.java │ │ │ │ ├── config │ │ │ │ ├── ApiVersions.java │ │ │ │ ├── ClockConfig.java │ │ │ │ └── ServicesProperties.java │ │ │ │ ├── ddd │ │ │ │ ├── DomainService.java │ │ │ │ ├── ValueObject.java │ │ │ │ ├── DomainEntity.java │ │ │ │ ├── AggregateRoot.java │ │ │ │ ├── DomainFactory.java │ │ │ │ └── ApplicationService.java │ │ │ │ ├── dto │ │ │ │ ├── AggregateIdDto.java │ │ │ │ └── ErrorDto.java │ │ │ │ ├── SharedLibApplication.java │ │ │ │ └── annotations │ │ │ │ └── ApiClient.java │ │ └── resources │ │ │ ├── application.yml │ │ │ └── application-serviceLocator.yml │ └── test │ │ └── java │ │ └── com │ │ └── bottega │ │ └── sharedlib │ │ ├── fixtures │ │ ├── RepoEntries.java │ │ ├── UUIDs.java │ │ ├── FakeEventPublisher.java │ │ └── ErrorAssert.java │ │ ├── config │ │ ├── CdcStubs.java │ │ └── TestClockConfig.java │ │ └── vo │ │ └── error │ │ └── ErrorResult_toException_microSpec.groovy │ └── .gitignore ├── SystemTests └── TicketingTests │ ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── bottega │ │ │ └── Main.java │ └── test │ │ └── java │ │ └── com │ │ └── bottega │ │ └── tickets │ │ └── concert │ │ ├── SeleniumFixtures.java │ │ └── CreateConcert_SystemTest.java │ └── build.gradle ├── settings.gradle ├── .run ├── promoter-ui update webdriver [project].run.xml ├── promoter-ui run [with Promoter stubs].run.xml ├── Promoter run.run.xml ├── promoter-ui run.run.xml ├── Kafka run.run.xml ├── Pricing run.run.xml ├── Ticketing System --run.run.xml ├── promoter-ui guiTest.run.xml ├── SharedLib test --all.run.xml ├── Promoter api-stubs run.run.xml ├── Pricing apiTest.run.xml ├── Pricing unitTest.run.xml ├── Pricing microTest.run.xml ├── Promoter unitTest.run.xml ├── Pricing componentTest.run.xml ├── Promoter microTest.run.xml ├── Promoter componentTest.run.xml ├── Pricing contract publish.run.xml ├── Promoter contract publish.run.xml ├── Pricing [pactPublish].run.xml ├── Promoter [pactPublish].run.xml ├── Pricing test --all.run.xml ├── Promoter test --all.run.xml ├── Promoter apiTest.run.xml ├── Pricing dependencyTest.run.xml ├── Promoter dependencyTest.run.xml ├── Pricing contractTest.run.xml └── Promoter contractTest.run.xml ├── infra └── kafka │ └── docker-compose.yml ├── .gitignore └── .github ├── rebaser.sh ├── workflows └── ci-shared-lib.yml └── dependabot.yml /services/promoter-ui/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /services/promoter-ui/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /services/promoter-ui/src/app/concerts/create-concert/create-concert.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /services/promoter-ui/src/app/concerts/list-concerts/list-concerts.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/TicketsArchitecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killuamagic/Tickets/HEAD/docs/TicketsArchitecture.jpg -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killuamagic/Tickets/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /services/Pricing/src/main/resources/config/application-db.yml: -------------------------------------------------------------------------------- 1 | spring.datasource.url: jdbc:h2:mem:pricing;MODE=PostgreSQL -------------------------------------------------------------------------------- /services/Promoter/src/main/resources/config/application-db.yml: -------------------------------------------------------------------------------- 1 | spring.datasource.url: jdbc:h2:mem:promote;MODE=PostgreSQL -------------------------------------------------------------------------------- /services/promoter-ui/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /services/promoter-ui/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killuamagic/Tickets/HEAD/services/promoter-ui/src/favicon.ico -------------------------------------------------------------------------------- /libs/SharedLib/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killuamagic/Tickets/HEAD/libs/SharedLib/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /services/Pricing/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killuamagic/Tickets/HEAD/services/Pricing/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /services/Promoter/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killuamagic/Tickets/HEAD/services/Promoter/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/event/EventVersion.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.event; 2 | 3 | public enum EventVersion { 4 | v1 5 | } 6 | -------------------------------------------------------------------------------- /services/Pricing/src/main/resources/config/application.yml: -------------------------------------------------------------------------------- 1 | spring.profiles.include: 2 | serviceLocator, 3 | db, 4 | kafka 5 | 6 | server.port: ${services.pricing.port} -------------------------------------------------------------------------------- /services/Pricing/src/test/java/com/bottega/pricing/fixtures/PriceReadFixtures.java: -------------------------------------------------------------------------------- 1 | package com.bottega.pricing.fixtures; 2 | 3 | public class PriceReadFixtures { 4 | } 5 | -------------------------------------------------------------------------------- /services/Promoter/src/main/resources/config/application.yml: -------------------------------------------------------------------------------- 1 | spring.profiles.include: 2 | serviceLocator, 3 | db, 4 | kafka 5 | 6 | server.port: ${services.promoter.port} -------------------------------------------------------------------------------- /services/promoter-ui/src/app/concerts/http-client/create-concert-result-dto.model.ts: -------------------------------------------------------------------------------- 1 | export class CreateConcertResultDto { 2 | 3 | // @ts-ignore 4 | public id: string; 5 | } 6 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/repo/BaseEntity.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.repo; 2 | 3 | public interface BaseEntity { 4 | AggregateId getId(); 5 | } 6 | -------------------------------------------------------------------------------- /services/Pricing/src/main/java/com/bottega/pricing/price/domain/FactorType.java: -------------------------------------------------------------------------------- 1 | package com.bottega.pricing.price.domain; 2 | 3 | public enum FactorType { 4 | PERCENTAGE 5 | } 6 | -------------------------------------------------------------------------------- /services/Promoter/api-stubs/stub-runner/stub-runner-boot-3.1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/killuamagic/Tickets/HEAD/services/Promoter/api-stubs/stub-runner/stub-runner-boot-3.1.2.jar -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/vo/error/ErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.vo.error; 2 | 3 | public interface ErrorCode { 4 | 5 | String toString(); 6 | } 7 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/config/ApiVersions.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.config; 2 | 3 | public class ApiVersions { 4 | 5 | public static final String V1 = "api/v1"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /SystemTests/TicketingTests/src/main/java/com/bottega/Main.java: -------------------------------------------------------------------------------- 1 | package com.bottega; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | System.out.println("Hello world!"); 6 | } 7 | } -------------------------------------------------------------------------------- /services/Pricing/src/main/java/com/bottega/pricing/price/api/rest/PercentageFactorRequestDto.java: -------------------------------------------------------------------------------- 1 | package com.bottega.pricing.price.api.rest; 2 | 3 | public record PercentageFactorRequestDto( 4 | int percentage 5 | ) { 6 | } 7 | -------------------------------------------------------------------------------- /services/Pricing/gradle/test-suites.gradle: -------------------------------------------------------------------------------- 1 | sourceSets { 2 | test { 3 | groovy { 4 | srcDirs = ['src/test/java'] 5 | } 6 | } 7 | } 8 | 9 | tasks.withType(Test) { 10 | useJUnitPlatform() 11 | } -------------------------------------------------------------------------------- /services/Promoter/gradle/test-suites.gradle: -------------------------------------------------------------------------------- 1 | sourceSets { 2 | test { 3 | groovy { 4 | srcDirs = ['src/test/java'] 5 | } 6 | } 7 | } 8 | 9 | tasks.withType(Test) { 10 | useJUnitPlatform() 11 | } -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/api/rest/DiscountConcertRequestDto.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.api.rest; 2 | 3 | public record DiscountConcertRequestDto( 4 | int percentage 5 | ) { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /services/promoter-ui/src/styles.scss: -------------------------------------------------------------------------------- 1 | @import '~@angular/material/theming'; 2 | @import '~@angular/material/prebuilt-themes/purple-green.css'; 3 | 4 | html, body { height: 100%; } 5 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } 6 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/infra/client/pricing/PercentagePriceFactorRequestDto.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.infra.client.pricing; 2 | 3 | public record PercentagePriceFactorRequestDto ( 4 | int percentage 5 | ){ 6 | } 7 | -------------------------------------------------------------------------------- /services/promoter-ui/src/app/concerts/http-client/concert-dto.model.ts: -------------------------------------------------------------------------------- 1 | export class ConcertDto { 2 | 3 | // @ts-ignore 4 | public id: string; 5 | // @ts-ignore 6 | public title: string; 7 | // @ts-ignore 8 | public date: string; 9 | } 10 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/vo/error/GenericErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.vo.error; 2 | 3 | public enum GenericErrorCode implements ErrorCode{ 4 | 5 | illegal_argument, 6 | invalid_request, 7 | not_found 8 | } 9 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring.profiles.include: 2 | - serviceLocator 3 | 4 | spring: 5 | jackson: 6 | visibility: 7 | field: any 8 | 9 | jpa: 10 | hibernate: 11 | ddl-auto: create 12 | open-in-view: false -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/api/rest/CreateConcertRequestDto.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.api.rest; 2 | 3 | record CreateConcertRequestDto( 4 | String title, 5 | String date, 6 | String promoterId 7 | ) { 8 | } 9 | -------------------------------------------------------------------------------- /services/promoter-ui/src/app/shared/interfaces/menu-item.interface.ts: -------------------------------------------------------------------------------- 1 | export interface MenuItemInterface { 2 | readonly name: string; 3 | readonly icon: string; 4 | readonly link: string; 5 | readonly isOpened: boolean; 6 | readonly sub?: Array; 7 | } 8 | -------------------------------------------------------------------------------- /services/Promoter/src/test/resources/requests.http: -------------------------------------------------------------------------------- 1 | 2 | ### Create Concert 3 | POST http://localhost:8080/api/v1/concert 4 | Content-Type: application/json 5 | 6 | { 7 | "title": "some-title", 8 | "dateTime": "2023-11-05T08:15:30-05:00", 9 | "promoterId": "some-uuid" 10 | } -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/PriceFactor.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert; 2 | 3 | import java.util.Map; 4 | 5 | public record PriceFactor ( 6 | String type, 7 | int value, 8 | Map params 9 | ){ 10 | } 11 | -------------------------------------------------------------------------------- /libs/SharedLib/src/test/java/com/bottega/sharedlib/fixtures/RepoEntries.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.fixtures; 2 | 3 | public record RepoEntries( 4 | int allEntriesCount) { 5 | 6 | 7 | public static final RepoEntries SINGULAR = new RepoEntries(1); 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /libs/SharedLib/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 4 | validateDistributionUrl=true 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /services/Pricing/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 4 | validateDistributionUrl=true 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /services/Promoter/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 4 | validateDistributionUrl=true 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/agreements/PromoterAgreement.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.agreements; 2 | 3 | import lombok.Builder; 4 | 5 | @Builder 6 | public record PromoterAgreement( 7 | PromoterId promoterId, 8 | int profitMarginPercentage 9 | ) { 10 | } 11 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/event/EventPublisher.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.event; 2 | 3 | import com.bottega.sharedlib.vo.error.ErrorResult; 4 | import io.vavr.control.Either; 5 | 6 | public interface EventPublisher { 7 | Either publish(Event event); 8 | } 9 | -------------------------------------------------------------------------------- /services/promoter-ui/src/app/app.server-uris.ts: -------------------------------------------------------------------------------- 1 | export class AppServerUris { 2 | 3 | public static readonly API_PREFIX = '/api/v1'; 4 | public static readonly CONCERT_CREATE = AppServerUris.API_PREFIX + "/concert"; 5 | public static readonly CONCERT_GET_ALL = AppServerUris.API_PREFIX + "/concert/promoter"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /services/promoter-ui/src/e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/api/app/ConcertErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.api.app; 2 | 3 | import com.bottega.sharedlib.vo.error.ErrorCode; 4 | 5 | public enum ConcertErrorCode implements ErrorCode { 6 | 7 | invalid_date, 8 | invalid_title, 9 | http_error; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/ddd/DomainService.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.ddd; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.lang.annotation.*; 6 | 7 | @Component 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | public @interface DomainService { 11 | } 12 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/event/EventType.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.event; 2 | 3 | import lombok.*; 4 | 5 | @AllArgsConstructor 6 | @Getter 7 | public enum EventType { 8 | PRICE_CHANGE("pricing.price"), 9 | CONCERT_CREATED("promoter.concert"); 10 | 11 | private String kafkaTopic; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/resources/application-serviceLocator.yml: -------------------------------------------------------------------------------- 1 | services: 2 | promoter: 3 | port: 8080 4 | host: http://localhost 5 | pricing: 6 | port: 8081 7 | host: http://localhost 8 | 9 | --- 10 | 11 | spring.config.activate.on-profile: test 12 | 13 | services: 14 | promoter: 15 | port: 8180 16 | pricing: 17 | port: 8181 18 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Tickets' 2 | include ':libs:SharedLib', ':services:Promoter', ':services:Pricing', ':SystemTests:TicketingTests' 3 | 4 | project(":libs:SharedLib").name = "SharedLib" 5 | project(":services:Promoter").name = "Promoter" 6 | project(":services:Pricing").name = "Pricing" 7 | project(':SystemTests:TicketingTests').name = 'TicketingTests' 8 | 9 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/event/payload/PriceChangeEventPayload.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.event.payload; 2 | 3 | import com.bottega.sharedlib.event.EventPayload; 4 | 5 | public record PriceChangeEventPayload( 6 | String priceId, 7 | String itemId, 8 | int price 9 | ) implements EventPayload { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/dto/AggregateIdDto.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.dto; 2 | 3 | import com.bottega.sharedlib.repo.AggregateId; 4 | 5 | public record AggregateIdDto( 6 | String id) { 7 | 8 | public static AggregateIdDto fromAggregateId(AggregateId id){ 9 | return new AggregateIdDto(id.asString()); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /services/promoter-ui/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /.run/promoter-ui update webdriver [project].run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /services/Promoter/src/test/java/com/bottega/promoter/fixtures/LogicTestBase.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.fixtures; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | 5 | public class LogicTestBase { 6 | 7 | public SharedFixtures sharedFixtures; 8 | 9 | @BeforeEach 10 | protected void setUp() { 11 | sharedFixtures = SharedFixtures.init(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /services/promoter-ui/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/infra/repo/TagRepo.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.infra.repo; 2 | 3 | import com.bottega.promoter.concert.domain.*; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface TagRepo extends CrudRepository { 9 | } 10 | -------------------------------------------------------------------------------- /services/Pricing/src/test/resources/config/application-test.yml: -------------------------------------------------------------------------------- 1 | server.port: ${services.pricing.port} 2 | 3 | logging: 4 | test-level: OFF 5 | level: 6 | org.apache.kafka: ${logging.test-level} 7 | kafka: ${logging.test-level} 8 | state.change.logger: ${logging.test-level} 9 | # org.springframework.kafka.listener: ${logging.test-level} 10 | org.apache.zookeeper: ${logging.test-level} -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/Price.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert; 2 | 3 | import java.util.List; 4 | 5 | import com.bottega.sharedlib.vo.Money; 6 | import lombok.*; 7 | 8 | @EqualsAndHashCode 9 | @AllArgsConstructor 10 | @ToString 11 | @Getter 12 | public class Price { 13 | 14 | private Money price; 15 | private List factors; 16 | } 17 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/ddd/ValueObject.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.ddd; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | public @interface ValueObject { 11 | } 12 | -------------------------------------------------------------------------------- /services/Promoter/src/test/resources/config/application-test.yml: -------------------------------------------------------------------------------- 1 | server.port: ${services.promoter.port} 2 | 3 | logging: 4 | test-level: OFF 5 | level: 6 | org.apache.kafka: ${logging.test-level} 7 | kafka: ${logging.test-level} 8 | state.change.logger: ${logging.test-level} 9 | org.springframework.kafka.listener: ${logging.test-level} 10 | org.apache.zookeeper: ${logging.test-level} -------------------------------------------------------------------------------- /infra/kafka/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | zookeeper: 4 | image: wurstmeister/zookeeper 5 | ports: 6 | - "2181:2181" 7 | kafka: 8 | image: wurstmeister/kafka 9 | ports: 10 | - "9092:9092" 11 | environment: 12 | KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1 13 | KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 14 | KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true' 15 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/infra/repo/CategoryRepo.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.infra.repo; 2 | 3 | import com.bottega.promoter.concert.domain.*; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface CategoryRepo extends CrudRepository { 9 | } 10 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/vo/error/ErrorException.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.vo.error; 2 | 3 | import lombok.Getter; 4 | 5 | public class ErrorException extends RuntimeException { 6 | 7 | @Getter 8 | private final ErrorResult error; 9 | 10 | public ErrorException(ErrorResult error) { 11 | super(error.toString()); 12 | this.error = error; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /libs/SharedLib/src/test/java/com/bottega/sharedlib/config/CdcStubs.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.config; 2 | 3 | public class CdcStubs { 4 | public static final int SCC_PRICING_PORT = 8281; 5 | public static final String CDC_STUB_ID_PRICING = "com.bottega:Pricing:1.0.0-SNAPSHOT:stubs:" + SCC_PRICING_PORT; 6 | public static final String CDC_STUB_ID_PROMOTER = "com.bottega:Promoter:1.0.0-SNAPSHOT:stubs:9192"; 7 | } 8 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/infra/repo/ConcertRepo.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.infra.repo; 2 | 3 | import com.bottega.promoter.concert.domain.*; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.stereotype.Repository; 6 | 7 | @Repository 8 | public interface ConcertRepo extends CrudRepository { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/config/ClockConfig.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | 6 | import java.time.Clock; 7 | 8 | @Configuration 9 | public class ClockConfig { 10 | 11 | @Bean 12 | Clock clock(){ 13 | return Clock.systemUTC(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/ddd/DomainEntity.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.ddd; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | @DomainEntity 11 | public @interface DomainEntity { 12 | } 13 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/ddd/AggregateRoot.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.ddd; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | @DomainEntity 11 | public @interface AggregateRoot { 12 | } 13 | -------------------------------------------------------------------------------- /services/Promoter/src/test/java/com/bottega/promoter/concert/fixtures/InMemoryTagRepo.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.fixtures; 2 | 3 | import com.bottega.promoter.concert.domain.*; 4 | import com.bottega.promoter.concert.infra.repo.TagRepo; 5 | import com.bottega.sharedlib.infra.repo.InMemoryRepo; 6 | 7 | public class InMemoryTagRepo 8 | extends InMemoryRepo 9 | implements TagRepo { 10 | } 11 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/event/payload/ConcertCreatedEventPayload.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.event.payload; 2 | 3 | import com.bottega.sharedlib.event.EventPayload; 4 | 5 | public record ConcertCreatedEventPayload ( 6 | String concertId, 7 | String title, 8 | String date, 9 | String[] tags, 10 | int profitMarginPercentage 11 | ) implements EventPayload { 12 | } 13 | -------------------------------------------------------------------------------- /services/promoter-ui/src/main.ts: -------------------------------------------------------------------------------- 1 | import {enableProdMode} from '@angular/core'; 2 | import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; 3 | 4 | import {AppModule} from './app/app.module'; 5 | import {environment} from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /services/Pricing/src/main/java/com/bottega/pricing/price/domain/PriceFactorFactory.java: -------------------------------------------------------------------------------- 1 | package com.bottega.pricing.price.domain; 2 | 3 | import com.bottega.sharedlib.ddd.DomainFactory; 4 | 5 | @DomainFactory 6 | public class PriceFactorFactory { 7 | public static PriceFactor percentageFactor(int percentage, ItemPrice price) { 8 | return new PriceFactor(new FactorId(), price, PercentageFactor.init(percentage)); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /services/promoter-ui/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.run/promoter-ui run [with Promoter stubs].run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /services/Pricing/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %d{HH:mm:ss.SSS} %p [%t] %C{0}:%line: %m %n 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/api/rest/DiscountedPriceResponseDto.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.api.rest; 2 | 3 | import com.bottega.promoter.concert.Price; 4 | 5 | public record DiscountedPriceResponseDto( 6 | int price) { 7 | 8 | public static DiscountedPriceResponseDto fromPrice(Price price) { 9 | return new DiscountedPriceResponseDto(price.getPrice().toInt()); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /services/Promoter/src/test/java/com/bottega/promoter/concert/fixtures/InMemoryConcertRepo.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.fixtures; 2 | 3 | import com.bottega.promoter.concert.domain.*; 4 | import com.bottega.promoter.concert.infra.repo.ConcertRepo; 5 | import com.bottega.sharedlib.infra.repo.InMemoryRepo; 6 | 7 | public class InMemoryConcertRepo 8 | extends InMemoryRepo 9 | implements ConcertRepo { 10 | } 11 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/SharedLibApplication.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SharedLibApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SharedLibApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /services/Promoter/src/test/java/com/bottega/promoter/concert/fixtures/InMemoryCategoryRepo.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.fixtures; 2 | 3 | import com.bottega.promoter.concert.domain.*; 4 | import com.bottega.promoter.concert.infra.repo.CategoryRepo; 5 | import com.bottega.sharedlib.infra.repo.InMemoryRepo; 6 | 7 | public class InMemoryCategoryRepo 8 | extends InMemoryRepo 9 | implements CategoryRepo { 10 | } 11 | -------------------------------------------------------------------------------- /services/promoter-ui/proxy.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "/api": { 3 | "target": "http://localhost:8080/", 4 | "secure": false, 5 | "pathRewrite": { 6 | "^/api": "/api" 7 | }, 8 | "logLevel": "debug", 9 | "changeOrigin": true, 10 | "headers": { 11 | "X-Forwarded-Proto": "http", 12 | "Host": "localhost", 13 | "X-Forwarded-Port": 4200 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /services/promoter-ui/src/app/shared/snack-bar.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {MatSnackBar} from '@angular/material/snack-bar'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class SnackBarService { 8 | 9 | constructor(private snackBar: MatSnackBar) { } 10 | 11 | public open(message: string): void { 12 | this.snackBar.open(message, "", {verticalPosition: 'top', duration: 20000}) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/domain/TagId.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.domain; 2 | 3 | import com.bottega.sharedlib.repo.AggregateId; 4 | import jakarta.persistence.Embeddable; 5 | 6 | 7 | @Embeddable 8 | public class TagId extends AggregateId { 9 | 10 | public TagId() { 11 | super(AggregateId.generate()); 12 | } 13 | 14 | public TagId(String tagId) { 15 | super(tagId); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.run/Promoter run.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | -------------------------------------------------------------------------------- /services/Pricing/src/main/java/com/bottega/pricing/price/domain/PriceId.java: -------------------------------------------------------------------------------- 1 | package com.bottega.pricing.price.domain; 2 | 3 | import com.bottega.sharedlib.repo.AggregateId; 4 | import jakarta.persistence.Embeddable; 5 | 6 | 7 | @Embeddable 8 | public class PriceId extends AggregateId { 9 | 10 | public PriceId() { 11 | super(AggregateId.generate()); 12 | } 13 | 14 | public PriceId(String priceId) { 15 | super(priceId); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /services/Pricing/src/main/java/com/bottega/pricing/PricingApplication.java: -------------------------------------------------------------------------------- 1 | package com.bottega.pricing; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication(scanBasePackages = "com.bottega") 7 | public class PricingApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(PricingApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/agreements/PromoterId.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.agreements; 2 | 3 | import com.bottega.sharedlib.repo.AggregateId; 4 | import jakarta.persistence.Embeddable; 5 | 6 | 7 | @Embeddable 8 | public class PromoterId extends AggregateId { 9 | public PromoterId() { 10 | super(AggregateId.generate()); 11 | } 12 | 13 | public PromoterId(String idString) { 14 | super(idString); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/domain/CategoryId.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.domain; 2 | 3 | import com.bottega.sharedlib.repo.AggregateId; 4 | import jakarta.persistence.Embeddable; 5 | 6 | 7 | @Embeddable 8 | public class CategoryId extends AggregateId { 9 | 10 | public CategoryId() { 11 | super(AggregateId.generate()); 12 | } 13 | 14 | public CategoryId(String id) { 15 | super(id); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/ddd/DomainFactory.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.ddd; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.TYPE) 12 | @Component 13 | public @interface DomainFactory { 14 | } 15 | -------------------------------------------------------------------------------- /services/Pricing/src/main/java/com/bottega/pricing/price/domain/FactorId.java: -------------------------------------------------------------------------------- 1 | package com.bottega.pricing.price.domain; 2 | 3 | import com.bottega.sharedlib.repo.AggregateId; 4 | import jakarta.persistence.Embeddable; 5 | 6 | 7 | @Embeddable 8 | public class FactorId extends AggregateId { 9 | 10 | public FactorId() { 11 | super(AggregateId.generate()); 12 | } 13 | 14 | public FactorId(String factorId) { 15 | super(factorId); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/PromoterApplication.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication(scanBasePackages = "com.bottega") 7 | public class PromoterApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(PromoterApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/agreements/PromoterService.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.agreements; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | @Component 6 | public class PromoterService { 7 | 8 | public PromoterAgreement getPromoterAgreement(String promoterIdString) { 9 | //cheating a bit - any promoterId exists, and has margin 5 10 | return new PromoterAgreement(new PromoterId(promoterIdString), 5); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /services/Promoter/src/main/java/com/bottega/promoter/concert/domain/ConcertId.java: -------------------------------------------------------------------------------- 1 | package com.bottega.promoter.concert.domain; 2 | 3 | import com.bottega.sharedlib.repo.AggregateId; 4 | import jakarta.persistence.Embeddable; 5 | 6 | 7 | @Embeddable 8 | public class ConcertId extends AggregateId { 9 | 10 | public ConcertId() { 11 | super(AggregateId.generate()); 12 | } 13 | 14 | public ConcertId(String concertId) { 15 | super(concertId); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/annotations/ApiClient.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.annotations; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.TYPE) 12 | @Component 13 | public @interface ApiClient { 14 | } 15 | -------------------------------------------------------------------------------- /libs/SharedLib/src/main/java/com/bottega/sharedlib/ddd/ApplicationService.java: -------------------------------------------------------------------------------- 1 | package com.bottega.sharedlib.ddd; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Component 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.TYPE) 13 | public @interface ApplicationService { 14 | } 15 | -------------------------------------------------------------------------------- /.run/promoter-ui run.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |