Page MenuHomePhabricator

📜P1: make remaining GET endpoints for upcoming, current and all policies of a given type
Closed, ResolvedPublic

Description


Get upcoming policy version (ToU/HP)
GET /v1/policies/{policy_type}/upcoming

{
  "metadata": {
    "policy_id": 4
    "type": "terms-of-use",
    "active_from": "2028-11-02",
    "content_vue_file": "terms-of-use/version-3.vue"
  }
}

If there is no upcoming policy of this type we should return a 404.
If there are multiple upcoming policies (either with or without an active_from date) we should return a 500


Get the metadata of all policies (of a single type)
GET /v1/policies/{policy_type}

{ 
  "items": [
    {
      "metadata": {
        "policy_id": 1
   "type": "terms-of-use",
   "active_from": "2020-01-01",
   "content_vue_file": "terms-of-use/version-1.vue"
      }
    },
    {
      "metadata": {
        "policy_id": 4
        "type": "terms-of-use",
        "active_from": "2022-11-02",
        "content_vue_file": "terms-of-use/version-2.vue"
      }
    },
    {
      "metadata": {
        "policy_id": 5
        "type": "terms-of-use",
        "content_vue_file": "terms-of-use/version-3.vue"
      }
    },
    ...
  ]
}

If there are no policies of this type we should return an empty items array.


Get the reference to the metadata of the current policy version of a single type
GET /v1/policies/{policy_type}/current

{
  "metadata": {
    "policy_id": 3
    "type": "terms-of-use",
    "active_from": "2024-11-07",
    "content_vue_file": "terms-of-use/version-2.vue"
  }
}

If there is no current policy of this type we should return a 404.

PRs:

Event Timeline

dena renamed this task from P1: make remaining GET endpoints for upcoming, current and all policies of a given type to 📜P1: make remaining GET endpoints for upcoming, current and all policies of a given type.

Two observations:

1. api route order matters
this one works:

$router->get('v1/policies/current', ['uses' => 'PoliciesController@getCurrentPolicies']);
$router->get('v1/policies/{policy_type}', ['uses' => 'PoliciesController@getPoliciesByType']);

this one doesnt: v1/policies/{policy_type} swallows the later ones:

$router->get('v1/policies/{policy_type}', ['uses' => 'PoliciesController@getPoliciesByType']);
$router->get('v1/policies/current', ['uses' => 'PoliciesController@getCurrentPolicies']);

2. Explicit nulling of active_from
Due to our PolicyFactory implementation we *need* to set active_from to null if we want it to be not filled.
this works:

Policy::factory()->create([
    'policy_type' => 'terms-of-use',
    'active_from' => null,
]);

this fills with 'active_from' => now()

Policy::factory()->create([
    'policy_type' => 'terms-of-use',
]);
dena removed dena as the assignee of this task.Fri, Jul 24, 10:12 AM
dena moved this task from Doing to Waiting for Peer Review on the Wikibase Cloud (Kanban Board) board.
dena updated the task description. (Show Details)

Just now I was wondering if the GET /v1/policies/{policy_type} endpoint should also contain upcoming policies - as per the example from the senior notes doc it seems the answer is "yes":

Get the metadata of all policies (of a single type)
GET /v1/policies/{policy_type}

{ 
  "items": [
    {
      "metadata": {
        "policy_id": 1
   "type": "hosting-policy",
   "active_from": "2023-12-25",
   "content_vue_file": "hosting-policy/version-1.vue"
      }
    },
    {
      "metadata": {
        "policy_id": 4
        "type": "terms-of-use",
        "active_from": "2028-11-02",
        "content_vue_file": "terms-of-use/version-3.vue"
      }
    },
    ...
  ]
}

found a bug while trying this on staging; reverted.

if active_from is null it gets filled with todays date

App\Policy {#8325
  id: 3,
  policy_type: "terms-of-use",
  active_from: null,
  content_vue_file: "terms-of-use/version-2.vue",
  created_at: "2026-07-23 14:42:57",
  updated_at: "2026-07-23 14:42:57",
},
 $ curl -Ls https://www.wikibase.dev/api/v1/policies/terms-of-use/upcoming | jq
{
  "metadata": {
    "policy_id": 3,
    "type": "terms-of-use",
    "active_from": "2026-07-24",
    "content_vue_file": "terms-of-use/version-2.vue"
  }
}

tests on staging:

0 15:42 » deer@wmde-102295 ~
 $ curl -Ls https://www.wikibase.dev/api/v1/policies/terms-of-use | jq
{
  "items": [
    {
      "metadata": {
        "policy_id": 3,
        "type": "terms-of-use",
        "active_from": null,
        "content_vue_file": "terms-of-use/version-2.vue"
      }
    },
    {
      "metadata": {
        "policy_id": 1,
        "type": "terms-of-use",
        "active_from": "2022-01-01",
        "content_vue_file": "terms-of-use/version-1.vue"
      }
    }
  ]
}
0 15:42 » deer@wmde-102295 ~
 $ curl -Ls https://www.wikibase.dev/api/v1/policies/terms-of-use/current | jq
{
  "metadata": {
    "policy_id": 1,
    "type": "terms-of-use",
    "active_from": "2022-01-01",
    "content_vue_file": "terms-of-use/version-1.vue"
  }
}
0 15:42 » deer@wmde-102295 ~
 $ curl -Ls https://www.wikibase.dev/api/v1/policies/terms-of-use/upcoming | jq
{
  "metadata": {
    "policy_id": 3,
    "type": "terms-of-use",
    "active_from": null,
    "content_vue_file": "terms-of-use/version-2.vue"
  }
}