### Usage of Leanpub Sync Script Source: https://github.com/siy/coding-technology/blob/main/book/LEANPUB_SETUP.md Demonstrates commands for interacting with the Leanpub sync script. These commands allow for previewing builds, publishing new versions, and checking the status of the current build. The script automates common publishing workflows. ```bash ./sync-leanpub.sh preview ``` ```bash ./sync-leanpub.sh publish ``` ```bash ./sync-leanpub.sh status ``` -------------------------------- ### Adapter Placement Example (Java) Source: https://github.com/siy/coding-technology/blob/main/ai-tools/skills/jbct/project-structure/organization.md Demonstrates the organization of adapter implementations based on their direction and technology. This example shows persistence adapters for database interactions. ```text com.example.adapter.persistence/ ├── UserRepositoryAdapter.java ├── OrderRepositoryAdapter.java └── ProductRepositoryAdapter.java ``` -------------------------------- ### Install Website Dependencies Locally Source: https://github.com/siy/coding-technology/blob/main/website/DEPLOYMENT.md Installs all necessary Node.js dependencies for the website project. This command should be run from the 'website' directory. ```bash cd website npm install ``` -------------------------------- ### Leanpub Book Project Directory Structure Source: https://github.com/siy/coding-technology/blob/main/book/LEANPUB_SETUP.md Illustrates the standard directory structure for a Leanpub book project. Key directories include 'manuscript' for content and 'images' for assets. The 'sync-leanpub.sh' script is used for build and sync operations. ```tree book/ ├── manuscript/ # Leanpub content directory │ ├── Book.txt # Chapter order manifest │ ├── Sample.txt # Free sample chapters │ ├── ch01-*.md # Chapter files │ ├── ... │ └── images/ │ └── title_page.png ├── sync-leanpub.sh # Sync and build script └── LEANPUB_SETUP.md # This file ``` -------------------------------- ### Example Usage Patterns Source: https://github.com/siy/coding-technology/blob/main/CLAUDE.md Illustrative examples of common usage patterns for Promises and Results. ```APIDOC ## Example Usage Patterns ### Adapter with exception handling: ```java public Promise findUser(UserId id) { return Promise.lift( CoreError::database, () -> jdbcTemplate.queryForObject("SELECT * FROM users WHERE id = ?", new Object[]{id.value()}, this::mapUser) ); } ``` ### Lifting sync Result to async Promise: ```java public Promise execute(Request request) { return ValidRequest.validRequest(request) // returns Result .async() // converts to Promise .flatMap(step1::apply) .flatMap(step2::apply); } ``` ### Option to Result/Promise: ```java Option optUser = findUserById(id); // To Result Result result = optUser.toResult(UserError.NotFound.INSTANCE); // To Promise Promise promise = optUser.async(UserError.NotFound.INSTANCE); ``` ``` -------------------------------- ### Minimal TOML Configuration Example Source: https://github.com/siy/coding-technology/blob/main/proposals/rfc/RFC-0006-slice-runtime-config.md Provides a minimal example of a TOML configuration file for a slice, specifying only the required `instances` property. ```toml [blueprint] instances = 2 ``` -------------------------------- ### Install JBCT CLI (Linux/macOS) Source: https://github.com/siy/coding-technology/blob/main/CLI-TOOLING.md Installs the JBCT CLI using a curl script. It verifies Java installation (JDK 25+), downloads the latest release, and sets up the necessary files and PATH environment variable. Supports custom installation locations. ```bash curl -fsSL https://raw.githubusercontent.com/siy/jbct-cli/main/install.sh | sh ``` ```bash JBCT_HOME=/custom/path sh install.sh ``` -------------------------------- ### Code Style Examples Source: https://github.com/siy/coding-technology/blob/main/CLAUDE.md Examples demonstrating recommended coding practices for error handling and type matching. ```APIDOC ## Code Style Examples ### Use switch expressions for type matching - Replace `if (instanceof)` chains with pattern matching switch - Use multi-case matching: `case A ignored, B ignored ->` **Example:** ```java // DO private Promise recoverNetworkError(Cause cause) { return switch (cause) { case NetworkError.Timeout ignored -> TIMEOUT.promise(); case NetworkError.Connection ignored -> UNREACHABLE.promise(); default -> cause.promise(); }; } // DON'T private Promise recoverNetworkError(Cause cause) { if (cause instanceof NetworkError.Timeout) { return TIMEOUT.promise(); } if (cause instanceof NetworkError.Connection) { return UNREACHABLE.promise(); } return cause.promise(); } ``` ### Extract error constants - Define Cause instances as static final constants - Never construct inline with fixed strings **Example:** ```java // DO private static final Cause TIMEOUT = new ServiceUnavailable("User service timed out"); private static final Cause UNREACHABLE = new ServiceUnavailable("User service unreachable"); // DON'T return switch (cause) { case NetworkError.Timeout ignored -> new ServiceUnavailable("Timed out").promise(); default -> cause.promise(); }; ``` ``` -------------------------------- ### Smart Wrapper (Monad) Mental Model Examples in Java Source: https://github.com/siy/coding-technology/blob/main/series/part-01-foundations.md Provides illustrative examples of the 'Do, If/When Available' mental model using Java's Smart Wrappers (Monads) like Option, Result, and Promise. These examples show how operations are applied conditionally based on the wrapper's state. ```java // Option: "Do this, IF value is present" Option user = findUser(id); Option email = user.map(User::email); // You: "Extract email" // Option: "OK, I'll do that IF I have a user. I don't? Then I won't." ``` ```java // Result: "Do this, IF no error yet" Result email = Email.email(raw); Result user = email.flatMap(this::findByEmail); // You: "Find user by email" // Result: "OK, I'll do that IF email is valid. It failed? Then I skip this." ``` ```java // Promise: "Do this, WHEN result arrives" Promise user = fetchUser(id); Promise profile = user.flatMap(this::loadProfile); // You: "Load profile" // Promise: "OK, I'll do that WHEN the user fetch completes. Not done? I'll wait." ``` -------------------------------- ### Adapter with Exception Handling Example Source: https://github.com/siy/coding-technology/blob/main/book/appendix-a-api-reference.md Shows an example of creating a Promise by lifting a synchronous operation that might throw an exception into a Promise context using Promise.lift. Includes database query and user mapping. ```java public Promise findUser(UserId id) { return Promise.lift( CoreError::database, () -> jdbcTemplate.queryForObject( "SELECT * FROM users WHERE id = ?", new Object[]{id.value()}, this::mapUser) ); } ``` -------------------------------- ### Verify.ensure Usage Examples Source: https://github.com/siy/coding-technology/blob/main/book/appendix-a-api-reference.md Demonstrates the usage of Verify.ensure with Verify.Is predicates for performing runtime validations. Shows examples for string length and numeric range checks. ```java Verify.ensure(password, Verify.Is::lenBetween, 8, 128) Verify.ensure(age, Verify.Is::between, 0, 150) ``` -------------------------------- ### Factory Method Patterns for Type Creation (Java) Source: https://github.com/siy/coding-technology/blob/main/series/part-10-systematic-application.md This snippet demonstrates the pattern for writing factory methods in Java, focusing on validation and return types. It shows examples of factories for `Email` and `Config` records, illustrating how to incorporate validation and adhere to return type conventions. ```java public record Email(String value) { // Factory with validation → Result public static Result email(String raw) { return Verify.ensure(raw, Verify.Is::notNull) .map(String::trim) .filter(INVALID_EMAIL, s -> PATTERN.matcher(s).matches()) .map(Email::new); } } public record Config(DbUrl url, DbPassword pass) { // Factory without validation (fields pre-validated) → T public static Config config(DbUrl url, DbPassword pass) { return new Config(url, pass); } } ``` -------------------------------- ### Complete RTB Auction Pipeline Example (Java) Source: https://github.com/siy/coding-technology/blob/main/training/slides/session-3.md This Java code illustrates a complete Real-Time Bidding (RTB) auction pipeline, combining multiple design patterns. It starts with parsing a raw request (Adapter pattern), then proceeds to query DSPs in parallel (Fork-Join), evaluate bid responses (Iteration), and finally select the winning bid (Sequencer). The `processAuction` method orchestrates these steps, returning an `AuctionResult` wrapped in a Promise. ```java /// Process a complete RTB auction. Promise processAuction(String rawRequest) { // Adapter: parse external input return parseBidRequest(rawRequest) .toPromise() // Domain: fork to DSPs .flatMap(request -> queryAllDsps(request, getDsps()) // Domain: evaluate each response .map(responses -> evaluateAllBids(responses, request)) // Domain: select winner .flatMap(bids -> selectWinner(bids, request))); } /// Evaluate all bid responses (Iteration) Result> evaluateAllBids(List responses, BidRequest request) { return responses.stream() .map(r -> evaluateBid(r, request)) // Sequencer for each .filter(Result::isSuccess) .map(Result::unwrap) .collect(collectingAndThen(toList(), bids -> bids.isEmpty() ? Result.failure(BidError.NO_BIDS) : Result.success(bids))); } ``` -------------------------------- ### Example Usage Patterns Source: https://github.com/siy/coding-technology/blob/main/book/appendix-a-api-reference.md Illustrative examples demonstrating common patterns for using the provided utility libraries, such as handling exceptions and lifting synchronous results. ```APIDOC ## Example Usage Patterns ### Description Demonstrates practical application of the utility libraries in common scenarios like database access and asynchronous request handling. ### Method N/A (Illustrative code examples) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```java // Adapter with exception handling public Promise findUser(UserId id) { return Promise.lift( CoreError::database, () -> jdbcTemplate.queryForObject( "SELECT * FROM users WHERE id = ?", new Object[]{id.value()}, this::mapUser) ); } // Lifting sync Result to async Promise public Promise execute(Request request) { return ValidRequest.validRequest(request) // Result .async() // Promise .flatMap(step1::apply) .flatMap(step2::apply); } ``` ### Response #### Success Response (200) Illustrative code snippets showing how to implement common patterns. #### Response Example ```java // Code examples provided above. ``` ``` -------------------------------- ### JBCT CLI Installation and Basic Commands Source: https://github.com/siy/coding-technology/blob/main/training/slides/session-2.md Provides instructions for installing the JBCT CLI tool using Maven or direct download, and outlines basic commands for checking code against JBCT rules, formatting code, and initializing a new project configuration. ```bash # Install via Maven mvn dependency:get -Dartifact=org.pragmatica.jbct:jbct-cli:0.6.0 # Or download directly curl -L https://... -o jbct chmod +x jbct ``` ```bash # Check code against JBCT rules jbct check src/ # Format code to JBCT style jbct format src/ # Initialize new project with jbct.toml jbct init ``` -------------------------------- ### Example: Chaining Operations with Promise Source: https://github.com/siy/coding-technology/blob/main/book/ch02-four-return-types.md An example of executing a request by chaining operations using Promise. It starts with validating the request and then applies sequential steps. ```java public Promise execute(Request request) { return ValidRequest.validRequest(request) .async() // Result → Promise .flatMap(step1::apply) .flatMap(step2::apply); } ``` -------------------------------- ### Nested Record vs. Lambda Pattern in Java Source: https://github.com/siy/coding-technology/blob/main/book/ch16-systematic-application.md Provides examples for two implementation patterns: the nested record pattern for stateful objects and the lambda pattern for functional interfaces without state. The nested record example shows how to define a stateful cache, while the lambda example demonstrates a simple validation step. ```java static GenerationCache generationCache(WorkConfig config) { record generationCache( AtomicReference lastRefreshTime, ConcurrentMap cache, WorkConfig config ) implements GenerationCache { @Override public Result refresh() { ... } } return new generationCache( new AtomicReference<>(Instant.EPOCH), new ConcurrentHashMap<>(), config ); } ``` ```java static Step validate(Validator validator) { return ctx -> validator.validate(ctx.input()); } ``` -------------------------------- ### Pattern Separation: Sequencer vs. Fork-Join in Java Source: https://github.com/siy/coding-technology/blob/main/book/ch16-systematic-application.md Demonstrates how to refactor code that mixes Sequencer and Fork-Join operations. The 'VIOLATION' example shows a less optimal approach, while the 'FIX' example extracts the Fork-Join logic into a separate method for better clarity and maintainability. ```java // VIOLATION: Mixing Sequencer + Fork-Join return validate(request) .flatMap(req -> Result.all( checkInventory(req), validatePayment(req) ).map((inv, pay) -> proceed(req))); // FIX: Extract Fork-Join return validate(request) .flatMap(this::validateOrder) .flatMap(this::processOrder); private Result validateOrder(ValidRequest req) { return Result.all(checkInventory(req), validatePayment(req)) .map((inv, pay) -> req); } ``` -------------------------------- ### Install AI Tools for Claude Code Source: https://github.com/siy/coding-technology/blob/main/README.md Installs the necessary JBCT skills and agents for Claude Code integration, including jbct skill, jbct-coder, and jbct-reviewer. This setup facilitates learning, quick reference, pattern understanding, autonomous code generation, and code review for JBCT compliance. ```bash mkdir -p ~/.claude/skills ~/.claude/agents cp -r skills/jbct skills/jbct-review ~/.claude/skills/ cp jbct-coder.md jbct-reviewer.md ~/.claude/agents/ ``` -------------------------------- ### JBCT TOML Configuration File Example Source: https://github.com/siy/coding-technology/blob/main/training/slides/session-2.md Illustrates the structure and content of a 'jbct.toml' configuration file. It shows how to set project metadata, enable/disable specific rules, configure return type requirements (Result, Option), define naming conventions for factory methods, and set formatting options like indentation. ```toml # jbct.toml - JBCT configuration [project] name = "rtb-training" java-version = "25" [rules] # Which rules to enable (default: all) enabled = ["all"] # Rules to disable disabled = [] [rules.return-types] # Require Result for methods that can fail require-result = true # Require Option for nullable returns require-option = true [rules.naming] # Factory method naming: type() not of() or create() factory-style = "type-name" [format] # Indentation indent-size = 4 use-tabs = false ``` -------------------------------- ### Infrastructure Dependencies Definition and Example Source: https://github.com/siy/coding-technology/blob/main/proposals/rfc/RFC-0007-dependency-sections.md Defines [infra] dependencies as infrastructure components with shared instances, identified by artifactId starting with 'infra-'. These are loaded in SharedLibraryClassLoader with shared instances via InfraStore. ```ini [infra] org.pragmatica-lite.aether:infra-cache:^0.7.5 org.pragmatica-lite.aether:infra-database:^0.7.5 ``` -------------------------------- ### JBCT Configuration Example (jbct.toml) Source: https://github.com/siy/coding-technology/blob/main/CLI-TOOLING.md A sample `jbct.toml` file demonstrating various configuration options for formatting and linting. It includes settings for max line length, indent size, chained call alignment, and rule severities. ```toml [format] maxLineLength = 120 indentSize = 4 alignChainedCalls = true [lint] failOnWarning = false businessPackages = ["**.usecase.**", "**.domain.**"] slicePackages = ["**.usecase.**"] # Required for JBCT-SLICE-01 [lint.rules] JBCT-RET-01 = "error" JBCT-STY-01 = "warning" JBCT-LOG-01 = "off" ``` -------------------------------- ### Example Persistence Adapter Structure (Java) Source: https://github.com/siy/coding-technology/blob/main/CODING_GUIDE.md Shows the directory structure for a Java persistence adapter, specifically demonstrating how a repository implementation adheres to a use case's step interface. This highlights the adapter's role in implementing I/O operations. ```java com.example.app.adapter.persistence/ └── JooqProfileRepository.java # implements UpdateProfile.SaveProfile ``` -------------------------------- ### Java Cross-Field Validation Example Source: https://github.com/siy/coding-technology/blob/main/articles/parse-dont-validate.md Illustrates cross-field validation in Java with a `DateRange` record. It ensures that the end date is not before the start date, demonstrating how validation logic can depend on the relationship between multiple fields. ```java public record DateRange(LocalDate start, LocalDate end) { private static final Cause END_BEFORE_START = Causes.cause("End date must be after start date"); public static Result dateRange(LocalDate start, LocalDate end) { return Verify.ensure(end, e -> !e.isBefore(start), END_BEFORE_START) .map(_ -> new DateRange(start, end)); } } ``` -------------------------------- ### Repository Adapter Example (Java) Source: https://github.com/siy/coding-technology/blob/main/book/ch17-migration-strategies.md Demonstrates a repository adapter implementation in Java using JOOQ. It wraps database operations within a `Promise.lift` to ensure asynchronous execution and error handling, adhering to the adapter isolation principle. ```java // Step interface public interface SaveUser { Promise apply(ValidUser user); } // Adapter implementation @Repository public class JooqUserRepository implements SaveUser { private final DSLContext dsl; @Override public Promise apply(ValidUser user) { return Promise.lift( RepositoryError.DatabaseFailure::new, () -> { String id = dsl.insertInto(USERS) .set(USERS.EMAIL, user.email().value()) .set(USERS.PASSWORD_HASH, user.passwordHash().value()) .returningResult(USERS.ID) .fetchSingle() .value1(); return new UserId(id); } ); } } ``` -------------------------------- ### Steps as Single-Method Interfaces Example Source: https://github.com/siy/coding-technology/blob/main/TECHNOLOGY.md Demonstrates defining steps (e.g., CheckCredentials, SaveUser) as single-method interfaces. This allows them to be passed directly to flatMap via method references, promoting clean composition and testability. ```Java @FunctionalInterface public interface CheckCredentials { Result check(String username, String password); } // Usage within a sequencer: // Result userResult = ...; // Result credentialsCheckResult = userResult.flatMap(user -> checkCredentials.check(user.username(), user.password())); ``` -------------------------------- ### Data Flow Analysis Example Source: https://github.com/siy/coding-technology/blob/main/ai-tools/agents/jbct-coder.md Presents a visual representation of data flow analysis for an account creation process. It details the starting data, intermediate transformations (validation, fetching, hashing, saving), and the final response, highlighting dependencies between stages. ```text START: raw email, raw password │ ├─[validate]──→ Email, Password (validated) │ ├─[fetch]─────→ + Customer (from DB, needs Email) │ ├─[hash]──────→ + HashedPassword (needs Password) │ └─[save]──────→ UserId (needs Customer + HashedPassword) END: Response(UserId) ``` -------------------------------- ### Factory Method Pattern for Object Creation (Java) Source: https://github.com/siy/coding-technology/blob/main/book/ch16-systematic-application.md Provides examples of factory methods in Java for creating objects, demonstrating validation logic within the factory and returning `Result` for fallible creations. It also shows a simple factory for immutable records without explicit validation. ```java public record Email(String value) { // Factory with validation -> Result public static Result email(String raw) { return Verify.ensure(raw, Verify.Is::notNull) .map(String::trim) .filter(INVALID_EMAIL, s -> PATTERN.matcher(s).matches()) .map(Email::new); } } public record Config(DbUrl url, DbPassword pass) { // Factory without validation -> T public static Config config(DbUrl url, DbPassword pass) { return new Config(url, pass); } } ``` -------------------------------- ### Place Order Step Interfaces in Java Source: https://github.com/siy/coding-technology/blob/main/book/ch13-placeorder-example.md Defines the interfaces for each step in the place order use case, including checking inventory, reserving inventory, processing payment, creating the order record, sending confirmation, and releasing inventory. It also includes a factory method for assembling the complete order process with compensation logic. ```java package com.example.shop.usecase.placeorder; import org.pragmatica.lang.Promise; import org.pragmatica.lang.Result; import com.example.shop.domain.shared.OrderId; import com.example.shop.domain.shared.Money; public interface PlaceOrder { record Response(OrderId orderId, Money total) {} Promise execute(OrderRequest request); // Step 1: Check inventory for all items (Fork-Join) interface CheckInventory { Promise apply(ValidOrderRequest request); } // Step 2: Reserve inventory interface ReserveInventory { Promise apply(ValidOrderRequest request); } // Step 3: Process payment interface ProcessPayment { Promise apply(ReservedInventory reservation, Money total); } // Step 4: Create order record interface CreateOrder { Promise apply(ReservedInventory reservation, PaymentConfirmation payment); } // Step 5: Send confirmation (best-effort) interface SendConfirmation { Promise apply(OrderId orderId, ValidOrderRequest request); } // Step 6: Release inventory (compensation) interface ReleaseInventory { Promise apply(ReservedInventory reservation); } // Factory static PlaceOrder placeOrder( CheckInventory checkInventory, ReserveInventory reserveInventory, ProcessPayment processPayment, CreateOrder createOrder, SendConfirmation sendConfirmation, ReleaseInventory releaseInventory, PriceCalculator priceCalculator ) { return request -> ValidOrderRequest.validOrderRequest(request) .async() .flatMap(checkInventory::apply) .flatMap(valid -> executeWithCompensation( valid, reserveInventory, processPayment, createOrder, releaseInventory, priceCalculator )) .onSuccess(response -> sendConfirmation.apply(response.orderId(), null) .onFailure(e -> { /* log but don't fail */ })); } private static Promise executeWithCompensation( ValidOrderRequest request, ReserveInventory reserveInventory, ProcessPayment processPayment, CreateOrder createOrder, ReleaseInventory releaseInventory, PriceCalculator priceCalculator ) { var total = priceCalculator.calculate(request); return reserveInventory.apply(request) .flatMap(reservation -> processPayment.apply(reservation, total) .flatMap(payment -> createOrder.apply(reservation, payment)) .map(orderId -> new Response(orderId, total)) .recover(cause -> compensateAndFail(reservation, releaseInventory, cause))); } private static Promise compensateAndFail( ReservedInventory reservation, ReleaseInventory releaseInventory, Cause cause ) { return releaseInventory.apply(reservation) .flatMap(_ -> cause.promise()); } } ``` -------------------------------- ### Test Data Builder Pattern for Request Objects in Java Source: https://github.com/siy/coding-technology/blob/main/articles/integration-first-testing.md Implements a RequestBuilder class using the builder pattern to facilitate the creation of Request objects with customizable email and password fields. This pattern simplifies test setup by allowing chained method calls. The example shows how to instantiate and use the builder. ```java class RequestBuilder { private String email = "valid@example.com"; private String password = "ValidPassword123"; RequestBuilder withEmail(String email) { this.email = email; return this; } Request build() { return new Request(email, password); } } // Usage var request = new RequestBuilder().withEmail("invalid").build(); ``` -------------------------------- ### Sequencer Example: Bid Evaluation (Java) Source: https://github.com/siy/coding-technology/blob/main/training/slides/session-3.md An example of the Sequencer pattern applied to bid evaluation. It chains five steps: checking the deadline, matching targeting, applying floor price, calculating the final bid, and creating the Bid object. ```java import com.example.Result; import com.example.BidRequest; import com.example.BidResponse; import com.example.Bid; // Assuming Result, BidRequest, BidResponse, Bid types are defined elsewhere public class BidEvaluator { /// Evaluate a single bid response against the request. public Result evaluateBid(BidResponse response, BidRequest request) { return checkDeadline(request.deadline()) // Step 1: Time check .flatMap(_ -> matchTargeting(request)) // Step 2: Targeting .flatMap(amount -> applyFloorPrice( // Step 3: Floor response.amount(), request.floorPrice())) .flatMap(amount -> calculateFinalBid( // Step 4: Adjustments amount, request.placement())) .map(amount -> Bid.bid( response.dspId(), amount, response.adMarkup())); // Step 5: Create result } // Placeholder for checkDeadline private Result checkDeadline(Object deadline) { return Result.success(new Object()); } // Placeholder for matchTargeting private Result matchTargeting(BidRequest request) { return Result.success(new Object()); } // Placeholder for applyFloorPrice private Result applyFloorPrice(double amount, double floorPrice) { return Result.success(amount); } // Placeholder for calculateFinalBid private Result calculateFinalBid(double amount, Object placement) { return Result.success(amount); } // Assuming Bid.bid is a static factory method // Assuming BidResponse and BidRequest have necessary methods like deadline(), amount(), floorPrice(), etc. } ``` -------------------------------- ### Create Option Instances (Java) Source: https://github.com/siy/coding-technology/blob/main/book/appendix-a-api-reference.md Provides examples of creating `Option` instances, including present options (`some`, `present`), empty options (`none`, `empty`), and options from nullable values or Java's `Optional`. ```java Option.some(value) Option.present(value) // Alias for some() Option.none() Option.empty() // Alias for none() Option.option(nullable) // Converts null to none, value to some Option.from(Optional) // Converts Java Optional ``` -------------------------------- ### Configure Environment Variables for Leanpub API Key and Book Slug Source: https://github.com/siy/coding-technology/blob/main/book/LEANPUB_SETUP.md Sets environment variables for the Leanpub API key and book slug in the shell profile. This is essential for scripts or tools that interact with the Leanpub API. Ensure to replace placeholders with your actual key and slug. Reload the shell profile after adding these variables. ```bash export LEANPUB_API_KEY="your-api-key-here" export LEANPUB_BOOK_SLUG="jbct" # your book's URL slug ``` -------------------------------- ### Create Transitional Adapter for Legacy Code Source: https://github.com/siy/coding-technology/blob/main/book/ch17-migration-strategies.md Provides an example of a transitional adapter layer that wraps legacy Java services (which throw exceptions) with JBCT Promises. This facilitates gradual migration by allowing new JBCT code to interact with old code safely. ```java // Legacy service (throws exceptions) public class LegacyUserService { public User findUser(String id) throws UserNotFoundException { // ... legacy implementation } } // JBCT adapter wrapping legacy service public class UserServiceAdapter implements FindUser { private final LegacyUserService legacy; @Override public Promise apply(UserId id) { return Promise.lift( this::mapLegacyError, () -> legacy.findUser(id.value()) ); } private Cause mapLegacyError(Throwable t) { return switch (t) { case UserNotFoundException e -> UserError.NotFound.INSTANCE; default -> Causes.fromThrowable(t); }; } } ``` -------------------------------- ### Using fold() Alternatives for Monadic Operations (Java) Source: https://github.com/siy/coding-technology/blob/main/ai-tools/agents/jbct-coder.md Provides a guide and examples for preferring dedicated monadic methods over `fold()` for common scenarios involving Options and Results. It contrasts 'before' and 'after' code snippets to illustrate how alternatives like `async`, `toResult`, `map`, `or`, `onFailure`, and `option` lead to more explicit and readable code. ```java import io.vavr.control.Option; import io.vavr.control.Promise; import io.vavr.control.Result; import java.util.function.Function; import java.util.function.Supplier; // Assume Repository, NotFoundError, ConfigLoader, Log are defined elsewhere public class FoldAlternatives { // Dummy instances for compilation Repository repository = null; // Placeholder Log log = new Log(); // Placeholder String id = "someId"; String path = "somePath"; // Scenario: Option empty → error Promise public Promise handleOptionEmptyToErrorPromise() { // BEFORE: fold obscures intent // return repository.findById(id) // .fold( // () -> new NotFoundError(id).promise(), // order -> validateOrder(order) // ); // AFTER: intent is explicit return repository.findById(id) .async(new NotFoundError(id)) .flatMap(this::validateOrder); } // Scenario: Option empty → error Result public Result handleOptionEmptyToErrorResult() { Option opt = Option.none(); String errorMsg = "Option was empty"; // Instead of: opt.fold(() -> Result.failure(new IllegalArgumentException(errorMsg)), Result::success); return opt.toResult(new IllegalArgumentException(errorMsg)).flatMap(Result::success); } // Scenario: Option empty → default value public String handleOptionEmptyToDefault() { Option opt = Option.none(); String defaultValue = "default"; Function fn = String::toUpperCase; // Instead of: opt.fold(() -> defaultValue, fn); return opt.map(fn).or(defaultValue); } // Scenario: Result failure → log + Option public Option handleResultFailureToOption() { Result res = Result.failure(new Exception("Something went wrong")); // BEFORE: side effect mixed with transformation // return res.fold( // cause -> { log.error("Failed: {}", cause.getMessage()); return Option.none(); }, // Option::some // ); // AFTER: side effect separate return res.onFailure(cause -> log.error("Failed: {}", cause.getMessage())) .option(); } // Scenario: Result failure → fallback public String handleResultFailureToFallback() { Result res = Result.failure(new Exception("Failed to load")); String fallbackValue = "fallback"; // Instead of: res.fold(_ -> fallbackValue, Function.identity()); return res.or(fallbackValue); } // Dummy methods and classes for compilation private Promise validateOrder(Order order) { return Promise.successful(order); } } // Dummy classes/interfaces for compilation class Repository { Option findById(String id) { return Option.none(); } } class NotFoundError extends RuntimeException { public NotFoundError(String id) { super(id); } public Promise promise() { return null; } } class Order { } class ConfigLoader { public static Result load(String path) { return Result.failure(new Exception("Load failed")); } } class Log { public void error(String format, Object... args) { System.err.printf(format + "\n", args); } } ``` -------------------------------- ### User Registration Use Case Composition Example (Java) Source: https://github.com/siy/coding-technology/blob/main/ai-tools/agents/jbct-designer.md Demonstrates the composition of steps for a user registration use case using a fluent API style. It shows how validation, uniqueness checks, user creation, and welcome email sending are chained together, including asynchronous operations and error handling. ```java ValidRequest.validRequest(request) // Fork-Join validation .async() .flatMap(checkUniqueness::execute) // Leaf .flatMap(createUser::execute) // Leaf .flatMap(sendWelcome::execute) // Leaf ``` -------------------------------- ### Preview Website Locally Source: https://github.com/siy/coding-technology/blob/main/website/DEPLOYMENT.md Starts a local development server to preview the website. Changes made to the code will often be reflected in real-time. The default port is usually 8000. ```bash npm run dev ``` -------------------------------- ### Verify JBCT CLI Installation Source: https://github.com/siy/coding-technology/blob/main/CLI-TOOLING.md Verifies that the JBCT CLI has been installed correctly by checking its version. ```bash jbct --version ``` -------------------------------- ### Organize Project Structure for User Registration Source: https://github.com/siy/coding-technology/blob/main/book/appendix-b-exercises.md This example outlines a typical Java project structure for a user registration feature. It categorizes components into domain (value objects, errors), use case (interfaces, factory methods), and adapters (persistence, web). The structure promotes separation of concerns and modularity. Note that some interfaces like `UserRepository` are integrated directly into the use case. ```directory src/main/java/com/example/user/ ├── domain/ │ ├── Email.java # Value object │ ├── Password.java # Value object │ ├── Username.java # Value object │ └── RegistrationError.java # Domain errors ├── usecase/ │ └── RegisterUser.java # Use case with: │ # - Request record │ # - ValidRegistration record │ # - Response record │ # - Step interfaces (SaveUser, CheckEmailUnique, etc.) │ # - Factory method ├── adapter/ │ ├── persistence/ │ │ └── JpaUserRepository.java # Implements step interface │ └── web/ │ ├── UserController.java # REST controller │ └── UserDto.java # API DTO └── config/ └── UserConfiguration.java # Spring wiring ``` -------------------------------- ### Install JBCT AI Tools (Bash) Source: https://github.com/siy/coding-technology/blob/main/ai-tools/README.md This snippet demonstrates the quick installation process for all JBCT AI tools. It involves cloning the repository and copying the skills and agents to the Claude configuration directory. No external dependencies beyond Git and a standard Unix-like environment are required. ```bash # Clone repository git clone https://github.com/siy/coding-technology.git cd coding-technology/ai-tools # Install skills and agents cp -r skills agents ~/.claude/ ``` -------------------------------- ### Creating Option Instances Source: https://github.com/siy/coding-technology/blob/main/book/ch03-pragmatica-lite-essentials.md Provides examples of how to create instances of the Option type, representing the presence or absence of a value. It covers creating 'some' (present) and 'none' (empty) options, as well as converting nullable values. ```java // Option Option.some(value) // Present Option.none() // Empty Option.option(nullable) // null -> none, value -> some ``` -------------------------------- ### UserId Value Object Example - Java Source: https://github.com/siy/coding-technology/blob/main/ai-tools/skills/jbct/fundamentals/parse-dont-validate.md This Java code snippet provides a complete example of a UserId value object, demonstrating the "Parse, Don't Validate" principle. It includes validation for null and empty strings, and uses UUID.fromString to parse the input. ```java public record UserId(UUID value) { private static final Fn1 INVALID_USER_ID = Causes.forValue("Invalid user ID: {}"); private UserId {} public static Result userId(String raw) { return Verify.ensure(raw, Verify.Is::notNull) .map(String::trim) .filter(INVALID_USER_ID, Verify.Is::notEmpty) .flatMap(str -> Result.lift(() -> UUID.fromString(str)) .mapError(e -> INVALID_USER_ID.apply(raw))) .map(UserId::new); } public static Result userId(UUID value) { return Verify.ensure(value, Verify.Is::notNull) .mapError(e -> INVALID_USER_ID.apply("null")) .map(UserId::new); } } ``` -------------------------------- ### Instance Creation Source: https://github.com/siy/coding-technology/blob/main/book/manuscript/appendix-a-api-reference.md Provides examples for creating instances of Option, Result, and Promise. ```APIDOC ## Creating Instances ### Option ```java Option.some(value) Option.present(value) Option.none() Option.empty() Option.option(nullable) Option.from(Optional) ``` ### Result ```java Result.success(value) Result.ok(value) Result.unitResult() Result.failure(cause) Result.err(cause) ``` ### Promise ```java Promise.success(value) Promise.ok(value) Promise.unitPromise() Promise.failure(cause) Promise.resolved(Result result) Promise.promise() Promise.promise(Consumer>) Promise.promise(Supplier>) ``` ``` -------------------------------- ### Password Value Object Example - Java Source: https://github.com/siy/coding-technology/blob/main/ai-tools/skills/jbct/fundamentals/parse-dont-validate.md This Java code snippet provides a complete example of a Password value object, demonstrating the "Parse, Don't Validate" principle with multiple validation rules, such as minimum length, presence of digits, and presence of uppercase characters. ```java public record Password(String value) { private static final int MIN_LENGTH = 8; private static final Pattern HAS_DIGIT = Pattern.compile(".*\\d.*"); private static final Pattern HAS_UPPER = Pattern.compile(".*[A-Z].*"); private static final Fn1 TOO_SHORT = Causes.forValue("Password too short (min " + MIN_LENGTH + "): {}"); private static final Fn1 NO_DIGIT = Causes.forValue("Password must contain digit: {}"); private static final Fn1 NO_UPPER = Causes.forValue("Password must contain uppercase: {}"); private Password {} public static Result password(String raw) { return Verify.ensure(raw, Verify.Is::notNull) .map(String::trim) .filter(TOO_SHORT, s -> s.length() >= MIN_LENGTH) .filter(NO_DIGIT, HAS_DIGIT.asMatchPredicate()) .filter(NO_UPPER, HAS_UPPER.asMatchPredicate()) .map(Password::new); } } ``` -------------------------------- ### Static Import Example for Factory Method (Java) Source: https://github.com/siy/coding-technology/blob/main/CODING_GUIDE.md Illustrates how static imports can be used with the Factory Method pattern, allowing for cleaner call sites by directly referencing the factory method. ```java import static com.example.domain.Email.email; // At call site: var result = email(raw); // Clear what's being created ``` -------------------------------- ### Minimal TOML Blueprint Example Source: https://github.com/siy/coding-technology/blob/main/proposals/rfc/RFC-0005-blueprint-format.md A basic example of a `blueprint.toml` file containing only the essential top-level ID and a single slice entry. ```toml id = "org.example:my-app:1.0.0" [[slices]] artifact = "org.example:my-service:1.0.0" instances = 1 ``` -------------------------------- ### Example Implementations Source: https://github.com/siy/coding-technology/blob/main/book/manuscript/Book.txt Practical examples of common use cases like user registration, order placement, article publishing, and fund transfers. ```APIDOC ## Example Implementations ### Description This section provides practical examples for common scenarios including user registration, order placement, article publishing, and fund transfers. ### Method N/A ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response N/A ```