🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)
🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)

🔧 Programmierung 🕛 kürzlich 5 Min Lesezeit
0

Building Skill Align - Part 6 - Project Staffing Assistant(Backend)

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

I started with the first feature in this project: Project Staffing Assistant.



Project Staffing Assistant helps managers decide which candidates are suitable for a project based on actual project requirements.



I began with the backend, building the intelligence layer in Apex.









The Core Service – SkillEvaluatorService




CODE
public with sharing class SkillEvaluatorService 




Two important design decisions:




  • public → Required because LWC will call this Apex class


  • with sharing → Ensures record-level security is respected




I had previously configured roles, OWD, and sharing rules (Refer here).

Using with sharing ensures this evaluation logic follows those configurations.



Apex Sharing Behavior:




  • Apex runs in system context by default. Object-level and field-level permissions are not automatically enforced.


  • with sharing enforces record-level sharing rules only, ensuring queries and DML respect the current user’s access.


  • with sharing does not enforce object or field permissions. You must explicitly handle CRUD/FLS (e.g., WITH SECURITY_ENFORCED or Security.stripInaccessible()).


  • If no sharing keyword is defined, the class inherits sharing from its caller, so behavior may vary depending on depending on how it is invoked.


  • Triggers run in system context. Even if a helper class is marked with sharing, the trigger executes in system mode.










Designing Data Transfer Objects



Instead of returning raw Employee__c or Employee_Skill__c records, I created Data Transfer Objects or DTOs.



DTOs define the structured connection between backend and UI. They wrap only the fields required by the frontend, preventing unnecessary exposure of internal data.



For this feature, the UI needed:




  1. Detailed skill gap information (for manager-level decision making)


  2. Candidate-level summary information





Note: @AuraEnabled is required for LWC(UI) to access Apex properties and methods.










Skill-Level DTO




CODE
public class SkillGapDetail {
@AuraEnabled public String skillName;
@AuraEnabled public Integer requiredLevel;
@AuraEnabled public Integer impact;
}




Represents a single skill gap for a candidate.



Advantages:




  • All evaluation logic runs in Apex, so UI performs no calculations


  • Business logic stays in the backend


  • UI remains lightweight


  • Future logic changes don’t affect frontend code










Candidate-Level DTO




CODE
public class CandidateResult {
@AuraEnabled public String employeeName;
@AuraEnabled public Decimal gapScore;
@AuraEnabled public Boolean isProjectReady;
@AuraEnabled public SkillGapDetail detail;
}




For each evaluated employee, the UI receives:




  • Employee name


  • Final gap score


  • Ready / Not Ready flag


  • Skill Gap Detail




This keeps the response clean and structured.









Entry Point – evaluateProject()




CODE
@AuraEnabled
public static List<CandidateResult> evaluateProject(Id projectId, Integer topN)




Responsibilities:




  • Accept a Project Id


  • Evaluate unallocated employees


  • Rank them


  • Return top N candidates


  • Persist evaluation results










Guard Clause




  • Guard clauses help prevent unnecessary processing and avoid unexpected or confusing UI behavior.




CODE
if (projectId == null) return new List<CandidateResult>();






If no project is provided, evaluation stops.



Prevents:




  • Null pointer exceptions


  • Unexpected UI errors


  • Wasted governor limits










Load Project Requirements




CODE
List<Project_Skill_Requirement__c> reqs = [
SELECT Skill__c, Required_Level__c,
Importance__c, Weight__c
FROM Project_Skill_Requirement__c
WHERE Project__c = :projectId
];




Each requirement contains:




  • Skill


  • Required Level


  • Importance (Required / Nice-to-have)


  • Weight




After fetching, I converted them into Maps for fast access.



Why Maps?



Governor limits restrict queries per transaction. Querying inside loops risks hitting limits. By storing data in Maps:




  • Avoid repeated SOQL calls


  • Ensure constant-time lookups (O(1))


  • Keep code bulk-safe




Maps are essential in Apex for this reason.









Weighted Impact Formula



This is the heart of the evaluation engine.



I first compute the deficit to rank candidates:

deficit = requiredLevel - employeeLevel;



By itself, this treats all skills equally. To make evaluations more realistic, I introduced weighted scoring:




CODE
Integer impact = deficit * importanceMultiplier * weight;




Where:




  • Required skill → multiplier = 2


  • Nice-to-have → multiplier = 1


  • Weight → configurable per skill




From this I ensured,




  • Missing a critical skill has higher impact


  • Minor skills don’t disproportionately penalize a candidate




The result is a system that is realistic and flexible rather than rigid.









Effective Level – Making It Smarter



Raw skill levels aren’t always reliable. To improve accuracy, I introduced two adjustments:




  1. Confidence adjustment

  2. Staleness adjustment









1. Confidence Adjustment




CODE
Boolean isTrusted = (src == 'Manager-assessed');
Integer confidenceAdjust = isTrusted ? 0 : 1;
Integer afterConfidence = rawLevel - confidenceAdjust;





  • Self-assessed → reduce slightly

  • Manager-assessed → keep unchanged









2. Staleness Adjustment




CODE
Date staleCutoff = Date.today().addMonths(-12);

if (lastVerified == null) {
stalenessAdjust = 2;
} else if (lastVerified <= staleCutoff) {
stalenessAdjust = 1;
}




Never verified → larger reduction


Verified >12 months ago → slight reduction

Finally, the effective level is computed as:




CODE
Integer effectiveLevel = afterConfidence - stalenessAdjust;
if (effectiveLevel < 0) effectiveLevel = 0;




This makes the evaluation time and credibility aware, preventing outdated or inflated skill ratings from misleading staffing decisions.









Ranking Candidates




CODE
results.sort(new CandidateComparator());




Custom comparator:




CODE
private class CandidateComparator implements System.Comparator<CandidateResult> {
public Integer compare(CandidateResult x, CandidateResult y) {
if (x.gapScore != y.gapScore) {
return (x.gapScore < y.gapScore) ? -1 : 1;
}
return x.employeeName.toLowerCase()
.compareTo(y.employeeName.toLowerCase());
}
}




Sorting priority :




  1. Lowest gap score


  2. Alphabetical order as tie-breaker




Using this comparator ensures deterministic sorting, providing consistent results across repeated evaluations.









Project Ready Logic




CODE
cr.isProjectReady = (requiredImpact == 0);




If all required skills have zero impact, the candidate is ready.



Nice-to-have gaps don’t block readiness, preventing unnecessary hiring when existing employees are suitable.









Persisting Recommendations



The evaluation results are stored in the Project_Candidate__c object.



A composite key is used to uniquely identify each candidate for a project:




CODE
pc.Project_Employee_Key__c =
String.valueOf(projectId) + '|' + String.valueOf(employeeId);





Note: - The Project_Employee_Key__c is a Text field marked Unique and Required.




The records are then saved using:




CODE
upsert candidates Project_Employee_Key__c;




upsert ensures:




  • Insert if record doesn’t exist


  • Updates the record if it already exists


  • Prevents duplicate records



  • Allows re-evaluation to update previous scores





Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Hackers Just Poisoned the Rust Supply Chain | Threat Wire
1 Quelle
Hackers Found a Way Into Humanoid Robots | Threat Wire
1 Quelle
Bits und so #1021 (Passwort für Laufwerk)
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Building Skill Align - Part 6 - Project Staffing Assistant(Backend)

Thematisch verwandte Begriffe: Building, Skill, Align, Part · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...