Page MenuHomePhabricator

Add significant changes endpoint to labs
Closed, ResolvedPublic

Description

Create a significant changes endpoint that the "Article as a living document" experiment will use to populate this data. We will keep this going in a labs environment. This is what the endpoint will need to do to gather the data we need. Specific contract TBD.

  • Flag large and small changes based on a particular byte or character threshold. Would be ideal if we can flag based on number of characters added and deleted, not just overall article size deltas between revisions. [DONE]
  • Detect if a reference added, generate readable snippet (not wikitext) from that. [DONE, returning structured object for client to turn into readable snippet]
  • Detect large changes, generate readable snippet (not wikitext) from that. [DONE, though occasionally the highlighting tags change the parsoid output. If this feels like a problem we can completely remove highlighting indicators & truncating.]
  • Detect what section this happened in in the above 3 pieces. [DONE]
  • Flag small changes and bundle them up with a count. [DONE]
  • Detect if a new section was added in an article's talk page, generate readable snippet (not wikitext) from that [DONE]
  • Detect if vandalism was reverted in an article's talk page, generate readable snippet (not wikitext) from that. [DONE]
  • Have an in-memory caching setup for each revision that is processed of an article and article's talk page revision history. Check this cache first before going forward with processing. [DONE, caching up to 100 significant article events. Events will stop returning beyond that].
  • Also return global counts used to make "x changes by x editors in x days" snippet based solely on cached objects. In theory we should have a decent amount cached at all times. [DONE]
  • Once the correct threshold is decided upon, remove that configurable component (as well as page size). Changing thresholds causes the caching objects to double, and there would be no need for this functionality when we go live.
  • Consider adding editor counts as a last step - though keep in mind this shouldn't be cached since it may change with each call. [DONE]
  • We should limit how far back in history we can go so users aren't building up cache that will never be seen client side. [DONE]
  • If snippet or counts endpoints fail, do not let the endpoint error out. [DONE]
  • Note for article readable snippets, they need to be set up in a way so that we can easily seek it out in the article content to highlight, but also maybe not include the entire line because we need these snippets to be short and easy to read (with ... before and after added text perhaps). This might be a balancing act, or we return one snippet meant for the modal screen, and a separate snippet meant for highlighting on the content screen.

Questions for Product/Design:

  • How far back do we allow users to go? For both the significant changes paging as well as the "x changes by n editors in z days" question at the top? - Per product 100 events
  • Requirements above were based on types gleaned from the mocks, but it would be good if we could have the types documented/hashed out. - new mocks for every type in parent task

Event Timeline

LGoto triaged this task as Medium priority.Jul 13 2020, 6:40 PM
LGoto moved this task from Needs Triage to Engineering Backlog on the Wikipedia-iOS-App-Backlog board.
LGoto removed a project: Epic.

We have a new labs instance spun up with my refactored prototype that we can start working against.

Contract example (so far, new types will be added):

{
	"nextRvStartId": 965476831,
	"significantChanges": [{
		"revid": 942789183,
		"timestamp": "2020-07-16T21:47:17Z",
		"outputType": "vandalism-revert",
		"user": "ClueBot NG",
		"userid": 13286072,
		"section": "Intro"
	},{
		"revid": 967880655,
		"timestamp": "2020-07-15T21:47:17Z",
		"outputType": "new-talk-page-topic",
		"snippet": "The phrasing here implies that \"American\" is exclusively synonymous with a citizen of the US, which is not the case. Citizens of the US are Americans, but not all Americans reside in the US. Indeed, the majority do not. Because a nation-specific demonym referring exclusively to the US has not come into the lexicon does not mean that this implication should occur. This discussion should be either (1) made more complete, perhaps explaining it as erroneous despite its common use or (2) removed. Though the rise in the English language and its lexical inconsistencies continue, it is prudent as a public service within a wiki to dissuade such errors.",
		"user": "2600:1700:19E0:90E0:F950:FEA0:EC4B:B754",
		"userid": 0,
		"section": "== \"American\" demonym =="
	},{
		"revid": 967830663,
		"timestamp": "2020-07-15T15:35:56Z",
		"outputType": "new-reference",
		"user": "Mason.Jones",
		"userid": 246091,
		"section": "=== Language ===",
		"templates": [{
			"name": "cite web ",
			"access-date": "September 2, 2013",
			"publisher": "[[Modern Language Association]]",
			"title": "United States",
			"url": "http://www.mla.org/map_data"
		}, {
			"name": "cite web ",
			"access-date": "May 29, 2017",
			"archive-date": "February 12, 2020",
			"archive-url": "https://archive.today/20200212213140/http://factfinder.census.gov/faces/tableservices/jsf/pages/productview.xhtml?pid=ACS_10_1YR_B16001&prodType=table",
			"first": "U.S. Census",
			"last": "Bureau",
			"publisher": "",
			"title": "American FactFinder—Results",
			"url": "http://factfinder.census.gov/faces/tableservices/jsf/pages/productview.xhtml?pid=ACS_10_1YR_B16001&prodType=table",
			"url-status": "dead"
		}]
	},{
		"revid": 966156336,
		"timestamp": "2020-07-05T11:55:23Z",
		"outputType": "large-change",
		"snippet": "The <a href=\"./United_States_Census_Bureau\" title=\"United States Census Bureau\">U.S. Census Bureau</a> officially estimated the country's population to be 328,239,523 as of July 1, 2019.<sup class=\"mw-ref\" id=\"cite_ref-auto_1-0\"><a href=\"./United_States#cite_note-auto-1\" style=\"counter-reset: mw-Ref 1;\"><span class=\"mw-reflink-text\">[1]</span></a></sup> In addition, the Census Bureau provides a continuously updated <a href=\"./U.S._and_World_Population_Clock\" title=\"U.S. and World Population Clock\">U.S. Population Clock</a> that approximates the latest population of the 50 states and District of Columbia based on the Bureau's most recent demographic trends.<sup class=\"mw-ref\" id=\"cite_ref-2\"><a href=\"./United_States#cite_note-2\" style=\"counter-reset: mw-Ref 2;\"><span class=\"mw-reflink-text\">[2]</span></a></sup> According to the clock, on May 23, 2020, the U.S. population exceeded 329 million residents, with <span class=\"delete-highlight\">one</span><span class=\"add-highlight\">a</span> <span class=\"delete-highlight\">person,</span><span class=\"add-highlight\">net</span> <span class=\"delete-highlight\">was</span><span class=\"add-highlight\">gain</span> <span class=\"delete-highlight\">being</span><span class=\"add-highlight\">of</span> <span class=\"delete-highlight\">added</span><span class=\"add-highlight\">one</span> <span class=\"delete-highlight\">(a net gain)</span><span class=\"add-highlight\">person</span> every 19 seconds, or about 4,547 people per day. The United States is the third most populous nation in the world, after <a href=\"./China\" title=\"China\">China</a> and <a href=\"./India\" title=\"India\">India</a>. In 2018 the <a href=\"./Median_age\" title=\"Median age\" class=\"mw-redirect\">median age</a> of the United States population was 38.1 years.<sup class=\"mw-ref\" id=\"cite_ref-3\"><a href=\"./United_States#cite_note-3\" style=\"counter-reset: mw-Ref 3;\"><span class=\"mw-reflink-text\">[3]</span></a></sup>\n",
		"user": "Dhtwiki",
		"userid": 9475572,
		"characterChange": {
			"addedCount": 19,
			"deletedCount": 35
		},
		"section":  "=== Population ===",
	}, {
		"count": 7,
		"outputType": "small-change"
	}]
}

So far outputType's supported are large-change, small-change, vandalism-revert, new-talk-page-topic, and new-reference. I will add more types as I continue to work on this. Details about the important keys are below:

  • I'm hoping we can use snippet for both highlighting in the article content and for showing a preview snippet in the timeline modal. I am only pulling the most changed line from the full diff for the snippet. I am surrounding areas that were added or deleted with <span class=\"delete-highlight\"> or <span class=\"add-highlight\">. If the entire line was added, you would see <span class=\"add-highlight\"> and </span> wrapping the entire text block.
  • characterChange includes the added and deleted characters in the entire diff (not just that diff line).
  • section includes what section the change occurred on.
  • small-change outputTypes aren't given more detail besides a count of how many small changes there are to indicate in the timeline.

Remaining types to be added from mocks are reference added - we will also discuss the other types next week.

There are some notes from my spike comment that I have addressed here:

  • I am now counting characters now via the diff endpoint rather than using a byte size change in the revision file size. This means we should now catch larger changes where a user deleted a lot, added a lot, and the ultimate article byte size evened out.
  • I was able to convert the wikitext snippet into an (html, sorry) readable format via the transform/wikitext/to/mobile-html endpoint. There are some bugs around it (my add-highlight and delete-highlight spans are sometimes stripped, will look into those) but for the most part I hope it's usable and we can still use native view by leaning on our existing String.byAttributingHTML methods in the iOS codebase.
  • I have added some basic in-memory caching for revisions we have already processed, so hopefully reloads are a bit quicker.

Some vandalism revert revisions and new talk page topics are now being detected. Labs endpoint has been updated and notes in above comment are updated with the latest.

new-reference types are now being detected and returning the template details from parsoid. Labs endpoint has been updated and notes in above comment are updated with the latest.

Tsevener updated the task description. (Show Details)

Note, when I tried to generate a readable snippet via wikitext/to/mobile-html for the new-reference template wikitext, the snippet looked like this:

<cite class=\"citation web cs1\"><a rel=\"mw:ExtLink\" href=\"http://www.mla.org/map_data\" class=\"external text\">\"United States\"</a>. <a href=\"./Modern_Language_Association\" title=\"Modern Language Association\">Modern Language Association</a><span class=\"reference-accessdate\">. Retrieved <span class=\"nowrap\">September 2,</span> 2013</span>.</cite><style data-mw-deduplicate=\"TemplateStyles:r951705291\" typeof=\"mw:Extension/templatestyles\">.mw-parser-output cite.citation{font-style:inherit}.mw-parser-output .citation q{quotes:\"\\\"\"\"\\\"\"\"'\"\"'\"}.mw-parser-output .id-lock-free a,.mw-parser-output .citation .cs1-lock-free a{background-image:url(\"//upload.wikimedia.org/wikipedia/commons/thumb/6/65/Lock-green.svg/9px-Lock-green.svg.png\");background-image:linear-gradient(transparent,transparent),url(\"//upload.wikimedia.org/wikipedia/commons/6/65/Lock-green.svg\");background-repeat:no-repeat;background-size:9px;background-position:right .1em center}.mw-parser-output .id-lock-limited a,.mw-parser-output .id-lock-registration a,.mw-parser-output .citation .cs1-lock-limited a,.mw-parser-output .citation .cs1-lock-registration a{background-image:url(\"//upload.wikimedia.org/wikipedia/commons/thumb/d/d6/Lock-gray-alt-2.svg/9px-Lock-gray-alt-2.svg.png\");background-image:linear-gradient(transparent,transparent),url(\"//upload.wikimedia.org/wikipedia/commons/d/d6/Lock-gray-alt-2.svg\");background-repeat:no-repeat;background-size:9px;background-position:right .1em center}.mw-parser-output .id-lock-subscription a,.mw-parser-output .citation .cs1-lock-subscription a{background-image:url(\"//upload.wikimedia.org/wikipedia/commons/thumb/a/aa/Lock-red-alt-2.svg/9px-Lock-red-alt-2.svg.png\");background-image:linear-gradient(transparent,transparent),url(\"//upload.wikimedia.org/wikipedia/commons/a/aa/Lock-red-alt-2.svg\");background-repeat:no-repeat;background-size:9px;background-position:right .1em center}.mw-parser-output .cs1-subscription,.mw-parser-output .cs1-registration{color:#555}.mw-parser-output .cs1-subscription span,.mw-parser-output .cs1-registration span{border-bottom:1px dotted;cursor:help}.mw-parser-output .cs1-ws-icon a{background-image:url(\"//upload.wikimedia.org/wikipedia/commons/thumb/4/4c/Wikisource-logo.svg/12px-Wikisource-logo.svg.png\");background-image:linear-gradient(transparent,transparent),url(\"//upload.wikimedia.org/wikipedia/commons/4/4c/Wikisource-logo.svg\");background-repeat:no-repeat;background-size:12px;background-position:right .1em center}.mw-parser-output code.cs1-code{color:inherit;background:inherit;border:inherit;padding:inherit}.mw-parser-output .cs1-hidden-error{display:none;font-size:100%}.mw-parser-output .cs1-visible-error{font-size:100%}.mw-parser-output .cs1-maint{display:none;color:#33aa33;margin-left:0.3em}.mw-parser-output .cs1-subscription,.mw-parser-output .cs1-registration,.mw-parser-output .cs1-format{font-size:95%}.mw-parser-output .cs1-kern-left,.mw-parser-output .cs1-kern-wl-left{padding-left:0.2em}.mw-parser-output .cs1-kern-right,.mw-parser-output .cs1-kern-wl-right{padding-right:0.2em}.mw-parser-output .citation .mw-selflink{font-weight:inherit}</style>

That's a bit much for the client to parse through and turn into an NSAttributableString. Since we're already getting somewhat structured-looking templates in the output, I think the client can take that and put together it's own snippet to match the mocks:

"templates": [{
			"name": "cite web ",
			"access-date": "September 2, 2013",
			"publisher": "[[Modern Language Association]]",
			"title": "United States",
			"url": "http://www.mla.org/map_data"
		}, {
			"name": "cite web ",
			"access-date": "May 29, 2017",
			"archive-date": "February 12, 2020",
			"archive-url": "https://archive.today/20200212213140/http://factfinder.census.gov/faces/tableservices/jsf/pages/productview.xhtml?pid=ACS_10_1YR_B16001&prodType=table",
			"first": "U.S. Census",
			"last": "Bureau",
			"publisher": "",
			"title": "American FactFinder—Results",
			"url": "http://factfinder.census.gov/faces/tableservices/jsf/pages/productview.xhtml?pid=ACS_10_1YR_B16001&prodType=table",
			"url-status": "dead"
		}]
	}

@JMinor @cmadeo I have added a couple of extra endpoints as discussed to aid in looking through added templates and new talk page topics:

https://mobileapps-ios-experiments.wmflabs.org/en.wikipedia.org/v1/page/added-templates/United_States

If any templates are detected as added in the diff (not just cite types), you will see the result in that endpoint. ^

https://mobileapps-ios-experiments.wmflabs.org/en.wikipedia.org/v1/page/new-talk-topics/United_States

This spits out talk page revisions that are detected as new topics. It's very similar to the output in the original endpoint except that I'm only displaying talk page types and am showing the entire revision object so you can inspect the parsedComment field.

Both support paging in the same way as the original endpoint (add rvstartid as a query item). Since these new ones are so heavily filtered I also added the ability for you to increase the page size like so:

https://mobileapps-ios-experiments.wmflabs.org/en.wikipedia.org/v1/page/added-templates/United_States?pageSize=100

Note I stripped out caching logic on these so they're kinda slow.

Hi @Tsevener, sorry this took so long for me to parse through!

Would it be possible to present the citations in the history view as follows?

Screen Shot 2020-07-31 at 5.29.24 PM.png (908×1 px, 153 KB)

@cmadeo I found some documentation on these templates and it looks like not many fields are required, so some of these might be very bare-bones. I'm guessing Suggested isn't enforced in any way by the system but Required is. If you are good with me populating it as best I can but knowing a lot of this could be missing, I can try that.

Website
Required: title & url
Suggested: last name, first name, source date, url status, archive url, archive date, url access date, name of website
Optional: everything else

News
Required: source title
Suggested: last name, first name, source date, name of publication, url, url status, url access date
Optional: everything else

Book
Required: title
Suggested: last name, first name, publisher, year of publication, isbn, location of publication, page(s) cited
Optional: everything else

Journal
Required: title, journal
Suggested: last name, first name, source date, url, volume, pages, content deliverer
Optional: everything else

Also here are some examples of each I found after traversing the United_States response for a while:

@cmadeo one followup question - I think I can add the [Citation #] by pulling up that snapshot of the article in history and getting it's number that way. What would it link to?

@Tsevener Thanks for this update! Yes, the required, suggested, optional fields for each type look great. Totally expect that a fair amount of these will be pretty barebones but that's okay since we just want to reflect the info that's available.

Will taking the snapshot slow loading in anyway? If so we can lose the citation number, if not i think the idea is that we'll link it to the associated ref list item.

One discussion @MattCleinman and I were having today was that we might not want to actually include the external links in the 'card' featured in the list as this could make moving back and forth from the app out to the web a bit confusing...it'd be good to still include the links in any endpoint though in case this link-less version performs poorly with users and we want to add it back in.

@cmadeo well, the reason I asked about where the citation number links to is that this could be an added reference that is no longer in the current reference list, since this is a reference added back in history. So do you want me to get the reference number as it existed in that particular revision of the article? If so I think we'd have to link to an older article version when tapping it which could be weird. Or we could try to only populate the [Citation #] if it exists in the latest article revision that the user already has fetched on their screen. I'm not sure how often references are deleted but hopefully it's rare enough that you wouldn't have too many without an associated citation number.

@Tsevener ah, super good point I hadn't thought about the deleting of references. Let's not show the ref number if it's been deleted and I think we'll need to have links in deleted references go to the individual revision in history...perhaps we want to consider a way of visually indicating that 'added' text has been 'deleted' in some way in this view.

Generally this brings up a lot of questions for me though around the differences between this view and the history view --- in that this is curated a bit more something to think about as we move forward but nothing I have a definitive answer for right now.

Per our meeting:

  • lets consider deleting as a separate "change" within the same event. So Adding and Deleting a reference in the same edit all result in two notable changes one for the addition(s) one for the deletion(s). New "deletion" versions of the supported types will need to be mocked up, but they will be simpler and less info rich than the existing "addition" focused ones.
  • Lets cap events emitted at 100, so you only need to parse back into the history until you hit 100 events or run out of history.
  • We're going to cut highlighting changes, in general, for now. We'd like to have it, but given the additional complexities and timeline, lets simplify here.

Updated endpoint has been deployed. Details (note endpoint path has changed from significant-changes to significant-events):

First page: https://mobileapps-ios-experiments.wmflabs.org/en.wikipedia.org/v1/page/significant-events/United_States.
Subsequent pages: add nextRvStartId value from previous page as query item rvstartid. E.g. https://mobileapps-ios-experiments.wmflabs.org/en.wikipedia.org/v1/page/significant-events/United_States?rvstartid=964157912
Threshold: For signifying small vs. large change. 100 bytes by default, but you can adjust with the threshold query item, E.g. https://mobileapps-ios-experiments.wmflabs.org/en.wikipedia.org/v1/page/significant-events/United_States?threshold=50 or https://mobileapps-ios-experiments.wmflabs.org/en.wikipedia.org/v1/page/significant-events/United_States?rvstartid=964157912&threshold=50
Page size: It analyzes 20 revisions per page, not configurable.

New contract:

{
	"nextRvStartId": 971549570,
	"sha": "d43cfe20767ecae41763b15167f0ebb86c512f3ae4ff851c50f6d9aa92305096",
	"timeline": [{
		"count": 8,
		"outputType": "small-change"
	}, {
		"revid": 973550989,
		"timestamp": "2020-08-17T21:10:06Z",
		"outputType": "large-change",
		"user": "Dhtwiki",
		"userid": 9475572,
		"significantChanges": [{
			"outputType": "added-text",
			"snippet": "...<span class='highlight-start'>used</span> them <span class='highlight-start'>on</span> <span class='highlight-start'>Japan</span> <span class='highlight-start'>in</span>...",
			"snippetType": 3,
			"characterCount": 47,
			"sections": ["=== World War I, Great Depression, and World War II ==="]
		}, {
			"outputType": "deleted-text",
			"characterCount": 559,
			"sections": ["=== World War I, Great Depression, and World War II ==="]
		}],
		"userGroups": ["extendedconfirmed", "*", "user", "autoconfirmed"],
		"userEditCount": 31196
	}, {
		"revid": 973092925,
		"timestamp": "2020-08-15T09:23:08Z",
		"outputType": "new-talk-page-topic",
		"snippet": "I miss a category of (political) geographical areas composed of multiple topologically separate parts on the continuous land (others would be e.g. <a href=\"./Azerbaijan\" title=\"Azerbaijan\">Azerbaijan</a>, <a href=\"./Puducherry\" title=\"Puducherry\">Puducherry</a>), i.e. region that has exclaves, in principle. Could some geographer gnostic of the corresponding terminus technicus do that&nbsp;? —<a href=\"./User:Mykhal\" title=\"User:Mykhal\">Mykhal</a> (<a href=\"./User_talk:Mykhal\" title=\"User talk:Mykhal\">talk</a>) 09:23, 15 August 2020 (UTC)",
		"user": "Mykhal",
		"userid": 88116,
		"section": "== Discontinuous region category ==",
		"userGroups": ["extendedconfirmed", "*", "user", "autoconfirmed"],
		"userEditCount": 3636
	},{
		"revid": 969418049,
		"timestamp": "2020-07-25T08:53:48Z",
		"outputType": "large-change",
		"user": "TempDog123",
		"userid": 14623512,
		"significantChanges": [{
			"outputType": "new-template",
			"sections": ["=== Language ==="],
			"templates": [{
				"name": "cite web ",
				"access-date": "September 2, 2013",
				"publisher": "[[Modern Language Association]]",
				"title": "United States",
				"url": "http://www.mla.org/map_data"
			}, {
				"name": "cite web ",
				"access-date": "May 29, 2017",
				"archive-date": "February 12, 2020",
				"archive-url": "https://archive.today/20200212213140/http://factfinder.census.gov/faces/tableservices/jsf/pages/productview.xhtml?pid=ACS_10_1YR_B16001&prodType=table",
				"first": "U.S. Census",
				"last": "Bureau",
				"publisher": "",
				"title": "American FactFinder—Results",
				"url": "http://factfinder.census.gov/faces/tableservices/jsf/pages/productview.xhtml?pid=ACS_10_1YR_B16001&prodType=table",
				"url-status": "dead"
			}]
	},{
		"revid": 944605060,
		"timestamp": "2020-03-08T20:59:25Z",
		"outputType": "large-change",
		"user": "S0091",
		"userid": 35056011,
		"significantChanges": [{
			"outputType": "new-template",
			"sections": ["Intro"],
			"templates": [{
				"name": "cite journal ",
				"doi": "10.1080/07352680903133252",
				"first1": "M.",
				"first2": "H. J.",
				"first3": "I.",
				"first4": "K. H. M.",
				"issue": "6",
				"journal": "Critical Reviews in Plant Sciences",
				"last1": "Kumari",
				"last2": "Clarke",
				"last3": "Small",
				"last4": "Siddique",
				"pages": "393–409",
				"title": "Albinism in plants: A major bottleneck in wide hybridization, androgenesis and doubled haploid culture",
				"url": "http://researchonline.nd.edu.au/sci__article/29/",
				"volume": "28",
				"year": "2009"
			}
                 ]
	},{
		"revid": 445891,
		"timestamp": "2020-08-17T15:50:22Z",
		"outputType": "large-change",
		"user": "47.184.2.63",
		"userid": 0,
		"significantChanges": [{
			"outputType": "new-template",
			"sections": [],
			"templates": [{
				"1": "Domestic animal",
				"name": "short description"
			}]
		}]
	},{
		"revid": 942789183,
		"timestamp": "2020-02-26T21:08:37Z",
		"outputType": "vandalism-revert",
		"user": "ClueBot NG",
		"userid": 13286072,
		"sections": ["Intro"],
		"userGroups": ["bot", "reviewer", "rollbacker", "*", "user", "autoconfirmed"],
		"userEditCount": 5533062
	}],
	"summary": {
		"earliestTimestamp": "2020-07-23T18:57:20Z",
		"numChanges": 60,
		"numUsers": 31
	}
}

Notable new things:

  • sha is to be used for the new changes indicator on the article view. It only returns when you fetch the first page. The client should persist it, and if it changes the next time the article is visited, that's an indication that there are new changes for them to see.
  • large-change type now has a child array of significantChanges, which can contain added-text, deleted-text, and new-template types.
  • section changed from singular to an array for most objects, since changes can occur across multiple sections.
  • userGroups - just some extra information to detect if the user was a bot or not.
  • userEditCount - edit count of users to display in cell
  • summary - data to power the green text at the top of the modal.
  • now snippets of the added-text outputType integrate <span class='highlight-start'> where we should try highlighting with an NSAttributableString. If snippetType == 1 for these, you won't see the tags but we should highlight the entire snippet. If this doesn't work reliably enough, however, (I've seen some bugs server-side with this), it's easy enough for me to disable these tags server-side.

Attaching final load test results. So far I don't see anything alarming, though page sizes are small (20 revisions analyzed at a time + additional talk page items interspersed) so it may feel slower as you're scrolling if pages have to be fetched often. Once it's in the app we'll want to play with a right balance of page size vs. load time.

I also tried pummelling the server by increasing the number of concurrent calls. It seemed to hold it's own up to 500 concurrent calls, I saw timeout errors when I tried 1000 concurrent calls.

Moving into Waiting to switch to fetching this data in the app.

PR was reviewed here. Labs environment is pointing directly this branch, so no merging necessary.

This is substantially done, but I'm going to move it to the 6.7.2 board just in case we need to iterate or refer to it for that release.

@Tsevener Thanks for taking this wild ride with us and great work!