Compare commits
2 Commits
de38e20d3a
...
7a58035d0c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a58035d0c | ||
|
|
3fa7649877 |
@@ -2,8 +2,8 @@
|
|||||||
# see https://diesel.rs/guides/configuring-diesel-cli
|
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||||
|
|
||||||
[print_schema]
|
[print_schema]
|
||||||
file = "src/schema.rs"
|
file = "src/model/schema.rs"
|
||||||
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
||||||
|
|
||||||
[migrations_directory]
|
[migrations_directory]
|
||||||
dir = "/data/codes/helios-server-rs/migrations"
|
dir = "./migrations"
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ DROP TABLE IF EXISTS "transactions";
|
|||||||
DROP TABLE IF EXISTS "transaction_tag_rels";
|
DROP TABLE IF EXISTS "transaction_tag_rels";
|
||||||
DROP TABLE IF EXISTS "accounts";
|
DROP TABLE IF EXISTS "accounts";
|
||||||
DROP TABLE IF EXISTS "amounts";
|
DROP TABLE IF EXISTS "amounts";
|
||||||
|
|
||||||
DROP TABLE IF EXISTS "users";
|
DROP TABLE IF EXISTS "users";
|
||||||
|
DROP TABLE IF EXISTS "operations";
|
||||||
|
DROP TABLE IF EXISTS "operation_snapshots";
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
-- Your SQL goes here
|
-- Your SQL goes here
|
||||||
-- Your SQL goes here
|
|
||||||
CREATE TABLE "categories" (
|
CREATE TABLE "categories" (
|
||||||
"id" BIGSERIAL PRIMARY KEY,
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
"uid" BIGINT NOT NULL,
|
"uid" BIGINT NOT NULL,
|
||||||
@@ -7,6 +6,7 @@ CREATE TABLE "categories" (
|
|||||||
"name" TEXT NOT NULL,
|
"name" TEXT NOT NULL,
|
||||||
"level" INT NOT NULL DEFAULT 0,
|
"level" INT NOT NULL DEFAULT 0,
|
||||||
"parent_category_id" BIGINT NOT NULL DEFAULT 0,
|
"parent_category_id" BIGINT NOT NULL DEFAULT 0,
|
||||||
|
"op_id" BIGINT NOT NULL DEFAULT 0,
|
||||||
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
@@ -19,6 +19,7 @@ CREATE TABLE "tags" (
|
|||||||
"name" TEXT NOT NULL,
|
"name" TEXT NOT NULL,
|
||||||
"level" INT NOT NULL DEFAULT 0,
|
"level" INT NOT NULL DEFAULT 0,
|
||||||
"parent_tag_id" BIGINT NOT NULL DEFAULT 0,
|
"parent_tag_id" BIGINT NOT NULL DEFAULT 0,
|
||||||
|
"op_id" BIGINT NOT NULL DEFAULT 0,
|
||||||
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
@@ -28,6 +29,7 @@ CREATE TABLE "books" (
|
|||||||
"id" BIGSERIAL PRIMARY KEY,
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
"uid" BIGINT NOT NULL,
|
"uid" BIGINT NOT NULL,
|
||||||
"name" TEXT NOT NULL,
|
"name" TEXT NOT NULL,
|
||||||
|
"op_id" BIGINT NOT NULL DEFAULT 0,
|
||||||
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
@@ -39,6 +41,7 @@ CREATE TABLE "transactions" (
|
|||||||
"book_id" BIGINT NOT NULL,
|
"book_id" BIGINT NOT NULL,
|
||||||
"description" TEXT NOT NULL,
|
"description" TEXT NOT NULL,
|
||||||
"category_id" BIGINT NOT NULL,
|
"category_id" BIGINT NOT NULL,
|
||||||
|
"op_id" BIGINT NOT NULL DEFAULT 0,
|
||||||
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
"time" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT current_timestamp,
|
"time" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT current_timestamp,
|
||||||
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
@@ -50,6 +53,7 @@ CREATE TABLE "transaction_tag_rels" (
|
|||||||
"uid" BIGINT NOT NULL,
|
"uid" BIGINT NOT NULL,
|
||||||
"transaction_id" BIGINT NOT NULL,
|
"transaction_id" BIGINT NOT NULL,
|
||||||
"tag_id" BIGINT NOT NULL,
|
"tag_id" BIGINT NOT NULL,
|
||||||
|
"op_id" BIGINT NOT NULL DEFAULT 0,
|
||||||
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
@@ -60,6 +64,7 @@ CREATE TABLE "accounts" (
|
|||||||
"uid" BIGINT NOT NULL,
|
"uid" BIGINT NOT NULL,
|
||||||
"name" TEXT NOT NULL,
|
"name" TEXT NOT NULL,
|
||||||
"account_type" BIGINT NOT NULL DEFAULT 0,
|
"account_type" BIGINT NOT NULL DEFAULT 0,
|
||||||
|
"op_id" BIGINT NOT NULL DEFAULT 0,
|
||||||
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
@@ -73,6 +78,7 @@ CREATE TABLE "amounts" (
|
|||||||
"value" BIGINT NOT NULL DEFAULT 0,
|
"value" BIGINT NOT NULL DEFAULT 0,
|
||||||
"expo" BIGINT NOT NULL DEFAULT 5,
|
"expo" BIGINT NOT NULL DEFAULT 5,
|
||||||
"currency" TEXT NOT NULL DEFAULT '',
|
"currency" TEXT NOT NULL DEFAULT '',
|
||||||
|
"op_id" BIGINT NOT NULL DEFAULT 0,
|
||||||
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
"is_delete" BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
@@ -87,3 +93,20 @@ CREATE TABLE "users" (
|
|||||||
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "operations" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
|
"uid" BIGINT NOT NULL,
|
||||||
|
"entity_type" BIGINT NOT NULL,
|
||||||
|
"entity_id" BIGINT NOT NULL,
|
||||||
|
"action" BIGINT NOT NULL,
|
||||||
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp,
|
||||||
|
"update_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE "operation_snapshots" (
|
||||||
|
"id" BIGSERIAL PRIMARY KEY,
|
||||||
|
"uid" BIGINT NOT NULL,
|
||||||
|
"max_op_id" BIGINT NOT NULL,
|
||||||
|
"create_at" TIMESTAMP NOT NULL DEFAULT current_timestamp
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::sync::Arc;
|
||||||
// use std::sync::Arc;
|
// use std::sync::Arc;
|
||||||
use axum::routing::{get, post};
|
use axum::routing::{get, post};
|
||||||
use axum::{
|
use axum::{
|
||||||
@@ -19,15 +22,13 @@ use chrono::prelude::*;
|
|||||||
use tracing::info;
|
use tracing::info;
|
||||||
use crate::middleware::auth;
|
use crate::middleware::auth;
|
||||||
use crate::middleware::auth::Claims;
|
use crate::middleware::auth::Claims;
|
||||||
|
use crate::model::db_model::Category;
|
||||||
|
use crate::util::operation::{
|
||||||
|
EntityType, ENTITY_CATEGORY,
|
||||||
|
ActionType, ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct CreateCategoryResponse {
|
|
||||||
id: i64,
|
|
||||||
name: String,
|
|
||||||
level: i32,
|
|
||||||
parent_category_id: i64,
|
|
||||||
book_id: i64,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_nest_handlers() -> Router<crate::AppState> {
|
pub fn get_nest_handlers() -> Router<crate::AppState> {
|
||||||
Router::new()
|
Router::new()
|
||||||
@@ -43,12 +44,17 @@ pub struct CreateCategoryRequest {
|
|||||||
book_id: i64,
|
book_id: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct CreateCategoryResponse {
|
||||||
|
id: i64,
|
||||||
|
}
|
||||||
|
|
||||||
#[debug_handler]
|
#[debug_handler]
|
||||||
pub async fn create_category(
|
pub async fn create_category(
|
||||||
State(app_state): State<crate::AppState>,
|
State(app_state): State<crate::AppState>,
|
||||||
claims: Claims,
|
claims: Claims,
|
||||||
Json(payload): Json<CreateCategoryRequest>,
|
Json(payload): Json<CreateCategoryRequest>,
|
||||||
) -> Result<Json<db_model::Category>, (StatusCode, String)> {
|
) -> Result<Json<CreateCategoryResponse>, (StatusCode, String)> {
|
||||||
let uid: i64 = claims.uid.clone(); // TODO replace with actual user id.
|
let uid: i64 = claims.uid.clone(); // TODO replace with actual user id.
|
||||||
// let ret = CreateCategoryResponse{id: 134132413541, name: "24532452".to_string()};
|
// let ret = CreateCategoryResponse{id: 134132413541, name: "24532452".to_string()};
|
||||||
let conn = app_state
|
let conn = app_state
|
||||||
@@ -63,18 +69,48 @@ pub async fn create_category(
|
|||||||
parent_category_id: payload.parent_category_id,
|
parent_category_id: payload.parent_category_id,
|
||||||
book_id: payload.book_id,
|
book_id: payload.book_id,
|
||||||
};
|
};
|
||||||
let res = conn
|
let new_operation = db_model::CreateOperation{
|
||||||
|
uid: uid,
|
||||||
|
entity_type: ENTITY_CATEGORY,
|
||||||
|
entity_id: 0,
|
||||||
|
action: ACTION_CREATE,
|
||||||
|
};
|
||||||
|
let mut create_response = CreateCategoryResponse{
|
||||||
|
id: 0,
|
||||||
|
};
|
||||||
|
let cuid = uid;
|
||||||
|
conn
|
||||||
.interact(move |conn| {
|
.interact(move |conn| {
|
||||||
diesel::insert_into(schema::categories::table)
|
conn.transaction(|conn| {
|
||||||
|
let category = diesel::insert_into(schema::categories::table)
|
||||||
.values(&new_category)
|
.values(&new_category)
|
||||||
.returning(db_model::Category::as_returning())
|
.returning(db_model::Category::as_returning())
|
||||||
.get_result(conn)
|
.get_result(conn)?;
|
||||||
|
let operation = diesel::insert_into(schema::operations::table)
|
||||||
|
.values(&new_operation)
|
||||||
|
.returning(db_model::Operation::as_returning())
|
||||||
|
.get_result(conn)?;
|
||||||
|
diesel::update(schema::categories::table)
|
||||||
|
.filter(schema::categories::id.eq(category.id))
|
||||||
|
.filter(schema::categories::uid.eq(cuid))
|
||||||
|
.set((schema::categories::op_id.eq(operation.id)))
|
||||||
|
.execute(conn)?;
|
||||||
|
diesel::update(schema::operations::table)
|
||||||
|
.filter(schema::operations::id.eq(operation.id))
|
||||||
|
.filter(schema::operations::uid.eq(cuid))
|
||||||
|
.set((schema::operations::entity_id.eq(category.id)))
|
||||||
|
.execute(conn)?;
|
||||||
|
diesel::result::QueryResult::Ok(())
|
||||||
|
})
|
||||||
|
// diesel::insert_into(schema::categories::table)
|
||||||
|
// .values(&new_category)
|
||||||
|
// .returning(db_model::Category::as_returning())
|
||||||
|
// .get_result(conn)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.map_err(util::req::internal_error)?
|
.map_err(util::req::internal_error)?
|
||||||
.map_err(util::req::internal_error)?;
|
.map_err(util::req::internal_error)?;
|
||||||
// let ret = CreateCategoryResponse{id: res.id, name: res.name};
|
Ok(Json(create_response))
|
||||||
Ok(Json(res))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_category(
|
pub async fn update_category(
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ pub mod tag;
|
|||||||
pub mod book;
|
pub mod book;
|
||||||
pub mod account;
|
pub mod account;
|
||||||
pub mod transaction;
|
pub mod transaction;
|
||||||
|
pub mod operation;
|
||||||
|
|||||||
111
src/ledger/operation.rs
Normal file
111
src/ledger/operation.rs
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
use diesel::prelude::*;
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use axum::{extract::{Path, State, Query}, http::StatusCode, Json, Router};
|
||||||
|
use axum::routing::get;
|
||||||
|
use diesel::dsl::max;
|
||||||
|
use crate::model::{db_model, schema};
|
||||||
|
use crate::middleware::auth::Claims;
|
||||||
|
use crate::model::db_model::Operation;
|
||||||
|
use crate::model::schema::operation_snapshots::max_op_id;
|
||||||
|
use crate::util;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct GetOperationsResponse {
|
||||||
|
start: i64,
|
||||||
|
end: i64,
|
||||||
|
total: i64,
|
||||||
|
operations: Vec<db_model::Operation>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct GetOperationsParam {
|
||||||
|
start: i64,
|
||||||
|
limit: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_nest_handlers() -> Router<crate::AppState> {
|
||||||
|
Router::new()
|
||||||
|
.route("/", get(get_operations))
|
||||||
|
}
|
||||||
|
|
||||||
|
// get_single_operation
|
||||||
|
|
||||||
|
pub async fn get_operations(
|
||||||
|
query_param: Query<GetOperationsParam>,
|
||||||
|
State(app_state): State<crate::AppState>,
|
||||||
|
claims: Claims,
|
||||||
|
) -> Result<Json<GetOperationsResponse>, (StatusCode, String)> {
|
||||||
|
let uid: i64 = claims.uid.clone();
|
||||||
|
let start: i64 = match query_param.start {
|
||||||
|
..0 => 0,
|
||||||
|
_ => query_param.start
|
||||||
|
};
|
||||||
|
let limit: i32 = match query_param.limit {
|
||||||
|
..0 => 0,
|
||||||
|
crate::model::req::MAX_QUERY_LIMIT.. => crate::model::req::MAX_QUERY_LIMIT,
|
||||||
|
_ => query_param.limit
|
||||||
|
};
|
||||||
|
let conn = app_state
|
||||||
|
.db
|
||||||
|
.get()
|
||||||
|
.await
|
||||||
|
.map_err(util::req::internal_error)?;
|
||||||
|
let mut res = conn
|
||||||
|
.interact(move |conn| {
|
||||||
|
schema::operations::table
|
||||||
|
.filter(schema::operations::uid.eq(uid))
|
||||||
|
.filter(schema::operations::id.ge(start))
|
||||||
|
.limit(limit as i64)
|
||||||
|
.select(Operation::as_select())
|
||||||
|
.load(conn)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(util::req::internal_error)?
|
||||||
|
.map_err(util::req::internal_error)?;
|
||||||
|
res.sort_by(|a,b| a.id.cmp(&b.id));
|
||||||
|
let res_start: i64 = match res.first() {
|
||||||
|
Some(r) => r.id,
|
||||||
|
None => 0,
|
||||||
|
};
|
||||||
|
let res_end = match res.last() {
|
||||||
|
Some(r) => r.id,
|
||||||
|
None => 0,
|
||||||
|
};
|
||||||
|
let resp = GetOperationsResponse{
|
||||||
|
start: res_start,
|
||||||
|
end: res_end,
|
||||||
|
total: res.len() as i64,
|
||||||
|
operations: res,
|
||||||
|
};
|
||||||
|
Ok(Json(resp))
|
||||||
|
// Ok(Json(res))
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GetOperationSnapshotResponse {
|
||||||
|
max_op_id: i64,
|
||||||
|
}
|
||||||
|
pub async fn get_operation_snapshot(
|
||||||
|
State(app_state): State<crate::AppState>,
|
||||||
|
claims: Claims,
|
||||||
|
) -> Result<Json<GetOperationSnapshotResponse>, (StatusCode, String)> {
|
||||||
|
let uid: i64 = claims.uid.clone();
|
||||||
|
let conn = app_state
|
||||||
|
.db
|
||||||
|
.get()
|
||||||
|
.await
|
||||||
|
.map_err(util::req::internal_error)?;
|
||||||
|
let res = conn.interact(move |conn| {
|
||||||
|
schema::operation_snapshots::table
|
||||||
|
.filter(schema::operation_snapshots::uid.eq(uid))
|
||||||
|
.select(max(schema::operation_snapshots::max_op_id))
|
||||||
|
.limit(1)
|
||||||
|
.get_result(conn)
|
||||||
|
.map(|x| x as i64)
|
||||||
|
}).await
|
||||||
|
.map_err(util::req::internal_error)?
|
||||||
|
.map_err(util::req::internal_error)?;
|
||||||
|
let resp = GetOperationSnapshotResponse{
|
||||||
|
max_op_id: res,
|
||||||
|
};
|
||||||
|
Ok(Json(resp))
|
||||||
|
}
|
||||||
@@ -97,6 +97,7 @@ async fn main() {
|
|||||||
.nest("/api/v1/account", ledger::account::get_nest_handlers())
|
.nest("/api/v1/account", ledger::account::get_nest_handlers())
|
||||||
.nest("/api/v1/transaction", ledger::transaction::get_nest_handlers())
|
.nest("/api/v1/transaction", ledger::transaction::get_nest_handlers())
|
||||||
.nest("/api/v1/user", user::handler::get_nest_handlers())
|
.nest("/api/v1/user", user::handler::get_nest_handlers())
|
||||||
|
.nest("/api/v1/operation", ledger::operation::get_nest_handlers())
|
||||||
.with_state(shared_state)
|
.with_state(shared_state)
|
||||||
.layer(global_layer);
|
.layer(global_layer);
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,20 @@
|
|||||||
use crate::model::schema;
|
use crate::model::schema;
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
|
use crate::model::schema::operations::entity_id;
|
||||||
|
|
||||||
#[derive(Queryable, Selectable, serde::Serialize, serde::Deserialize)]
|
#[derive(Queryable, Selectable, serde::Serialize, serde::Deserialize)]
|
||||||
#[diesel(table_name = schema::categories)]
|
#[diesel(table_name = schema::categories)]
|
||||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||||
pub struct Category {
|
pub struct Category {
|
||||||
#[serde(with = "string")]
|
#[serde(with = "string")]
|
||||||
id: i64,
|
pub id: i64,
|
||||||
uid: i64,
|
uid: i64,
|
||||||
name: String,
|
name: String,
|
||||||
level: i32,
|
level: i32,
|
||||||
parent_category_id: i64,
|
parent_category_id: i64,
|
||||||
book_id: i64,
|
book_id: i64,
|
||||||
|
op_id: i64,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
is_delete: bool,
|
is_delete: bool,
|
||||||
create_at: chrono::NaiveDateTime,
|
create_at: chrono::NaiveDateTime,
|
||||||
@@ -39,6 +41,7 @@ pub struct Tag {
|
|||||||
name: String,
|
name: String,
|
||||||
level: i32,
|
level: i32,
|
||||||
parent_tag_id: i64,
|
parent_tag_id: i64,
|
||||||
|
op_id: i64,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
is_delete: bool,
|
is_delete: bool,
|
||||||
create_at: chrono::NaiveDateTime,
|
create_at: chrono::NaiveDateTime,
|
||||||
@@ -63,6 +66,7 @@ pub struct Book {
|
|||||||
id: i64,
|
id: i64,
|
||||||
uid: i64,
|
uid: i64,
|
||||||
name: String,
|
name: String,
|
||||||
|
op_id: i64,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
is_delete: bool,
|
is_delete: bool,
|
||||||
create_at: chrono::NaiveDateTime,
|
create_at: chrono::NaiveDateTime,
|
||||||
@@ -84,6 +88,7 @@ pub struct Account {
|
|||||||
uid: i64,
|
uid: i64,
|
||||||
name: String,
|
name: String,
|
||||||
account_type: i64,
|
account_type: i64,
|
||||||
|
op_id: i64,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
is_delete: bool,
|
is_delete: bool,
|
||||||
create_at: chrono::NaiveDateTime,
|
create_at: chrono::NaiveDateTime,
|
||||||
@@ -111,6 +116,7 @@ pub struct Transaction {
|
|||||||
#[serde(with = "string")]
|
#[serde(with = "string")]
|
||||||
pub category_id: i64,
|
pub category_id: i64,
|
||||||
pub time: chrono::DateTime<Utc>,
|
pub time: chrono::DateTime<Utc>,
|
||||||
|
pub op_id: i64,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
is_delete: bool,
|
is_delete: bool,
|
||||||
create_at: chrono::NaiveDateTime,
|
create_at: chrono::NaiveDateTime,
|
||||||
@@ -139,6 +145,7 @@ pub struct Amount {
|
|||||||
value: i64,
|
value: i64,
|
||||||
expo: i64,
|
expo: i64,
|
||||||
currency: String,
|
currency: String,
|
||||||
|
pub op_id: i64,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
is_delete: bool,
|
is_delete: bool,
|
||||||
create_at: chrono::NaiveDateTime,
|
create_at: chrono::NaiveDateTime,
|
||||||
@@ -175,6 +182,26 @@ pub struct UserForm {
|
|||||||
pub mail: String,
|
pub mail: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable,Queryable, Selectable, serde::Serialize)]
|
||||||
|
#[diesel(table_name = schema::operations)]
|
||||||
|
pub struct Operation {
|
||||||
|
pub id: i64,
|
||||||
|
pub uid: i64,
|
||||||
|
pub entity_type: i64,
|
||||||
|
pub entity_id: i64,
|
||||||
|
pub action: i64,
|
||||||
|
create_at: chrono::NaiveDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Insertable)]
|
||||||
|
#[diesel(table_name = schema::operations)]
|
||||||
|
pub struct CreateOperation {
|
||||||
|
pub uid: i64,
|
||||||
|
pub entity_type: i64,
|
||||||
|
pub entity_id: i64,
|
||||||
|
pub action: i64,
|
||||||
|
}
|
||||||
|
|
||||||
mod string {
|
mod string {
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ diesel::table! {
|
|||||||
uid -> Int8,
|
uid -> Int8,
|
||||||
name -> Text,
|
name -> Text,
|
||||||
account_type -> Int8,
|
account_type -> Int8,
|
||||||
|
op_id -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -21,6 +22,7 @@ diesel::table! {
|
|||||||
value -> Int8,
|
value -> Int8,
|
||||||
expo -> Int8,
|
expo -> Int8,
|
||||||
currency -> Text,
|
currency -> Text,
|
||||||
|
op_id -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -32,6 +34,7 @@ diesel::table! {
|
|||||||
id -> Int8,
|
id -> Int8,
|
||||||
uid -> Int8,
|
uid -> Int8,
|
||||||
name -> Text,
|
name -> Text,
|
||||||
|
op_id -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -46,12 +49,34 @@ diesel::table! {
|
|||||||
name -> Text,
|
name -> Text,
|
||||||
level -> Int4,
|
level -> Int4,
|
||||||
parent_category_id -> Int8,
|
parent_category_id -> Int8,
|
||||||
|
op_id -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
operation_snapshots (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
max_op_id -> Int8,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
operations (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
entity_type -> Int8,
|
||||||
|
entity_id -> Int8,
|
||||||
|
action -> Int8,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
tags (id) {
|
tags (id) {
|
||||||
id -> Int8,
|
id -> Int8,
|
||||||
@@ -60,6 +85,7 @@ diesel::table! {
|
|||||||
name -> Text,
|
name -> Text,
|
||||||
level -> Int4,
|
level -> Int4,
|
||||||
parent_tag_id -> Int8,
|
parent_tag_id -> Int8,
|
||||||
|
op_id -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -72,6 +98,7 @@ diesel::table! {
|
|||||||
uid -> Int8,
|
uid -> Int8,
|
||||||
transaction_id -> Int8,
|
transaction_id -> Int8,
|
||||||
tag_id -> Int8,
|
tag_id -> Int8,
|
||||||
|
op_id -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -85,6 +112,7 @@ diesel::table! {
|
|||||||
book_id -> Int8,
|
book_id -> Int8,
|
||||||
description -> Text,
|
description -> Text,
|
||||||
category_id -> Int8,
|
category_id -> Int8,
|
||||||
|
op_id -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
time -> Timestamptz,
|
time -> Timestamptz,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
@@ -109,6 +137,8 @@ diesel::allow_tables_to_appear_in_same_query!(
|
|||||||
amounts,
|
amounts,
|
||||||
books,
|
books,
|
||||||
categories,
|
categories,
|
||||||
|
operation_snapshots,
|
||||||
|
operations,
|
||||||
tags,
|
tags,
|
||||||
transaction_tag_rels,
|
transaction_tag_rels,
|
||||||
transactions,
|
transactions,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ diesel::table! {
|
|||||||
uid -> Int8,
|
uid -> Int8,
|
||||||
name -> Text,
|
name -> Text,
|
||||||
account_type -> Int8,
|
account_type -> Int8,
|
||||||
|
version_v1 -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -21,6 +22,7 @@ diesel::table! {
|
|||||||
value -> Int8,
|
value -> Int8,
|
||||||
expo -> Int8,
|
expo -> Int8,
|
||||||
currency -> Text,
|
currency -> Text,
|
||||||
|
version_v1 -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -32,6 +34,7 @@ diesel::table! {
|
|||||||
id -> Int8,
|
id -> Int8,
|
||||||
uid -> Int8,
|
uid -> Int8,
|
||||||
name -> Text,
|
name -> Text,
|
||||||
|
version_v1 -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -46,6 +49,7 @@ diesel::table! {
|
|||||||
name -> Text,
|
name -> Text,
|
||||||
level -> Int4,
|
level -> Int4,
|
||||||
parent_category_id -> Int8,
|
parent_category_id -> Int8,
|
||||||
|
version_v1 -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -60,6 +64,7 @@ diesel::table! {
|
|||||||
name -> Text,
|
name -> Text,
|
||||||
level -> Int4,
|
level -> Int4,
|
||||||
parent_tag_id -> Int8,
|
parent_tag_id -> Int8,
|
||||||
|
version_v1 -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -72,6 +77,7 @@ diesel::table! {
|
|||||||
uid -> Int8,
|
uid -> Int8,
|
||||||
transaction_id -> Int8,
|
transaction_id -> Int8,
|
||||||
tag_id -> Int8,
|
tag_id -> Int8,
|
||||||
|
version_v1 -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
update_at -> Timestamp,
|
update_at -> Timestamp,
|
||||||
@@ -85,6 +91,7 @@ diesel::table! {
|
|||||||
book_id -> Int8,
|
book_id -> Int8,
|
||||||
description -> Text,
|
description -> Text,
|
||||||
category_id -> Int8,
|
category_id -> Int8,
|
||||||
|
version_v1 -> Int8,
|
||||||
is_delete -> Bool,
|
is_delete -> Bool,
|
||||||
time -> Timestamptz,
|
time -> Timestamptz,
|
||||||
create_at -> Timestamp,
|
create_at -> Timestamp,
|
||||||
@@ -104,6 +111,18 @@ diesel::table! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
versions_v1 (id) {
|
||||||
|
id -> Int8,
|
||||||
|
uid -> Int8,
|
||||||
|
entity_type -> Int8,
|
||||||
|
entity_id -> Int8,
|
||||||
|
action -> Int8,
|
||||||
|
create_at -> Timestamp,
|
||||||
|
update_at -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
diesel::allow_tables_to_appear_in_same_query!(
|
diesel::allow_tables_to_appear_in_same_query!(
|
||||||
accounts,
|
accounts,
|
||||||
amounts,
|
amounts,
|
||||||
@@ -113,4 +132,5 @@ diesel::allow_tables_to_appear_in_same_query!(
|
|||||||
transaction_tag_rels,
|
transaction_tag_rels,
|
||||||
transactions,
|
transactions,
|
||||||
users,
|
users,
|
||||||
|
versions_v1,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
pub mod req;
|
pub mod req;
|
||||||
pub mod pass;
|
pub mod pass;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
|
pub mod operation;
|
||||||
|
|||||||
16
src/util/operation.rs
Normal file
16
src/util/operation.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
pub type EntityType = i64;
|
||||||
|
|
||||||
|
pub const ENTITY_CATEGORY: EntityType = 1;
|
||||||
|
pub const ENTITY_TAG: EntityType = 2;
|
||||||
|
pub const ENTITY_BOOK: EntityType = 3;
|
||||||
|
pub const ENTITY_ACCOUNT: EntityType = 4;
|
||||||
|
pub const ENTITY_TRANSACTION: EntityType = 5;
|
||||||
|
pub const ENTITY_AMOUNT: EntityType = 6;
|
||||||
|
|
||||||
|
|
||||||
|
pub type ActionType = i64;
|
||||||
|
|
||||||
|
pub const ACTION_CREATE: ActionType = 1;
|
||||||
|
pub const ACTION_UPDATE: ActionType = 2;
|
||||||
|
pub const ACTION_DELETE: ActionType = 3;
|
||||||
Reference in New Issue
Block a user