Automating Dependency Analysis and Pack Selection for Monolithic Apps: Is It Possible?

This message was imported from the Ruby/Rails Modularity Slack server. Find more info in the import thread.

After spending a couple of weeks pretty much focused on hand-picking files from our main app to move into new/existing packs, deciding a layer for each of those packs and so on… I’ve just confirmed what we all know already: this is hard stuff and it takes longer than we want. :sweat_smile: But then an idea came to mind… do you think it would be possible to leverage the nice tooling they guys at Gusto have created… to try and automate something around this?

I’m not talking about something perfect. Not even close. But something to start with. Something that could analyze the existing dependencies in a monolith via packwerk and then suggest the set of X packs that would throw the least amount of violations/todos… :thinking_face:. The resulting architecture might not reflect the reality of the project from a business POV, but it would from the POV of the existing code. This could mean less work to take it from there to a point where the process to transition into a better architecture is done with less “noise”. I might be just dreaming an impossible here…

Message originally sent by slack user U721PQJPN3K

This actually was a pretty solid idea that helped me
https://rubymod.slack.com/archives/C0164JN9H5F/p1692896472151559

Oh! that’s great!

thanks for the pointer.

Message originally sent by slack user U7213XMGS3H

Oh and please let me know how it goes!

Message originally sent by slack user U7213XMGS3H

And if you rif on it!

Message originally sent by slack user U7213XMGS3H

I think it could be awesome to make a gem to suggest “good enough” packs

I guess I first need to learn more about neo4j or some other graph theory-related tool and… and… convince some key stake-holders that it’s ok for me to reserve a bunch of time for this :sweat_smile:

But at least it’s refreshing to know I’m not the only one feeling a tool like this could be useful.

Message originally sent by slack user U721PQJPN3K

If it’s helpful, here was the rake task I put together. Guessing it can be improved but I am a noob at graph dbs as well

desc "Send ActiveRecord models and their associations to Neo4j for visualization"
  task neo4j_relations: :environment do
    # Eager load all application classes (including models)
    Rails.application.eager_load!

    driver = Neo4j::Driver::GraphDatabase.driver('<bolt://localhost:7687>') # replace with your Neo4j configuration

    ActiveRecord::Base.descendants.each do |model|
      next if model.abstract_class?

      session = driver.session
      session.write_transaction do |tx|
        tx.run("CREATE (a:Model {name: '#{model.name}'})") # Create nodes for each model

        model.reflections.each do |name, reflection|
          target_model = reflection.class_name
          relation = reflection.macro.to_s

          # Create relationships between models
          tx.run("MATCH (a:Model {name: '#{model.name}'}), (b:Model {name: '#{target_model}'})
                 MERGE (a)-[r:#{relation.upcase}]->(b)")
        end
      end
      session.close
    end
  end

Thanks for sharing!

Message originally sent by slack user U7213XMGS3H

this is very similar to what i did, i went to json first