SmartExchange · .NET 10 · Chapter 03
CRM annotations and Diagram
CRM declares which entity paths are available to authorization. The same metadata drives context selection, scope validation and SQL relationship mapping.
Declarations for both export examples
Person → Company
[CrmAuthorizationRelation("companyIds",
nameof(Person.PersonInCompanies),
nameof(PersonInCompany.Company))]Provides companyIds through the linking entity.
InterestedParty → Project
[CrmAuthorizationRelation("projectIds",
nameof(InterestedParty.Project))]Provides projectIds through the declared Project reference.
Both annotations feed DiagramCrm.Generate(). Both aliases are used in their derived-role conditions. Neither annotation activates export; each resource policy must explicitly allow that action.
Metadata already implemented
| Class / member | Output / use |
|---|---|
DiagramCrm.Generate(assemblies) | Builds the CRM diagram using the existing reflection workflow, including ACL and relationship annotations. |
DiagramClass.AuthorizationRelations | Declarations belonging to this resource. |
DiagramAuthorizationRelation | AttributeName, NavigationPath, resolved TargetEntity. |
DiagramAcl from CrmAclAttribute | Legacy entity/permission codes used by the adapter. Numeric identifiers stay at this conversion boundary. |
The diagram resolves navigation targets; the authorization registry validates the usable relationship and generates its neutral join steps. We reuse the existing foreign-key/reverse-navigation metadata; policies do not contain SQL paths.
Seven declared relationships
| Resource | Policy alias | CRM navigation |
|---|---|---|
| Person | companyIds | PersonInCompanies → Company |
| Company | personIds | PersonInCompanies → Person |
| Project | interestedPartyIds | InterestedPartys |
| InterestedParty | projectIds / investorIds | Project / Investor |
| Investor | interestedPartyIds / projectIds | InterestedParties / InterestedParties → Project |
Cerbos receives the relationship attribute name in expressions, not the CRM graph or FK metadata. In list planning it leaves unknown record attributes in the returned condition. Our SQL mapping supplies their database meaning.