Create invoice table

This commit is contained in:
silverpill 2022-08-24 19:36:57 +00:00
parent 423eec0a2c
commit 084e0064be
6 changed files with 166 additions and 0 deletions

View file

@ -0,0 +1,10 @@
CREATE TABLE invoice (
id UUID PRIMARY KEY,
sender_id UUID NOT NULL REFERENCES actor_profile (id) ON DELETE CASCADE,
recipient_id UUID NOT NULL REFERENCES user_account (id) ON DELETE CASCADE,
chain_id VARCHAR(50) NOT NULL,
payment_address VARCHAR(200) NOT NULL,
invoice_status SMALLINT NOT NULL DEFAULT 1,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE (chain_id, payment_address)
);

View file

@ -136,6 +136,17 @@ CREATE TABLE timeline_marker (
UNIQUE (user_id, timeline)
);
CREATE TABLE invoice (
id UUID PRIMARY KEY,
sender_id UUID NOT NULL REFERENCES actor_profile (id) ON DELETE CASCADE,
recipient_id UUID NOT NULL REFERENCES user_account (id) ON DELETE CASCADE,
chain_id VARCHAR(50) NOT NULL,
payment_address VARCHAR(200) NOT NULL,
invoice_status SMALLINT NOT NULL DEFAULT 1,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE (chain_id, payment_address)
);
CREATE TABLE subscription (
id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
sender_id UUID NOT NULL REFERENCES actor_profile (id) ON DELETE CASCADE,

View file

@ -0,0 +1,2 @@
pub mod queries;
mod types;

View file

@ -0,0 +1,87 @@
use tokio_postgres::GenericClient;
use uuid::Uuid;
use crate::database::catch_unique_violation;
use crate::errors::DatabaseError;
use crate::utils::caip2::ChainId;
use crate::utils::id::new_uuid;
use super::types::DbInvoice;
pub async fn create_invoice(
db_client: &impl GenericClient,
sender_id: &Uuid,
recipient_id: &Uuid,
chain_id: &ChainId,
payment_address: &str,
) -> Result<DbInvoice, DatabaseError> {
let invoice_id = new_uuid();
let row = db_client.query_one(
"
INSERT INTO invoice (
id,
sender_id,
recipient_id,
chain_id,
payment_address
)
VALUES ($1, $2, $3, $4, $5)
RETURNING invoice
",
&[
&invoice_id,
&sender_id,
&recipient_id,
&chain_id,
&payment_address,
],
).await.map_err(catch_unique_violation("invoice"))?;
let invoice = row.try_get("invoice")?;
Ok(invoice)
}
#[cfg(test)]
mod tests {
use serial_test::serial;
use crate::database::test_utils::create_test_database;
use crate::models::{
invoices::types::InvoiceStatus,
profiles::queries::create_profile,
profiles::types::ProfileCreateData,
users::queries::create_user,
users::types::UserCreateData,
};
use super::*;
#[tokio::test]
#[serial]
async fn test_create_invoice() {
let db_client = &mut create_test_database().await;
let sender_data = ProfileCreateData {
username: "sender".to_string(),
..Default::default()
};
let sender = create_profile(db_client, sender_data).await.unwrap();
let recipient_data = UserCreateData {
username: "recipient".to_string(),
..Default::default()
};
let recipient = create_user(db_client, recipient_data).await.unwrap();
let chain_id = ChainId {
namespace: "monero".to_string(),
reference: "mainnet".to_string(),
};
let payment_address = "8MxABajuo71BZya9";
let invoice = create_invoice(
db_client,
&sender.id,
&recipient.id,
&chain_id,
payment_address,
).await.unwrap();
assert_eq!(invoice.sender_id, sender.id);
assert_eq!(invoice.recipient_id, recipient.id);
assert_eq!(invoice.chain_id, chain_id);
assert_eq!(invoice.payment_address, payment_address);
assert!(matches!(invoice.invoice_status, InvoiceStatus::Open));
}
}

View file

@ -0,0 +1,55 @@
use std::convert::TryFrom;
use chrono::{DateTime, Utc};
use postgres_types::FromSql;
use uuid::Uuid;
use crate::database::int_enum::{int_enum_from_sql, int_enum_to_sql};
use crate::errors::ConversionError;
use crate::utils::caip2::ChainId;
#[derive(Debug)]
pub enum InvoiceStatus {
Open,
Paid,
Forwarded,
}
impl From<&InvoiceStatus> for i16 {
fn from(value: &InvoiceStatus) -> i16 {
match value {
InvoiceStatus::Open => 1,
InvoiceStatus::Paid => 2,
InvoiceStatus::Forwarded => 3,
}
}
}
impl TryFrom<i16> for InvoiceStatus {
type Error = ConversionError;
fn try_from(value: i16) -> Result<Self, Self::Error> {
let invoice_status = match value {
1 => Self::Open,
2 => Self::Paid,
3 => Self::Forwarded,
_ => return Err(ConversionError),
};
Ok(invoice_status)
}
}
int_enum_from_sql!(InvoiceStatus);
int_enum_to_sql!(InvoiceStatus);
#[derive(FromSql)]
#[postgres(name = "invoice")]
pub struct DbInvoice {
pub id: Uuid,
pub sender_id: Uuid,
pub recipient_id: Uuid,
pub chain_id: ChainId,
pub payment_address: String,
pub invoice_status: InvoiceStatus,
pub created_at: DateTime<Utc>,
}

View file

@ -1,5 +1,6 @@
pub mod attachments;
pub mod cleanup;
pub mod invoices;
pub mod markers;
pub mod notifications;
pub mod oauth;