Page MenuHomePhabricator

Intended for reuse flag - inferred from intended use data
Open, Needs TriagePublic5 Estimated Story Points

Description

Context

📍KR: In order to better understand the needs of our users on the visibility of the Wikibase instances available on the ecosystem, we deliver a prototype, by the end of Q2, that facilitates ecosystem-wide discovery of stable Wikibases that are intended for federation and reuse by wider audiences.

The Suite team is building a prototype for a tool that facilitates discovery of Wikibases in the ecosystem (analog of Cloud's discovery page, but with known Suite instances included). The scope of the prototype includes possibility to recognize instances that are intended by their managers for federation and reuse by wider audiences.

As part of the data governance process, the Cloud team is planning to implement a question that explicitly asks the manager whether they believe the instance is intended for reuse / intended, but not ready for reuse / not intended for reuse / unsure. This work is planned when the Wiki profile implementation starts (see Iteration 1).

Until then, for the purposes of the prototype, we would like to return a flag that is an approximation of the manager's intent based on the data we already collect in the Intended Use section of the wiki profile:

  • data hub
  • permanent
  • intended for wider audience.

The prototype currently gets metadata on Cloud instances from the Cloud's discovery page API.

Story

As a reuser navigating the Wikibase Ecosystem,
I would like to discover and recognize instances intended for reuse and federation by their managers,
In order to understand which data I can confidently rely on in my projects.

Acceptance Criteria

  • The discovery page API returns one additional flag per instance: reuse_prototype.
  • The flag is 1/true if the instance has:
    • purpose = data_hub AND
    • lifespan = permanent AND
    • audience = wide
  • The flag is 0/false otherwise.

Notes

  • The flag will be replaced in the future with the one reflecting the answer of the manager to an explicit question. We might also choose to expose it through a different API. This solution is temporary and good enough for the prototype for now to support Suite achieve their learning goals when they validate the prototype with users.
  • The intended use data is stored in wiki_profiles table - look for the most recent record for the given wiki_id.

Pre-Breakdown

Task Breakdown

We noted that we haven't had an answer from Suite yet about what their requirements are. We will break down both possibilities.

  • We want a query parameter to enable or disable this feature. It should be disabled by default. enable_suite_reuse_prototype=true/false.
  • Add a reuse_prototype field to PublicWikiResource that is boolean or null; probably following the same pattern as the logo_url
  • If a new field in the output is required:
    • If the enable_suite_reuse_prototype query parameter is true:
      • use something like $query->leftJoinWhere() to join on the wiki_profiles table ordering by the updated_at field
      • For this prototype we will try and do the purpose = data_hub AND lifespan = permanent AND audience = wide logic as part of the DB query rather than modifying the Laravel Model to keep the prototype code more contained.
  • If a query parameter to filter the results is required:
    • add a new is_reusable=true/false query parameter to the PublicWikiController and add validation
    • If the enable_suite_reuse_prototype query parameter is true:
      • if is_reusable=true, use something like $query->leftJoinWhere() to join on the wiki_profiles table where purpose = data_hub AND lifespan = permanent AND audience = wide and ordering by the updated_at field (descending)
      • if is_reusable=false the "where" should be inverted i.e. NOT (purpose = data_hub AND lifespan = permanent AND audience = wide)

Note: the difference between Model::where() and Model::query()->where() is described here: https://laravel-news.com/effective-eloquent#:~:text=perspective%2E-,To,query%2E

Event Timeline

TBD: communicate to Suite about the limit in parameters

Ollie.Shotton_WMDE changed the task status from Open to Stalled.Apr 10 2026, 9:16 AM
Ollie.Shotton_WMDE subscribed.

We've broken this down as much as we can for now. Waiting on answers to follow up question from Wikibase Suite Team which will likely happen next week.

Ugh! We made a few errors during the task breakdown:

I then took a step back and reviewed what we currently have:

  • As we are currently using the Eloquent Builder in PublicWikiController I had another look at Eloquent docs and the Wiki model.
  • The Wiki model has a lot of these Relations methods (e.g. wikiSiteStats(), wikiManagers(), and settings()).
  • One of these methods is the wikiLatestProfile() which, as the name implies, returns the latest WikiProfile. Sounds just like what we need!
  • These methods can be used with the Model::with() static method to include extra information from other models with the Model e.g. like $wiki = Wiki::with('wikiDb')->firstWhere('domain', $domain); in WikiDbVersionController.
  • The Model::query() static method returns an Eloquent Builder which also has an equivalent ->with() method. This means it can be used like Model::query()->with() which is perfect for our case where we want to conditionally do with('wikiLatestProfile()') based on if the enable_suite_reuse_prototype query parameter is truthy.

Before I claimed an early victory, I thought I would do a quick test locally to verify my findings:

  • To start off, I wanted to add the three columns from the WikiProfile tables to the PublicWikiResource just to see if I could return the correct values from the database.
  • That's when I noticed the $logoSetting = $this->settings()->where('name', 'wgLogo')->first(); line in PublicWikiResource.
  • How come this is calling a class method ($this->settings()) where all the other fields are retrieved via class properties? What is this settings()? I don't see any mention of settings in PublicWikiController. It also looks surprisingly like the settings() method on the Wiki model.
  • Indeed adding 'test_wiki_latest_profile' => $this->wikiLatestProfile()->latest()->first(), to PublicWikiResource::toArray() resulted in an object like this being included in the JSON response:
"test_wiki_latest_profile": {
  "id": 3,
  "wiki_id": 1,
  "purpose": "data_hub",
  "purpose_other": null,
  "audience": "narrow",
  "audience_other": null,
  "temporality": "permanent",
  "temporality_other": null,
  "created_at": "2026-04-10T09:46:37.000000Z",
  "updated_at": "2026-04-10T09:46:37.000000Z"
}
  • After some more playing around the following code:
// TODO: delete these three fields before merging; here to easily prove the `reuse_prototype` logic works
'test_purpose' => $this->wikiLatestProfile ? $this->wikiLatestProfile->purpose : null,
'test_temporality' => $this->wikiLatestProfile ? $this->wikiLatestProfile->temporality : null,
'test_audience' => $this->wikiLatestProfile ? $this->wikiLatestProfile->audience : null,

'reuse_prototype' => $this->wikiLatestProfile
    ? $this->wikiLatestProfile->purpose === 'data_hub'
      && $this->wikiLatestProfile->temporality === 'permanent'
      && $this->wikiLatestProfile->audience === 'wide'
    : null,

results in key:value pairs like these in the JSON response:

      "test_purpose": "data_hub",
      "test_temporality": "permanent",
      "test_audience": "narrow",
      "reuse_prototype": false
...
      "test_purpose": "data_hub",
      "test_temporality": "permanent",
      "test_audience": "wide",
      "reuse_prototype": true
  • Interestingly, the code in PublicWikiController works regardless of whether PublicWikiController contains $query = $query->with('wikiLatestProfile'); or not. I guess this isn't really a surprise given how PublicWikiResource retrieves the wgLogo settings without needing to use ->with('settings'). Perhaps something to do with Laravel's "lazy loading" features? I didn't look into this any further.

So if we wanted this task completed in the shortest time possible we have a 5 line change that would do the job.

However, in the Pre-Breakdown we discussed ensuring that this change doesn't create a huge spike in extra database queries (e.g. an extra query for each Wiki), so lets have a quick look at the effect of some of these changes on database queries.

Following https://inspector.dev/logging-database-queries-with-eloquent-orm-and-laravel-fast-tips/ I logged all database queries by creating an event listener for QueryExecuted events. I followed the logs using:

docker compose exec -it api tail --follow /var/www/html/storage/logs/laravel-$(date '+%Y-%m-%d').log

The results are from a docker compose development environment with 20 wikis and calling the following request:
http://localhost:8082/wiki?sort=pages&direction=desc&page=1&per_page=10.

`origin/main` with only the event listener added - 22 queries executed
local.DEBUG: Query Executed:  {"sql":"select count(*) as aggregate from `wikis` where `wikis`.`deleted_at` is null","bindings":[],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wikis` where `wikis`.`deleted_at` is null order by (select `pages` from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = `wikis`.`id`) desc limit 10 offset 0","bindings":[],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[1,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[1],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[2,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[2],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[3,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[3],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[4,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[4],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[5,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[5],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[6,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[6],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[7,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[7],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[8,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[8],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[9,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[9],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[10,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[10],"connection":"mysql"}
Only `$query = $query->with('wikiLatestProfile');` in `PublicWikiController` - 23 queries executed
local.DEBUG: Query Executed:  {"sql":"select count(*) as aggregate from `wikis` where `wikis`.`deleted_at` is null","bindings":[],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wikis` where `wikis`.`deleted_at` is null order by (select `pages` from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = `wikis`.`id`) desc limit 10 offset 0","bindings":[],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id`","bindings":[],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[1,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[1],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[2,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[2],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[3,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[3],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[4,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[4],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[5,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[5],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[6,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[6],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[7,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[7],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[8,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[8],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[9,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[9],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[10,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[10],"connection":"mysql"}
Only `'reuse_prototype' => $this->wikiLatestProfile ...` in `PublicWikiResource` - 32 queries executed
local.DEBUG: Query Executed:  {"sql":"select count(*) as aggregate from `wikis` where `wikis`.`deleted_at` is null","bindings":[],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wikis` where `wikis`.`deleted_at` is null order by (select `pages` from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = `wikis`.`id`) desc limit 10 offset 0","bindings":[],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[1,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[1],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null limit 1","bindings":[1,1],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[2,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[2],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null limit 1","bindings":[2,2],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[3,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[3],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null limit 1","bindings":[3,3],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[4,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[4],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null limit 1","bindings":[4,4],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[5,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[5],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null limit 1","bindings":[5,5],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[6,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[6],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null limit 1","bindings":[6,6],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[7,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[7],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null limit 1","bindings":[7,7],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[8,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[8],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null limit 1","bindings":[8,8],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[9,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[9],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null limit 1","bindings":[9,9],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[10,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[10],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id` where `wiki_profiles`.`wiki_id` = ? and `wiki_profiles`.`wiki_id` is not null limit 1","bindings":[10,10],"connection":"mysql"}
`$query = $query->with('wikiLatestProfile');` and `'reuse_prototype' => $this->wikiLatestProfile ...` - 23 queries
local.DEBUG: Query Executed:  {"sql":"select count(*) as aggregate from `wikis` where `wikis`.`deleted_at` is null","bindings":[],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wikis` where `wikis`.`deleted_at` is null order by (select `pages` from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = `wikis`.`id`) desc limit 10 offset 0","bindings":[],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select `wiki_profiles`.* from `wiki_profiles` inner join (select MAX(`wiki_profiles`.`id`) as `id_aggregate`, `wiki_profiles`.`wiki_id` from `wiki_profiles` where `wiki_profiles`.`wiki_id` in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) group by `wiki_profiles`.`wiki_id`) as `latestOfMany` on `latestOfMany`.`id_aggregate` = `wiki_profiles`.`id` and `latestOfMany`.`wiki_id` = `wiki_profiles`.`wiki_id`","bindings":[],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[1,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[1],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[2,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[2],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[3,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[3],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[4,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[4],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[5,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[5],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[6,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[6],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[7,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[7],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[8,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[8],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[9,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[9],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_settings` where `wiki_settings`.`wiki_id` = ? and `wiki_settings`.`wiki_id` is not null and `name` = ? limit 1","bindings":[10,"wgLogo"],"connection":"mysql"} 
local.DEBUG: Query Executed:  {"sql":"select * from `wiki_site_stats` where `wiki_site_stats`.`wiki_id` = ? and `wiki_site_stats`.`wiki_id` is not null limit 1","bindings":[10],"connection":"mysql"}

I found it interesting that only modifying PublicWikiResource required more queries than including the changes in both PublicWikiController and PublicWikiResource (32 vs 23). This could be the difference between eager loading and lazy loading, but I didn't look into this further.

Given that, when modifying PublicWikiController and PublicWikiResource, it only results in 1 more query than on origin/main I don't think we need to worry about this prototype feature having a big impact on the database. There appears to be other places to investigate excessive database queries first if we wanted to start optimizing.

@Anton.Kokh I also noticed that there is no lifespan column in the wiki_profiles table. I assume you mean temporality?

outdooracorn opened https://github.com/wbstack/api/pull/1082

PoC: Add reuse_prototype field to /wiki API endpoint

Tarrow changed the task status from Stalled to Open.Wed, Apr 15, 10:06 AM
Tarrow subscribed.

Had a reply from Wikibase Suite Team

we've discussed it and the best option for us would be adding the new "intended_for_reuse" boolean field and then we'll handle the filtering for UI