SFDO-Community / declarative-lookup-rollup-summaries

Declarative Lookup Rollup Summaries (DLRS) is a community built and maintained Salesforce application that allows you to create cross object roll-ups declaratively - no code! For install instructions and documentation, visit our website https://sfdo-community-sprints.github.io/DLRS-Documentation/
https://sfdo-community-sprints.github.io/DLRS-Documentation/
BSD 3-Clause "New" or "Revised" License
693 stars 237 forks source link

DLRS should work towards not needing an API-enabled session to manage it's configuration/triggers #1060

Closed aheber closed 5 months ago

aheber commented 3 years ago

[I expect discussion around this, I doubt I'm going to cover all the edge cases in my first draft. Please add or make arguments for or against.]

Is your feature request related to a problem? Please describe. A common issue is users receiving an Salesforce Metadata API connection failure... error message which can be caused by all sorts of things, some of them are missing remote site settings and others are limitations caused by how Salesforce session security can be managed. (Limit to originating IP being one example)

Describe the solution you'd like If I understand correctly DLRS currently uses sessions taken from the UI to change Metadata Records and to manage child triggers. Most of changing Metadata records could be done without the Metadata API using Apex platform APIs.

If we make that change we don't need API Access to create or update Metadata Records. The asynchronous Metadata Changes aren't my favorite but it would eliminate a whole class of connectivity issues. We could inactivate rollups through that update path by changing the Active__c field value. Actually deleting records through our custom UI would be more difficult (if I'm right in remembering the existing API's don't support delete). This could be handled by asynchronous code like from inside a Queueable, making the assumption that these orgs have My Domain enabled and we could use the platform APIs to get the root org URL. If they do not have My Domain enabled then we could fall back to leveraging a session taken from the UI, just as we do today with the known limitations. A concern would be how do we communicate back to the user the progress and outcome of changes done asynchronously?

API to get the canonical URL for an org

Async Context Gets a Usable Session Id

In asynchronous Apex (Batch, Future, Queueable, or Scheduled Apex), this method returns the session ID only when the code is run by an active, valid user.

The other significant challenge will be the ability to manage the child triggers. I don't think we can do this without using some kind of external APIs. I suggest we invest in being able to do this through async code with some method for monitoring progress, would be a similar solution to how we might handle this for Custom Metadata record deletes.

Side benefit to this would mean we wouldn't need to be hosted in a Visualforce Page anymore and could move the UI to Lightning Components hosted natively on the platform. Knowing the application could get some significant UI efforts to clean up UX I believe this would be a significant improvement.

Describe alternatives you've considered The current pattern works for most orgs but has been a significant frustration for a subset of users of the years. The current pattern is arguably against best practices on the platform. I only say that in a "if Salesforce wanted it to work this way they would make it easier" logical conclusion related to using a session pulled from the UI. A lot of these newer patterns I'm recommending weren't available when DLRS was originally introduced and I suspect some of the newer patterns were at least a little influenced by the difficulties this application has had trying to do this work.

aheber commented 3 years ago

Another less-ideal option for me might be if we considered having an alternate path where we could leverage a Named Credential (created and managed by the user) instead of trying to pull the UI Session. It would be more work to setup but could provide a path for those orgs where the session is never going to work out. Still better than expecting them to hand-manage Custom Metadata Records and hand-deploy triggers/test code.

brianmfear commented 3 years ago

The Metadata REST API would be awesome to use, we can deploy new changes and delete old triggers, if necessary. The Named Credential flow is one option, but it might be even easier if we can just do a direct OAuth login at the moment they need to do a deployment. If we're allowed to include OSS, Zippex can build the ZIP file we need for deployment, then make a direct REST call from the server. After that, it's just a matter of polling the server until it's done. What do you think?

aheber commented 3 years ago

@brianmfear, I'm trying to imagine how we do direct OAuth without an external server. In the past this project hasn't needed an external support server and the idea of adding one would have significant security implications. If we just get the session from a Queueable/async context then for the most part we shouldn't need any kind of OAuth, yes? I think it might require that the user has API access but that is already a given for administering this application.

aheber commented 5 months ago

Much of this is implemented in our new LWC wizard, available in v2.21. We still need to use the SOAP API to delete CMDT records as well as deploy the triggers but those actions aren't available via the Apex Metadata API. We are working towards getting the Session ID via Async context instead of taking it from the VF session. The deletes in the LWC UI are doing that and I hope to move the triggers down the road too.