
Link records to eligible people and partners
A referenced person or organization can exist without being eligible for this record. Wildo can require the declared membership or partnership before accepting the link.
That keeps relationships meaningful: an assignee belongs to the account, an escalation contact belongs to its rota, or a partner belongs to an approved relationship.
Example — Assign work to an account member
A task can refer to a user only when that user has the required membership in the task’s organization. Knowing somebody’s user ID is not enough.
For engineers
This is the task-assignee declaration in Wonder Todos. scopeMembership: true asks the registry to resolve the organization-membership junction. The context settings separately control the related information returned with the task:
This implementation excerpt from tasks-manager.relationships.ts shows the decision in context; explanatory source comments are omitted.
createResourcesRelationship(
TasksManager_ResourceType.TODOS, CoreResourceType.USERS,
ResourceRelationshipCardinality.MANY, ResourceRelationshipCardinality.ONE,
{
nature: RelationshipNature.REFERENCE,
foreignKeyField: 'assignedToUserId', // Explicit for Edge Case #1 - multiple FKs to same type
parentResourceRequirement: ResourceParentResourceRequirement.OPTIONAL,
accessScopeStrategy: ResourceRelationshipAccessScopeStrategy.OPTIONAL_CONTEXT,
scopeMembership: true,
contextPolicy: {
objectMode: ContextPolicy_ObjectMode.SUMMARY,
operationOverrides: {
[CoreResourceOperation.READ]: { objectMode: ContextPolicy_ObjectMode.FULL },
[CoreResourceOperation.LIST]: { enabled: false },
[CoreResourceOperation.SEARCH]: { enabled: false },
}
}
}
),
Use an explicit junction when membership means something else
For a rota or partnership, set scopeMembership to an object naming the junction. junctionScopeField and junctionTargetField identify its columns when they cannot be inferred. The target’s existence and the junction’s existence answer different questions; both matter.
Create and update integrity checks evaluate referenced foreign keys before storing the write. An operation can add referenceConstraints to tighten eligibility, such as requiring a particular membership status. Related-record resolution uses the declared membership semantics as well.
Separate who may assign from who may be assigned
Wonder Todos’ assign-lead operation uses the same assignedToUserId relationship shown above and declares an active organization administrator as its eligible target. The caller must also be an administrator. The example below uses built-in organization roles: permission to make the change does not make every selected person eligible.
This is the operation declaration from todos.resources-config.ts, with comments omitted. Todos_Operations belongs to the application; the other enums come from @wildo-ai/saas-models, and z comes from zod.
[Todos_Operations.ASSIGN_LEAD]: {
variants: [
{
variantType: ResourceOperationVariantType.API_CALL,
isDefault: true,
roles: [CORE_ORG_ROLES.ORG_ADMIN],
riskLevel: ResourceOperationRiskLevel.MEDIUM,
resourceOperationLike: CoreResourceOperation.UPDATE,
requestDto: z.object({
assignedToUserId: z.string().min(1),
}),
referenceConstraints: {
assignedToUserId: {
qualifyingStatuses: [OrganizationMemberStatus.ACTIVE],
requiredRoles: { scope: ResourcePrimaryScope.ORGANIZATIONS, roles: [CORE_ORG_ROLES.ORG_ADMIN] },
},
},
},
],
},
Place this inside the resource’s operationsConfiguration. The shared tasks-manager module contributes its factory map through resourceConfigurations and its relationship list through resourceRelationships. Both are needed: the relationship identifies the membership junction; this operation adds the eligibility criteria. Merely adding an input field does not declare that relationship.
For an existing todo, call the addressed operation with the organization’s administrator session. API_BASE includes the backend API prefix; ASSIGNEE_USER_ID is the selected user’s ID, not their membership ID.
curl --fail-with-body --request PUT "$API_BASE/organizations/$ORGANIZATION_ID/todos/$TODO_ID/assign-lead" \
--header "Authorization: Bearer $ADMIN_ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data "{\"assignedToUserId\":\"$ASSIGNEE_USER_ID\"}"
| Selected person using built-in roles | Result with an authorized caller |
|---|---|
| Active administrator in this organization | Eligible; verify the stored assignedToUserId after the update |
| Active owner in this organization | Eligible through role inheritance: owner includes administrator authority |
Member holding only ORG_MEMBER in this organization | Refused by this operation’s role requirement on the target |
| Administrator belonging only to another organization | Refused: the required membership is in the todo’s organization |
| Membership outside the qualifying status | Refused even if the membership carries an administrator role |
Run the permitted case before testing refusals, and confirm refused writes leave the previous assignee unchanged. The ordinary assign operation on this resource does not add these status/role criteria: it retains the relationship’s membership check. If several operations must enforce the stricter policy, declare it on each applicable variant.
Target roles are resolved against the application’s current role definitions in the declared scope. A custom role can qualify through its inheritance; an unknown role grants nothing. Related-record search can offer members who do not meet a stricter write policy, so handle an assignment refusal even when the person appeared in a picker.
Make exceptions deliberate
This policy is opt-in on the relationship. An organization-less target without it may receive an existence check rather than a membership check. A variant that explicitly waives membership changes the contract for that variant; do not use that escape hatch to make an ordinary assignment work around an incomplete declaration.