Chapters: 

This prototype is to demonstrate that SharePoint Online can support this requirement without requiring users to manually copy a Contact value and perform a separate search.

The current cross-reference table is intentionally used as a non-invasive proof of concept. It allows us to demonstrate the routing logic without changing the existing Playbook or Contacts structures.

For production, the final design would depend on the existing data and business rules. For example, the relationship could remain in a mapping table, or the Contacts library could be extended with additional metadata such as a ContactKey or group classification.

The important point is that SharePoint can support the pattern:

Play selected → routing value identified → matching Contacts returned

A single Play can return multiple Contacts, and the design does not require manually maintained hyperlinks between individual Playbook pages and individual Contact pages.

The next step is therefore not to redesign the data immediately, but to review the existing Playbook and Contacts metadata and determine the most appropriate way to represent the business relationship.

Thursday Demo

Play selected
    ↓
[Contacts]
    ↓
`SoC` is passed automatically
    ↓
SharePoint applies the filter/search
    ↓
matching Contact pages are shown

So the Contacts button is the user action that triggers the handoff.

And the rule still fits:

No Contact value
    → no [Contacts] button

Contact value present
    → show [Contacts] button

That is probably the clearest way to explain it to the page owner tomorrow: the user sees a Contacts button only when the Play has a Contact reference, and clicking it performs the lookup they currently do manually.


 

SharePoint Playbook → Contacts Prototype

1. What problem are we solving?

Current user experience

Desired experience

User opens a Play

User opens a Play

Sees a Contact reference

Sees a Contacts option

Copies the Contact value

Clicks once

Searches SharePoint manually

Matching Contacts are shown

Interprets results

No manual search required

Core requirement:

Play selected → routing value identified → matching Contacts returned


2. What has been built so far?

Component

Current state

Playbook

Existing SharePoint content

Contacts

Existing SharePoint pages

Cross-reference / mapping table

Prototype helper

JSON formatting

Working

Passed value

%title% / routing value such as SoC

Filtering

Proven against pseudo Contacts data

Manual links

Not required

JavaScript

No custom JavaScript

Power Apps / Power Automate / SPFx

Not required for prototype

Current prototype flow:

Playbook ToC
    ↓
Selected Play
    ↓
JSON passes routing value
    ↓
Mapping / xref
    ↓
Pseudo Contacts
    ↓
filtered results

Example:

Security Incident
      ↓
     SoC
      ↓
Security Operations Centre
Bob, Station 2
Security Duty Officer

3. Why the xref / mapping table exists

The mapping table was created deliberately so the prototype could be built without changing the existing Playbook or Contacts structures.

It can represent relationships such as:

Play

Contact Group

Security Incident

SoC

Security Incident

NOC

Network Outage

NOC

This also allows one Play to route to more than one Contact group.

The mapping table therefore answers:

Which Contact groups are relevant to this Play?


4. Important design distinction

The Play does not need to point directly to individual Contacts.

Instead:

Play
   ↓
routing/classification value
   ↓
Contact group
   ↓
matching Contacts

Example:

Security Incident
   ↓
SoC + NOC
   ↓
all Contacts classified as SoC or NOC

This avoids:

Security Incident → Bob
Security Incident → Jane
Security Incident → SOC page

and therefore avoids maintaining individual Contact relationships across hundreds of Plays.


5. What the real Contacts source looks like

Contacts are SharePoint pages, not conventional list rows.

That is fine.

The likely production improvement is to add structured metadata to the Contact page library / Contact Page Template.

Possible fields:

Field

Purpose

ContactKey

Routing/classification value

Contact Type

Team / individual / role

Support Level

L2 / L3

Email

Optional

Phone

Optional

Status

Active / inactive

Example:

Contact Page

ContactKey

Email

Phone

Security Operations Centre

SoC

soc@...

555-0199

Bob, Station 2

SoC

 

555-0003

Security Duty Officer

SoC

duty@...

 

Network Operations Centre

NOC

noc@...

555-0123

The Contact page itself remains free-form.

The metadata simply makes it searchable/filterable.


6. Likely production flow

Playbook
    ↓
selected Play
    ↓
mapping identifies SoC / NOC / etc.
    ↓
parameter passed
    ↓
Contacts pages filtered by ContactKey
    ↓
matching Contact pages displayed

Eventually:

Something Happened
        ↓
    [Contacts]
        ↓
   SoC + NOC
        ↓
┌────────────────────────────┐
│ Contacts                   │
│                            │
│ Security Operations Centre │
│ Bob, Station 2             │
│ Network Operations Centre  │
└────────────────────────────┘

7. What the prototype proves

Question

Answer

Can SharePoint pass a value from the Playbook?

Yes

Can JSON construct the navigation/filter request?

Yes

Can the destination be filtered dynamically?

Yes

Can one Play route to multiple Contact groups?

Yes, through the mapping model

Do users need to copy and search manually?

No

Do we need hard-coded Contact hyperlinks?

No

Does the final business taxonomy need to be known yet?

No

The prototype demonstrates technical feasibility.

It does not attempt to define the client's final business model.


8. Next technical steps

Priority

Task

1

Demo the current prototype

2

Confirm the business likes the parameter-driven behaviour

3

Review the real Contacts page library

4

Determine what metadata already exists

5

Propose a structured metadata block for the Contact Page Template

6

Decide whether ContactKey or similar is appropriate

7

Test filtering real Contact pages instead of pseudo Contacts

8

Test multiple routing values such as SoC + NOC

9

Determine the cleanest native SharePoint presentation for filtered Contact pages

10

Decide whether the mapping table remains permanent or becomes a migration/translation layer


9. Questions for the client after the demo

These are the business questions you do not need to answer yourself:

Question

Why it matters

What makes a Contact relevant to a Play?

Defines the routing rule

Are Contact groups already defined?

May avoid inventing new taxonomy

Can one Play require multiple groups?

Likely yes

Can one Contact belong to multiple groups?

Affects metadata design

Is there existing metadata in Contacts that can be reused?

Avoids unnecessary schema changes

Who maintains the classifications?

Determines governance

Should the mapping table remain?

Depends on business complexity


10. One-sentence architecture summary

The Playbook supplies a routing value, the mapping layer resolves the relevant Contact classification, and SharePoint returns the Contact pages whose metadata matches that classification.

And the most important sentence for tomorrow:

We have demonstrated the behaviour without changing the existing Playbook or Contacts structures; the next step is to determine how the client's existing data should represent that relationship in production.

 

Friday User Experience Design

Let's keep the xref/mapping table for now.

The reason is simple: we do not know the business rules well enough yet to confidently bake the relationship directly into the real Contacts library.

The current prototype has already proven a useful pattern:

Layer

Role

Play

Provides the selected Play/title/acronym

Xref / mapping table

Translates that Play value into the relevant Contact classification/value

Contacts

Holds the actual Contact pages

JSON

Passes the selected value into the query/filter

The production version can therefore become:

Selected Play
    ↓
mapping/xref
    ↓
ContactKey(s)
    ↓
ProdCopy Contacts library
    ↓
filter Contact pages

That is safer than jumping straight to:

Play acronym = ContactKey

because you already know the naming is not necessarily clean. Sometimes the title is the filename-derived value; sometimes you had to manually create acronyms. That is exactly the kind of mismatch a mapping table is good at absorbing.

What I would do with ProdCopy Contacts

Add one structured metadata field to the copied Contacts library, something like:

ContactKey

Then populate a small test set only:

Contact page

ContactKey

Security Operations Centre.aspx

SoC

Bob Station 2.aspx

SoC

Network Operations Centre.aspx

NOC

Now your xref can say:

PlayKey

ContactKey

Security Incident

SoC

Major Incident

SoC

Major Incident

NOC

That gives you a genuine many-to-many model without forcing you to alter hundreds of Plays.

The Contacts library can then be filtered on a real column. SharePoint supports filtering lists and libraries on columns, and views can be built around those filters. (Microsoft Support)

Why I prefer xref + ContactKey right now

Because they solve different problems:

xref
= which Contact classifications apply to this Play?

ContactKey on Contacts
= which Contact pages belong to that classification?

That separation is valuable while you are still discovering the client's data.

Later, after you understand the business, you may discover:

The Play acronym already is the ContactKey everywhere.

If that proves true, fabulous. The xref becomes unnecessary and you can simplify to:

Play acronym
    ↓
Contacts.ContactKey

But I would discover that, not assume it.

So my recommendation for the ProdCopy experiment is:

  1. Keep your working xref.
  2. Add ContactKey to ProdCopy Contacts.
  3. Tag perhaps 5 to 10 Contact pages.
  4. Point the current JSON/filter flow at those real pages.
  5. Test one Play → one ContactKey.
  6. Test one Play → multiple ContactKeys such as SoC + NOC.
  7. Only then decide whether the xref is architectural or merely scaffolding.

That gives you the most useful answer for the client:

We can make this work without restructuring the existing Playbook. The prototype uses a mapping layer, while the Contacts copy uses structured metadata. Once we understand the actual business relationships, we can determine whether the mapping layer is still needed.

That is where I think you are now.


Yes. You have crossed from Proof of Concept into credible sandbox implementation.

And six is a very good number. Enough variation to prove the design, small enough that you can hand-curate the data and make the experience convincing.

I would change the objective now:

Do not prove that the mechanism works. Prove that this is what the production user experience could look like. ⚽️

Sandbox Demo: six real Plays 🏀

Build six representative Plays from the production copy, preferably chosen to exercise different Contact patterns:

Play

Contact routing

Why include it

Play A

SoC

Simple single group

Play B

NOC

Different single group

Play C

SoC + NOC

Multiple Contact groups

Play D

Service Desk / another real group

Different Contact type

Play E

No Contacts

Proves [Contacts] should not appear

Play F

One of the messier real cases

Demonstrates that this isn't just a toy example

Use the real Play titles, real layout, real page style and real Contact pages from ProdCopy. You can hard-code or manually configure the routing for these six. At this stage that's not cheating. You are validating the user experience and the proposed data structure, not designing the bulk migration yet.

Still keep the xref for this demo

Don't make structural modifications before knowing the final business model!!

For six Plays:

REAL PLAY
    ↓
existing Play identifier
    ↓
XREF / mapping
    ↓
SoC / NOC / etc.
    ↓
[Contacts]
    ↓
real ProdCopy Contacts
    ↓
matching real Contact pages

Then add ContactKey to the ProdCopy Contacts library, not production.

Populate it only for the Contacts needed by those six Plays.

For example:

Real Contact page

ContactKey

Security Operations Centre

SoC

Security Duty Officer

SoC

Network Operations Centre

NOC

Network Duty Officer

NOC

Now you have the real end-to-end chain without pretending you've solved 500 Plays.

Make the destination look real too

I would absolutely create a dedicated Contacts view in ProdCopy.

The user should click:

[Contacts]

and land on something that looks intentional:

Contacts for this Play

Contact

Email

Phone

Security Operations Centre

soc@...

555-0199

Bob, Station 2

 

555-0003

The Contact name should open the actual Contact page.

If Email and Phone aren't structured metadata yet, don't invent a large migration project just for the demo. For the six cases, populate enough metadata to demonstrate what the future view could expose. The full Contact page remains available behind the title.

One case I really want in the six

Include one Play with no Contacts.

That proves an important UX rule:

Play has Contact mapping
        → [Contacts]

Play has no Contact mapping
        → nothing

That is much more convincing than six happy-path records all behaving identically.

What you are not committing to

This sandbox does not establish that:

  • ContactKey is definitely the final field name.
  • the xref must remain forever.
  • somebody will manually classify 500 Plays.
  • every Contact needs restructuring.
  • the six manually configured relationships represent the final taxonomy.

Instead:

We are using six representative production examples to validate the complete user experience and determine what metadata and mapping are required before designing the production-scale implementation.

That is a very defensible next stage.

And crucially, Business gets to see:

real Play
   ↓
real [Contacts] button
   ↓
real routing
   ↓
real Contacts library
   ↓
real Contact pages

No pseudo-Contacts. No abstract “imagine this is production.” The plumbing behind those six can be partially hand-tuned because the thing under evaluation now is the proposed interface and information model.

Your POC proved can we do it?

The six-Play sandbox now answers:

Is this actually how we want it to work?

That is the right next question.

 

🟢🟢🟢🟢🟢  Friday Build 🟢🟢🟢🟢🟢

 

Yes. That explains why the swap failed.

Your original PoC quietly depended on something the production copy did not preserve in the same shape:

the acronym was the routing key.

The previous prototype already had the right business key hiding in plain sight. Users were doing this manually:

Play
  ↓
read acronym
  ↓
copy acronym
  ↓
query Contacts

Your PoC automated the middle:

Play
  ↓
acronym
  ↓
JSON passes acronym
  ↓
Contacts query

So if the original Excel contains the authoritative Play-to-acronym mapping, then that Excel data needs to feed the sandbox PlaysToC.

Revised sandbox model

Source

Role

Original Excel

Authoritative Play + acronym source

PlaysToC

Presents the six selected Plays and retains acronym

JSON

Passes acronym when [Contacts] is clicked

ProdCopy Contacts

Real Contact pages

Contact metadata/search

Matches the passed acronym

So:

Original Excel
     ↓
Play title + acronym
     ↓
Sandbox PlaysToC
     ↓
user selects Play
     ↓
[Contacts]
     ↓
JSON passes acronym
     ↓
ProdCopy Contacts
     ↓
matching real Contact pages

That also changes how I would think about the xref.

If Excel already says:

Play X → SoC
Play Y → NOC

then you may not need to invent a second mapping table for those six. Excel is already carrying the mapping.

Your earlier xref was useful because you needed somewhere to manufacture the relationship in the PoC. Now you have discovered the actual source of that relationship.

So the immediate task is probably:

  1. Take the original Excel as the source for the six sandbox Plays.
  2. Preserve both Play title and acronym when building PlaysToC.
  3. Make sure the JSON passes the acronym, not a filename-derived title.
  4. Point the resulting Contacts action at the real ProdCopy Contacts source.
  5. See whether the existing Contact pages can already be found reliably by that acronym.
  6. Only add ContactKey metadata to ProdCopy Contacts if the existing Contacts search is too loose or inconsistent.

That last point matters.

You may have been racing toward ContactKey before confirming whether the existing acronym is already the production key on both sides.

If it is, the production concept may be beautifully small:

Excel / PlaysToC acronym
        ↓
     [Contacts]
        ↓
existing Contacts acronym/search
        ↓
matching pages

Then the real improvement is simply:

Automate the acronym lookup users already perform manually.

That is a much stronger story because you are not proposing a new business relationship at all. You are using the one they already have.

 

Parse the URL Path for the actual FILENAME

Yes. That is a sensible next check.

If the production PlayToC already stores a Product/Play URL, and the actual file name embedded in that URL is the stable value that corresponds to the Contact lookup, then you may be able to derive the routing key from the URL instead of depending on a manually maintained acronym list.

Conceptually:

Prod PlayToC
    Product URL
        ↓
extract file name
        ↓
derive stable Play key
        ↓
[Contacts]
        ↓
query/filter Contacts

For example:

.../SitePages/Security-Incident.aspx

could yield:

Security-Incident

or, if your convention supports it:

SoC

The important question is not whether you can strip the filename. You can.

The important question is whether that filename is 100% reliable as the business key across the production data.

I would test exactly that before changing the sandbox design.

What to validate

Check

Why it matters

Every Play has a URL

Otherwise extraction fails

Filename is stable

Renaming a page could break routing

Filename uniquely identifies the intended Contact lookup

Avoid false matches

Naming convention is consistent

No SOC, SoC, SecurityOps, etc. chaos

Existing Contacts query understands the derived value

Confirms end-to-end compatibility

Special characters / spaces are predictable

Important for JSON URL construction

If those all hold, you may have found a very clean production key that already exists.

If they do not hold, then the acronym from Excel is probably still the safer authoritative routing value.



Yes. This is exactly where Python earns its lunch. 🐍

You have a very suitable little validation job:

Input:
production Play URLs + existing acronym/source data

Python checks:
- extract folder classification
- extract page filename / identity
- normalize values
- compare against existing acronym data
- flag exceptions
- summarize consistency

For example, from:

https://tenant.sharepoint.com/sites/Playbook/SECURE/SomePlay.aspx

Python can derive:

PlayType = SECURE
PlayIdentity = SomePlay

Then you can compare that against the existing Excel row:

Acronym = SoC

and produce something useful like:

URL

PlayType

PlayIdentity

Acronym

Status

.../SECURE/SomePlay.aspx

SECURE

SomePlay

SoC

OK

.../ADMIN/OtherPlay.aspx

ADMIN

OtherPlay

NOC

OK

.../PUBLIC/Weird%20Name.aspx

PUBLIC

Weird Name

DBA

Review

That lets you answer the real architecture question with evidence:

Are folder, filename, and acronym reliable enough to become three separate derived attributes?

And Python is ideal because this is analysis and validation, not something that has to run inside SharePoint.

So the pattern would be:

Excel / export
    ↓
Python audit
    ↓
confidence report + exceptions
    ↓
decide SharePoint rules

Much better than eyeballing 500 rows until the alphabet starts moving.

 

SUMMARY

Absolutely. Here’s the revised “morning re-entry” summary.

Playbook → Contacts Sandbox Demo

Where we are

The Proof of Concept passed.

Business now wants to see a realistic sandbox version using production-like data and a real-looking interface.

The next demo should use six real Plays. It does not need to cover all Plays yet.

The purpose of the sandbox demo is to prove the real user experience, not to complete the production migration.


Current user problem

Today, the user must:

Open a Play
    ↓
read the Contact acronym
    ↓
copy the acronym
    ↓
navigate to the Contacts folder
    ↓
paste the acronym into SharePoint search
    ↓
open the matching Contact page

The requirement is to remove those manual copy-and-search steps.

Desired behaviour:

Play selected
    ↓
[Contacts]
    ↓
Contact acronym passed automatically
    ↓
Contacts queried
    ↓
matching Contact pages returned

The existing acronym is therefore important.

It is not something newly invented by the prototype. It is already part of the current business process.


Why the original PoC worked

The first PoC was based on the previous designer's prototype data.

That data already contained the acronym relationship needed for Contact lookup.

The PoC then automated the manual process:

Play
    ↓
acronym
    ↓
JSON
    ↓
filtered pseudo-Contacts

When the PoC data was simply replaced with production-copy data, the relationship stopped working because the production version did not expose the acronym in the same way.

That explains the failure.


Source for the sandbox Plays

The original Excel appears to contain the important Play information, including the Contact acronym.

For the six sandbox Plays, use that Excel as the source for the PlayToC data.

Preserve:

Value

Purpose

Play title

Display / identification

Play URL

Navigation and possible derived metadata

Contact acronym

Contact lookup

Other existing fields

As required


Production-style sandbox flow

Original Excel
    ↓
six real Plays
    ↓
Sandbox PlayToC
    ↓
user selects Play
    ↓
[Contacts]
    ↓
JSON passes Contact acronym
    ↓
ProdCopy Contacts
    ↓
matching real Contact pages

The six Plays should look and behave like the real system.

Hard-coding or manually configuring those six is acceptable for this demo.

The goal is to validate the experience.


Contacts

The real Contacts are SharePoint pages stored in the Contacts folder/library.

They remain pages.

Do not redesign them yet.

The immediate question is:

Is the existing acronym lookup against ProdCopy Contacts reliable enough to use directly?

If yes, very little new structure may be required.

If not, a future ContactKey metadata field on the Contacts library remains an option.


Mapping / xref

The xref proved useful in the PoC because it allowed the relationship to be demonstrated without changing existing production structures.

For the next sandbox demo:

  • keep the xref if needed;
  • do not remove it merely for architectural neatness;
  • use the actual acronym source where possible;
  • determine later whether the xref is permanent or only scaffolding.

The decision depends on the real data.


Three useful values now emerging

We now have three different concepts that should not be collapsed into one field.

Value

Likely role

Folder name

Primary Play classification

Page filename

Play identity

Acronym

Contact routing / lookup

This is a much cleaner model.


Primary Play classification

Business is planning the folder structure.

The requested folder classifications are:

ADMIN
SECURE
PUBLIC

These can be treated as the primary Play classification.

That means the Play URL may eventually contain useful structured information:

/.../SECURE/SomePlay.aspx
      ↑       ↑
   PlayType   Play identity

Potential derived values:

PlayType = SECURE
PlayIdentity = SomePlay

The acronym remains separate:

ContactAcronym = SoC

Tomorrow morning: checks to perform

Check

Purpose

Confirm acronym in original Excel

Verify the existing Contact routing value

Compare acronym against six real Plays

Ensure the sandbox uses real relationships

Test ProdCopy Contact search

Determine whether acronym lookup is reliable

Parse Play URL filename

Determine whether filename can serve as Play identity

Parse Play URL folder

Confirm ADMIN, SECURE, PUBLIC can be derived reliably

Check unusual URLs

Spaces, encoded characters, renamed pages, odd paths

Check duplicates

Duplicate acronyms or filenames

Check missing values

Plays without acronym or URL

Select six representative Plays

Build a convincing sandbox demo

Include one no-Contact case if possible

Demonstrate button behaviour


Six sandbox Plays

Choose six real examples that exercise different scenarios.

Ideally include:

Example

Reason

ADMIN Play

Tests classification

SECURE Play

Tests classification

PUBLIC Play

Tests classification

Play with one Contact acronym

Simple case

Play with multiple relevant Contact groups if applicable

More complex case

Play with no Contact

Tests [Contacts] visibility

The exact business combinations can be chosen after inspecting the data.


Contacts button rule

Desired behaviour:

Play has Contact value
    ↓
show [Contacts]

Play has no Contact value
    ↓
do not show [Contacts]

The button should trigger the lookup the user currently performs manually.


Python audit

Yes: use Python to validate the data before deciding the final SharePoint rules.

Input:

production-style Play URLs
+ original Excel
+ acronym data

Python should:

extract folder classification
extract page filename
decode URL values
normalize identifiers
compare against acronym data
flag exceptions
identify duplicates
identify missing values
summarize consistency

Example output:

Play URL

PlayType

PlayIdentity

Acronym

Status

.../SECURE/SomePlay.aspx

SECURE

SomePlay

SoC

OK

.../ADMIN/OtherPlay.aspx

ADMIN

OtherPlay

NOC

OK

.../PUBLIC/Weird%20Name.aspx

PUBLIC

Weird Name

DBA

Review

The Python exercise answers:

Are folder, filename, and acronym reliable enough to become three separate attributes?


Likely architecture if the checks pass

Play URL
    ├── folder → PlayType
    └── filename → PlayIdentity

Original Play data
    └── acronym → Contact routing

Play selected
    ↓
[Contacts]
    ↓
acronym passed automatically
    ↓
ProdCopy Contacts queried
    ↓
matching Contact pages shown

What not to decide yet

Do not commit yet to:

  • removing the xref;
  • manually updating hundreds of Plays;
  • adding ContactKey to all Contact pages;
  • restructuring Contacts;
  • introducing SPFx;
  • Power Apps;
  • Power Automate;
  • custom JavaScript.

The sandbox exists to determine what is actually necessary.


What the sandbox demo should prove

The existing Contact acronym can be used to automate the Contact lookup users currently perform manually.

And, separately:

The planned folder structure can provide a primary Play classification such as ADMIN, SECURE, or PUBLIC.

The six-Play sandbox should answer:

Does this look and behave like something Business would accept as the real solution?


One-sentence morning reminder

Use the original Excel to restore the real acronym relationship, use six real Plays, point the Contacts button at ProdCopy Contacts, and use Python to validate whether folder, filename, and acronym can become reliable derived attributes before designing anything larger.

That should be enough to get you moving again in the morning without reopening the entire archaeology pit.