Skip to content

Commit

Permalink
fix: check for receipt_outcome on add_rfp and add_proposal
Browse files Browse the repository at this point in the history
feat: add endpoint /rfp/<id>/snapshots
  • Loading branch information
Tguntenaar committed Nov 15, 2024
1 parent 3bdc9a7 commit 8da3f7c
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 18 deletions.
19 changes: 9 additions & 10 deletions .github/workflows/fly-deploy.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
# # See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/

# name: Fly Deploy
# on:
# push:
# branches:
# - main

# jobs:
# deploy:
# name: Deploy Applications
# runs-on: ubuntu-latest
name: Fly Deploy
on:
push:
branches:
- main
jobs:
deploy:
name: Deploy Applications
runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - uses: superfly/flyctl-actions/setup-flyctl@master
Expand Down
42 changes: 39 additions & 3 deletions src/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,12 +662,48 @@ impl DB {
p.id = $1
"#;

let rfp = sqlx::query_as::<_, RfpWithLatestSnapshotView>(sql)
let result = sqlx::query_as::<_, RfpWithLatestSnapshotView>(sql)
.bind(id)
.fetch_one(&self.0)
.await?;
.await;

match result {
Ok(rfp) => Ok(rfp),
Err(e) => {
eprintln!("Failed to get rfp with latest snapshot: {:?}", e);
Err(anyhow::anyhow!("Failed to get rfp with latest snapshot"))
}
}
}

Ok(rfp)
pub async fn get_rfp_with_all_snapshots(
&self,
id: i32,
) -> anyhow::Result<Vec<RfpSnapshotRecord>> {
// Group by ts
// Build the SQL query for fetching data with the validated order clause
let data_sql = r#"
SELECT
rfp.*
FROM
rfp_snapshots rfp
WHERE
rfp.rfp_id = $1
"#;

// Execute the data query
let result = sqlx::query_as::<_, RfpSnapshotRecord>(&data_sql)
.bind(id)
.fetch_all(&self.0)
.await;

match result {
Ok(recs) => Ok(recs),
Err(e) => {
eprintln!("Failed to get rfp with all snapshots: {:?}", e);
Err(anyhow::anyhow!("Failed to get rfp with all snapshots"))
}
}
}

pub async fn search_rfps_with_latest_snapshot(
Expand Down
27 changes: 24 additions & 3 deletions src/entrypoints/rfp/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use self::rfp_types::*;
use crate::db::db_types::RfpWithLatestSnapshotView;
use crate::db::db_types::{RfpSnapshotRecord, RfpWithLatestSnapshotView};
use crate::db::DB;
use crate::rpc_service::RpcService;
use crate::types::PaginatedResponse;
Expand Down Expand Up @@ -147,7 +147,7 @@ async fn get_rfps(
)))
}

#[utoipa::path(get, path = "/rfps/{rfp_id}")]
#[utoipa::path(get, path = "/rfp/{rfp_id}")]
#[get("/<rfp_id>")]
async fn get_rfp(rfp_id: i32, contract: &State<AccountId>) -> Result<Json<VersionedRFP>, Status> {
// TODO Get cached rfp
Expand All @@ -163,10 +163,31 @@ async fn get_rfp(rfp_id: i32, contract: &State<AccountId>) -> Result<Json<Versio
}
}

#[utoipa::path(get, path = "/{rfp_id}/snapshots")]
#[get("/<rfp_id>/snapshots")]
async fn get_rfp_with_all_snapshots(
rfp_id: i32,
db: &State<DB>,
) -> Result<Json<Vec<RfpSnapshotRecord>>, Status> {
match db.get_rfp_with_all_snapshots(rfp_id).await {
Err(e) => {
eprintln!("Failed to get rfps: {:?}", e);
// Ok(Json(vec![]))
Err(Status::InternalServerError)
}
Ok(result) => Ok(Json(result)),
}
}

pub fn stage() -> rocket::fairing::AdHoc {
rocket::fairing::AdHoc::on_ignite("Rfp Stage", |rocket| async {
println!("Rfp stage on ignite!");

rocket.mount("/rfps/", rocket::routes![get_rfps, get_rfp, search])
rocket
.mount("/rfps/", rocket::routes![get_rfps, search])
.mount(
"/rfp/",
rocket::routes![get_rfp, get_rfp_with_all_snapshots],
)
})
}
6 changes: 6 additions & 0 deletions src/entrypoints/rfp/rfp_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ pub struct PartialEditRFPArgs {
pub id: i32,
}

#[derive(Deserialize)]
pub struct PartialEditRFPTimelineArgs {
pub id: i32,
pub timeline: String,
}

#[derive(Clone, Debug, FromForm, ToSchema)]
pub struct GetRfpFilters {
pub category: Option<String>,
Expand Down
84 changes: 82 additions & 2 deletions src/nearblocks_client/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,25 @@ pub async fn process(
"edit_proposal_internal" => {
handle_edit_proposal(transaction.to_owned(), db, contract.clone()).await
}
// TODO: find out which one I need to index the content from and not call the RPC for the latest snapshot
"edit_rfp_timeline" => {
println!("edit_rfp_timeline");
handle_edit_rfp_timeline(transaction.to_owned(), db).await
}
"edit_rfp" => {
println!("edit_rfp");
handle_edit_rfp(transaction.to_owned(), db, contract.clone()).await
}
"edit_rfp" => handle_edit_rfp(transaction.to_owned(), db, contract.clone()).await,
"edit_rfp_internal" => {
println!("edit_rfp_internal");
handle_edit_rfp(transaction.to_owned(), db, contract.clone()).await
}
"cancel_rfp" => {
println!("cancel_rfp");
handle_edit_rfp(transaction.to_owned(), db, contract.clone()).await
}
"cancel_rfp" => handle_edit_rfp(transaction.to_owned(), db, contract.clone()).await,
"set_rfp_block_height_callback" => {
println!("set_rfp_block_height_callback");
handle_set_rfp_block_height_callback(
transaction.to_owned(),
db,
Expand All @@ -77,6 +87,15 @@ async fn handle_set_rfp_block_height_callback(
db: &State<DB>,
contract: AccountId,
) -> Result<(), Status> {
if !transaction.receipt_outcome.status {
eprintln!(
"RFP receipt outcome status is {:?}",
transaction.receipt_outcome.status
);
eprintln!("On transaction: {:?}", transaction);
return Ok(());
}

let action = transaction
.actions
.as_ref()
Expand Down Expand Up @@ -183,11 +202,72 @@ async fn handle_edit_rfp(
Ok(())
}

async fn handle_edit_rfp_timeline(transaction: Transaction, db: &State<DB>) -> Result<(), Status> {
let action = transaction
.actions
.as_ref()
.and_then(|actions| actions.first())
.ok_or(Status::InternalServerError)?;

let args: PartialEditRFPTimelineArgs = serde_json::from_str(action.args.as_ref().unwrap())
.map_err(|e| {
eprintln!("Failed to parse JSON: {:?}", e);
"Failed to parse proposal arguments"
})
.map_err(|_e| Status::InternalServerError)?;

// Get snapshot from database with id
let snapshot = db
.get_rfp_with_latest_snapshot_by_id(args.id)
.await
.map_err(|_e| Status::InternalServerError)?;
// Insert snapshot with new timeline and timestamp
let mut tx = db.begin().await.map_err(|_e| Status::InternalServerError)?;

let snapshot = RfpSnapshotRecord {
rfp_id: args.id,
block_height: transaction.block.block_height as i64,
ts: transaction.block_timestamp.parse().unwrap(),
editor_id: transaction.predecessor_account_id,
social_db_post_block_height: snapshot.social_db_post_block_height,
labels: snapshot.labels,
linked_proposals: snapshot.linked_proposals,
rfp_version: "V0".to_string(),
rfp_body_version: "V0".to_string(),
name: snapshot.name,
category: snapshot.category,
summary: snapshot.summary,
description: snapshot.description,
timeline: Some(args.timeline.parse().unwrap()),
submission_deadline: snapshot.submission_deadline,
views: snapshot.views,
};

DB::insert_rfp_snapshot(&mut tx, &snapshot)
.await
.map_err(|_e| Status::InternalServerError)?;

tx.commit()
.await
.map_err(|_e| Status::InternalServerError)?;

Ok(())
}

async fn handle_set_block_height_callback(
transaction: Transaction,
db: &State<DB>,
contract: AccountId,
) -> Result<(), Status> {
if !transaction.receipt_outcome.status {
eprintln!(
"Proposal receipt outcome status is {:?}",
transaction.receipt_outcome.status
);
eprintln!("On transaction: {:?}", transaction);
return Ok(());
}

let action = transaction
.actions
.as_ref()
Expand Down

0 comments on commit 8da3f7c

Please sign in to comment.