Skip to content

Commit

Permalink
feat: all proposals endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mateuszjasiuk committed Jul 9, 2024
1 parent c66c31f commit 1df3c11
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 50 deletions.
2 changes: 1 addition & 1 deletion swagger-codegen.config → swagger-codegen.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"npmName": "@anomaorg/namada-indexer-client",
"npmVersion": "0.0.16"
"npmVersion": "0.0.17"
}

30 changes: 30 additions & 0 deletions swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,36 @@ paths:
$ref: '#/components/schemas/Proposal'
pagination:
$ref: '#/components/schemas/Pagination'
/api/v1/gov/proposal/all:
get:
summary: Get a list of all governance proposals
parameters:
- in: query
name: status
schema:
type: string
enum: [pending, votingPeriod, passed, rejected]
description: The status of the proposal
- in: query
name: kind
schema:
type: string
enum: [default, defaultWithWasm, pgfSteward, pgfFunding]
description: The status of the proposal
- in: query
name: pattern
schema:
type: string
description: The status of the proposal
responses:
'200':
description: A list of governance proposals.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Proposal'
/api/v1/gov/proposal/{id}:
get:
summary: Get a governance proposal by proposal id
Expand Down
4 changes: 4 additions & 0 deletions webserver/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ impl ApplicationServer {
"/gov/proposal",
get(gov_handlers::get_governance_proposals),
)
.route(
"/gov/proposal/all",
get(gov_handlers::get_governance_proposals),
)
.route(
"/gov/proposal/:id",
get(gov_handlers::get_governance_proposal_by_id),
Expand Down
14 changes: 14 additions & 0 deletions webserver/src/handler/governance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ pub async fn get_governance_proposals(
Ok(Json(response))
}

#[debug_handler]
pub async fn get_all_governance_proposals(
_headers: HeaderMap,
Query(query): Query<ProposalQueryParams>,
State(state): State<CommonState>,
) -> Result<Json<Vec<Proposal>>, ApiError> {
let proposals = state
.gov_service
.find_all_governance_proposals(query.status, query.kind, query.pattern)
.await?;

Ok(Json(proposals))
}

#[debug_handler]
pub async fn get_governance_proposal_by_id(
_headers: HeaderMap,
Expand Down
75 changes: 58 additions & 17 deletions webserver/src/repository/governance.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use axum::async_trait;
use diesel::dsl::IntoBoxed;
use diesel::pg::Pg;
use diesel::{
BoolExpressionMethods, ExpressionMethods, PgTextExpressionMethods,
QueryDsl, RunQueryDsl, SelectableHelper,
Expand All @@ -23,12 +25,19 @@ pub trait GovernanceRepoTrait {

async fn find_governance_proposals(
&self,
status: Vec<GovernanceProposalResultDb>,
status: Option<GovernanceProposalResultDb>,
kind: Option<GovernanceProposalKindDb>,
pattern: Option<String>,
page: i64,
) -> Result<PaginatedResponseDb<GovernanceProposalDb>, String>;

async fn find_all_governance_proposals(
&self,
status: Option<GovernanceProposalResultDb>,
kind: Option<GovernanceProposalKindDb>,
pattern: Option<String>,
) -> Result<Vec<GovernanceProposalDb>, String>;

async fn find_governance_proposals_by_id(
&self,
proposal_id: i32,
Expand Down Expand Up @@ -60,29 +69,15 @@ impl GovernanceRepoTrait for GovernanceRepo {

async fn find_governance_proposals(
&self,
status: Vec<GovernanceProposalResultDb>,
status: Option<GovernanceProposalResultDb>,
kind: Option<GovernanceProposalKindDb>,
pattern: Option<String>,
page: i64,
) -> Result<PaginatedResponseDb<GovernanceProposalDb>, String> {
let conn = self.app_state.get_db_connection().await;
let query = self.governance_proposals(status, kind, pattern);

conn.interact(move |conn| {
let mut query = governance_proposals::table.into_boxed().filter(
governance_proposals::dsl::result.eq_any(status.clone()),
);

if let Some(kind) = kind {
query = query.filter(governance_proposals::dsl::kind.eq(kind));
}

if let Some(pattern) = pattern {
query = query.filter(
governance_proposals::dsl::content
.ilike(format!("%{}%", pattern)),
);
}

query
.select(GovernanceProposalDb::as_select())
.paginate(page)
Expand All @@ -93,6 +88,23 @@ impl GovernanceRepoTrait for GovernanceRepo {
.map_err(|e| e.to_string())
}

async fn find_all_governance_proposals(
&self,
status: Option<GovernanceProposalResultDb>,
kind: Option<GovernanceProposalKindDb>,
pattern: Option<String>,
) -> Result<Vec<GovernanceProposalDb>, String> {
let conn = self.app_state.get_db_connection().await;
let query = self.governance_proposals(status, kind, pattern);

conn.interact(move |conn| {
query.select(GovernanceProposalDb::as_select()).load(conn)
})
.await
.map_err(|e| e.to_string())?
.map_err(|e| e.to_string())
}

async fn find_governance_proposals_by_id(
&self,
proposal_id: i32,
Expand Down Expand Up @@ -166,3 +178,32 @@ impl GovernanceRepoTrait for GovernanceRepo {
.map_err(|e| e.to_string())
}
}

impl<'a> GovernanceRepo {
fn governance_proposals(
&self,
status: Option<GovernanceProposalResultDb>,
kind: Option<GovernanceProposalKindDb>,
pattern: Option<String>,
) -> IntoBoxed<'a, governance_proposals::table, Pg> {
let mut query = governance_proposals::table.into_boxed();

if let Some(status) = status {
query = query
.filter(governance_proposals::dsl::result.eq(status.clone()))
}

if let Some(kind) = kind {
query = query.filter(governance_proposals::dsl::kind.eq(kind));
}

if let Some(pattern) = pattern {
query = query.filter(
governance_proposals::dsl::content
.ilike(format!("%{}%", pattern)),
);
}

query
}
}
102 changes: 70 additions & 32 deletions webserver/src/service/governance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,38 +30,8 @@ impl GovernanceService {
pattern: Option<String>,
page: u64,
) -> Result<(Vec<Proposal>, u64, u64), GovernanceError> {
let status = status
.map(|s| match s {
ProposalStatus::Pending => {
vec![GovernanceProposalResultDb::Pending]
}
ProposalStatus::VotingPeriod => {
vec![GovernanceProposalResultDb::VotingPeriod]
}
ProposalStatus::Passed => {
vec![GovernanceProposalResultDb::Passed]
}
ProposalStatus::Rejected => {
vec![GovernanceProposalResultDb::Rejected]
}
})
.unwrap_or_else(|| {
vec![
GovernanceProposalResultDb::Pending,
GovernanceProposalResultDb::VotingPeriod,
GovernanceProposalResultDb::Passed,
GovernanceProposalResultDb::Rejected,
]
});

let kind = kind.map(|t| match t {
ProposalKind::Default => GovernanceProposalKindDb::Default,
ProposalKind::DefaultWithWasm => {
GovernanceProposalKindDb::DefaultWithWasm
}
ProposalKind::PgfSteward => GovernanceProposalKindDb::PgfSteward,
ProposalKind::PgfFunding => GovernanceProposalKindDb::PgfFunding,
});
let kind = self.map_kind(kind);
let status = self.map_status(status);

let (db_proposals, total_pages, total_items) = self
.governance_repo
Expand Down Expand Up @@ -98,6 +68,46 @@ impl GovernanceService {
))
}

pub async fn find_all_governance_proposals(
&self,
status: Option<ProposalStatus>,
kind: Option<ProposalKind>,
pattern: Option<String>,
) -> Result<Vec<Proposal>, GovernanceError> {
let kind = self.map_kind(kind);
let status = self.map_status(status);

let db_proposals = self
.governance_repo
.find_all_governance_proposals(status, kind, pattern)
.await
.map_err(GovernanceError::Database)?;

let chain_state = self
.chain_repo
.get_chain_state()
.await
.map_err(GovernanceError::Database)?;

let parameters = self
.chain_repo
.find_chain_parameters()
.await
.map_err(GovernanceError::Database)?;

Ok(db_proposals
.into_iter()
.map(|p| {
Proposal::from_proposal_db(
p,
&chain_state,
parameters.min_num_of_blocks,
parameters.min_duration,
)
})
.collect())
}

pub async fn find_governance_proposal_by_id(
&self,
proposal_id: u64,
Expand Down Expand Up @@ -206,4 +216,32 @@ impl GovernanceService {
.map(ProposalVote::from)
.collect())
}

fn map_status(
&self,
status: Option<ProposalStatus>,
) -> Option<GovernanceProposalResultDb> {
status.map(|s| match s {
ProposalStatus::Pending => GovernanceProposalResultDb::Pending,
ProposalStatus::VotingPeriod => {
GovernanceProposalResultDb::VotingPeriod
}
ProposalStatus::Passed => GovernanceProposalResultDb::Passed,
ProposalStatus::Rejected => GovernanceProposalResultDb::Rejected,
})
}

fn map_kind(
&self,
kind: Option<ProposalKind>,
) -> Option<GovernanceProposalKindDb> {
kind.map(|t| match t {
ProposalKind::Default => GovernanceProposalKindDb::Default,
ProposalKind::DefaultWithWasm => {
GovernanceProposalKindDb::DefaultWithWasm
}
ProposalKind::PgfSteward => GovernanceProposalKindDb::PgfSteward,
ProposalKind::PgfFunding => GovernanceProposalKindDb::PgfFunding,
})
}
}

0 comments on commit 1df3c11

Please sign in to comment.