EPMS·Data Model Explorer
seco_Pass 3

Vocabulary tables

59 vocabulary tables replace what would otherwise have been 59 Choice columns. There is no Choice column anywhere in the solution: every dropdown is a lookup, so administrators manage options in EPMS Admin without a deployment. Rows are deactivated, never deleted, so historic records keep resolving.

The keys

seco_code is what logic branches on. seco_legacyoptionvalue exists only so migration can map a legacy integer to a row. Neither is the row GUID, and the GUID is never used for anything.

Lookup row GUIDs are generated per environment and differ between Dev, Test and Prod. A plugin or flow that branches on a GUID passes every test in Dev and fails silently in Prod, because the row it matched no longer exists under that id. Resolve the lookup, read seco_code, branch on the code. This applies to all 55 vocabulary tables, both tiers.

13 vocabularies diverge between the prototypes — Platform 1 is authoritative

Platform 1 carries the fixed integers and states they are fixed. Platform 2 marks every inherited vocabulary UNCONFIRMED because Platform 1’s file was not supplied with its pack, so it invented plausible members and built against them. Ten to twelve years of migrated Smartsheet history carries Platform 1’s integers. Seed from Platform 1 throughout. Only four agree: seco_approvaltrack, seco_approvaldecision, seco_gatekind, seco_yesno.

VocabularyPlatform 1 (authoritative)Platform 2Consequence
seco_restrictionkindNo · ITAR · Other restriction · NDA restricted (100000003)No · ITAR · Other restrictionPlatform 2 is missing NdaRestricted 100000003 entirely, and that is the December default. Any Platform 2 rule that defaults restriction handling defaults to a member that does not exist in the real set.
seco_accountcategoryCustomer · Partner · SupplierCustomer · Prospect · MachineToolBuilder · Distributor · InternalMachineToolBuilder and Distributor are channel concepts, not account categories, and seco_channel already exists as a reference table. Platform 2 conflated two ideas.
seco_resourcekindPerson · EquipmentInternal · Contractor · Partner · EquipmentPlatform 2's cost-rate and capacity rules branch on members that do not exist.
seco_agreementkindPurchase order · Letter of intent · Long-term agreementStatementOfWork · Framework · NDA · AmendmentCompletely disjoint. SOW is a separate table (seco_sow), so Platform 2 modelled it twice.
seco_proposalkindTechnical · CommercialBudgetary · Firm · RevisedDisjoint. Nothing written against Platform 2's members resolves.
seco_participantroleCustomer contact · Partner contact · ObserverSponsor · Engineer · Buyer · OtherDiverges — seed from Platform 1.
seco_feedbacksourceCustomer · SalespersonSurvey · Meeting · Email · PortalDiverges — seed from Platform 1.
seco_requestoriginOpportunity · Internal · PortalInternal · Portal · CRM · IntegrationDiverges — seed from Platform 1.
seco_costcategoryLabour · Tooling · Materials · Travel · Subcontract · Equipment · OtherLabour · Material · Logistics · OverheadDiverges — seed from Platform 1.
seco_languageEnglish · German · French · Spanish · Swedish · OtherEnglish · German · Swedish · ChineseDiverges — seed from Platform 1.
seco_eventkindScope change · Specification change · Schedule change · Commercial change · Escalation · OtherMeeting · Milestone · Issue · NoteDiverges — seed from Platform 1.
seco_projectrouteTooling led · Solution led · Back to sales · Application engineeringStandard · FastTrack · StrategicDiverges — seed from Platform 1.
seco_syncstateNot applicable · Pending · Synced · Failed · SupersededPending · Synced · Failed · SkippedDiverges — seed from Platform 1.
59
Vocabularies
30
Business tier
29
System tier
240
Seeded rows
1
Rows without a legacy integer
Rule — settled

The two-tier split is confirmed.

Business tier and system tier are agreed, not proposed. Build against them.

Shared column contract — every vocabulary table

seco_nameText (100) — primary nameLabel shown to users; administrators may rename on business-tier tables.
seco_codeText (50) — unique, alternate keyBusiness logic branches on this, never on the GUID.
seco_descriptionMultiline text (2000)Plain-English explanation of when the row applies.
seco_sortorderWhole numberDisplay order in lookups and views.
seco_legacyoptionvalueWhole number — not requiredThe fixed Dataverse option-set integer this row replaces. Migration maps a legacy integer to this row; nothing else reads it. Business logic branches on seco_code, never on this column and never on the row GUID.
seco_masteredbyLookup → seco_masteredbyWhich system owns the row: EPMS, D365 or Manual.
seco_crmreferenceText (100)Matching key in D365 when the row is CRM-sourced.
seco_lastsyncedonDate and timeLast successful synchronisation timestamp.
statecodeStandard stateRows are deactivated, never deleted, so historic records keep resolving.
Tier
Source
59 shown