sf-fflib-selector-layer

Implements and reviews Apex selector classes extending fflib_SObjectSelector with fflib_QueryFactory.

2|Updated Sep 12, 2026
One-click install
npx skills add https://github.com/grzmol/vibe-force --skill sf-fflib-selector-layer-grzmol
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: sf-fflib-selector-layer
Source: https://github.com/grzmol/vibe-force/tree/main/skills/sf-fflib-selector-layer
Command: npx skills add https://github.com/grzmol/vibe-force --skill sf-fflib-selector-layer-grzmol

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes references (resource) components.

What problem does it solve? Writing and reviewing fflib selector classes in Apex is error-prone: constructor flags change security posture and field sorting, bind variables fail silently when local names mismatch, subselects and parent traversal throw obscure exceptions, and dynamic filters invite SOQL injection. This Skill grounds every decision in the actual fflib-apex-common source so selectors are correct, secure, and mockable. ## Core Features & Use Cases - Selector construction and security posture: Covers the constructor and DataAccess matrix (USER_MODE, SYSTEM_MODE, LEGACY), field sets, getOrderBy parsing, and CRUD/FLS enforcement old versus WITH USER_MODE. - Full fflib_QueryFactory API: selectField, setCondition, addOrdering, setLimit, setOffset, subselectQuery, toSOQL, deepClone, parent field traversal, and child subselects via configureQueryFactoryFields and addQueryFactorySubselect. - Safe dynamic queries and batch support: Dynamic filters without SOQL injection using Database.queryWithBinds, QueryLocator selectors for Batch Apex, aggregate wrappers, and a 20-item anti-pattern review checklist. - Use Case: When writing an AccountsSelector that needs a filtered query with a child subselect and user-supplied search criteria, use this Skill to build it with newQueryFactory, bind maps, and WITH USER_MODE instead of concatenated strings. ## Quick Start Ask the assistant to write or review an Apex selector class extending fflib_SObjectSelector, for example to add a filtered query method with a child subselect and user-mode enforcement.

Frequently Asked Questions about sf-fflib-selector-layer

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I write an Apex selector class extending fflib_SObjectSelector?

Extend fflib_SObjectSelector, implement getSObjectType and getSObjectFieldList, and call super(false, fflib_SObjectSelector.DataAccess.USER_MODE) in the constructor. Add typed methods that start from newQueryFactory() with setCondition, and register the selector in Application.cls.

How do I add a child subselect or parent fields with fflib_QueryFactory?

Use addQueryFactorySubselect(parentFactory, 'RelationshipName') from the child selector, then contribute parent fields with configureQueryFactoryFields(factory, 'PricebookEntry.Product2'). For ad-hoc parent traversal, call selectField('Account.Owner.Name') directly.

Should fflib selectors use WITH USER_MODE or the legacy enforceFLS constructor?

Use the modern super(false, DataAccess.USER_MODE) constructor, which emits WITH USER_MODE and lets the platform enforce object and field permissions. The deprecated enforceCRUD/enforceFLS flags run expensive per-field describe checks and throw different exception types.

How do I prevent SOQL injection in dynamic fflib selector filters?

Build the condition with bind tokens and pass values through Database.queryWithBinds(soql, bindMap, AccessLevel.USER_MODE) instead of concatenating strings. Caller-supplied field names must be validated against the SObject describe before reaching selectField.

Why does fflib_QueryFactory throw NonReferenceFieldException or InvalidSubqueryRelationshipException?

NonReferenceFieldException means a mid-path segment in a dotted field path is not a lookup or master-detail field. InvalidSubqueryRelationshipException means the child relationship name passed to subselectQuery is unknown; use the relationship-name overload rather than the deprecated SObjectType one.

Can fflib_QueryFactory run aggregate or COUNT queries?

No, toSOQL always emits SELECT with a field list and has no COUNT, GROUP BY, or HAVING support. Write the aggregate query inline inside the selector, add WITH USER_MODE by hand, and return a typed wrapper instead of AggregateResult.