Skip to content
This repository has been archived by the owner on Jun 30, 2021. It is now read-only.

Commit

Permalink
Composable filters as request params (#440)
Browse files Browse the repository at this point in the history
* Remove unused SearchParser.search_with_terms()

* Base code for FilterParser

* Implement filtering of subfields

* Add filtering to transaction controller

* Add MatchAnyParser

* Match the same supporting comparators as MatchAllParser

* Check that the provided filters do not go over the supported max associations

* Disable cyclomatic complexity check for MatchAnyParserHelper

* Add `starts_with` operator

* Add filtering docs and API specs
  • Loading branch information
unnawut authored Oct 1, 2018
1 parent bfef082 commit 0cf03c9
Show file tree
Hide file tree
Showing 13 changed files with 2,087 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ defmodule AdminAPI.V1.TransactionController do
alias Ecto.Changeset
alias EWallet.TransactionGate
alias EWallet.TransactionPolicy
alias EWallet.Web.{Paginator, Preloader, SearchParser, SortParser}
alias EWallet.Web.{MatchAllParser, Paginator, Preloader, SearchParser, SortParser}
alias EWalletDB.{Account, Repo, Transaction, User}

# The field names to be mapped into DB column names.
Expand All @@ -22,6 +22,30 @@ defmodule AdminAPI.V1.TransactionController do
# Note that these values *must be in the schema associations*.
@preload_fields [:from_token, :to_token]

# The fields that are allowed to be filtered.
@filter_fields [
# From
from_amount: nil,
from_token: [:id, :name, :symbol, :inserted_at, :created_at],
from_wallet: [:address, :name, :identifier, :inserted_at, :created_at],
from_account: [:id, :name, :inserted_at, :created_at],
from_user: [:id, :username, :email, :provider_user_id, :inserted_at, :created_at],
# To
to_amount: nil,
to_token: [:id, :name, :symbol],
to_wallet: [:address, :name, :identifier],
to_account: [:id, :name, :inserted_at, :created_at],
to_user: [:id, :username, :email, :provider_user_id, :inserted_at, :created_at],
# Exchange
exchange_account: [:id, :name, :inserted_at, :created_at],
exchange_wallet: [:address, :name, :identifier, :inserted_at, :created_at],
# Other data
status: nil,
type: nil,
inserted_at: nil,
updated_at: nil
]

# The fields that are allowed to be searched.
# Note that these values here *must be the DB column names*
# Because requests cannot customize which fields to search (yet!),
Expand Down Expand Up @@ -149,6 +173,7 @@ defmodule AdminAPI.V1.TransactionController do
defp query_records_and_respond(query, attrs, conn) do
query
|> Preloader.to_query(@preload_fields)
|> MatchAllParser.to_query(attrs, @filter_fields)
|> SearchParser.to_query(attrs, @search_fields)
|> SortParser.to_query(attrs, @sort_fields, @mapped_fields)
|> Paginator.paginate_attrs(attrs)
Expand Down
166 changes: 162 additions & 4 deletions apps/admin_api/priv/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,43 @@
} ]
}
},
"/token.enable_or_disable" : {
"post" : {
"tags" : [ "Token" ],
"summary" : "Enable or disable an existing token",
"operationId" : "token_enable_or_disable",
"requestBody" : {
"$ref" : "#/components/requestBodies/TokenToggleStatusBody"
},
"responses" : {
"200" : {
"description" : "Returns a single tokens",
"content" : {
"application/vnd.omisego.v1+json" : {
"schema" : {
"$ref" : "#/components/schemas/TokenResponseSchema"
}
}
}
},
"500" : {
"description" : "Returns an internal server error",
"content" : {
"application/vnd.omisego.v1+json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorResponseSchema"
}
}
}
}
},
"security" : [ {
"ProviderAuth" : [ ]
}, {
"AdminAuth" : [ ]
} ]
}
},
"/token.stats" : {
"post" : {
"tags" : [ "Token" ],
Expand Down Expand Up @@ -2055,6 +2092,43 @@
} ]
}
},
"/wallet.enable_or_disable" : {
"post" : {
"tags" : [ "Wallet" ],
"summary" : "Enable or disable a specific wallet",
"operationId" : "wallet_enable_or_disable",
"requestBody" : {
"$ref" : "#/components/requestBodies/WalletEnableOrDisableBody"
},
"responses" : {
"200" : {
"description" : "Returns a single wallet",
"content" : {
"application/vnd.omisego.v1+json" : {
"schema" : {
"$ref" : "#/components/schemas/WalletResponseSchema"
}
}
}
},
"500" : {
"description" : "Returns an internal server error",
"content" : {
"application/vnd.omisego.v1+json" : {
"schema" : {
"$ref" : "#/components/schemas/ErrorResponseSchema"
}
}
}
}
},
"security" : [ {
"ProviderAuth" : [ ]
}, {
"AdminAuth" : [ ]
} ]
}
},
"/transaction.all" : {
"post" : {
"tags" : [ "Transaction" ],
Expand Down Expand Up @@ -3029,6 +3103,12 @@
}
}
},
"AdvancedFilteringSchema" : {
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/AdvancedFilteringSchema_inner"
}
},
"ErrorSchema" : {
"required" : [ "code", "description", "messages", "object" ],
"type" : "object",
Expand Down Expand Up @@ -3168,7 +3248,7 @@
} ]
},
"TokenSchema" : {
"required" : [ "created_at", "id", "name", "object", "subunit_to_unit", "symbol", "updated_at" ],
"required" : [ "created_at", "enabled", "id", "name", "object", "subunit_to_unit", "symbol", "updated_at" ],
"type" : "object",
"properties" : {
"object" : {
Expand Down Expand Up @@ -3200,6 +3280,9 @@
},
"encrypted_metadata" : {
"type" : "object"
},
"enabled" : {
"type" : "boolean"
}
},
"description" : "The object schema for a token"
Expand All @@ -3226,7 +3309,8 @@
"name" : "ABC Point",
"subunit_to_unit" : 100,
"created_at" : "2018-01-01T00:00:00Z",
"updated_at" : "2018-01-01T10:00:00Z"
"updated_at" : "2018-01-01T10:00:00Z",
"enabled" : true
}
}
} ]
Expand Down Expand Up @@ -3268,7 +3352,8 @@
"name" : "ABC Point",
"subunit_to_unit" : 100,
"created_at" : "2018-01-01T00:00:00Z",
"updated_at" : "2018-01-01T10:00:00Z"
"updated_at" : "2018-01-01T10:00:00Z",
"enabled" : true
} ],
"pagination" : {
"per_page" : 10,
Expand Down Expand Up @@ -4138,7 +4223,7 @@
} ]
},
"WalletSchema" : {
"required" : [ "account", "account_id", "address", "balances", "encrypted_metadata", "identifier", "metadata", "name", "object", "socket_topic", "user", "user_id" ],
"required" : [ "account", "account_id", "address", "balances", "enabled", "encrypted_metadata", "identifier", "metadata", "name", "object", "socket_topic", "user", "user_id" ],
"type" : "object",
"properties" : {
"object" : {
Expand All @@ -4162,6 +4247,9 @@
"encrypted_metadata" : {
"type" : "object"
},
"enabled" : {
"type" : "boolean"
},
"user_id" : {
"type" : "string"
},
Expand Down Expand Up @@ -4191,6 +4279,7 @@
"identifier" : "primary",
"metadata" : { },
"encrypted_metadata" : { },
"enabled" : true,
"user_id" : "usr_01cbfg6v9thrc3sd9m1v4gazjv",
"user" : { },
"account_id" : null,
Expand Down Expand Up @@ -4256,6 +4345,7 @@
"identifier" : "primary",
"metadata" : { },
"encrypted_metadata" : { },
"enabled" : true,
"user_id" : "usr_01cbfg6v9thrc3sd9m1v4gazjv",
"user" : { },
"account_id" : null,
Expand Down Expand Up @@ -4312,6 +4402,7 @@
"identifier" : "primary",
"metadata" : { },
"encrypted_metadata" : { },
"enabled" : true,
"user_id" : "usr_01cbfg6v9thrc3sd9m1v4gazjv",
"user" : { },
"account_id" : null,
Expand Down Expand Up @@ -5343,6 +5434,19 @@
}
} ]
},
"AdvancedFilteringSchema_inner" : {
"properties" : {
"field" : {
"type" : "string"
},
"comparator" : {
"type" : "string"
},
"value" : {
"type" : "string"
}
}
},
"TransactionSchema_from" : {
"properties" : {
"object" : {
Expand Down Expand Up @@ -6010,6 +6114,29 @@
},
"required" : true
},
"TokenToggleStatusBody" : {
"description" : "The parameters to enable/disable a token. Send enabled=true to enable, enabled=false to disable.",
"content" : {
"application/vnd.omisego.v1+json" : {
"schema" : {
"required" : [ "enabled", "id" ],
"properties" : {
"id" : {
"type" : "string"
},
"enabled" : {
"type" : "boolean"
}
},
"example" : {
"id" : "tok_ABC_01ce846km1syzwezxfmgdn7dt7",
"enabled" : false
}
}
}
},
"required" : true
},
"TokenMintBody" : {
"description" : "The parameters to create a token. Note that if amount is specified, the token will be minted automatically.",
"content" : {
Expand Down Expand Up @@ -7167,6 +7294,29 @@
},
"required" : true
},
"WalletEnableOrDisableBody" : {
"description" : "The parameters to use to enable or disable a wallet.",
"content" : {
"application/vnd.omisego.v1+json" : {
"schema" : {
"required" : [ "address", "enabled" ],
"properties" : {
"address" : {
"type" : "string"
},
"enabled" : {
"type" : "boolean"
}
},
"example" : {
"address" : "ce3982f5-4a27-498d-a91b-7bb2e2a8d3d1",
"enabled" : false
}
}
}
},
"required" : true
},
"WalletCreateBody" : {
"description" : "The parameters to use for creating a wallet",
"content" : {
Expand Down Expand Up @@ -7244,6 +7394,12 @@
"search_term" : {
"type" : "string"
},
"match_all" : {
"$ref" : "#/components/schemas/AdvancedFilteringSchema"
},
"match_any" : {
"$ref" : "#/components/schemas/AdvancedFilteringSchema"
},
"sort_by" : {
"type" : "string"
},
Expand All @@ -7256,6 +7412,8 @@
"page" : 1,
"per_page" : 10,
"search_term" : "",
"match_all" : [ ],
"match_any" : [ ],
"sort_by" : "created_at",
"sort_dir" : "desc"
}
Expand Down
25 changes: 25 additions & 0 deletions apps/admin_api/priv/spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1507,6 +1507,25 @@ components:
is_first_page: true
is_last_page: true

######################################
# ADVANCED FILTERING SCHEMAS #
######################################
AdvancedFilteringSchema:
type: array
items:
type: object
properties:
field:
type: string
comparator:
type: string
value:
type: string
required:
- field
- comparator
- value

######################################
# ERROR SCHEMAS #
######################################
Expand Down Expand Up @@ -4680,6 +4699,10 @@ components:
minimum: 1
search_term:
type: string
match_all:
$ref: '#/components/schemas/AdvancedFilteringSchema'
match_any:
$ref: '#/components/schemas/AdvancedFilteringSchema'
sort_by:
type: string
sort_dir:
Expand All @@ -4689,6 +4712,8 @@ components:
page: 1
per_page: 10
search_term: ""
match_all: []
match_any: []
sort_by: "created_at"
sort_dir: "desc"

Expand Down
Loading

0 comments on commit 0cf03c9

Please sign in to comment.