From 1acedd48b74266bbaaeb7f658376ab315cb0474d Mon Sep 17 00:00:00 2001 From: Darrell Malone Jr Date: Sun, 2 Feb 2025 11:35:49 -0600 Subject: [PATCH 1/8] Update the OAS to reflect the latest UI changes - Added Auth endpoints - Added Search endpoints - Added Users endpoints - Added `(content_type)/latest` endpoints --- oas/2.0/agencies.yaml | 4 +- oas/2.0/authentication.yaml | 194 +++++++++++++++++++ oas/2.0/complaints.yaml | 45 ++++- oas/2.0/incidents.yaml | 360 ------------------------------------ oas/2.0/litigation.yaml | 48 ++++- oas/2.0/officers.yaml | 38 +++- oas/2.0/search.yaml | 182 ++++++++++++++++++ oas/2.0/sources.yaml | 61 ++++-- oas/2.0/users.yaml | 192 +++++++++++++++++++ oas/common/error.yaml | 6 + 10 files changed, 738 insertions(+), 392 deletions(-) create mode 100644 oas/2.0/authentication.yaml delete mode 100644 oas/2.0/incidents.yaml create mode 100644 oas/2.0/search.yaml create mode 100644 oas/2.0/users.yaml diff --git a/oas/2.0/agencies.yaml b/oas/2.0/agencies.yaml index 86b98bf4..1bd8eada 100644 --- a/oas/2.0/agencies.yaml +++ b/oas/2.0/agencies.yaml @@ -4,9 +4,9 @@ info: description: "API Description" version: "0.1.0" servers: - - url: "http://dev-api.nationalpolicedata.org/api/v1" + - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" - - url: "https://stage-api.nationalpolicedata.org/api/v1" + - url: "https://dev.nationalpolicedata.org/api/v1" description: "Staging environment" - url: "https://api.nationalpolicedata.org" description: "Production environment" diff --git a/oas/2.0/authentication.yaml b/oas/2.0/authentication.yaml new file mode 100644 index 00000000..e18855db --- /dev/null +++ b/oas/2.0/authentication.yaml @@ -0,0 +1,194 @@ +openapi: "3.0.3" +info: + title: "Authentication" + description: "API Description" + version: "0.1.0" +servers: + - url: "http://dev.nationalpolicedata.org/api/v1" + description: "Development environment" + - url: "https://dev.nationalpolicedata.org/api/v1" + description: "Staging environment" + - url: "https://api.nationalpolicedata.org" + description: "Production environment" +x-readme: + explorer-enabled: true + proxy-enabled: true + samples-enabled: true +security: + - bearerAuth: [] +tags: + - name: "Authentication" + description: "API for authenticating and creating user accounts." +paths: + /auth/register: + post: + summary: "register User Account" + operationId: "register" + description: "Create a new user account." + tags: + - Authentication + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/RegisterRequest" + responses: + "200": + description: "Logs in and returns the created user object." + content: + application/json: + schema: + $ref: "#/components/schemas/RegisterResponse" + "400": + $ref: '../common/error.yaml#/components/responses/validationError' + "409": + $ref: '../common/error.yaml#/components/responses/conflictError' + /auth/login: + post: + summary: "Log in" + operationId: "login" + description: "Log in to an existing user account." + tags: + - Authentication + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/LoginRequest" + responses: + '200': + description: 'Returns JWT that may be used to authenticate future API requests.' + content: + application/json: + schema: + $ref: '#/components/schemas/LoginResponse' + '400': + $ref: '../common/error.yaml#/components/responses/validationError' + /auth/refresh: + post: + summary: "Refresh Access Token" + operationId: "refreshToken" + description: > + Refreshes the current access token to reset the expiration date. + tags: + - Authentication + responses: + '200': + description: > + Returns the updated employment records. The response also includes + information about any records that could not be added. + content: + application/json: + schema: + $ref: '#/components/schemas/LoginResponse' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' + /auth/logout: + post: + summary: "Log out" + operationId: "logout" + description: "Revokes the access token used to autheticate this request." + tags: + - Authentication + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/LogoutResponse" + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' + /auth/whoami: + get: + summary: "Who Am I" + operationId: "whoami" + description: "Returns the user that matches the access token used to authenticate the request." + tags: + - Authentication + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/CurrentUser" + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + schemas: + RegisterRequest: + type: "object" + properties: + email: + type: "string" + description: "The user's email address." + password: + type: "string" + description: "The user's desired password." + first_name: + type: "string" + description: "The user's first name." + last_name: + type: "string" + description: "The user's last name." + phone_number: + type: "string" + description: "The user's phone number." + required: + - email + - first_name + - last_name + - password + - phone_number + RegisterResponse: + type: "object" + properties: + msg: + type: string + description: information about the registration action. + access_token: + type: string + description: The JWT that can be used to authenticate API requests on behalf of the user. + LoginRequest: + type: object + properties: + email: + type: string + description: The user's email address. + password: + type: string + description: The user's password. + required: + - email + - password + LoginResponse: + type: object + properties: + access_token: + type: string + description: The JWT that can be used to authenticate API requests on behalf of the user. + message: + type: string + description: Additional detail aboout the login action. + CurrentUser: + type: object + properties: + first_name: + type: string + description: The user's first name. + last_name: + type: string + description: The user's last name. + LogoutResponse: + type: object + properties: + msg: + type: string + description: A report of the logout action. + \ No newline at end of file diff --git a/oas/2.0/complaints.yaml b/oas/2.0/complaints.yaml index a58e5d60..456e8ac7 100644 --- a/oas/2.0/complaints.yaml +++ b/oas/2.0/complaints.yaml @@ -4,9 +4,9 @@ info: description: "API Description" version: "0.1.0" servers: - - url: "http://dev-api.nationalpolicedata.org/api/v1" + - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" - - url: "https://stage-api.nationalpolicedata.org/api/v1" + - url: "https://dev.nationalpolicedata.org/api/v1" description: "Staging environment" - url: "https://api.nationalpolicedata.org" description: "Production environment" @@ -43,6 +43,8 @@ paths: $ref: "#/components/schemas/Complaint" '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' patch: tags: - "Complaints" @@ -70,6 +72,8 @@ paths: $ref: '../common/error.yaml#/components/responses/validationError' '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' /complaints: post: @@ -96,6 +100,8 @@ paths: $ref: "#/components/schemas/Complaint" '400': $ref: '../common/error.yaml#/components/responses/validationError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' get: tags: - "Complaints" @@ -114,6 +120,28 @@ paths: application/json: schema: $ref: "#/components/schemas/ComplaintList" + "401": + $ref: '../common/error.yaml#/components/responses/unauthorizedError' + /complaints/latest: + get: + tags: + - "Complaints" + summary: "Latest Complaint Updates" + operationId: "getLatestComplaints" + description: > + Returns the most recently updated or added complaints. + parameters: + - $ref: '../common/pagination.yaml#/components/parameters/page' + - $ref: '../common/pagination.yaml#/components/parameters/per_page' + responses: + "200": + description: "A JSON array of complaint objects" + content: + application/json: + schema: + $ref: "#/components/schemas/ComplaintList" + "401": + $ref: '../common/error.yaml#/components/responses/unauthorizedError' components: securitySchemes: bearerAuth: @@ -481,14 +509,14 @@ components: description: "A description of the attachment." SourceDetails: oneOf: - - $ref: '#/components/schemas/LegalAction' + - $ref: '#/components/schemas/LegalCaseEvent' - $ref: '#/components/schemas/PersonalAccount' - $ref: '#/components/schemas/NewsReport' - $ref: '#/components/schemas/GovernmentRecord' discriminator: propertyName: record_type mapping: - Legal Action: '#/components/schemas/LegalAction' + Legal Case Event: '#/components/schemas/LegalCaseEvent' Personal Account: '#/components/schemas/PersonalAccount' News Report: '#/components/schemas/NewsReport' Government Record: '#/components/schemas/GovernmentRecord' @@ -502,14 +530,14 @@ components: - Personal Account - News Report - Government Record - LegalAction: + LegalCaseEvent: type: "object" properties: record_type: type: "string" description: "The type of record the complaint is associated with." enum: - - Legal Action + - Legal Case Event court: type: "string" description: "The court the legal action was filed in." @@ -519,7 +547,10 @@ components: docket_number: type: "string" description: "The docket number of the case." - date_of_action: + event_summary: + type: "string" + description: "A summary of the event." + date_of_event: type: "string" format: "date-time" description: "The date the legal action was filed." diff --git a/oas/2.0/incidents.yaml b/oas/2.0/incidents.yaml deleted file mode 100644 index e231e206..00000000 --- a/oas/2.0/incidents.yaml +++ /dev/null @@ -1,360 +0,0 @@ -openapi: "3.0.3" -info: - title: "Incidents" - description: "API Description" - version: "0.1.0" -servers: - - url: "http://dev-api.nationalpolicedfata.org/api/v1" - description: "Development environment" - - url: "https://stage-api.nationalpolicedata.org/api/v1" - description: "Staging environment" - - url: "https://api.nationalpolicedata.org" - description: "Production environment" -x-readme: - explorer-enabled: true - proxy-enabled: true - samples-enabled: true -security: - - bearerAuth: [] -tags: - - name: "Incidents" - description: "Incident related endpoints" -paths: - /incidents/{incident_id}: - parameters: - - name: incident_id - in: path - required: true - schema: - type: string - get: - summary: "Get Incident" - operationId: "getIncident" - description: > - Returns information about a single incident. - responses: - "200": - description: "An incident object" - content: - application/json: - schema: - $ref: "#/components/schemas/Incident" - '404': - $ref: '../common/error.yaml#/components/responses/notFoundError' - patch: - summary: "Update Incident" - operationId: "updateIncident" - description: > - Update a single incident. Only an admin of the contributing - organization or the original user who submitted the incident - can update the incident. - requestBody: - description: "Incident object that needs to be updated in the database" - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/UpdateIncident" - responses: - "200": - description: "An incident object" - content: - application/json: - schema: - $ref: "#/components/schemas/Incident" - '400': - $ref: '../common/error.yaml#/components/responses/validationError' - '404': - $ref: '../common/error.yaml#/components/responses/notFoundError' - - /incidents: - post: - summary: "Create Incident" - operationId: "createIncident" - description: > - Create a single incident. User must be a - contributor to create an incident. - requestBody: - description: "Incident object that needs to be added to the database" - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/CreateIncident" - responses: - "200": - description: "A JSON array of user names" - content: - application/json: - schema: - $ref: "#/components/schemas/Incident" - '400': - $ref: '../common/error.yaml#/components/responses/validationError' - get: - summary: "Get all Incidents" - operationId: "getIncidents" - description: > - Returns all incidents in the database. Filters can be applied - to narrow down the results. - parameters: - - $ref: '../common/pagination.yaml#/components/parameters/page' - - $ref: '../common/pagination.yaml#/components/parameters/per_page' - responses: - "200": - description: "A JSON array of incident objects" - content: - application/json: - schema: - $ref: "#/components/schemas/IncidentList" - /incidents/matchPerpetrator: - post: - summary: "Match Perpetrator" - operationId: "matchPerpetrator" - description: > - Identifies potential matches for a perpetrator based on the - provided information. - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/Perpetrator" - responses: - "200": - description: "A set of possible matches for the perpetrator." - content: - application/json: - schema: - $ref: "#/components/schemas/PerpetratorMatches" - '400': - $ref: '../common/error.yaml#/components/responses/validationError' -components: - schemas: - BaseIncident: - type: "object" - description: "Base incident object" - properties: - source_id: - type: "string" - description: "The ID of the partner that reported the incident." - date_record_created: - type: "string" - format: "date-time" - description: "The date and time the incident was recorded." - time_of_incident: - type: "string" - format: "date-time" - description: "The date and time the incident occurred." - time_confidence: - type: "string" - description: "The confidence level of the time of the incident." - complaint_date: - type: "string" - format: "date-time" - description: "The date the complaint was filed." - closed_date: - type: "string" - format: "date-time" - description: "The date the incident was closed." - location: - type: "string" - description: "The location of the incident." - latitude: - type: "number" - description: "The latitude of the incident." - longitude: - type: "number" - description: "The longitude of the incident." - description: - type: "string" - description: "A description of the incident." - stop_type: - type: "string" - description: "The type of stop." - call_type: - type: "string" - description: "The type of call." - has_attachments: - type: "boolean" - description: "Whether the incident has attachments." - from_report: - type: "boolean" - description: "Whether the incident was reported." - was_victim_arrested: - type: "boolean" - description: "Whether the victim was arrested." - was_victim_charged: - type: "boolean" - description: "Whether a criminal case was brought." - was_citation_issued: - type: "boolean" - description: "Whether a citation was issued." - criminal_case_id: - type: "string" - description: "The ID of the criminal case." - complaintant: - type: "array" - description: "The aggrevated party. The name of the person who filed the complaint might not be included with the record if the complaint was reported through counsel." - items: - $ref: "#/components/schemas/Victim" - perpetrators: - type: "array" - description: "Officers involved in the incident" - items: - $ref: "#/components/schemas/Perpetrator" - participants: - type: "array" - description: "Named individuals who are neither complaintants nor perpetrators." - items: - $ref: "#/components/schemas/Participant" - attachements: - type: "array" - description: "Multimedia associated with the incident" - items: - $ref: "#/components/schemas/Multimedia" - investigations: - type: "array" - description: "Investigations associated with the incident" - items: - $ref: "#/components/schemas/Investigation" - results_of_stop: - type: "array" - description: "Results of stop associated with the incident" - items: - $ref: "#/components/schemas/ResultOfStop" - actions: - type: "array" - description: "Actions associated with the incident" - items: - $ref: "#/components/schemas/Action" - use_of_force: - type: "array" - description: "Use of force associated with the incident" - items: - $ref: "#/components/schemas/UseOfForce" - - CreateIncident: - type: "object" - description: "Incident object" - properties: - victims: - type: "array" - description: "Victims of the incident" - items: - $ref: "#/components/schemas/Victim" - officers: - type: "array" - description: "Officers involved in the incident" - items: - $ref: "#/components/schemas/Officer" - tags: - type: "array" - description: "Tags associated with the incident" - items: - type: "string" - participants: - type: "array" - description: "Participants in the incident" - items: - $ref: "#/components/schemas/Participant" - multimedias: - type: "array" - description: "Multimedia associated with the incident" - items: - $ref: "#/components/schemas/Multimedia" - investigations: - type: "array" - description: "Investigations associated with the incident" - items: - $ref: "#/components/schemas/Investigation" - results_of_stop: - type: "array" - description: "Results of stop associated with the incident" - items: - $ref: "#/components/schemas/ResultOfStop" - actions: - type: "array" - description: "Actions associated with the incident" - items: - $ref: "#/components/schemas/Action" - use_of_force: - type: "array" - description: "Use of force associated with the incident" - items: - $ref: "#/components/schemas/UseOfForce" - legal_case: - type: "array" - description: "Legal case associated with the incident" - items: - $ref: "#/components/schemas/LegalCase" - Incident: - type: "object" - description: "Incident object" - properties: - victims: - type: "array" - description: "Victims of the incident" - items: - $ref: "#/components/schemas/Victim" - officers: - type: "array" - description: "Officers involved in the incident" - items: - $ref: "#/components/schemas/Officer" - tags: - type: "array" - description: "Tags associated with the incident" - items: - type: "string" - participants: - type: "array" - description: "Participants in the incident" - items: - $ref: "#/components/schemas/Participant" - attachment: - type: "array" - description: "File attachments associated with the incident" - items: - $ref: "#/components/schemas/Attachment" - investigations: - type: "array" - description: "Investigations associated with the incident" - items: - $ref: "#/components/schemas/Investigation" - results_of_stop: - type: "array" - description: "Results of stop associated with the incident" - items: - $ref: "#/components/schemas/ResultOfStop" - actions: - type: "array" - description: "Actions associated with the incident" - items: - $ref: "#/components/schemas/Action" - use_of_force: - type: "array" - description: "Use of force associated with the incident" - items: - $ref: "#/components/schemas/UseOfForce" - legal_case: - type: "array" - description: "Legal case associated with the incident" - items: - $ref: "#/components/schemas/LegalCase" - IncidentList: - type: "object" - description: "Incident list response" - properties: - results: - type: "array" - description: "List of incidents" - items: - $ref: "#/components/schemas/Incident" - page: - type: "integer" - description: "Page number of the results" - totalPages: - type: "integer" - description: "Total number of pages" - totalResults: - type: "integer" - description: "Total number of results" diff --git a/oas/2.0/litigation.yaml b/oas/2.0/litigation.yaml index 33ca9950..133e689f 100644 --- a/oas/2.0/litigation.yaml +++ b/oas/2.0/litigation.yaml @@ -4,9 +4,9 @@ info: description: "API Description" version: "0.1.0" servers: - - url: "http://dev-api.nationalpolicedata.org/api/v1" + - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" - - url: "https://stage-api.nationalpolicedata.org/api/v1" + - url: "https://dev.nationalpolicedata.org/api/v1" description: "Staging environment" - url: "https://api.nationalpolicedata.org" description: "Production environment" @@ -67,6 +67,8 @@ paths: application/json: schema: $ref: "#/components/schemas/LitigationList" + "401": + $ref: '../common/error.yaml#/components/responses/unauthorizedError' post: tags: - "Litigation" @@ -90,6 +92,28 @@ paths: $ref: '#/components/schemas/Litigation' '400': $ref: '../common/error.yaml#/components/responses/validationError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' + /litigation/latest: + get: + tags: + - "Litigation" + summary: "Latest Litigation Updates" + operationId: "getLatestLitigation" + description: > + Get a list of the most recently updated or added litigation cases. + parameters: + - $ref: '../common/pagination.yaml#/components/parameters/page' + - $ref: '../common/pagination.yaml#/components/parameters/per_page' + responses: + "200": + description: "Successful response" + content: + application/json: + schema: + $ref: "#/components/schemas/LitigationList" + "401": + $ref: '../common/error.yaml#/components/responses/unauthorizedError' /litigation/{uid}: parameters: - name: uid @@ -114,6 +138,8 @@ paths: $ref: "#/components/schemas/Litigation" '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' patch: tags: - "Litigation" @@ -138,6 +164,8 @@ paths: $ref: '../common/error.yaml#/components/responses/validationError' '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' delete: tags: - "Litigation" @@ -152,6 +180,8 @@ paths: description: "No content" '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' /litigation/{uid}/documents: parameters: - name: "uid" @@ -179,6 +209,8 @@ paths: $ref: "#/components/schemas/DocumentList" '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' post: tags: - "Documents" @@ -209,6 +241,8 @@ paths: $ref: '../common/error.yaml#/components/responses/validationError' '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' /litigation/{uid}/documents/{document_uid}: parameters: - name: "uid" @@ -239,6 +273,8 @@ paths: $ref: '#/components/schemas/Document' '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' /litigation/{uid}/disposition: parameters: - name: uid @@ -260,16 +296,18 @@ paths: schema: $ref: "#/components/schemas/Disposition" responses: - 200: + '200': description: 'Successful response' content: application/json: schema: $ref: '#/components/schemas/Litigation' - 400: + '400': $ref: '../common/error.yaml#/components/responses/validationError' - 404: + '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' components: securitySchemes: bearerAuth: diff --git a/oas/2.0/officers.yaml b/oas/2.0/officers.yaml index 68f33a9c..7d746fc6 100644 --- a/oas/2.0/officers.yaml +++ b/oas/2.0/officers.yaml @@ -4,9 +4,9 @@ info: description: "API Description" version: "0.1.0" servers: - - url: "http://dev-api.nationalpolicedata.org/api/v1" + - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" - - url: "https://stage-api.nationalpolicedata.org/api/v1" + - url: "https://dev.nationalpolicedata.org/api/v1" description: "Staging environment" - url: "https://api.nationalpolicedata.org" description: "Production environment" @@ -38,6 +38,8 @@ paths: application/json: schema: $ref: "#/components/schemas/OfficerList" + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' post: tags: - Officers @@ -57,6 +59,28 @@ paths: $ref: '#/components/schemas/Officer' '400': $ref: '../common/error.yaml#/components/responses/validationError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' + /officers/latest: + get: + tags: + - "Officers" + summary: "Latest Officer Updates" + description: > + Get the most recently updated or added officers. + operationId: "getLatestOfficers" + parameters: + - $ref: '../common/pagination.yaml#/components/parameters/page' + - $ref: '../common/pagination.yaml#/components/parameters/per_page' + responses: + "200": + description: "Successful operation" + content: + application/json: + schema: + $ref: "#/components/schemas/OfficerList" + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' /officers/{uid}: parameters: - name: uid @@ -79,6 +103,8 @@ paths: $ref: "#/components/schemas/Officer" '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' patch: tags: - "Officers" @@ -100,6 +126,8 @@ paths: $ref: "#/components/schemas/Officer" '400': $ref: '../common/error.yaml#/components/responses/validationError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' delete: tags: - "Officers" @@ -119,6 +147,8 @@ paths: description: "No content" '404': $ref: '../common/error.yaml#/components/responses/notFoundError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' /officers/{uid}/employment: parameters: - name: uid @@ -142,6 +172,8 @@ paths: application/json: schema: $ref: '#/components/schemas/EmploymentList' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' put: summary: "Update Employment History" operationId: "updateEmploymentHistory" @@ -164,6 +196,8 @@ paths: $ref: '#/components/schemas/EmploymentList' '400': $ref: '../common/error.yaml#/components/responses/validationError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' components: securitySchemes: bearerAuth: diff --git a/oas/2.0/search.yaml b/oas/2.0/search.yaml new file mode 100644 index 00000000..1a2723c0 --- /dev/null +++ b/oas/2.0/search.yaml @@ -0,0 +1,182 @@ +openapi: "3.0.3" +info: + title: "Search" + description: "API Description" + version: "0.1.0" +servers: + - url: "http://127.0.0.1:5001/api/v1" + description: "Local environment" + - url: "https://dev.nationalpolicedata.org/api/v1" + description: "Staging environment" + - url: "https://api.nationalpolicedata.org" + description: "Production environment" +x-readme: + explorer-enabled: true + proxy-enabled: true + samples-enabled: true +security: + - bearerAuth: [] +tags: + - name: "Search" + description: "Search API" +paths: + /search: + post: + tags: + - "Search" + summary: "Search" + operationId: "search" + description: > + Search the index for items that match the query. The search results can be filtered + by content type, location, data source, and date range. + parameters: + - $ref: '../common/pagination.yaml#/components/parameters/page' + - $ref: '../common/pagination.yaml#/components/parameters/per_page' + requestBody: + description: > + The search terms and the filters that should be applied to the search. + required: false + content: + application/json: + schema: + $ref: "#/components/schemas/SearchRequest" + responses: + "200": + description: "Search results." + content: + application/json: + schema: + $ref: "#/components/schemas/SearchResultList" + '400': + $ref: '../common/error.yaml#/components/responses/validationError' + '404': + $ref: '../common/error.yaml#/components/responses/notFoundError' + + /search/auto: + post: + tags: + - "Search" + summary: "Autocomplete Search Term" + operationId: "autocomplete" + description: > + Returns a list of suggestions based on the search term. + parameters: + - $ref: '../common/pagination.yaml#/components/parameters/page' + - $ref: '../common/pagination.yaml#/components/parameters/per_page' + requestBody: + description: > + The search term to get suggestions and any filters that should be applied to the search. + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/SearchRequest" + responses: + "200": + description: "A list of suggested search terms." + content: + application/json: + schema: + $ref: "#/components/schemas/SearchTerms" + '400': + $ref: '../common/error.yaml#/components/responses/validationError' +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + schemas: + SearchRequest: + type: "object" + properties: + query: + type: "string" + description: "The search terms." + filters: + type: "object" + properties: + content_type: + type: "string" + description: "The type of content to search." + enum: + - "complaint" + - "officer" + - "agency" + - "unit" + - "litigation" + location: + $ref: "#/components/schemas/Location" + data_source: + type: "string" + description: "The data source to search." + date_earliest: + type: "string" + description: "Lower bound of the date range." + date_latest: + type: "string" + description: "Upper bound of the date range." + SearchResultList: + allOf: + - $ref: '../common/pagination.yaml#/components/schemas/PaginatedResponse' + - type: "object" + properties: + results: + type: "array" + items: + $ref: "#/components/schemas/SearchResult" + SearchResult: + type: "object" + properties: + uid: + type: "string" + description: The unique identifier for the search result. + title: + type: "string" + description: The title of the search result. + subtitle: + type: "string" + description: The subtitle of the search result. + details: + type: "string" + description: The details of the search result. + content_type: + type: "string" + description: The type of content. + source: + $ref: "#/components/schemas/SourceRef" + last_updated: + type: "string" + description: The date the content was last updated. + href: + type: "string" + description: The URL of the search result. + Location: + type: "object" + properties: + name: + type: "string" + description: The name of the location. + type: + type: "string" + description: The type of location. + enum: + - "city" + - "county" + - "state" + SourceRef: + type: "object" + properties: + name: + type: "string" + description: The name of the data source. + href: + type: "string" + description: The URL of the data source. + SearchTerms: + type: "object" + properties: + terms: + type: "array" + items: + type: "string" \ No newline at end of file diff --git a/oas/2.0/sources.yaml b/oas/2.0/sources.yaml index c1757aee..aa42caf9 100644 --- a/oas/2.0/sources.yaml +++ b/oas/2.0/sources.yaml @@ -4,9 +4,9 @@ info: description: "API Description" version: "0.1.0" servers: - - url: "http://dev-api.nationalpolicedata.org/api/v1" + - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" - - url: "https://stage-api.nationalpolicedata.org/api/v1" + - url: "https://dev.nationalpolicedata.org/api/v1" description: "Staging environment" - url: "https://api.nationalpolicedata.org" description: "Production environment" @@ -34,17 +34,17 @@ paths: schema: type: "array" items: - $ref: "#/components/schemas/PartnerList" + $ref: "#/components/schemas/SourceList" post: tags: - "Sources" summary: "Create a new source" - operationId: "createPartner" + operationId: "createSource" requestBody: content: application/json: schema: - $ref: "#/components/schemas/CreatePartner" + $ref: "#/components/schemas/CreateSource" responses: '201': description: 'Successful operation' @@ -66,7 +66,7 @@ paths: tags: - "Sources" summary: "Get Source" - operationId: "getPartnerById" + operationId: "getSourceById" description: > Returns a single source. responses: @@ -82,12 +82,12 @@ paths: tags: - "Sources" summary: "Update an existing source" - operationId: "updatePartner" + operationId: "updateSource" requestBody: content: application/json: schema: - $ref: "#/components/schemas/UpdatePartner" + $ref: "#/components/schemas/UpdateSource" responses: '200': description: 'Successful operation' @@ -133,31 +133,60 @@ components: scheme: bearer bearerFormat: JWT schemas: - BasePartner: + BaseSource: type: "object" properties: name: type: "string" description: "Name of the source organization." - url: + bio: + type: "string" + description: "Description of the source organization." + website_url: type: "string" description: "Website URL of the source." contact_email: type: "string" description: "Contact email for the source organization." - CreatePartner: + contact_phone: + type: "string" + description: "Contact phone number for the source organization." + social_media: + type: "object" + description: The user's social media profiles. + properties: + twitter_url: + type: "string" + description: The user's Twitter handle. + facebook_url: + type: "string" + description: The user's Facebook profile. + linkedin_url: + type: "string" + description: The user's LinkedIn profile. + instagram_url: + type: "string" + description: The user's Instagram profile. + youtube_url: + type: "string" + description: The user's YouTube channel. + tiktok_url: + type: "string" + description: The user's TikTok profile. + + CreateSource: allOf: - - $ref: "#/components/schemas/BasePartner" + - $ref: "#/components/schemas/BaseSource" - type: "object" required: - name - contact_email - UpdatePartner: + UpdateSource: allOf: - - $ref: "#/components/schemas/BasePartner" + - $ref: "#/components/schemas/BaseSource" Source: allOf: - - $ref: "#/components/schemas/BasePartner" + - $ref: "#/components/schemas/BaseSource" - type: "object" properties: uid: @@ -169,7 +198,7 @@ components: reported_complaints: type: string description: "Url to get all complaints reported by the source." - PartnerList: + SourceList: allOf: - $ref: '../common/pagination.yaml#/components/schemas/PaginatedResponse' - type: "object" diff --git a/oas/2.0/users.yaml b/oas/2.0/users.yaml new file mode 100644 index 00000000..8be6df7d --- /dev/null +++ b/oas/2.0/users.yaml @@ -0,0 +1,192 @@ +openapi: "3.0.3" +info: + title: "Users" + description: "User Management API" + version: "0.1.0" +servers: + - url: "http://127.0.0.1:5001/api/v1" + description: "Development environment" + - url: "https://dev.nationalpolicedata.org/api/v1" + description: "Staging environment" + - url: "https://api.nationalpolicedata.org" + description: "Production environment" +x-readme: + explorer-enabled: true + proxy-enabled: true + samples-enabled: true +security: + - bearerAuth: [] +tags: + - name: "Users" + description: "Users API" +paths: + /users: + get: + tags: + - "Users" + summary: "Get all users" + operationId: "getUsers" + responses: + "200": + description: "Successful operation" + content: + application/json: + schema: + type: "array" + items: + $ref: "#/components/schemas/UserList" + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' + /users/{uid}: + parameters: + - name: uid + in: path + description: UID of the user + required: true + schema: + type: string + get: + tags: + - "Users" + summary: "Get User" + operationId: "getUserById" + description: > + Returns a single user. + responses: + '200': + description: "Successful operation" + content: + application/json: + schema: + $ref: "#/components/schemas/User" + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' + '404': + $ref: '../common/error.yaml#/components/responses/notFoundError' + patch: + tags: + - "Users" + summary: "Update an existing user" + operationId: "updateUser" + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UpdateUser" + responses: + '200': + description: 'Successful operation' + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '400': + $ref: '../common/error.yaml#/components/responses/validationError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' + '404': + $ref: '../common/error.yaml#/components/responses/notFoundError' + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + schemas: + BaseUser: + type: "object" + properties: + first_name: + type: "string" + description: The first name of the user. + last_name: + type: "string" + description: The last name of the user. + primary_email: + type: "string" + description: The primary email address of the user. This is the email address used for login. + contact_info: + type: "object" + description: Contact information for the user. + properties: + additional_emails: + type: "array" + items: + type: "string" + description: Additional email addresses for the user. + phone_numbers: + type: "array" + items: + type: "string" + description: Phone numbers for the user. + website: + type: "string" + description: The user's website. + location: + type: "object" + properties: + city: + type: "string" + description: The city where the user is located. + state: + type: "string" + description: The state where the user is located. This should be the two-letter abbreviation. + employment: + type: "object" + description: Employment information for the user. + properties: + employer: + type: "string" + description: The user's employer. + title: + type: "string" + description: The user's job title. + bio: + type: "string" + description: A short biography of the user. + profile_image: + type: "string" + description: URL to the user's profile image. + social_media: + type: "object" + description: The user's social media profiles. + properties: + twitter_url: + type: "string" + description: The user's Twitter handle. + facebook_url: + type: "string" + description: The user's Facebook profile. + linkedin_url: + type: "string" + description: The user's LinkedIn profile. + instagram_url: + type: "string" + description: The user's Instagram profile. + youtube_url: + type: "string" + description: The user's YouTube channel. + tiktok_url: + type: "string" + description: The user's TikTok profile. + UpdateUser: + allOf: + - $ref: "#/components/schemas/BaseUser" + User: + allOf: + - $ref: "#/components/schemas/BaseUser" + - type: "object" + properties: + uid: + type: "string" + description: "Unique identifier for the user." + UserList: + allOf: + - $ref: '../common/pagination.yaml#/components/schemas/PaginatedResponse' + - type: "object" + properties: + results: + type: "array" + items: + $ref: "#/components/schemas/User" \ No newline at end of file diff --git a/oas/common/error.yaml b/oas/common/error.yaml index 4033215a..2dedfcb2 100644 --- a/oas/common/error.yaml +++ b/oas/common/error.yaml @@ -17,6 +17,12 @@ components: $ref: "#/components/schemas/ErrorResponse" notFoundError: description: "Resource not found" + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + unauthorizedError: + description: "Unauthorized" content: application/json: schema: From 2733917af74a45d6c5c26107247f86074502e4df Mon Sep 17 00:00:00 2001 From: Darrell Malone Jr Date: Sun, 2 Feb 2025 18:17:17 -0600 Subject: [PATCH 2/8] Update Version --- oas/2.0/agencies.yaml | 2 +- oas/2.0/authentication.yaml | 2 +- oas/2.0/complaints.yaml | 2 +- oas/2.0/litigation.yaml | 2 +- oas/2.0/officers.yaml | 2 +- oas/2.0/search.yaml | 2 +- oas/2.0/sources.yaml | 2 +- oas/2.0/users.yaml | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/oas/2.0/agencies.yaml b/oas/2.0/agencies.yaml index 1bd8eada..960bb5ec 100644 --- a/oas/2.0/agencies.yaml +++ b/oas/2.0/agencies.yaml @@ -2,7 +2,7 @@ openapi: "3.0.3" info: title: "Agencies" description: "API Description" - version: "0.1.0" + version: "0.7.0" servers: - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" diff --git a/oas/2.0/authentication.yaml b/oas/2.0/authentication.yaml index e18855db..e1edbe96 100644 --- a/oas/2.0/authentication.yaml +++ b/oas/2.0/authentication.yaml @@ -2,7 +2,7 @@ openapi: "3.0.3" info: title: "Authentication" description: "API Description" - version: "0.1.0" + version: "0.7.0" servers: - url: "http://dev.nationalpolicedata.org/api/v1" description: "Development environment" diff --git a/oas/2.0/complaints.yaml b/oas/2.0/complaints.yaml index 456e8ac7..679136fb 100644 --- a/oas/2.0/complaints.yaml +++ b/oas/2.0/complaints.yaml @@ -2,7 +2,7 @@ openapi: "3.0.3" info: title: "Complaints" description: "API Description" - version: "0.1.0" + version: "0.7.0" servers: - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" diff --git a/oas/2.0/litigation.yaml b/oas/2.0/litigation.yaml index 133e689f..72e14576 100644 --- a/oas/2.0/litigation.yaml +++ b/oas/2.0/litigation.yaml @@ -2,7 +2,7 @@ openapi: "3.0.3" info: title: "Litigation" description: "API Description" - version: "0.1.0" + version: "0.7.0" servers: - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" diff --git a/oas/2.0/officers.yaml b/oas/2.0/officers.yaml index 7d746fc6..09cf9a8f 100644 --- a/oas/2.0/officers.yaml +++ b/oas/2.0/officers.yaml @@ -2,7 +2,7 @@ openapi: "3.0.3" info: title: "Officers" description: "API Description" - version: "0.1.0" + version: "0.7.0" servers: - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" diff --git a/oas/2.0/search.yaml b/oas/2.0/search.yaml index 1a2723c0..ef3f5317 100644 --- a/oas/2.0/search.yaml +++ b/oas/2.0/search.yaml @@ -2,7 +2,7 @@ openapi: "3.0.3" info: title: "Search" description: "API Description" - version: "0.1.0" + version: "0.7.0" servers: - url: "http://127.0.0.1:5001/api/v1" description: "Local environment" diff --git a/oas/2.0/sources.yaml b/oas/2.0/sources.yaml index aa42caf9..5ec92eb3 100644 --- a/oas/2.0/sources.yaml +++ b/oas/2.0/sources.yaml @@ -2,7 +2,7 @@ openapi: "3.0.3" info: title: "Sources" description: "API Description" - version: "0.1.0" + version: "0.7.0" servers: - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" diff --git a/oas/2.0/users.yaml b/oas/2.0/users.yaml index 8be6df7d..53b54dda 100644 --- a/oas/2.0/users.yaml +++ b/oas/2.0/users.yaml @@ -2,7 +2,7 @@ openapi: "3.0.3" info: title: "Users" description: "User Management API" - version: "0.1.0" + version: "0.7.0" servers: - url: "http://127.0.0.1:5001/api/v1" description: "Development environment" From 69c8cfdf353ff9040cbcc3e07dfe4de0674f2dfe Mon Sep 17 00:00:00 2001 From: Darrell Malone Jr Date: Tue, 4 Feb 2025 19:46:35 -0600 Subject: [PATCH 3/8] WIP --- oas/2.0/officers.yaml | 174 +++++++++++++++++++++++++++++++++++++++++- oas/2.0/search.yaml | 4 +- 2 files changed, 175 insertions(+), 3 deletions(-) diff --git a/oas/2.0/officers.yaml b/oas/2.0/officers.yaml index 09cf9a8f..979e2c40 100644 --- a/oas/2.0/officers.yaml +++ b/oas/2.0/officers.yaml @@ -26,11 +26,106 @@ paths: get: tags: - "Officers" - summary: "Get all officers" + summary: "Get officers" operationId: "getOfficers" + description: > + Returns a list of officer. A number of simple filters can be applied to limit the results. If no filters + are applied, a random sample of officers will be returned. parameters: - $ref: '../common/pagination.yaml#/components/parameters/page' - $ref: '../common/pagination.yaml#/components/parameters/per_page' + - active_after: + name: active_after + in: query + description: > + Filter officers who were active after this date. The date should be in the format YYYY-MM-DD. + required: false + schema: + type: string + format: date + - active_before: + name: active_before + in: query + description: > + Filter officers who were active before this date. The date should be in the format YYYY-MM-DD. + required: false + schema: + type: string + format: date + - state_id_value: + name: state_id_value + in: query + description: > + Filter officers by their state ID value. This may be a tax number, officer training number, or + any other unique identifier used by a state. The state_id_state and state_id_name parameters + must also be provided. + required: false + schema: + type: string + - state_id_name: + name: state_id_name + in: query + description: > + Filter officers by the name of their state ID. For example, "Driver's License", "Tax ID", etc. + required: false + schema: + type: string + - state_id_state: + name: state_id_state + in: query + description: > + Filter officers by the state of their state ID. For example, "CA" for California. + required: false + schema: + type: string + - agency: + name: agency + in: query + description: > + Filter officers by the agency they are employed by. The value should be a comma-separated list of agency uids. + required: false + schema: + type: string + - rank: + name: rank + in: query + description: > + Filter officers by their rank. The value should be a comma-separated list of ranks. + required: false + schema: + type: string + - unit: + name: unit + in: query + description: > + Filter officers by their unit. The value should be a comma-separated list of unit uids. + required: false + schema: + type: string + - name: + name: name + in: query + description: > + Filter officers by their name. The value should be a string in the format "first middle last suffix". + required: false + schema: + type: string + - ethnicity: + name: ethnicity + in: query + description: > + Filter officers by their ethnicity. The value should be a comma-separated list of ethnicities. + required: false + schema: + type: string + - badge_number: + name: badge_number + in: query + description: > + Filter officers by their badge number. The value should be a comma-separated list of badge numbers. + required: false + schema: + type: string responses: "200": description: "Successful operation" @@ -81,6 +176,37 @@ paths: $ref: "#/components/schemas/OfficerList" '401': $ref: '../common/error.yaml#/components/responses/unauthorizedError' + /officers/filter: + post: + tags: + - "Officers" + summary: "Advanced Officer Filter" + operationId: "getOfficersByFilter" + description: > + Get officers by advanced filter. This endpoint allows for more complex queries + using a JSON body to specify the filters. + parameters: + - $ref: '../common/pagination.yaml#/components/parameters/page' + - $ref: '../common/pagination.yaml#/components/parameters/per_page' + requestBody: + description: > + A JSON object containing the filters to apply to the search. + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/OfficerFilter" + responses: + "200": + description: "Successful operation" + content: + application/json: + schema: + $ref: "#/components/schemas/OfficerList" + '400': + $ref: '../common/error.yaml#/components/responses/validationError' + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' /officers/{uid}: parameters: - name: uid @@ -205,6 +331,52 @@ components: scheme: bearer bearerFormat: JWT schemas: + OfficerFilter: + type: object + description: > + An advanced filter that can be applied to an officer list request. + properties: + name: + type: string + description: > + Filter officers by their name. The value should be a string in the format "first middle last suffix". + location: + allOf: + - $ref: "#/components/schemas/LocationFilter" + - type: object + description: > + Filter officers by locations in which they have worked. This is assesed based on the operating theatre of the units to which they've been assigned. + state_ids: + type: array + description: > + Filter officers by their state IDs. This can be used to filter by tax number, officer training number, or any other unique identifier used by a state. + items: + $ref: "#/components/schemas/StateIdFilter" + ranks: + type: array + description: > + Filter officers by their rank. + items: + type: string + ethnicity: + type: array + description: > + Filter officers by ethnicity. + items: + $ref: "#/components/schemas/EthnicityFilter" + commanders: + type: array + description: > + Return officers who have worked under the selected commanders. + items: + type: string + description: The UIDs of the commanders to filter by. + allegations: + allOf: + - $ref: "#/components/schemas/AllegationFilter" + - type: object + description: > + Filter officers by allegations made against them. BaseEmployment: type: "object" properties: diff --git a/oas/2.0/search.yaml b/oas/2.0/search.yaml index ef3f5317..1ec8f9c4 100644 --- a/oas/2.0/search.yaml +++ b/oas/2.0/search.yaml @@ -24,8 +24,8 @@ paths: post: tags: - "Search" - summary: "Search" - operationId: "search" + summary: "Search All" + operationId: "searchAll" description: > Search the index for items that match the query. The search results can be filtered by content type, location, data source, and date range. From 9ed1cb8c9db24455189b2db0fe9bc2bc65c91b3d Mon Sep 17 00:00:00 2001 From: Darrell Malone Jr Date: Wed, 5 Feb 2025 20:15:24 -0600 Subject: [PATCH 4/8] Add advanced officer filters Remove "All users" operation Added `/users/self` endpoint --- oas/2.0/officers.yaml | 296 ++++++++++++++++++++++++++++-------------- oas/2.0/search.yaml | 3 +- oas/2.0/users.yaml | 53 ++++---- 3 files changed, 221 insertions(+), 131 deletions(-) diff --git a/oas/2.0/officers.yaml b/oas/2.0/officers.yaml index 979e2c40..8e49244d 100644 --- a/oas/2.0/officers.yaml +++ b/oas/2.0/officers.yaml @@ -34,98 +34,14 @@ paths: parameters: - $ref: '../common/pagination.yaml#/components/parameters/page' - $ref: '../common/pagination.yaml#/components/parameters/per_page' - - active_after: - name: active_after - in: query - description: > - Filter officers who were active after this date. The date should be in the format YYYY-MM-DD. - required: false - schema: - type: string - format: date - - active_before: - name: active_before - in: query - description: > - Filter officers who were active before this date. The date should be in the format YYYY-MM-DD. - required: false - schema: - type: string - format: date - - state_id_value: - name: state_id_value - in: query - description: > - Filter officers by their state ID value. This may be a tax number, officer training number, or - any other unique identifier used by a state. The state_id_state and state_id_name parameters - must also be provided. - required: false - schema: - type: string - - state_id_name: - name: state_id_name - in: query - description: > - Filter officers by the name of their state ID. For example, "Driver's License", "Tax ID", etc. - required: false - schema: - type: string - - state_id_state: - name: state_id_state - in: query - description: > - Filter officers by the state of their state ID. For example, "CA" for California. - required: false - schema: - type: string - - agency: - name: agency - in: query - description: > - Filter officers by the agency they are employed by. The value should be a comma-separated list of agency uids. - required: false - schema: - type: string - - rank: - name: rank - in: query - description: > - Filter officers by their rank. The value should be a comma-separated list of ranks. - required: false - schema: - type: string - - unit: - name: unit - in: query - description: > - Filter officers by their unit. The value should be a comma-separated list of unit uids. - required: false - schema: - type: string - - name: - name: name - in: query - description: > - Filter officers by their name. The value should be a string in the format "first middle last suffix". - required: false - schema: - type: string - - ethnicity: - name: ethnicity - in: query - description: > - Filter officers by their ethnicity. The value should be a comma-separated list of ethnicities. - required: false - schema: - type: string - - badge_number: - name: badge_number - in: query - description: > - Filter officers by their badge number. The value should be a comma-separated list of badge numbers. - required: false - schema: - type: string + - $ref: '#/components/parameters/active_after' + - $ref: '#/components/parameters/active_before' + - $ref: '#components/parameters/agency' + - $ref: '#components/parameters/rank' + - $ref: '#components/parameters/unit' + - $ref: '#components/parameters/name' + - $ref: '#components/parameters/ethnicity' + - $ref: '#components/parameters/badge_number' responses: "200": description: "Successful operation" @@ -188,6 +104,14 @@ paths: parameters: - $ref: '../common/pagination.yaml#/components/parameters/page' - $ref: '../common/pagination.yaml#/components/parameters/per_page' + - $ref: '#/components/parameters/active_after' + - $ref: '#/components/parameters/active_before' + - $ref: '#components/parameters/agency' + - $ref: '#components/parameters/rank' + - $ref: '#components/parameters/unit' + - $ref: '#components/parameters/name' + - $ref: '#components/parameters/ethnicity' + - $ref: '#components/parameters/badge_number' requestBody: description: > A JSON object containing the filters to apply to the search. @@ -325,45 +249,215 @@ paths: '401': $ref: '../common/error.yaml#/components/responses/unauthorizedError' components: + parameters: + - active_after: + name: active_after + in: query + description: > + Filter officers who were active after this date. The date should be in the format YYYY-MM-DD. + required: false + schema: + type: string + format: date + - active_before: + name: active_before + in: query + description: > + Filter officers who were active before this date. The date should be in the format YYYY-MM-DD. + required: false + schema: + type: string + format: date + - agency: + name: agency + in: query + description: > + Filter officers by the agency they are employed by. The value should be a comma-separated list of agency uids. + required: false + schema: + type: string + - rank: + name: rank + in: query + description: > + Filter officers by their rank. The value should be a comma-separated list of ranks. + required: false + schema: + type: string + - unit: + name: unit + in: query + description: > + Filter officers by their unit. The value should be a comma-separated list of unit uids. + required: false + schema: + type: string + - name: + name: name + in: query + description: > + Filter officers by their name. The value should be a string in the format "first middle last suffix". + required: false + schema: + type: string + - ethnicity: + name: ethnicity + in: query + description: > + Filter officers by their ethnicity. The value should be a comma-separated list of ethnicities. + required: false + schema: + type: string + - badge_number: + name: badge_number + in: query + description: > + Filter officers by their badge number. The value should be a comma-separated list of badge numbers. + required: false + schema: + type: string securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT schemas: - OfficerFilter: + NameFilter: + type: object + description: > + An advanced filter that can be applied to a officer list request. + properties: + first: + type: string + description: > + Filter officers by their first name. The value should be a string. + middle: + type: string + description: > + Filter officers by their middle name. The value should be a string. + last: + type: string + description: > + Filter officers by their last name. The value should be a string. + suffix: + type: string + description: > + Filter officers by their suffix. The value should be a string. + LocationFilter: + type: object + description: > + An advanced filter that can be applied to a officer list request. + properties: + state: + type: string + description: > + Filter locations by state. The value should be a string. + county: + type: string + description: > + Filter locations by county. The value should be a string. + city: + type: string + description: > + Filter locations by city. The value should be a string. + zip: + type: string + description: > + Filter locations by zip code. The value should be a string. + AllegationFilter: type: object description: > An advanced filter that can be applied to an officer list request. properties: - name: + uid: + type: array + description: > + Return officers who have any of the selected allegations. + items: + type: string + status: + type: array + description: > + Return officers who have allegations with the selected statuses. + items: + type: string + category: + type: array + description: > + Return officers who have allegations with the selected categories. + items: + type: string + subcategory: + type: array + description: > + Return officers who have allegations with the selected subcategory. + items: + type: string + sustained: + type: boolean + description: > + Return officers who have allegations that are either sustained not sustained. The value must be a boolean. + StateIdFilter: + type: object + description: > + An advanced filter that can be applied to a officer list request. + properties: + state: + type: string + description: > + Filter officers by their ID state. The value should be a string. + id_name: + type: string + description: > + Filter officers by their ID name. The value should be a string. + values: type: string description: > - Filter officers by their name. The value should be a string in the format "first middle last suffix". + Return officers with the selected ID values. Must be sent in tandem + with the `id_name` and `state` properties. + OfficerFilter: + type: object + description: > + An advanced filter that can be applied to an officer list request. + properties: + names: + type: array + description: > + Return officers whose name matches any of these filters. + items: + $ref: "#/components/schemas/NameFilter" location: allOf: - $ref: "#/components/schemas/LocationFilter" - type: object description: > Filter officers by locations in which they have worked. This is assesed based on the operating theatre of the units to which they've been assigned. - state_ids: + state_ids_sets: type: array description: > - Filter officers by their state IDs. This can be used to filter by tax number, officer training number, or any other unique identifier used by a state. + Filter officers by their state IDs. This can be used to filter by tax number, + officer training number, or any other unique identifier used by a state. items: $ref: "#/components/schemas/StateIdFilter" ranks: type: array description: > - Filter officers by their rank. + Return officers who have obtained the selected ranks. items: type: string - ethnicity: + ethnicities: type: array description: > - Filter officers by ethnicity. + Return officers who have the selected ethnicities. items: - $ref: "#/components/schemas/EthnicityFilter" + type: string + enum: + - American Indian or Alaska Native + - Asian + - Black or African American + - Hispanic or Latino + - Native Hawaiian or Other Pacific Islander + - White commanders: type: array description: > diff --git a/oas/2.0/search.yaml b/oas/2.0/search.yaml index 1ec8f9c4..efd922a5 100644 --- a/oas/2.0/search.yaml +++ b/oas/2.0/search.yaml @@ -50,8 +50,7 @@ paths: '400': $ref: '../common/error.yaml#/components/responses/validationError' '404': - $ref: '../common/error.yaml#/components/responses/notFoundError' - + $ref: '../common/error.yaml#/components/responses/notFoundError' /search/auto: post: tags: diff --git a/oas/2.0/users.yaml b/oas/2.0/users.yaml index 53b54dda..29535944 100644 --- a/oas/2.0/users.yaml +++ b/oas/2.0/users.yaml @@ -20,12 +20,12 @@ tags: - name: "Users" description: "Users API" paths: - /users: + /users/self: get: tags: - "Users" - summary: "Get all users" - operationId: "getUsers" + summary: "Get current user" + operationId: "getCurrentUser" responses: "200": description: "Successful operation" @@ -34,7 +34,28 @@ paths: schema: type: "array" items: - $ref: "#/components/schemas/UserList" + $ref: "#/components/schemas/User" + '401': + $ref: '../common/error.yaml#/components/responses/unauthorizedError' + patch: + tags: + - "Users" + summary: "Update the current user" + operationId: "updateCurrentUser" + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/UpdateUser" + responses: + '200': + description: 'Successful operation' + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '400': + $ref: '../common/error.yaml#/components/responses/validationError' '401': $ref: '../common/error.yaml#/components/responses/unauthorizedError' /users/{uid}: @@ -63,30 +84,6 @@ paths: $ref: '../common/error.yaml#/components/responses/unauthorizedError' '404': $ref: '../common/error.yaml#/components/responses/notFoundError' - patch: - tags: - - "Users" - summary: "Update an existing user" - operationId: "updateUser" - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/UpdateUser" - responses: - '200': - description: 'Successful operation' - content: - application/json: - schema: - $ref: '#/components/schemas/User' - '400': - $ref: '../common/error.yaml#/components/responses/validationError' - '401': - $ref: '../common/error.yaml#/components/responses/unauthorizedError' - '404': - $ref: '../common/error.yaml#/components/responses/notFoundError' - components: securitySchemes: bearerAuth: From 04407517ac643599c2bf7b1e0ad801064e264383 Mon Sep 17 00:00:00 2001 From: Darrell Malone Jr Date: Wed, 5 Feb 2025 22:05:48 -0600 Subject: [PATCH 5/8] Fix parameter syntax --- oas/2.0/complaints.yaml | 23 +++--- oas/2.0/officers.yaml | 156 ++++++++++++++++++++-------------------- 2 files changed, 92 insertions(+), 87 deletions(-) diff --git a/oas/2.0/complaints.yaml b/oas/2.0/complaints.yaml index 679136fb..e8d616e0 100644 --- a/oas/2.0/complaints.yaml +++ b/oas/2.0/complaints.yaml @@ -21,13 +21,13 @@ tags: description: "Complaints API" paths: /complaints/{complaint_uid}: - parameters: - - name: complaint_uid - in: path - required: true - schema: - type: string get: + parameters: + - name: complaint_uid + in: path + required: true + schema: + type: string tags: - "Complaints" summary: "Get Complaint" @@ -45,7 +45,13 @@ paths: $ref: '../common/error.yaml#/components/responses/notFoundError' '401': $ref: '../common/error.yaml#/components/responses/unauthorizedError' - patch: + patch: + parameters: + - name: complaint_uid + in: path + required: true + schema: + type: string tags: - "Complaints" summary: "Update Complaint" @@ -73,8 +79,7 @@ paths: '404': $ref: '../common/error.yaml#/components/responses/notFoundError' '401': - $ref: '../common/error.yaml#/components/responses/unauthorizedError' - + $ref: '../common/error.yaml#/components/responses/unauthorizedError' /complaints: post: tags: diff --git a/oas/2.0/officers.yaml b/oas/2.0/officers.yaml index 8e49244d..1bd4ee11 100644 --- a/oas/2.0/officers.yaml +++ b/oas/2.0/officers.yaml @@ -36,12 +36,12 @@ paths: - $ref: '../common/pagination.yaml#/components/parameters/per_page' - $ref: '#/components/parameters/active_after' - $ref: '#/components/parameters/active_before' - - $ref: '#components/parameters/agency' - - $ref: '#components/parameters/rank' - - $ref: '#components/parameters/unit' - - $ref: '#components/parameters/name' - - $ref: '#components/parameters/ethnicity' - - $ref: '#components/parameters/badge_number' + - $ref: '#/components/parameters/agency' + - $ref: '#/components/parameters/rank' + - $ref: '#/components/parameters/unit' + - $ref: '#/components/parameters/name' + - $ref: '#/components/parameters/ethnicity' + - $ref: '#/components/parameters/badge_number' responses: "200": description: "Successful operation" @@ -106,12 +106,12 @@ paths: - $ref: '../common/pagination.yaml#/components/parameters/per_page' - $ref: '#/components/parameters/active_after' - $ref: '#/components/parameters/active_before' - - $ref: '#components/parameters/agency' - - $ref: '#components/parameters/rank' - - $ref: '#components/parameters/unit' - - $ref: '#components/parameters/name' - - $ref: '#components/parameters/ethnicity' - - $ref: '#components/parameters/badge_number' + - $ref: '#/components/parameters/agency' + - $ref: '#/components/parameters/rank' + - $ref: '#/components/parameters/unit' + - $ref: '#/components/parameters/name' + - $ref: '#/components/parameters/ethnicity' + - $ref: '#/components/parameters/badge_number' requestBody: description: > A JSON object containing the filters to apply to the search. @@ -250,72 +250,72 @@ paths: $ref: '../common/error.yaml#/components/responses/unauthorizedError' components: parameters: - - active_after: - name: active_after - in: query - description: > - Filter officers who were active after this date. The date should be in the format YYYY-MM-DD. - required: false - schema: - type: string - format: date - - active_before: - name: active_before - in: query - description: > - Filter officers who were active before this date. The date should be in the format YYYY-MM-DD. - required: false - schema: - type: string - format: date - - agency: - name: agency - in: query - description: > - Filter officers by the agency they are employed by. The value should be a comma-separated list of agency uids. - required: false - schema: - type: string - - rank: - name: rank - in: query - description: > - Filter officers by their rank. The value should be a comma-separated list of ranks. - required: false - schema: - type: string - - unit: - name: unit - in: query - description: > - Filter officers by their unit. The value should be a comma-separated list of unit uids. - required: false - schema: - type: string - - name: - name: name - in: query - description: > - Filter officers by their name. The value should be a string in the format "first middle last suffix". - required: false - schema: - type: string - - ethnicity: - name: ethnicity - in: query - description: > - Filter officers by their ethnicity. The value should be a comma-separated list of ethnicities. - required: false - schema: - type: string - - badge_number: - name: badge_number - in: query - description: > - Filter officers by their badge number. The value should be a comma-separated list of badge numbers. - required: false - schema: - type: string + active_after: + name: active_after + in: query + description: > + Filter officers who were active after this date. The date should be in the format YYYY-MM-DD. + required: false + schema: + type: string + format: date + active_before: + name: active_before + in: query + description: > + Filter officers who were active before this date. The date should be in the format YYYY-MM-DD. + required: false + schema: + type: string + format: date + agency: + name: agency + in: query + description: > + Filter officers by the agency they are employed by. The value should be a comma-separated list of agency uids. + required: false + schema: + type: string + rank: + name: rank + in: query + description: > + Filter officers by their rank. The value should be a comma-separated list of ranks. + required: false + schema: + type: string + unit: + name: unit + in: query + description: > + Filter officers by their unit. The value should be a comma-separated list of unit uids. + required: false + schema: + type: string + name: + name: name + in: query + description: > + Filter officers by their name. The value should be a string in the format "first middle last suffix". + required: false + schema: + type: string + ethnicity: + name: ethnicity + in: query + description: > + Filter officers by their ethnicity. The value should be a comma-separated list of ethnicities. + required: false + schema: + type: string + badge_number: + name: badge_number + in: query + description: > + Filter officers by their badge number. The value should be a comma-separated list of badge numbers. + required: false + schema: + type: string securitySchemes: bearerAuth: type: http From dc58bc022d8212b12795405f16e2353cb9af1475 Mon Sep 17 00:00:00 2001 From: Darrell Malone Jr Date: Wed, 5 Feb 2025 22:48:24 -0600 Subject: [PATCH 6/8] Update reqs dockerfile --- requirements/Dockerfile | 2 +- requirements/docs.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/Dockerfile b/requirements/Dockerfile index 266aab74..f93a740c 100644 --- a/requirements/Dockerfile +++ b/requirements/Dockerfile @@ -2,7 +2,7 @@ # requirements, so this image starts with the same image as the database # containers and installs the same version of python as the api containers -FROM postgres:17 as base +FROM rust:slim-bookworm as base RUN apt-get update && apt-get install -y \ make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev \ diff --git a/requirements/docs.txt b/requirements/docs.txt index cdaf7f87..f9879794 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.12 +# This file is autogenerated by pip-compile with Python 3.13 # by the following command: # # pip-compile requirements/docs.in From 0cc91f7f172f4d1cc175d2656a7a1faf790a16f1 Mon Sep 17 00:00:00 2001 From: Darrell Malone Jr Date: Tue, 11 Feb 2025 18:18:00 -0600 Subject: [PATCH 7/8] Revert "Update reqs dockerfile" This reverts commit dc58bc022d8212b12795405f16e2353cb9af1475. --- requirements/Dockerfile | 2 +- requirements/docs.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/Dockerfile b/requirements/Dockerfile index f93a740c..266aab74 100644 --- a/requirements/Dockerfile +++ b/requirements/Dockerfile @@ -2,7 +2,7 @@ # requirements, so this image starts with the same image as the database # containers and installs the same version of python as the api containers -FROM rust:slim-bookworm as base +FROM postgres:17 as base RUN apt-get update && apt-get install -y \ make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev \ diff --git a/requirements/docs.txt b/requirements/docs.txt index f9879794..cdaf7f87 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.13 +# This file is autogenerated by pip-compile with Python 3.12 # by the following command: # # pip-compile requirements/docs.in From 0a5c08cce53cf35424a5b452f88cc24317a32ce7 Mon Sep 17 00:00:00 2001 From: Darrell Malone Jr Date: Tue, 11 Feb 2025 18:18:42 -0600 Subject: [PATCH 8/8] Update officer filters --- oas/2.0/officers.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/oas/2.0/officers.yaml b/oas/2.0/officers.yaml index 1bd4ee11..0aeeaec1 100644 --- a/oas/2.0/officers.yaml +++ b/oas/2.0/officers.yaml @@ -397,6 +397,14 @@ components: type: boolean description: > Return officers who have allegations that are either sustained not sustained. The value must be a boolean. + count__gte: + type: integer + description: > + Return officers who have at least the selected number of allegations. The value must be an integer. + count__lte: + type: integer + description: > + Return officers who have at most the selected number of allegations. The value must be an integer. StateIdFilter: type: object description: >