From c6404812081323412f6303c921315c0ec91e60bb Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Mon, 20 Apr 2026 21:16:25 +0900 Subject: [PATCH 1/2] demos: introduce DevModule + rename bin/app.php to bin/be.php Each runnable demo (hello-world, medical-triage, user-registration, order-processing) now wraps Becoming with a per-demo DevBecoming that flushes the semantic log to var/log/.json in a finally block, so failed runs are captured too. The dev-specific bindings are isolated in DevModule (AppModule stays focused on the demo's own bindings). A generated var/log/.json is checked in alongside each demo as a reference transcript, readable without running the code. Co-Authored-By: Claude Opus 4.7 --- demos/hello-world/bin/be.php | 29 +++ .../hello-world/src/Becoming/DevBecoming.php | 47 +++++ demos/hello-world/src/Module/AppModule.php | 3 +- demos/hello-world/src/Module/DevModule.php | 26 +++ .../src/Module/DevSemanticLoggerProvider.php | 21 +++ demos/hello-world/var/log/hello-world.json | 35 ++++ demos/medical-triage/bin/be.php | 30 ++++ .../src/Becoming/DevBecoming.php | 47 +++++ demos/medical-triage/src/Module/DevModule.php | 26 +++ .../src/Module/DevSemanticLoggerProvider.php | 21 +++ .../var/log/medical-triage.json | 79 +++++++++ .../order-processing/bin/{app.php => be.php} | 19 +- .../src/Becoming/DevBecoming.php | 47 +++++ .../order-processing/src/Module/DevModule.php | 26 +++ .../src/Module/DevSemanticLoggerProvider.php | 21 +++ .../var/log/order-processing.json | 73 ++++++++ demos/user-registration/bin/be.php | 33 ++++ .../src/Becoming/DevBecoming.php | 47 +++++ .../src/Module/AppModule.php | 5 +- .../src/Module/DevModule.php | 26 +++ .../src/Module/DevSemanticLoggerProvider.php | 21 +++ .../var/log/user-registration.json | 166 ++++++++++++++++++ 22 files changed, 836 insertions(+), 12 deletions(-) create mode 100644 demos/hello-world/bin/be.php create mode 100644 demos/hello-world/src/Becoming/DevBecoming.php create mode 100644 demos/hello-world/src/Module/DevModule.php create mode 100644 demos/hello-world/src/Module/DevSemanticLoggerProvider.php create mode 100644 demos/hello-world/var/log/hello-world.json create mode 100644 demos/medical-triage/bin/be.php create mode 100644 demos/medical-triage/src/Becoming/DevBecoming.php create mode 100644 demos/medical-triage/src/Module/DevModule.php create mode 100644 demos/medical-triage/src/Module/DevSemanticLoggerProvider.php create mode 100644 demos/medical-triage/var/log/medical-triage.json rename demos/order-processing/bin/{app.php => be.php} (61%) create mode 100644 demos/order-processing/src/Becoming/DevBecoming.php create mode 100644 demos/order-processing/src/Module/DevModule.php create mode 100644 demos/order-processing/src/Module/DevSemanticLoggerProvider.php create mode 100644 demos/order-processing/var/log/order-processing.json create mode 100644 demos/user-registration/bin/be.php create mode 100644 demos/user-registration/src/Becoming/DevBecoming.php create mode 100644 demos/user-registration/src/Module/DevModule.php create mode 100644 demos/user-registration/src/Module/DevSemanticLoggerProvider.php create mode 100644 demos/user-registration/var/log/user-registration.json diff --git a/demos/hello-world/bin/be.php b/demos/hello-world/bin/be.php new file mode 100644 index 0000000..1a2109e --- /dev/null +++ b/demos/hello-world/bin/be.php @@ -0,0 +1,29 @@ +getInstance(BecomingInterface::class); + +$final = $becoming(new HelloInput(name: 'World')); +assert($final instanceof Hello); +printf("greeting: %s\n", $final->greeting); + +echo "\n--- stree ---\n"; +passthru('vendor/bin/stree ' . escapeshellarg(dirname(__DIR__) . '/var/log/hello-world.json')); diff --git a/demos/hello-world/src/Becoming/DevBecoming.php b/demos/hello-world/src/Becoming/DevBecoming.php new file mode 100644 index 0000000..08f0236 --- /dev/null +++ b/demos/hello-world/src/Becoming/DevBecoming.php @@ -0,0 +1,47 @@ +becoming)($input); + } finally { + $dir = dirname(__DIR__, 2) . '/var/log'; + if (! is_dir($dir)) { + mkdir($dir, 0755, true); + } + + file_put_contents( + $dir . '/hello-world.json', + json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), + ); + } + } +} diff --git a/demos/hello-world/src/Module/AppModule.php b/demos/hello-world/src/Module/AppModule.php index 4d83001..1b6107f 100644 --- a/demos/hello-world/src/Module/AppModule.php +++ b/demos/hello-world/src/Module/AppModule.php @@ -4,15 +4,14 @@ namespace Be\Pattern\Hello\Module; -use Be\Pattern\Hello\Reason\Greeting; use Be\Framework\Module\BeModule; +use Be\Pattern\Hello\Reason\Greeting; use Ray\Di\AbstractModule; final class AppModule extends AbstractModule { protected function configure(): void { - // Install BeModule with demo's semantic namespace $this->install(new BeModule('Be\Pattern\Hello\Semantic')); $this->bind(Greeting::class); diff --git a/demos/hello-world/src/Module/DevModule.php b/demos/hello-world/src/Module/DevModule.php new file mode 100644 index 0000000..8717ae1 --- /dev/null +++ b/demos/hello-world/src/Module/DevModule.php @@ -0,0 +1,26 @@ +install(new AppModule()); + + $this->bind(Becoming::class); + $this->bind(BecomingInterface::class)->to(DevBecoming::class); + $this->bind(SemanticLoggerInterface::class) + ->toProvider(DevSemanticLoggerProvider::class) + ->in(Scope::SINGLETON); + } +} diff --git a/demos/hello-world/src/Module/DevSemanticLoggerProvider.php b/demos/hello-world/src/Module/DevSemanticLoggerProvider.php new file mode 100644 index 0000000..6692934 --- /dev/null +++ b/demos/hello-world/src/Module/DevSemanticLoggerProvider.php @@ -0,0 +1,21 @@ + */ +final class DevSemanticLoggerProvider implements ProviderInterface +{ + #[Override] + public function get(): SemanticLoggerInterface + { + return new DevSemanticLogger(new SemanticLogger()); + } +} diff --git a/demos/hello-world/var/log/hello-world.json b/demos/hello-world/var/log/hello-world.json new file mode 100644 index 0000000..d3ea7f3 --- /dev/null +++ b/demos/hello-world/var/log/hello-world.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://koriym.github.io/Koriym.SemanticLogger/schemas/combined.json", + "open": { + "id": "becoming_open_1", + "type": "becoming_open", + "schemaUrl": "https://be-framework.org/schemas/becoming-open.json", + "context": { + "from": "Be\\Pattern\\Hello\\Input\\HelloInput", + "be": "Be\\Pattern\\Hello\\Final\\Hello", + "input": { + "name": "Be\\Pattern\\Hello\\Input\\HelloInput::name" + }, + "inject": { + "greeting": "Be\\Pattern\\Hello\\Reason\\Greeting" + } + } + }, + "close": { + "id": "becoming_final_1", + "type": "becoming_final", + "schemaUrl": "https://be-framework.org/schemas/becoming-final.json", + "context": { + "final": "Be\\Pattern\\Hello\\Final\\Hello", + "prop": { + "greeting": "Hello World" + } + }, + "openId": "becoming_open_1", + "profile": { + "wallTime": 0.0012128353118896484, + "xdebug": [], + "xhprof": [] + } + } +} \ No newline at end of file diff --git a/demos/medical-triage/bin/be.php b/demos/medical-triage/bin/be.php new file mode 100644 index 0000000..8b8abb5 --- /dev/null +++ b/demos/medical-triage/bin/be.php @@ -0,0 +1,30 @@ +getInstance(BecomingInterface::class); + +$final = $becoming(new PatientInput( + patientId: 'PT-10001', + chiefComplaint: 'severe chest pain', + consciousnessLevel: 0, +)); +printf("triage: %s\n", $final::class); + +echo "\n--- stree ---\n"; +passthru('vendor/bin/stree ' . escapeshellarg(dirname(__DIR__) . '/var/log/medical-triage.json')); diff --git a/demos/medical-triage/src/Becoming/DevBecoming.php b/demos/medical-triage/src/Becoming/DevBecoming.php new file mode 100644 index 0000000..aa3f90c --- /dev/null +++ b/demos/medical-triage/src/Becoming/DevBecoming.php @@ -0,0 +1,47 @@ +becoming)($input); + } finally { + $dir = dirname(__DIR__, 2) . '/var/log'; + if (! is_dir($dir)) { + mkdir($dir, 0755, true); + } + + file_put_contents( + $dir . '/medical-triage.json', + json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), + ); + } + } +} diff --git a/demos/medical-triage/src/Module/DevModule.php b/demos/medical-triage/src/Module/DevModule.php new file mode 100644 index 0000000..a4fa9d4 --- /dev/null +++ b/demos/medical-triage/src/Module/DevModule.php @@ -0,0 +1,26 @@ +install(new AppModule()); + + $this->bind(Becoming::class); + $this->bind(BecomingInterface::class)->to(DevBecoming::class); + $this->bind(SemanticLoggerInterface::class) + ->toProvider(DevSemanticLoggerProvider::class) + ->in(Scope::SINGLETON); + } +} diff --git a/demos/medical-triage/src/Module/DevSemanticLoggerProvider.php b/demos/medical-triage/src/Module/DevSemanticLoggerProvider.php new file mode 100644 index 0000000..d11e6a1 --- /dev/null +++ b/demos/medical-triage/src/Module/DevSemanticLoggerProvider.php @@ -0,0 +1,21 @@ + */ +final class DevSemanticLoggerProvider implements ProviderInterface +{ + #[Override] + public function get(): SemanticLoggerInterface + { + return new DevSemanticLogger(new SemanticLogger()); + } +} diff --git a/demos/medical-triage/var/log/medical-triage.json b/demos/medical-triage/var/log/medical-triage.json new file mode 100644 index 0000000..d630bc1 --- /dev/null +++ b/demos/medical-triage/var/log/medical-triage.json @@ -0,0 +1,79 @@ +{ + "$schema": "https://koriym.github.io/Koriym.SemanticLogger/schemas/combined.json", + "open": { + "id": "becoming_open_2", + "type": "becoming_open", + "schemaUrl": "https://be-framework.org/schemas/becoming-open.json", + "context": { + "from": "Be\\Pattern\\MedicalTriage\\Being\\TriageLevelDetermined", + "be": "Be\\Pattern\\MedicalTriage\\Final\\EmergencyAdmitted", + "input": { + "being": "Be\\Pattern\\MedicalTriage\\Being\\TriageLevelDetermined::being", + "patientId": "Be\\Pattern\\MedicalTriage\\Being\\TriageLevelDetermined::patientId" + }, + "inject": {} + }, + "open": { + "id": "becoming_open_1", + "type": "becoming_open", + "schemaUrl": "https://be-framework.org/schemas/becoming-open.json", + "context": { + "from": "Be\\Pattern\\MedicalTriage\\Input\\PatientInput", + "be": "Be\\Pattern\\MedicalTriage\\Being\\TriageLevelDetermined", + "input": { + "patientId": "Be\\Pattern\\MedicalTriage\\Input\\PatientInput::patientId", + "chiefComplaint": "Be\\Pattern\\MedicalTriage\\Input\\PatientInput::chiefComplaint", + "consciousnessLevel": "Be\\Pattern\\MedicalTriage\\Input\\PatientInput::consciousnessLevel" + }, + "inject": { + "protocol": "Be\\Pattern\\MedicalTriage\\Reason\\JTASProtocol" + } + } + } + }, + "close": { + "id": "becoming_final_1", + "type": "becoming_final", + "schemaUrl": "https://be-framework.org/schemas/becoming-final.json", + "context": { + "final": "Be\\Pattern\\MedicalTriage\\Final\\EmergencyAdmitted", + "prop": { + "admissionId": "ADM-20260420-9b8b8250", + "status": "admitted", + "triageCode": "RED", + "being": { + "triageCode": "RED" + }, + "patientId": "PT-10001" + } + }, + "openId": "becoming_open_2", + "profile": { + "wallTime": 0.00016999244689941406, + "xdebug": [], + "xhprof": [] + }, + "close": { + "id": "becoming_being_1", + "type": "becoming_being", + "schemaUrl": "https://be-framework.org/schemas/becoming-being.json", + "context": { + "being": "Be\\Pattern\\MedicalTriage\\Being\\TriageLevelDetermined", + "prop": { + "being": { + "triageCode": "RED" + }, + "patientId": "PT-10001", + "chiefComplaint": "severe chest pain", + "consciousnessLevel": 0 + } + }, + "openId": "becoming_open_1", + "profile": { + "wallTime": 0.0005319118499755859, + "xdebug": [], + "xhprof": [] + } + } + } +} \ No newline at end of file diff --git a/demos/order-processing/bin/app.php b/demos/order-processing/bin/be.php similarity index 61% rename from demos/order-processing/bin/app.php rename to demos/order-processing/bin/be.php index c90da65..af4c73c 100644 --- a/demos/order-processing/bin/app.php +++ b/demos/order-processing/bin/be.php @@ -6,15 +6,20 @@ require dirname(__DIR__) . '/vendor/autoload.php'; -use Be\Pattern\OrderProcessing\Input\OrderInput; -use Be\Pattern\OrderProcessing\Module\AppModule; -use Be\Framework\Becoming; +use Be\Framework\BecomingInterface; use Be\Framework\Exception\SemanticVariableException; +use Be\Pattern\OrderProcessing\Final\OrderConfirmed; +use Be\Pattern\OrderProcessing\Input\OrderInput; +use Be\Pattern\OrderProcessing\Module\DevModule; use Ray\Di\Injector; + +use function assert; use function dirname; +use function escapeshellarg; +use function passthru; -$injector = new Injector(new AppModule()); -$becoming = new Becoming($injector, __NAMESPACE__ . '\\Semantic'); +$injector = new Injector(new DevModule()); +$becoming = $injector->getInstance(BecomingInterface::class); $input = new OrderInput( cartId: 'CART-001', @@ -27,7 +32,7 @@ ); try { $order = $becoming($input); - assert($order instanceof Final\OrderConfirmed); + assert($order instanceof OrderConfirmed); echo "Order confirmed: {$order->orderId}" . PHP_EOL; } catch (SemanticVariableException $e) { $messages = $e->getErrors()->getMessages('ja'); @@ -35,3 +40,5 @@ echo $errorMessage . PHP_EOL; } +echo "\n--- stree ---\n"; +passthru('vendor/bin/stree ' . escapeshellarg(dirname(__DIR__) . '/var/log/order-processing.json')); diff --git a/demos/order-processing/src/Becoming/DevBecoming.php b/demos/order-processing/src/Becoming/DevBecoming.php new file mode 100644 index 0000000..3befb7a --- /dev/null +++ b/demos/order-processing/src/Becoming/DevBecoming.php @@ -0,0 +1,47 @@ +becoming)($input); + } finally { + $dir = dirname(__DIR__, 2) . '/var/log'; + if (! is_dir($dir)) { + mkdir($dir, 0755, true); + } + + file_put_contents( + $dir . '/order-processing.json', + json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), + ); + } + } +} diff --git a/demos/order-processing/src/Module/DevModule.php b/demos/order-processing/src/Module/DevModule.php new file mode 100644 index 0000000..6c34ad4 --- /dev/null +++ b/demos/order-processing/src/Module/DevModule.php @@ -0,0 +1,26 @@ +install(new AppModule()); + + $this->bind(Becoming::class); + $this->bind(BecomingInterface::class)->to(DevBecoming::class); + $this->bind(SemanticLoggerInterface::class) + ->toProvider(DevSemanticLoggerProvider::class) + ->in(Scope::SINGLETON); + } +} diff --git a/demos/order-processing/src/Module/DevSemanticLoggerProvider.php b/demos/order-processing/src/Module/DevSemanticLoggerProvider.php new file mode 100644 index 0000000..91fcc81 --- /dev/null +++ b/demos/order-processing/src/Module/DevSemanticLoggerProvider.php @@ -0,0 +1,21 @@ + */ +final class DevSemanticLoggerProvider implements ProviderInterface +{ + #[Override] + public function get(): SemanticLoggerInterface + { + return new DevSemanticLogger(new SemanticLogger()); + } +} diff --git a/demos/order-processing/var/log/order-processing.json b/demos/order-processing/var/log/order-processing.json new file mode 100644 index 0000000..cb5f5ff --- /dev/null +++ b/demos/order-processing/var/log/order-processing.json @@ -0,0 +1,73 @@ +{ + "$schema": "https://koriym.github.io/Koriym.SemanticLogger/schemas/combined.json", + "open": { + "id": "becoming_open_1", + "type": "becoming_open", + "schemaUrl": "https://be-framework.org/schemas/becoming-open.json", + "context": { + "from": "Be\\Pattern\\OrderProcessing\\Input\\OrderInput", + "be": "Be\\Pattern\\OrderProcessing\\Final\\OrderConfirmed", + "input": {}, + "inject": { + "inventory": "Be\\Pattern\\OrderProcessing\\Moment\\InventoryReserved", + "payment": "Be\\Pattern\\OrderProcessing\\Moment\\PaymentCompleted", + "shipping": "Be\\Pattern\\OrderProcessing\\Moment\\ShippingArranged", + "been": "Be\\Framework\\SemanticLog\\Been" + } + } + }, + "events": [ + { + "id": "order_finalized_1", + "type": "order_finalized", + "schemaUrl": "https://be-framework.github.io/schemas/order-processing/order-finalized.json", + "context": { + "orderId": "ORD-20260420-c4a4a63f", + "status": "confirmed" + }, + "openId": "becoming_open_1" + } + ], + "close": { + "id": "becoming_final_1", + "type": "becoming_final", + "schemaUrl": "https://be-framework.org/schemas/becoming-final.json", + "context": { + "final": "Be\\Pattern\\OrderProcessing\\Final\\OrderConfirmed", + "prop": { + "orderId": "ORD-20260420-c4a4a63f", + "status": "confirmed", + "inventory": { + "reservation": { + "reservationId": "RSV-TOKYO-20260420121532-6023" + }, + "productId": "PROD-001", + "quantity": 1, + "warehouseId": "WH-TOKYO-01" + }, + "payment": { + "capture": { + "authorizationCode": "AUTH-10000-94924765", + "amount": 10000 + }, + "cardNumber": "4111111111111111", + "amount": 10000 + }, + "shipping": { + "dispatch": { + "trackingNumber": "YAMATO-202604201215326160", + "shippingRate": 800 + }, + "carrierId": "YAMATO", + "address": "Tokyo, Japan" + } + } + }, + "openId": "becoming_open_1", + "profile": { + "wallTime": 0.0006489753723144531, + "xdebug": [], + "xhprof": [] + } + } +} \ No newline at end of file diff --git a/demos/user-registration/bin/be.php b/demos/user-registration/bin/be.php new file mode 100644 index 0000000..95d24a1 --- /dev/null +++ b/demos/user-registration/bin/be.php @@ -0,0 +1,33 @@ +getInstance(BecomingInterface::class); + +$final = $becoming(new RegistrationInput( + email: 'alice@example.com', + password: 'Str0ngP@ss', + displayName: 'Alice', +)); +assert($final instanceof UserRegistered); +printf("userId: %s\n", $final->userId); + +echo "\n--- stree ---\n"; +passthru('vendor/bin/stree ' . escapeshellarg(dirname(__DIR__) . '/var/log/user-registration.json')); diff --git a/demos/user-registration/src/Becoming/DevBecoming.php b/demos/user-registration/src/Becoming/DevBecoming.php new file mode 100644 index 0000000..2c32981 --- /dev/null +++ b/demos/user-registration/src/Becoming/DevBecoming.php @@ -0,0 +1,47 @@ +becoming)($input); + } finally { + $dir = dirname(__DIR__, 2) . '/var/log'; + if (! is_dir($dir)) { + mkdir($dir, 0755, true); + } + + file_put_contents( + $dir . '/user-registration.json', + json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), + ); + } + } +} diff --git a/demos/user-registration/src/Module/AppModule.php b/demos/user-registration/src/Module/AppModule.php index 6ee7859..94c69e0 100644 --- a/demos/user-registration/src/Module/AppModule.php +++ b/demos/user-registration/src/Module/AppModule.php @@ -4,26 +4,23 @@ namespace Be\Pattern\UserRegistration\Module; +use Be\Framework\Module\BeModule; use Be\Pattern\UserRegistration\Reason\EmailVerifier; use Be\Pattern\UserRegistration\Reason\EmailVerifierInterface; use Be\Pattern\UserRegistration\Reason\GravatarResolver; use Be\Pattern\UserRegistration\Reason\PasswordHasher; use Be\Pattern\UserRegistration\Reason\UserIdGenerator; use Be\Pattern\UserRegistration\Reason\WelcomeTokenGenerator; -use Be\Framework\Module\BeModule; use Ray\Di\AbstractModule; final class AppModule extends AbstractModule { protected function configure(): void { - // Install BeModule with demo's semantic namespace $this->install(new BeModule('Be\Pattern\UserRegistration\Semantic')); - // Reason bindings (via interface for testability) $this->bind(EmailVerifierInterface::class)->to(EmailVerifier::class); - // Reason bindings (concrete classes) $this->bind(PasswordHasher::class); $this->bind(GravatarResolver::class); $this->bind(UserIdGenerator::class); diff --git a/demos/user-registration/src/Module/DevModule.php b/demos/user-registration/src/Module/DevModule.php new file mode 100644 index 0000000..57927cb --- /dev/null +++ b/demos/user-registration/src/Module/DevModule.php @@ -0,0 +1,26 @@ +install(new AppModule()); + + $this->bind(Becoming::class); + $this->bind(BecomingInterface::class)->to(DevBecoming::class); + $this->bind(SemanticLoggerInterface::class) + ->toProvider(DevSemanticLoggerProvider::class) + ->in(Scope::SINGLETON); + } +} diff --git a/demos/user-registration/src/Module/DevSemanticLoggerProvider.php b/demos/user-registration/src/Module/DevSemanticLoggerProvider.php new file mode 100644 index 0000000..3ef5658 --- /dev/null +++ b/demos/user-registration/src/Module/DevSemanticLoggerProvider.php @@ -0,0 +1,21 @@ + */ +final class DevSemanticLoggerProvider implements ProviderInterface +{ + #[Override] + public function get(): SemanticLoggerInterface + { + return new DevSemanticLogger(new SemanticLogger()); + } +} diff --git a/demos/user-registration/var/log/user-registration.json b/demos/user-registration/var/log/user-registration.json new file mode 100644 index 0000000..6d2764a --- /dev/null +++ b/demos/user-registration/var/log/user-registration.json @@ -0,0 +1,166 @@ +{ + "$schema": "https://koriym.github.io/Koriym.SemanticLogger/schemas/combined.json", + "open": { + "id": "becoming_open_4", + "type": "becoming_open", + "schemaUrl": "https://be-framework.org/schemas/becoming-open.json", + "context": { + "from": "Be\\Pattern\\UserRegistration\\Being\\ProfileEnriched", + "be": "Be\\Pattern\\UserRegistration\\Final\\UserRegistered", + "input": { + "email": "Be\\Pattern\\UserRegistration\\Being\\ProfileEnriched::email", + "displayName": "Be\\Pattern\\UserRegistration\\Being\\ProfileEnriched::displayName", + "hashedPassword": "Be\\Pattern\\UserRegistration\\Being\\ProfileEnriched::hashedPassword", + "avatarUrl": "Be\\Pattern\\UserRegistration\\Being\\ProfileEnriched::avatarUrl" + }, + "inject": { + "idGen": "Be\\Pattern\\UserRegistration\\Reason\\UserIdGenerator", + "tokenGen": "Be\\Pattern\\UserRegistration\\Reason\\WelcomeTokenGenerator", + "been": "Be\\Framework\\SemanticLog\\Been" + } + }, + "open": { + "id": "becoming_open_3", + "type": "becoming_open", + "schemaUrl": "https://be-framework.org/schemas/becoming-open.json", + "context": { + "from": "Be\\Pattern\\UserRegistration\\Being\\PasswordHashed", + "be": "Be\\Pattern\\UserRegistration\\Being\\ProfileEnriched", + "input": { + "email": "Be\\Pattern\\UserRegistration\\Being\\PasswordHashed::email", + "displayName": "Be\\Pattern\\UserRegistration\\Being\\PasswordHashed::displayName", + "hashedPassword": "Be\\Pattern\\UserRegistration\\Being\\PasswordHashed::hashedPassword" + }, + "inject": { + "resolver": "Be\\Pattern\\UserRegistration\\Reason\\GravatarResolver" + } + }, + "open": { + "id": "becoming_open_2", + "type": "becoming_open", + "schemaUrl": "https://be-framework.org/schemas/becoming-open.json", + "context": { + "from": "Be\\Pattern\\UserRegistration\\Being\\EmailVerified", + "be": "Be\\Pattern\\UserRegistration\\Being\\PasswordHashed", + "input": { + "email": "Be\\Pattern\\UserRegistration\\Being\\EmailVerified::email", + "password": "Be\\Pattern\\UserRegistration\\Being\\EmailVerified::password", + "displayName": "Be\\Pattern\\UserRegistration\\Being\\EmailVerified::displayName" + }, + "inject": { + "hasher": "Be\\Pattern\\UserRegistration\\Reason\\PasswordHasher" + } + }, + "open": { + "id": "becoming_open_1", + "type": "becoming_open", + "schemaUrl": "https://be-framework.org/schemas/becoming-open.json", + "context": { + "from": "Be\\Pattern\\UserRegistration\\Input\\RegistrationInput", + "be": "Be\\Pattern\\UserRegistration\\Being\\EmailVerified", + "input": { + "email": "Be\\Pattern\\UserRegistration\\Input\\RegistrationInput::email", + "password": "Be\\Pattern\\UserRegistration\\Input\\RegistrationInput::password", + "displayName": "Be\\Pattern\\UserRegistration\\Input\\RegistrationInput::displayName" + }, + "inject": { + "verifier": "Be\\Pattern\\UserRegistration\\Reason\\EmailVerifier" + } + } + } + } + } + }, + "events": [ + { + "id": "user_created_1", + "type": "user_created", + "schemaUrl": "https://be-framework.github.io/schemas/user-registration/user-created.json", + "context": { + "userId": "USR-20260420-4a8ea3e35a511f52", + "email": "alice@example.com" + }, + "openId": "becoming_open_4" + } + ], + "close": { + "id": "becoming_final_1", + "type": "becoming_final", + "schemaUrl": "https://be-framework.org/schemas/becoming-final.json", + "context": { + "final": "Be\\Pattern\\UserRegistration\\Final\\UserRegistered", + "prop": { + "userId": "USR-20260420-4a8ea3e35a511f52", + "welcomeToken": "196f1352baaba5bbc37a810a7aada57f4ab0dc36220c72ff3f57e387358c71c3", + "email": "alice@example.com", + "displayName": "Alice", + "hashedPassword": "$2y$12$vuAfAU/rMJR5X9RBX9n5tue/QTX59e2sX7dmNvH8Pt70waNGBqTxO", + "avatarUrl": "https://www.gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060" + } + }, + "openId": "becoming_open_4", + "profile": { + "wallTime": 0.0009629726409912109, + "xdebug": [], + "xhprof": [] + }, + "close": { + "id": "becoming_being_3", + "type": "becoming_being", + "schemaUrl": "https://be-framework.org/schemas/becoming-being.json", + "context": { + "being": "Be\\Pattern\\UserRegistration\\Being\\ProfileEnriched", + "prop": { + "avatarUrl": "https://www.gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060", + "email": "alice@example.com", + "displayName": "Alice", + "hashedPassword": "$2y$12$vuAfAU/rMJR5X9RBX9n5tue/QTX59e2sX7dmNvH8Pt70waNGBqTxO" + } + }, + "openId": "becoming_open_3", + "profile": { + "wallTime": 0.0002300739288330078, + "xdebug": [], + "xhprof": [] + }, + "close": { + "id": "becoming_being_2", + "type": "becoming_being", + "schemaUrl": "https://be-framework.org/schemas/becoming-being.json", + "context": { + "being": "Be\\Pattern\\UserRegistration\\Being\\PasswordHashed", + "prop": { + "hashedPassword": "$2y$12$vuAfAU/rMJR5X9RBX9n5tue/QTX59e2sX7dmNvH8Pt70waNGBqTxO", + "email": "alice@example.com", + "displayName": "Alice" + } + }, + "openId": "becoming_open_2", + "profile": { + "wallTime": 0.22963809967041016, + "xdebug": [], + "xhprof": [] + }, + "close": { + "id": "becoming_being_1", + "type": "becoming_being", + "schemaUrl": "https://be-framework.org/schemas/becoming-being.json", + "context": { + "being": "Be\\Pattern\\UserRegistration\\Being\\EmailVerified", + "prop": { + "email": "alice@example.com", + "password": "Str0ngP@ss", + "displayName": "Alice" + } + }, + "openId": "becoming_open_1", + "profile": { + "wallTime": 0.0003638267517089844, + "xdebug": [], + "xhprof": [] + } + } + } + } + } +} \ No newline at end of file From cf6e6047b96bbbdde2542efc01a309ac342aba03 Mon Sep 17 00:00:00 2001 From: Akihito Koriyama Date: Mon, 20 Apr 2026 21:28:08 +0900 Subject: [PATCH 2/2] demos: append trailing newline to DevBecoming log output Co-Authored-By: Claude Opus 4.7 --- .../hello-world/src/Becoming/DevBecoming.php | 2 +- demos/hello-world/var/log/hello-world.json | 4 ++-- .../src/Becoming/DevBecoming.php | 2 +- .../var/log/medical-triage.json | 6 ++--- .../src/Becoming/DevBecoming.php | 2 +- .../var/log/order-processing.json | 14 ++++++------ .../src/Becoming/DevBecoming.php | 2 +- .../var/log/user-registration.json | 22 +++++++++---------- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/demos/hello-world/src/Becoming/DevBecoming.php b/demos/hello-world/src/Becoming/DevBecoming.php index 08f0236..c208246 100644 --- a/demos/hello-world/src/Becoming/DevBecoming.php +++ b/demos/hello-world/src/Becoming/DevBecoming.php @@ -40,7 +40,7 @@ public function __invoke(object $input): object file_put_contents( $dir . '/hello-world.json', - json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), + json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . PHP_EOL, ); } } diff --git a/demos/hello-world/var/log/hello-world.json b/demos/hello-world/var/log/hello-world.json index d3ea7f3..d7c3a53 100644 --- a/demos/hello-world/var/log/hello-world.json +++ b/demos/hello-world/var/log/hello-world.json @@ -27,9 +27,9 @@ }, "openId": "becoming_open_1", "profile": { - "wallTime": 0.0012128353118896484, + "wallTime": 0.0008828639984130859, "xdebug": [], "xhprof": [] } } -} \ No newline at end of file +} diff --git a/demos/medical-triage/src/Becoming/DevBecoming.php b/demos/medical-triage/src/Becoming/DevBecoming.php index aa3f90c..57b14da 100644 --- a/demos/medical-triage/src/Becoming/DevBecoming.php +++ b/demos/medical-triage/src/Becoming/DevBecoming.php @@ -40,7 +40,7 @@ public function __invoke(object $input): object file_put_contents( $dir . '/medical-triage.json', - json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), + json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . PHP_EOL, ); } } diff --git a/demos/medical-triage/var/log/medical-triage.json b/demos/medical-triage/var/log/medical-triage.json index d630bc1..9ac1276 100644 --- a/demos/medical-triage/var/log/medical-triage.json +++ b/demos/medical-triage/var/log/medical-triage.json @@ -49,7 +49,7 @@ }, "openId": "becoming_open_2", "profile": { - "wallTime": 0.00016999244689941406, + "wallTime": 0.0006999969482421875, "xdebug": [], "xhprof": [] }, @@ -70,10 +70,10 @@ }, "openId": "becoming_open_1", "profile": { - "wallTime": 0.0005319118499755859, + "wallTime": 0.001873016357421875, "xdebug": [], "xhprof": [] } } } -} \ No newline at end of file +} diff --git a/demos/order-processing/src/Becoming/DevBecoming.php b/demos/order-processing/src/Becoming/DevBecoming.php index 3befb7a..906575a 100644 --- a/demos/order-processing/src/Becoming/DevBecoming.php +++ b/demos/order-processing/src/Becoming/DevBecoming.php @@ -40,7 +40,7 @@ public function __invoke(object $input): object file_put_contents( $dir . '/order-processing.json', - json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), + json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . PHP_EOL, ); } } diff --git a/demos/order-processing/var/log/order-processing.json b/demos/order-processing/var/log/order-processing.json index cb5f5ff..76a4b9a 100644 --- a/demos/order-processing/var/log/order-processing.json +++ b/demos/order-processing/var/log/order-processing.json @@ -22,7 +22,7 @@ "type": "order_finalized", "schemaUrl": "https://be-framework.github.io/schemas/order-processing/order-finalized.json", "context": { - "orderId": "ORD-20260420-c4a4a63f", + "orderId": "ORD-20260420-f239e28a", "status": "confirmed" }, "openId": "becoming_open_1" @@ -35,11 +35,11 @@ "context": { "final": "Be\\Pattern\\OrderProcessing\\Final\\OrderConfirmed", "prop": { - "orderId": "ORD-20260420-c4a4a63f", + "orderId": "ORD-20260420-f239e28a", "status": "confirmed", "inventory": { "reservation": { - "reservationId": "RSV-TOKYO-20260420121532-6023" + "reservationId": "RSV-TOKYO-20260420122626-7948" }, "productId": "PROD-001", "quantity": 1, @@ -47,7 +47,7 @@ }, "payment": { "capture": { - "authorizationCode": "AUTH-10000-94924765", + "authorizationCode": "AUTH-10000-08e6ef82", "amount": 10000 }, "cardNumber": "4111111111111111", @@ -55,7 +55,7 @@ }, "shipping": { "dispatch": { - "trackingNumber": "YAMATO-202604201215326160", + "trackingNumber": "YAMATO-202604201226261461", "shippingRate": 800 }, "carrierId": "YAMATO", @@ -65,9 +65,9 @@ }, "openId": "becoming_open_1", "profile": { - "wallTime": 0.0006489753723144531, + "wallTime": 0.0006608963012695312, "xdebug": [], "xhprof": [] } } -} \ No newline at end of file +} diff --git a/demos/user-registration/src/Becoming/DevBecoming.php b/demos/user-registration/src/Becoming/DevBecoming.php index 2c32981..5987750 100644 --- a/demos/user-registration/src/Becoming/DevBecoming.php +++ b/demos/user-registration/src/Becoming/DevBecoming.php @@ -40,7 +40,7 @@ public function __invoke(object $input): object file_put_contents( $dir . '/user-registration.json', - json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), + json_encode($this->logger->flush(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . PHP_EOL, ); } } diff --git a/demos/user-registration/var/log/user-registration.json b/demos/user-registration/var/log/user-registration.json index 6d2764a..079cfee 100644 --- a/demos/user-registration/var/log/user-registration.json +++ b/demos/user-registration/var/log/user-registration.json @@ -77,7 +77,7 @@ "type": "user_created", "schemaUrl": "https://be-framework.github.io/schemas/user-registration/user-created.json", "context": { - "userId": "USR-20260420-4a8ea3e35a511f52", + "userId": "USR-20260420-fb66ef83c08236b2", "email": "alice@example.com" }, "openId": "becoming_open_4" @@ -90,17 +90,17 @@ "context": { "final": "Be\\Pattern\\UserRegistration\\Final\\UserRegistered", "prop": { - "userId": "USR-20260420-4a8ea3e35a511f52", - "welcomeToken": "196f1352baaba5bbc37a810a7aada57f4ab0dc36220c72ff3f57e387358c71c3", + "userId": "USR-20260420-fb66ef83c08236b2", + "welcomeToken": "870dc0778580246f38d7248c24085eed34828ba07ee29540919c4f9e79156b30", "email": "alice@example.com", "displayName": "Alice", - "hashedPassword": "$2y$12$vuAfAU/rMJR5X9RBX9n5tue/QTX59e2sX7dmNvH8Pt70waNGBqTxO", + "hashedPassword": "$2y$12$ypkeDoTNzeS8BYm/.HsG0uAYXsOsCraLvKseZ6kiR2jIml0rBSE8e", "avatarUrl": "https://www.gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060" } }, "openId": "becoming_open_4", "profile": { - "wallTime": 0.0009629726409912109, + "wallTime": 0.0009059906005859375, "xdebug": [], "xhprof": [] }, @@ -114,12 +114,12 @@ "avatarUrl": "https://www.gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060", "email": "alice@example.com", "displayName": "Alice", - "hashedPassword": "$2y$12$vuAfAU/rMJR5X9RBX9n5tue/QTX59e2sX7dmNvH8Pt70waNGBqTxO" + "hashedPassword": "$2y$12$ypkeDoTNzeS8BYm/.HsG0uAYXsOsCraLvKseZ6kiR2jIml0rBSE8e" } }, "openId": "becoming_open_3", "profile": { - "wallTime": 0.0002300739288330078, + "wallTime": 0.00021505355834960938, "xdebug": [], "xhprof": [] }, @@ -130,14 +130,14 @@ "context": { "being": "Be\\Pattern\\UserRegistration\\Being\\PasswordHashed", "prop": { - "hashedPassword": "$2y$12$vuAfAU/rMJR5X9RBX9n5tue/QTX59e2sX7dmNvH8Pt70waNGBqTxO", + "hashedPassword": "$2y$12$ypkeDoTNzeS8BYm/.HsG0uAYXsOsCraLvKseZ6kiR2jIml0rBSE8e", "email": "alice@example.com", "displayName": "Alice" } }, "openId": "becoming_open_2", "profile": { - "wallTime": 0.22963809967041016, + "wallTime": 0.23204898834228516, "xdebug": [], "xhprof": [] }, @@ -155,7 +155,7 @@ }, "openId": "becoming_open_1", "profile": { - "wallTime": 0.0003638267517089844, + "wallTime": 0.0007009506225585938, "xdebug": [], "xhprof": [] } @@ -163,4 +163,4 @@ } } } -} \ No newline at end of file +}