← Extractions

Scaling Spree: Maintaining an Open Source E-Commerce Framework

Rafael Zamaris of Upside, now lead maintainer of the Spree e-commerce framework, shares lessons from taking over a 15-year-old Rails-based open-source project. He covers three major challenges — roadmap/vision, upgrades, and maintainability of user customizations — and discusses how dependency injection, UI customization interfaces, and optional typing with Sorbet/RBS help keep users happy.

Model
claude-opus-4-7
Ingestion
23cc7ad0
Input tokens
289,244
fresh
190,964
cached
81,900
cache write
16,380
Output tokens
11,446
Duration
205.7s
Roundtrips
6
Tool calls
21
Cost
$0.00
Nodes/edges extracted
21 / 43
Read set (nodes/edges)
132 / 1

Nodes (21)

create Rafael Zamaris person
kind (empty) → person
name (empty) → Rafael Zamaris
slug (empty) → rafael-zamaris
attrs (empty) → {"role" => "lead maintainer of Spree", "employer" => "Upside"}
description (empty) → Software engineer at Upside who became lead maintainer of the Spree open-source e-commerce framework when Upside took...
short_description (empty) → Software engineer at Upside; lead maintainer of the Spree e-commerce framework.
update Upside company
attrs (empty) → {"industry" => "software consultancy", "role_in_spree" => "lead maintainer since 2022"}
description Company where Karol Szuster worked as a software engineer when presenting 'Nightmare neighbours' at wroclove.rb 2022. → Software consultancy / software house. Employer of Karol Szuster (wroclove.rb 2022) and Rafael Zamaris (wroclove.rb 2...
short_description Employer of Karol Szuster at the time of the 2022 talk. → Software consultancy/house; lead maintainer of the Spree e-commerce framework since 2022.
create Spree tool
kind (empty) → tool
name (empty) → Spree
slug (empty) → spree
attrs (empty) → {"domain" => "e-commerce", "license" => "open-source", "started" => "2008", "built_on" => "Ruby on Rails", "category"...
description (empty) → Open-source e-commerce framework built on top of Ruby on Rails. Started in 2008 (predates GitHub's public launch) wit...
short_description (empty) → Open-source Rails-based e-commerce framework; 15 years old, now maintained by Upside.
create Solidus tool
kind (empty) → tool
name (empty) → Solidus
slug (empty) → solidus
attrs (empty) → {"domain" => "e-commerce", "license" => "open-source", "category" => "framework", "relation_to_spree" => "fork"}
description (empty) → Open-source e-commerce framework that is a community fork of Spree, created when Spree lacked clear vision/roadmap an...
short_description (empty) → Community fork of Spree created when upstream was underactively maintained.
create Deface tool
kind (empty) → tool
name (empty) → Deface
slug (empty) → deface
attrs (empty) → {"category" => "library", "ecosystem" => "Rails"}
description (empty) → Rails gem that lets extensions override or inject HTML into markup rendered by a host application by selecting elemen...
short_description (empty) → Rails gem for injecting HTML into existing view markup via selectors.
create Klaviyo tool
kind (empty) → tool
name (empty) → Klaviyo
slug (empty) → klaviyo
attrs (empty) → {"domain" => "email marketing", "category" => "service"}
description (empty) → Popular email marketing platform. Cited in Rafael Zamaris's wroclove.rb 2023 talk as an example of an external tool t...
short_description (empty) → Email marketing platform with integrations for e-commerce stores including Spree.
create Sorbet tool
kind (empty) → tool
name (empty) → Sorbet
slug (empty) → sorbet
attrs (empty) → {"origin" => "Stripe", "category" => "tool", "language" => "Ruby"}
description (empty) → Gradual static type checker for Ruby, originally created by Stripe. Provides type signatures, runtime checks, and IDE...
short_description (empty) → Stripe-authored gradual static type checker for Ruby.
create Dollar Shave Club company
kind (empty) → company
name (empty) → Dollar Shave Club
slug (empty) → dollar-shave-club
attrs (empty) → {"industry" => "e-commerce / subscription"}
description (empty) → Subscription-based razor e-commerce business that popularized $1 shaving subscriptions and was later acquired by a la...
short_description (empty) → Subscription razor e-commerce company; emblem of the 2010s subscription-commerce trend.
create Be conservative with breaking changes in mature frameworks takeaway
kind (empty) → takeaway
name (empty) → Be conservative with breaking changes in mature frameworks
slug (empty) → be-conservative-with-breaking-changes-in-mature-frameworks
attrs (empty) → {"type" => "lesson-learned"}
description (empty) → Lesson from maintaining Spree: users commonly stay on 1–2-year-old versions because upgrades are hard to budget, so e...
short_description (empty) → Prefer stable interfaces over refactors; users' installations are often years old.
create Scaling an Open Source E-Commerce Framework talk
kind (empty) → talk
name (empty) → Scaling an Open Source E-Commerce Framework
slug (empty) → scaling-an-open-source-e-commerce-framework
attrs (empty) → {"type" => "talk"}
description (empty) → Rafael Zamaris's wroclove.rb 2023 talk sharing stories and lessons from Upside's first year as lead maintainer of the...
short_description (empty) → wroclove.rb 2023 talk on maintaining Spree — roadmap, upgrades and maintainability.
create Fat Model Thin Controller concept
kind (empty) → concept
name (empty) → Fat Model Thin Controller
slug (empty) → fat-model-thin-controller
attrs (empty) → {"category" => "pattern"}
description (empty) → Long-standing Rails convention of putting business logic in ActiveRecord models (with lifecycle hooks like before_upd...
short_description (empty) → Rails convention of concentrating business logic in ActiveRecord models with lean controllers.
create Monkey Patching concept
kind (empty) → concept
name (empty) → Monkey Patching
slug (empty) → monkey-patching
attrs (empty) → {"category" => "pattern"}
description (empty) → Ruby practice of opening and modifying existing classes or modules (including private methods) from consumer code. Hi...
short_description (empty) → Ruby practice of modifying existing classes/methods at runtime from outside their source.
create Depreciation Schedule concept
kind (empty) → concept
name (empty) → Depreciation Schedule
slug (empty) → depreciation-schedule
attrs (empty) → {"category" => "practice"}
description (empty) → Pattern recommended by Rafael Zamaris for evolving open-source frameworks: rather than silently breaking behavior bet...
short_description (empty) → Phased deprecation of legacy behavior with explicit warnings before removal.
create Optional Gradual Typing concept
kind (empty) → concept
name (empty) → Optional Gradual Typing
slug (empty) → optional-gradual-typing
attrs (empty) → {"category" => "practice"}
description (empty) → Attitude, popularized in the TypeScript community, of publishing type definitions with a library so consumers get edi...
short_description (empty) → Shipping type signatures that support users without forcing them.
create Treat users' rewrites as a loud red flag takeaway
kind (empty) → takeaway
name (empty) → Treat users' rewrites as a loud red flag
slug (empty) → treat-users-rewrites-as-a-loud-red-flag
attrs (empty) → {"type" => "warning"}
description (empty) → Rafael Zamaris's warning to open-source maintainers: nobody replatforms for fun (companies have nearly gone out of bu...
short_description (empty) → When users start replatforming, the maintainability issues are already serious.
create Publish a roadmap to align contributors takeaway
kind (empty) → takeaway
name (empty) → Publish a roadmap to align contributors
slug (empty) → publish-a-roadmap-to-align-contributors
attrs (empty) → {"type" => "recommendation"}
description (empty) → Once an open-source project hits meaningful adoption, publishing a roadmap (Spree uses GitHub Projects built from iss...
short_description (empty) → A public roadmap gives users certainty and focuses community contributions.
create Give users customization interfaces or they'll patch your privates takeaway
kind (empty) → takeaway
name (empty) → Give users customization interfaces or they'll patch your privates
slug (empty) → give-users-customization-interfaces-or-they-ll-patch-your-privates
attrs (empty) → {"type" => "recommendation"}
description (empty) → If a framework doesn't give users the right public interfaces to customize behavior, they will eventually treat priva...
short_description (empty) → Without proper extension points users override private methods, making refactoring impossible.
create Look outside Ruby for better patterns takeaway
kind (empty) → takeaway
name (empty) → Look outside Ruby for better patterns
slug (empty) → look-outside-ruby-for-better-patterns
attrs (empty) → {"type" => "recommendation"}
description (empty) → Closing recommendation from Rafael Zamaris: stop sticking to well-known Ruby/Rails patterns and look at how other com...
short_description (empty) → Borrow ideas from TypeScript, Java, .NET to improve Ruby projects.
create How do you collect information about how people monkey-patch Spree? question
kind (empty) → question
name (empty) → How do you collect information about how people monkey-patch Spree?
slug (empty) → how-do-you-collect-information-about-how-people-monkey-patch-spree
attrs (empty) → {"answer_summary" => "Primarily through paid support engagements helping users upgrade and refactor, plus community c...
description (empty) → Audience question about the data sources that drive Spree's refactoring decisions. Rafael's answer: mostly one-on-one...
short_description (empty) → How does the Spree team find out what to refactor into dependency-injection points?
create Why haven't you introduced events into Spree? question
kind (empty) → question
name (empty) → Why haven't you introduced events into Spree?
slug (empty) → why-haven-t-you-introduced-events-into-spree
attrs (empty) → {"answer_summary" => "Events would be too disruptive a breaking change right now; Spree prefers smaller incremental s...
description (empty) → Audience question observing that the direction of giving users hooks for customization could naturally evolve to an e...
short_description (empty) → Have you considered an event-driven extension model instead of dependency injection?
create Should 'add item' be split into add-new and increase-existing? question
kind (empty) → question
name (empty) → Should 'add item' be split into add-new and increase-existing?
slug (empty) → should-add-item-be-split-into-add-new-and-increase-existing
attrs (empty) → {"answer_summary" => "Internally the two branches already exist. A better answer is to ship two DI-configurable strat...
description (empty) → Audience suggestion that since whether adding a product creates a new cart item or increases an existing one differs ...
short_description (empty) → Should cart APIs expose separate methods for new vs existing items?

Edges (43)

create Rafael Zamaris → works_at → Upside
attrs (empty) → {"role" => "software engineer / Spree lead maintainer"}
context (empty) → Self-introduction: 'I work at Upside which is a software consultancy / software house'.
relation (empty) → works_at
source_node_id (empty) → aad43a41-5bd8-42fe-8d04-fce14426bcc6
target_node_id (empty) → c99a9df4-e84c-47ae-a936-91e092184ff0
create Rafael Zamaris → works_on → Spree
attrs (empty) → {"role" => "lead maintainer"}
context (empty) → Leads Spree maintenance on behalf of Upside, the framework's third lead maintainer since 2022.
relation (empty) → works_on
source_node_id (empty) → aad43a41-5bd8-42fe-8d04-fce14426bcc6
target_node_id (empty) → bb8d5927-6044-47cf-b709-85ad5a42d86e
create Upside → works_on → Spree
attrs (empty) → {"role" => "lead maintainer"}
context (empty) → Upside took over Spree as its third lead maintainer in 2022.
relation (empty) → works_on
source_node_id (empty) → c99a9df4-e84c-47ae-a936-91e092184ff0
target_node_id (empty) → bb8d5927-6044-47cf-b709-85ad5a42d86e
create Rafael Zamaris → authored → Scaling an Open Source E-Commerce Framework
context (empty) → Delivered the talk on maintaining Spree at wroclove.rb 2023.
relation (empty) → authored
source_node_id (empty) → aad43a41-5bd8-42fe-8d04-fce14426bcc6
target_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
create Scaling an Open Source E-Commerce Framework → presented_at → wroclove.rb 2023
context (empty) → Talk delivered at wroclove.rb 2023 (source date 2023-03-31).
relation (empty) → presented_at
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → f1adcf6d-780c-4418-8a81-c88da8b4e631
create Rafael Zamaris → attended → wroclove.rb 2023
context (empty) → Speaker at the conference.
relation (empty) → attended
source_node_id (empty) → aad43a41-5bd8-42fe-8d04-fce14426bcc6
target_node_id (empty) → f1adcf6d-780c-4418-8a81-c88da8b4e631
create Scaling an Open Source E-Commerce Framework → about → Spree
context (empty) → Primary subject of the talk — scaling and maintaining Spree.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → bb8d5927-6044-47cf-b709-85ad5a42d86e
create Scaling an Open Source E-Commerce Framework → about → Ruby on Rails
context (empty) → Discusses Rails patterns and upgrade pain as they affect Spree maintainers.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → 7aac705a-0987-49f2-b665-9d4e08a6acee
create Scaling an Open Source E-Commerce Framework → about → Solidus
context (empty) → Cites Solidus as a community fork created when Spree's roadmap faltered.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → 26699889-8b58-4e7f-9965-6bc6e513ea5e
create Scaling an Open Source E-Commerce Framework → about → Deface
context (empty) → Discusses Deface-based HTML injection as a brittle extension approach Spree is replacing.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → 977d9832-e84b-4d6b-8485-84891bc4093c
create Scaling an Open Source E-Commerce Framework → about → Monkey Patching
context (empty) → Analyzes monkey-patching as the legacy customization style in Spree and its maintenance costs.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → 055158a7-01d0-407c-b292-1ce630c6341a
create Scaling an Open Source E-Commerce Framework → about → Dependency Injection
context (empty) → Promotes Spree's built-in dependency-injection system as the replacement for monkey patching.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → 06941a97-6c62-4450-8f9a-16cf172f5dd8
create Scaling an Open Source E-Commerce Framework → about → Duck Typing
context (empty) → Discusses limits of duck typing and how to complement it with optional typing.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → ba1b876d-f3aa-4e60-aab2-5b33047ba9d2
create Scaling an Open Source E-Commerce Framework → about → Sorbet
context (empty) → Team is experimenting with Sorbet to type service-object interfaces in Spree.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → 382ece0b-b485-4d9d-b344-59755e8e0f39
create Scaling an Open Source E-Commerce Framework → about → RBS
context (empty) → Compared to Sorbet; RBS is closer to Ruby but harder to find examples for.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → bbf22e30-34ab-40fd-964c-783bf88a65a4
create Scaling an Open Source E-Commerce Framework → about → TypeScript
context (empty) → Cites TypeScript's culture of shipping optional types as a model for Ruby libraries.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → 43a67685-cd1a-4515-82f2-37f8f1670634
create Scaling an Open Source E-Commerce Framework → about → Fat Model Thin Controller
context (empty) → Identifies fat-model thin-controller as a historical design that complicated Spree maintenance.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → 0dee84c7-843e-481b-98eb-b6ee12dce2d8
create Scaling an Open Source E-Commerce Framework → about → Klaviyo
context (empty) → Klaviyo's integration with Spree-based stores depends on the legacy API, influencing deprecation strategy.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → 20489b1e-c5bb-4665-a935-3c1b674d48a8
create Scaling an Open Source E-Commerce Framework → about → Dollar Shave Club
context (empty) → Referenced as kicking off the subscription-commerce trend that drove Spree adoption.
relation (empty) → about
source_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
target_node_id (empty) → 22c7672c-9422-43b8-a679-7ec3ab6e9f18
create Spree → uses → Ruby on Rails
context (empty) → Spree is a Rails-based framework since 2008.
relation (empty) → uses
source_node_id (empty) → bb8d5927-6044-47cf-b709-85ad5a42d86e
target_node_id (empty) → 7aac705a-0987-49f2-b665-9d4e08a6acee
create Spree → uses → Deface
context (empty) → Spree extensions use Deface to inject HTML into core views; Upside effectively maintains Deface.
relation (empty) → uses
source_node_id (empty) → bb8d5927-6044-47cf-b709-85ad5a42d86e
target_node_id (empty) → 977d9832-e84b-4d6b-8485-84891bc4093c
create Solidus → related_to → Spree
attrs (empty) → {"relation_type" => "fork"}
context (empty) → Solidus is a community fork of Spree created during a period of weak upstream maintenance.
relation (empty) → related_to
source_node_id (empty) → 26699889-8b58-4e7f-9965-6bc6e513ea5e
target_node_id (empty) → bb8d5927-6044-47cf-b709-85ad5a42d86e
create Klaviyo → related_to → Spree
context (empty) → Klaviyo integrates with Spree stores via Spree's legacy API.
relation (empty) → related_to
source_node_id (empty) → 20489b1e-c5bb-4665-a935-3c1b674d48a8
target_node_id (empty) → bb8d5927-6044-47cf-b709-85ad5a42d86e
create Rafael Zamaris → uses → Sorbet
context (empty) → Experimenting with Sorbet in the Spree codebase to type service-object interfaces.
relation (empty) → uses
source_node_id (empty) → aad43a41-5bd8-42fe-8d04-fce14426bcc6
target_node_id (empty) → 382ece0b-b485-4d9d-b344-59755e8e0f39
create Rafael Zamaris → recommends → Dependency Injection
context (empty) → Advocates replacing monkey patches with dependency-injected service objects.
relation (empty) → recommends
source_node_id (empty) → aad43a41-5bd8-42fe-8d04-fce14426bcc6
target_node_id (empty) → 06941a97-6c62-4450-8f9a-16cf172f5dd8
create Rafael Zamaris → recommends → Optional Gradual Typing
context (empty) → Advocates shipping optional type signatures for Ruby libraries, à la TypeScript.
relation (empty) → recommends
source_node_id (empty) → aad43a41-5bd8-42fe-8d04-fce14426bcc6
target_node_id (empty) → 9bb24ecc-6be4-4259-9844-7bf18ffc1867
create Rafael Zamaris → recommends → Depreciation Schedule
context (empty) → Recommends explicit deprecation with log warnings over abrupt breaking changes.
relation (empty) → recommends
source_node_id (empty) → aad43a41-5bd8-42fe-8d04-fce14426bcc6
target_node_id (empty) → 6ac41279-c405-48fe-ae64-543c9802dd43
create Treat users' rewrites as a loud red flag → from_talk → Scaling an Open Source E-Commerce Framework
context (empty) → Extracted from the talk's discussion of how escalating issues push users to replatform.
relation (empty) → from_talk
source_node_id (empty) → d11743ec-dd50-4494-ac38-3d08c0249be4
target_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
create Publish a roadmap to align contributors → from_talk → Scaling an Open Source E-Commerce Framework
context (empty) → Extracted from the roadmap section of the talk.
relation (empty) → from_talk
source_node_id (empty) → 09829d67-fbb0-44d8-b47c-e13bfb329f6b
target_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
create Be conservative with breaking changes in mature frameworks → from_talk → Scaling an Open Source E-Commerce Framework
context (empty) → Extracted from the upgrades section of the talk.
relation (empty) → from_talk
source_node_id (empty) → 6eb2e9ac-dae0-4b49-b943-e655a7798d8e
target_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
create Give users customization interfaces or they'll patch your privates → from_talk → Scaling an Open Source E-Commerce Framework
context (empty) → Extracted from the maintainability / service-objects section of the talk.
relation (empty) → from_talk
source_node_id (empty) → 97b7ecb3-4d70-4cce-ae3a-fcfcaf712239
target_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
create Look outside Ruby for better patterns → from_talk → Scaling an Open Source E-Commerce Framework
context (empty) → Extracted from the talk's closing remarks.
relation (empty) → from_talk
source_node_id (empty) → 14dafc42-8ad1-4c1c-91e7-8ba816a534ae
target_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
create Give users customization interfaces or they'll patch your privates → about → Dependency Injection
context (empty) → The takeaway's prescription is to expose behavior via DI-configurable service objects.
relation (empty) → about
source_node_id (empty) → 97b7ecb3-4d70-4cce-ae3a-fcfcaf712239
target_node_id (empty) → 06941a97-6c62-4450-8f9a-16cf172f5dd8
create Give users customization interfaces or they'll patch your privates → about → Monkey Patching
context (empty) → The takeaway explains why monkey patching private methods is a dead end.
relation (empty) → about
source_node_id (empty) → 97b7ecb3-4d70-4cce-ae3a-fcfcaf712239
target_node_id (empty) → 055158a7-01d0-407c-b292-1ce630c6341a
create Publish a roadmap to align contributors → about → Spree
context (empty) → Derived from Spree's experience publishing a GitHub-based roadmap.
relation (empty) → about
source_node_id (empty) → 09829d67-fbb0-44d8-b47c-e13bfb329f6b
target_node_id (empty) → bb8d5927-6044-47cf-b709-85ad5a42d86e
create Be conservative with breaking changes in mature frameworks → about → Depreciation Schedule
context (empty) → Recommends depreciation schedules over refactor-first breaking changes.
relation (empty) → about
source_node_id (empty) → 6eb2e9ac-dae0-4b49-b943-e655a7798d8e
target_node_id (empty) → 6ac41279-c405-48fe-ae64-543c9802dd43
create Look outside Ruby for better patterns → about → TypeScript
context (empty) → Explicitly cites TypeScript's typing culture as worth borrowing.
relation (empty) → about
source_node_id (empty) → 14dafc42-8ad1-4c1c-91e7-8ba816a534ae
target_node_id (empty) → 43a67685-cd1a-4515-82f2-37f8f1670634
create How do you collect information about how people monkey-patch Spree? → asked_at → Scaling an Open Source E-Commerce Framework
context (empty) → Audience question during Q&A.
relation (empty) → asked_at
source_node_id (empty) → ad73a23a-3478-4e03-abc0-34ed866bdef8
target_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
create Why haven't you introduced events into Spree? → asked_at → Scaling an Open Source E-Commerce Framework
context (empty) → Audience question during Q&A.
relation (empty) → asked_at
source_node_id (empty) → ba56100e-948b-4180-9542-6cb468ba823f
target_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
create Should 'add item' be split into add-new and increase-existing? → asked_at → Scaling an Open Source E-Commerce Framework
context (empty) → Audience question during Q&A.
relation (empty) → asked_at
source_node_id (empty) → 36099d0e-d595-4ba0-9beb-7337c3b9cf50
target_node_id (empty) → 85cc629a-66eb-40ca-a046-da26f3aa69a1
create How do you collect information about how people monkey-patch Spree? → about → Monkey Patching
context (empty) → Question is about which patches to observe and refactor away.
relation (empty) → about
source_node_id (empty) → ad73a23a-3478-4e03-abc0-34ed866bdef8
target_node_id (empty) → 055158a7-01d0-407c-b292-1ce630c6341a
create Why haven't you introduced events into Spree? → about → Solidus
context (empty) → Answer references Solidus's partial event experiments.
relation (empty) → about
source_node_id (empty) → ba56100e-948b-4180-9542-6cb468ba823f
target_node_id (empty) → 26699889-8b58-4e7f-9965-6bc6e513ea5e
create Should 'add item' be split into add-new and increase-existing? → about → Dependency Injection
context (empty) → Answer proposes shipping two DI-configurable strategies.
relation (empty) → about
source_node_id (empty) → 36099d0e-d595-4ba0-9beb-7337c3b9cf50
target_node_id (empty) → 06941a97-6c62-4450-8f9a-16cf172f5dd8

Read set

132 nodes

concept Cynefin Framework search_nodes project rails_event_store/ecommerce search_nodes company Shopify search_nodes tool Active Admin search_nodes tool Jumpstart Pro search_nodes tool cssbundling-rails search_nodes tool ViewComponent search_nodes company Helpling search_nodes project monolith framework search_nodes project Rails World Website search_nodes company Upside search_nodes+get_node_edges takeaway Name Things To Find Their Properties search_nodes tool ChatGPT search_nodes tool RealtimeBoard search_nodes project Ruby News search_nodes tool Uppy search_nodes project Ruby Romania search_nodes resource Rocket Real-Time Benchmark search_nodes takeaway Trailblazer tracing saves thousands of debugging hours search_nodes project AlphaZero search_nodes tool Ruby on Rails search_nodes tool Ruby search_nodes event Rails World search_nodes resource Woman on Rails search_nodes tool Rails 5.2 search_nodes takeaway Ruby as a Data Management Language search_nodes project logux-rails search_nodes talk When REST is Not Enough: Implementing Alternative Protocols in Ruby on Rails search_nodes talk Ruby on a $4 Computer search_nodes talk Introducing Sorbet into your Ruby codebase search_nodes tool Flow search_nodes tool dry-types search_nodes tool dry-struct search_nodes tool ruby-contracts search_nodes concept Duck Typing search_nodes tool Traveling Ruby search_nodes tool RBS search_nodes tool Standard RB search_nodes question Is Ruby dying? search_nodes tool RuboCop search_nodes concept Dependency Injection search_nodes takeaway Inject test doubles via dependency injection search_nodes concept Opaque Dependencies search_nodes question Can service objects and command handlers call each other? search_nodes tool dry-container search_nodes concept MVC Modularity Violations search_nodes concept Params-Driven Development search_nodes concept Aspect-Oriented Programming search_nodes concept Call Graph Visualization search_nodes takeaway Prefer class-method services over stateful service objects search_nodes concept Refinements search_nodes concept Ruby Module Customization Mechanics search_nodes concept ActiveSupport Core Extensions search_nodes takeaway Use Refinements for Coordinated Modernization search_nodes person Akira Matsuda search_nodes concept Method References in Ruby search_nodes talk To Refine or Not to Refine search_nodes concept yield_self search_nodes talk Methods Gem for Ruby Method References search_nodes takeaway Don't reuse service objects across applications search_nodes project granite search_nodes concept Rails Reload-Safe ES Configuration search_nodes tool aggregate_root search_nodes concept Pre-Compile Engine Assets at Build Time search_nodes concept Rails RouteSet clear search_nodes takeaway Don't create controllers at Rails boot time search_nodes concept Rails Engine search_nodes tool Webpacker search_nodes question Should enterprise libraries be paid or free? search_nodes tool Release Drafter search_nodes resource awesome-ddd search_nodes takeaway Be kind and build useful things search_nodes tool reviewdog search_nodes tool PR Labeler search_nodes concept Commit Transformations search_nodes tool Codecov search_nodes question How to detect coupling in a large existing project? search_nodes talk Ever shorter feedback loop search_nodes event wroclove.rb 2023 search_nodes event wroclove.rb 2022 search_nodes event wroclove.rb 2024 search_nodes event wroclove.rb 2019 search_nodes event wroclove.rb 2018 search_nodes event wroclove.rb 2025 search_nodes event wroclove.rb 2026 search_nodes talk Building LLM powered applications in Ruby search_nodes talk How wroclove.rb impacts developers and companies search_nodes talk Towards the post framework future search_nodes tool Discourse search_nodes talk Multi-region data governance in Rails application search_nodes talk Nightmare neighbours caveats of Rails based mutlitenancy search_nodes talk Working with RailsEventStore in Cashflow Management System search_nodes takeaway Contribute to Arkency aggregates repository search_nodes company Amplifr search_nodes concept Unique Per-Site Email Leak Detection search_nodes talk Events events events search_nodes company Auth0 search_nodes tool GraphQL search_nodes concept Direct Upload to Cloud search_nodes company Salesforce search_nodes takeaway Use Unique Per-Site Emails To Catch Leaks search_nodes company SpaceX search_nodes talk Offline Sandwich Focus Workflow search_nodes takeaway Buy Faster Hardware search_nodes question Projections affecting many streams at once search_nodes question Cross-region business reporting aggregation search_nodes tool knapsack_pro search_nodes concept Data Tokenization search_nodes concept Service Object search_nodes concept Stateless Service Object search_nodes talk The Curse of Service Object search_nodes question Wrapper Job vs Logic In Job search_nodes tool interactor search_nodes takeaway Service objects are mappers from params to commands search_nodes tool TypeScript search_nodes question Would you recommend TypeScript or Flow? search_nodes takeaway Adopt TypeScript or Flow for maintainability search_nodes tool ESLint search_nodes tool esbuild search_nodes tool PureScript search_nodes concept TC39 search_nodes tool GitHub Releases search_nodes concept GitHub Self-Hosted Runner search_nodes tool GitHub Actions search_nodes tool actions/upload-artifact search_nodes tool Rust search_nodes tool Brotli search_nodes person Adam Okoń search_nodes talk Ruby Standard Library Hidden Gems Lightning Talk search_nodes resource 12 Ways to Call a Method in Ruby search_nodes company Transloadit search_nodes concept Idempotency Key search_nodes

1 edges