Lynda Kane
Salesforce Developers Group, Cleveland
Community Group Leader
Achievements
Who has earned a certification or superbadge in the past 3 months?
Who has started a new job recently?
Who is new to the Salesforce Developer Group in Cleveland?
Anything else to share?
Announcements & Upcoming Events
Join us in-person tomorrow morning!
9am at Common Grounds (Lorain &
N Rocky River Dr)
Local developers will be on hand to
help you start assessing the technical
debt in your SF org.
Congrats to Orlando!
We’re sad he’s no longer our co-Leader
but excited to see him help lead the
new Arts and Culture Nonprofit User
Group (Virtual)!
Akron WIT
11/19 Jingle & Mingle in-person event
Assessing and
Resolving Technical
Debt
Presented by Lynda Kane
Salesforce Team Lead, Great Minds PBC
“Le unchecked, technical
debt will ensure that the only
work that gets done is
unplanned work!”
Gene Kim, The Phoenix Project: A Novel About
IT, DevOps, and Helping Your Business Win
Tools for Assessing Technical Debt
Getting Started → Advanced
Advanced
●Tooling API Queries
w/Postman
●Static Code Analyzer
(PMD)
●Planned/Scheduled Full
Org Assessment
Intermediate
●Code/Config Reviews
●Salesforce Security
Scanner
●Org Data & Metadata
Queries (DevConsole,
VSCode, SF Inspector
Reloaded, Workbench)
●Deeper Manual
investigation
Beginner
●SF Internal Tools:
Health Check,
Optimizer
●AppExchange: Field
Trip, OrgCheck
●Vendor Tools:
Elements.cloud,
Metazoa, Sonar
●Premier Support: Org
Health Assessment,
Code Review, Expert
Coaching
Checkbox
SELECT Id, <FieldName>
FROM <Object>
WHERE <FieldName> = TRUE
●0 results - no records with box checked
●If # records = same # with no WHERE,
then all have same value (is this useful
data?)
Most Fields
SELECT Id, <FieldName>
FROM <Object>
WHERE <FieldName> != null
●0 results = field has no data in it
Query: Single Field Usage
SELECT Name, Label
FROM PermissionSet
WHERE Id NOT IN (
SELECT PermissionSetId
FROM PermissionSetAssignment
WHERE Assignee.IsActive = TRUE)
AND Id NOT IN (
SELECT PermissionSetId
FROM PermissionSetGroupComponent)
AND IsCustom = TRUE
Review/Considerations
●In Permission Set, click Manage
Assignments.
●Also check your Permission Set Groups
to see if the Permission Set is included.
●An active PermissionSetAssignment ≠
active User (Assignee)
●Should inactive Users be assigned
Permission Sets?
Query: Unassigned Permission Sets
SELECT Id, Name, FolderName,
Owner.Name
FROM Report
USING SCOPE allPrivate
WHERE Owner.IsActive = FALSE
●Don’t keep reports in the Private
Folders of Inactive Users
●Same for Dashboards
SELECT ID, FolderName,
RunningUser.Name
FROM Dashboard
WHERE RunningUser.IsActive = FALSE
●If the Running User is Inactive, edits
and scheduled runs result in errors.
Query: Reports/Dashboards with Inactive User
* This Tooling API Query can run in Developer Console with the Tooling API box unchecked.
SELECT Name, APIVersion
FROM ApexClass
WHERE NamespacePrefix = null
ORDER BY Name
https://developer.salesforce.com/docs/at
las.en-us.api_tooling.meta/api_tooling/to
oling_api_objects_apexclass.htm
Review/Considerations
●API of Class vs. Current Release API #
●Important code changes for API
versions.
●Other available Fields:
○Description
○ManageableState
○MasterLabel
○LengthWithoutComments
○Status
Tooling API Query: Apex Class API Version
* This Tooling API Query can run in Developer Console with the Tooling API box unchecked.
SELECT Name, APIVersion
FROM ApexTrigger
WHERE NamespacePrefix = null
ORDER BY Name
https://developer.salesforce.com/docs/at
las.en-us.api_tooling.meta/api_tooling/to
oling_api_objects_apextrigger.htm
Review/Considerations
●API of Trigger vs. Current Release API
#
●Trigger Framework?
●Other available Fields:
○Description
○ManageableState
○MasterLabel
○LengthWithoutComments
○Status
○Usage <After|Before>
<Insert|Update|Delete|Undelete>
Tooling API Query: Apex Trigger API Version
* This Tooling API Query can run in Developer Console with the Tooling API box unchecked.
SELECT Name, APIVersion
FROM ApexPage
WHERE NamespacePrefix = null
ORDER BY Name
https://developer.salesforce.com/docs/at
las.en-us.api_tooling.meta/api_tooling/to
oling_api_objects_apexpage.htm
Review/Considerations
●API of VF Page vs. Current Release API
#
●Important code changes for API
versions.
●Other available Fields:
○Description
○ManageableState
○MasterLabel
○ControllerType
○ControllerKey
●Other Tooling API Objects:
ApexComponent (if you have Visualforce
Components)
Tooling API Query: Visualforce API Version
In Developer Console, check the Tooling API box.
SELECT DeveloperName, APIVersion
FROM AuraDefinitionBundle
WHERE NamespacePrefix = null
ORDER BY DeveloperName
https://developer.salesforce.com/docs/at
las.en-us.api_tooling.meta/api_tooling/to
oling_api_objects_auradefinitionbundle.h
tm
Review/Considerations
●API of Component vs. Current Release
API #
●Important code changes for API
versions.
●Other available Fields:
○Description
○ManageableState
○MasterLabel
●Other Tooling API Objects:
AuraDefinition
Tooling API Query: Aura Component API Version
In Developer Console, check the Tooling API box.
SELECT DeveloperName, APIVersion
FROM LightningComponentBundle
WHERE NamespacePrefix = null
ORDER BY DeveloperName
https://developer.salesforce.com/docs/at
las.en-us.api_tooling.meta/api_tooling/to
oling_api_objects_lightningcomponentbu
ndle.htm
Review/Considerations
●API of Component vs. Current Release
API #
●Important code changes for API
versions.
●Other available Fields:
○Description
○ManageableState
○MasterLabel
○IsExposed
○TargetConfigs
●Other Tooling API Objects:
LightningComponentResource
Tooling API Query: LWC API Version
In Developer Console, check the Tooling API box.
SELECT MasterLabel, VersionNumber,
Status, ApiVersion, ProcessType,
RunInMode, IsTemplate
FROM Flow
WHERE ManageableState = ‘unmanaged’
ORDER BY MasterLabel, VersionNumber
Review/Considerations
●Pulls all versions in the org
○How many prior or inactive versions is
too many?
●May want to limit by ProcessType and
Status
●Survey Flows cannot be removed
●FSL Mobile Flows have no version #
●Cannot get Name/API Name when
querying more than 1 Flow
●Other Tooling API Objects:
FlowTestCoverage
Tooling API Query: Flow API Version
In Developer Console, check the Tooling API box.
SELECT ApexClassOrTriggerId,
ApexClassOrTrigger.Name,
NumLinesCovered, NumLinesUncovered
FROM ApexCodeCoverageAggregate
ORDER BY ApexClassOrTrigger.Name ASC
Review/Considerations
●To get %: NumLinesCovered /
(NumLinesCovered +
NumLinesUncovered)
●Cannot include API Version in this
query
●Tests need recent run in your org
Tooling API Query: Apex Code Coverage
Pre-recorded video: Assessing Tech Debt: Using Postman & Excel
(https://youtu.be/eH9Y_Najzv8)
Resources:
●Quick Start: Connect Postman to Salesforce
(https://trailhead.salesforce.com/content/learn/projects/quick-star
t-connect-postman-to-salesforce)
●Convert JSON to Excel
(https://www.howtogeek.com/775651/how-to-convert-a-json-file-t
o-microsoft-excel/)
●Import JSON to Google Sheets
(https://www.lupagedigital.com/blog/json-to-google-sheets/)
Tools: Postman, Excel, Google Sheets
Evaluate the Results
1.Data
Use Health Check, Optimizer & Queries
2.Document
Compile a single document (multiple pages ok)
with Health Check Warnings/Issues, Optimizer
Items, Query results
3.Highlight
Establish limits - highlight records outside them
4.Exceptions
Identify & explain exceptions
5.Share
Review findings with team/manager/stakeholders
Resolving Technical Debt
Well…more like managing it since it’s never gone
Establish Practice
●What guidelines should be following
when doing Config/Code work in your
Salesforce org?
○API Version
○Code Coverage
○Standards
○Best Practices
●When can exceptions be accepted?
Plan (ahead?)
●Conduct periodic assessments
●Establish a Code/Config Review
process in your Development Timeline
●Pick the tech debt items to improve
with SMART Goals! (Keep current
capacity/demand in mind)
●Communicate often!