Typical Domain-Entity Entry Points for Business Logic
Goal
When deciding which business-logic entry points to implement around a domain-entity type, prefer a standard set of entry points instead of inventing ad hoc operations.
Treat the domain entity as the organizing center. Start from the entity type, then choose the entry point kind that matches the business operation:
- create
- update
- find by id
- search
- delete by id
- explicit mark-as operations for finite-state changes
- explicit assign or add operations for entity associations
- explicit check-whether-can-be operations for boolean feasibility checks
Basic Entry Points
Given a domain-entity type, prefer these basic entry points:
create- Creates a new domain entity.
update- Updates only fields whose value space is effectively infinite or quasi-infinite.
- Typical examples:
string,int,decimal,url,date,datetime, text fields, free-form names, descriptions, notes, counters, limits, and similar values.
find by id- Returns the entity by its identity, or an absence value (
null,undefined,None,Optional<T>, etc., idiomatic to the stack) when it does not exist. Absence is a valid result, not a failure.
- Returns the entity by its identity, or an absence value (
search- Returns a collection of entities or results.
- Supports filtering by any field or combination of fields.
- Supports pagination and sorting.
delete by id- Deletes the entity identified by its id.
check whether ... can be ...- Returns a boolean indicating whether a business operation is currently allowed.
Choose the Entry Point by Operation Kind
Use update only for quasi-unbounded fields
Use update when the operation changes fields whose possible values are open-ended or effectively unbounded.
Examples:
updateUserupdateCourseupdateRole
Typical fields for update:
- name
- description
- phone
- url
- amount
- date
- datetime
- numeric limits or thresholds
Do not use update for finite-state or relationship-changing operations when a more explicit entry point is appropriate.
Use find by id for single-entity retrieval
Use a dedicated find by id entry point when the caller needs one specific entity by identity.
Examples:
findUserByIdfindCourseByIdfindRoleByIdfindPermissionById
The operation returns the requested entity or an absence value (T | null, Optional<T>, etc., idiomatic to the stack). Absence is a valid result and must not be reported as a domain error from the entry point unless the use case truly demands it; the underlying repository operation never throws on not-found.
Use search for filtering, sorting, and pagination
Use search when callers need to retrieve entities by arbitrary criteria, combinations of criteria, sorting, or pagination.
Examples:
searchUserssearchCoursessearchRolessearchPermissions
Search should be the flexible query entry point:
- filter by one field
- filter by multiple fields
- sort
- paginate
Finite-State Changes Need Explicit Mark-As Entry Points
When the business operation changes a field with only a small set of possible values, do not hide that transition inside update.
Use an explicit entry point that names the new business state.
Typical finite-state fields:
- enum-based status fields
- boolean fields that represent status
- lifecycle flags whose values carry business meaning
Examples:
markUserAsEnabledmarkRoleAsDisabledmarkCourseAsCancelledmarkUserAsDisabled
Use this pattern when the change is really a business state transition, not just a free-form field edit.
Relationship Changes Need Explicit Assign or Add Entry Points
When the business operation associates one domain entity with another in a one-to-many or many-to-many relationship, do not hide that change inside update.
Use an explicit relationship entry point that names the association operation.
Examples:
assignPermissionToRoleaddUserToCourseremoveUserFromCourseunassignPermissionFromRole
Choose the verb that matches the business meaning of the association:
assignaddremoveunassign
Prefer the most specific business verb that fits the relationship.
Feasibility Checks Need Explicit Check-Whether Entry Points
When the business operation is to ask whether something can be done right now, use an explicit check-whether entry point that returns a boolean.
Use this pattern when the caller needs a yes-or-no answer about whether an action is currently allowed before attempting it.
Examples:
checkWhetherPostCanBePublishedcheckWhetherUserCanBeDisabledcheckWhetherCourseCanBeCancelledcheckWhetherRoleCanBeDeletedcheckWhetherPermissionCanBeAssignedToRole
Use this kind of entry point for business permission or feasibility checks, not for performing the action itself.
CQS Alignment
When the project is following Command-Query Separation:
create,update,delete by id,mark as ...,assign ..., andadd ...are commandsfind by id,search, andcheck whether ... can be ...are queries
Keep this skill focused on choosing the right entry point kind. If other skills already govern CQS return shapes, signatures, or payload typing, keep those rules too.
Detection Workflow
Start from the domain entity.
- Identify the primary entity type the requested operation acts on.
Identify the real business operation.
- Is the caller creating, editing open-ended fields, retrieving by id, searching, deleting, changing a finite state, associating entities, or checking whether an action is allowed?
Choose the standard entry point kind first.
- Prefer the standard entry point kind before inventing a custom one.
Reject overloaded
updateoperations when the meaning is more specific.- If the change is a finite-state transition, use
mark as .... - If the change is an association, use
assign ...oradd .... - If the operation is a yes-or-no feasibility check, use
check whether ... can be ....
- If the change is a finite-state transition, use
Writing or Changing Entry Points
Begin with the standard set.
- Check whether the requested behavior is simply
create,update,find by id,search,delete by id, orcheck whether ... can be ....
- Check whether the requested behavior is simply
Use
updatenarrowly.- Restrict
updateto quasi-unbounded fields. - Do not let
updateabsorb business state transitions or association operations.
- Restrict
Name state transitions explicitly.
- Prefer
mark as ...naming when the operation changes a finite-state field. - Make the resulting business state obvious in the entry point name.
- Prefer
Name associations explicitly.
- Prefer verbs like
assignoraddwhen the operation connects one entity to another. - Make both sides of the relationship obvious in the entry point name.
- Prefer verbs like
Keep
searchbroad and structured.- Let
searchhandle combinations of filters, ordering, and pagination instead of creating many narrow list-style entry points by default.
- Let
Use explicit check-whether entry points for boolean business decisions.
- Prefer
check whether ... can be ...naming when the caller needs to know whether an action is allowed. - Return a boolean instead of overloading a command or search operation for that purpose.
- Prefer
Examples
The findXById entry points return T | null (or the idiomatic absence value of the stack); the underlying repository operations never throw on not-found, per business-logic-entry-point-repository-operations.
Prefer this set for a User entity:
createUserupdateUserfindUserByIdsearchUsersdeleteUserByIdmarkUserAsEnabledmarkUserAsDisabledaddUserToCoursecheckWhetherUserCanBeDisabled
Prefer this set for a Role entity:
createRoleupdateRolefindRoleByIdsearchRolesdeleteRoleByIdassignPermissionToRoleunassignPermissionFromRolecheckWhetherRoleCanBeDeleted
Prefer this set for a Course entity:
createCourseupdateCoursefindCourseByIdsearchCoursesdeleteCourseByIdmarkCourseAsCancelledaddUserToCoursecheckWhetherCourseCanBeCancelled
Prefer this set for a Permission entity:
createPermissionupdatePermissionfindPermissionByIdsearchPermissionsdeletePermissionByIdassignPermissionToRolecheckWhetherPermissionCanBeAssignedToRole
Prefer this set for a Post entity:
createPostupdatePostfindPostByIdsearchPostsdeletePostByIdmarkPostAsCancelledcheckWhetherPostCanBePublished
Avoid these overloaded choices when a more specific entry point exists:
updateUserStatusupdateRolePermissionsupdateTeamMembers
Prefer instead:
markUserAsEnabledassignPermissionToRoleaddUserToCoursecheckWhetherPostCanBePublished
Review Questions
When reading or reviewing code, ask:
- Which domain entity is this entry point organized around?
- Is this operation really create, update, find by id, search, delete by id, or check whether something can be done?
- If not, is it actually a finite-state transition that should be
mark as ...? - If not, is it actually an association that should be
assign ...oradd ...? - If not, is it actually a feasibility check that should be
check whether ... can be ...? - Is
updatebeing overloaded with responsibilities better expressed as explicit business operations?
If the answer is yes, apply this skill.
Report the Outcome
When finishing the task:
- state which domain-entity entry points were identified or changed
- state which standard entry point kinds were used
- state where
updatewas replaced by explicitmark as ...,assign ...,add ..., orcheck whether ... can be ...operations - state how the final entry points align with the entity's business operations