diff --git a/policy-author/README.md b/policy-author/README.md new file mode 100644 index 000000000..98839edf9 --- /dev/null +++ b/policy-author/README.md @@ -0,0 +1,123 @@ +# Policy-Author API (draft) + +## Background + +The Policy API specifies an endpoint and a JSON schema for communicating mobility policy to providers. This document describes a companion API to the provider-facing Policy endpoints for creating and editing Policy and Geography objects. + +[Policy PR](https://github.com/CityOfLosAngeles/mobility-data-specification/pull/322) + +## Endpoints + +The agency-facing Policy Author API consists of the following endpoints. The endpoints to list Policy and Geography objects are defined in the Policy API. The only addition is that when calling the GET /policies endpoint, append ?unpublished to get the unpublished ones, separate from the published ones. Adding ?unpublished will have no effect if your access token has a provider_id. + +### Policy Endpoints + +Responses must set the `Content-Type` header, as specified in the [Provider versioning](../provider/README.md#versioning) section. They must also specify the API version in the JSON-formatted response body, under the `version` key. + +#### Schema + +See Policy API. + +Metadata is free-form JSON format. + +### GET /policies + +Get a list of policies. + +A note: the `get_published` and `get_unpublished` parameters only make sense in the Policy Author version of this endpoint, because the Policy Author API is intended for use by Agencies and not Providers. Providers should never be able to see unpublished Policies, as those are not yet meant for public consumption. + +Parameters: +| Name | Type | R/O | Description | +| ------------ | --------- | --- | ---------------------------------------------- | +| `policy_id` | UUID | Optional | If provided, returns one policy object with the matching UUID; default is to return all policy objects. | +| `get_published` | string | O | If set to the string 'true', returns metadata of published policies. | +| `get_unpublished` | string | O | If set to the string 'true', returns metadata of unpublished policies. | + +Response codes: +- 200 - success +- 400 - cannot return results because both params were set to true +- 401 - unauthorized +- 404 - not found +- 500 - server error + + +### POST /policies + +Create a new unpublished (mutable) Policy + +Payload: a new Policy object, without a `policy_id` + +Response codes: + +- 201 - Created. Returns: the Policy object on success, including a `policy_id` and a `version` indicating the current API version. +- 400 - Policy does not conform to schema +- 401 - Unauthorized (if any auth issue) +- 500 - Server error (hopefully doesn’t happen) + +### PUT /policies/{policy_id} + +Update an existing Policy. Must be unpublished. + +Payload: a new Policy object + +Response codes: + +- 200 - success, returns Policy object +- 400 - Policy does not conform to schema +- 401 - unauthorized +- 404 - not found +- 409 - conflict (if immutable) +- 500 - server error + +### PUT /policies/{policy_id}/publish + +Publish (make immutable) a Policy. Must be unpublished. + +Response codes: + +- 200 - success +- 401 - unauthorized +- 404 - not found +- 409 - conflict (if already published) +- 500 - server error + +### GET /policies/meta + +Get a list of policy metadata. + +Parameters: +| Name | Type | R/O | Description | +| ------------ | --------- | --- | ---------------------------------------------- | +| `get_published` | string | O | If set to the string 'true', returns metadata of published policies. | +| `get_unpublished` | string | O | If set to the string 'true', returns metadata of unpublished policies. | + +Response codes: +- 200 - success +- 400 - cannot return results because both params were set to true +- 401 - unauthorized +- 404 - not found +- 500 - server error + + +### GET /policies/{policy_id}/meta + +Get metadata for a specific policy. + +Response codes: +- 200 - success +- 401 - unauthorized +- 404 - not found +- 500 - server error + + +### PUT /policies/{policy_id}/meta +Edit metadata for a specific policy. Takes a PolicyMetadata object in the request body. + +Response codes: + - 200 - success + - 401 - unauthorized + - 404 - not found + - 500 - server error + + + diff --git a/policy/README.md b/policy/README.md index f95dc17fa..8390ef802 100644 --- a/policy/README.md +++ b/policy/README.md @@ -12,7 +12,7 @@ This specification describes the digital relationship between _mobility as a ser ## Background -The goal of this specification is to enable Agencies to create, revise, and publish machine-readable policies, as sets of rules for individual and collective device behavior exhibited by both _mobility as a service_ Providers and riders / users. Examples of policies include: +The goal of this specification is to enable Agencies to publish machine-readable policies, as sets of rules for individual and collective device behavior exhibited by both _mobility as a service_ Providers and riders / users. Examples of policies include: - City-wide and localized caps (e.g. "Minimum 500 and maximum 3000 scooters within city boundaries") - Exclusion zones (e.g. "No scooters are permitted in this district on weekends") @@ -22,6 +22,12 @@ The goal of this specification is to enable Agencies to create, revise, and publ The machine-readable format allows Providers to obtain policies and compute compliance where it can be determined entirely by data obtained internally. +Policies will typically be linked to one or more associated geographies. Geography descriptions (e.g. geofences or lists of street segments) must also be maintained by the Agency indefinitely. Policies without specific geographies (global policies) are assumed to apply to all jurisdictions managed by the Agency. + +Geographical data will be stored as immutable GeoJSON FeatureCollections (see https://tools.ietf.org/html/rfc7946 for details on what a FeatureCollection is), referenced by UUID. See the Geography and Geography Author specs for information on the Geography schema, and how Agencies are expected to create and maintain Geographies and serve them to Providers. Policies are not confined to describing their effects over a geographic area. They might prefer Points for locations such as drop-zones. Policy may be used for a variety of enforcement actions, so it's important for the Agency to persist and keep immutable both Policy and Geography data. + + + [Top](#table-of-contents) ## Distribution @@ -80,11 +86,10 @@ The response to a client request must include a valid HTTP status code defined i #### Policies -Endpoint: `/policies/{id}` -Method: `GET` -`data` Payload: `{ "policies": [] }`, an array of objects with the structure [outlined below](#policy). +#### GET `/policies/` +`data` Payload: `{ "policies": [] }`, an array of Policy objects. -##### Query Parameters +Parameters | Name | Type | Required / Optional | Description | | ------------ | --------- | --- | ---------------------------------------------- | @@ -98,18 +103,6 @@ Policies will be returned in order of effective date (see schema below), with pa `provider_id` is an implicit parameter and will be encoded in the authentication mechanism, or a complete list of policies should be produced. If the Agency decides that Provider-specific policy documents should not be shared with other Providers (e.g. punitive policy in response to violations), an Agency should filter policy objects before serving them via this endpoint. -#### Geographies - -Endpoint: `/geographies/{id}` -Method: `GET` -`data` Payload: `{ geographies: [] }`, an array of GeoJSON `Feature` objects. - -##### Query Parameters - -| Name | Type | Required / Optional | Description | -| ------------ | --------- | --- | ---------------------------------------------- | -| `id` | UUID | Optional | If provided, returns one geography object with the matching UUID; default is to return all geography objects. | - ### Flat Files To use flat files, policies shall be represented in two (2) files: @@ -168,6 +161,11 @@ The optional `end_date` field applies to all policies represented in the file. ## Schema + + +### Policy Fields + + All response fields must use `lower_case_with_underscores`. Response bodies must be a `UTF-8` encoded JSON object and must minimally include the MDS `version`, a timestamp indicating the last time the data was `updated`, and a `data` payload: