Merge pull request #22 from exstake/add-mutations-to-exchange-painel

add mutations to exchange painel
This commit is contained in:
João Geonizeli
2021-08-15 23:32:12 -03:00
committed by GitHub
29 changed files with 702 additions and 198 deletions

View File

@@ -12,6 +12,7 @@ class FiatBalanceDashboard < Administrate::BaseDashboard
id: Field::Number, id: Field::Number,
user: Field::BelongsTo, user: Field::BelongsTo,
amount_formatted: Field::String, amount_formatted: Field::String,
amount_cents: Field::String,
created_at: Field::DateTime, created_at: Field::DateTime,
updated_at: Field::DateTime, updated_at: Field::DateTime,
}.freeze }.freeze
@@ -30,7 +31,7 @@ class FiatBalanceDashboard < Administrate::BaseDashboard
# FORM_ATTRIBUTES # FORM_ATTRIBUTES
# an array of attributes that will be displayed # an array of attributes that will be displayed
# on the model's form (`new` and `edit`) pages. # on the model's form (`new` and `edit`) pages.
FORM_ATTRIBUTES = [:user, :amount_formatted].freeze FORM_ATTRIBUTES = [:user, :amount_cents].freeze
# COLLECTION_FILTERS # COLLECTION_FILTERS
# a hash that defines filters that can be used while searching via the search # a hash that defines filters that can be used while searching via the search

View File

@@ -9,7 +9,9 @@ module Mutations
currency_id = decode_id(order[:currency_id]) currency_id = decode_id(order[:currency_id])
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
current_user.fiat_balance.withdrawal!(order[:amount_cents]) current_user
.fiat_balance
.withdrawal!(order[:amount_cents])
record = BuyCryptoOrder.create!( record = BuyCryptoOrder.create!(
paid_amount_cents: order[:amount_cents], paid_amount_cents: order[:amount_cents],

View File

@@ -10,10 +10,12 @@ module Mutations
amount = BigDecimal(order[:amount]) amount = BigDecimal(order[:amount])
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
current_user.balances.find_by!(currency_id: currency_id) current_user
.balances
.find_by!(currency_id: currency_id)
.withdrawal!(amount) .withdrawal!(amount)
record = SellCryptoOrder.create( record = SellCryptoOrder.create!(
paid_amount: amount, paid_amount: amount,
currency_id: currency_id, currency_id: currency_id,
user_id: current_user.id, user_id: current_user.id,

View File

@@ -42,7 +42,7 @@ export const Pool = ({ pool }: PoolProps) => {
rewardTokenPrice: earningPrice, rewardTokenPrice: earningPrice,
stakingTokenPrice: stakingPrice, stakingTokenPrice: stakingPrice,
tokenPerBlock: parseFloat(pool.tokenPerBlock) / 1e-18, tokenPerBlock: parseFloat(pool.tokenPerBlock) / 1e-18,
totalStaked: totalStaked, totalStaked,
}); });
if (aprValue) { if (aprValue) {

View File

@@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import { pools } from "../constants/Pools"; import { pools } from "../constants/Pools";
import { Pool } from "./Poo"; import { Pool } from "./Pool";
export const PoolListing = () => { export const PoolListing = () => {
return ( return (

View File

@@ -1 +0,0 @@
export * from "./CreateExchangeOrderModal";

View File

@@ -1,23 +1,21 @@
/* eslint-disable relay/must-colocate-fragment-spreads */ /* eslint-disable relay/must-colocate-fragment-spreads */
import { graphql } from "babel-plugin-relay/macro"; import { graphql } from "babel-plugin-relay/macro";
import React, { useState } from "react"; import React from "react";
import { useLazyLoadQuery } from "react-relay"; import { useLazyLoadQuery } from "react-relay";
import { CreateExchangeOrderModal } from "./CreateExchangeOrderModel"; import { ExchangePanel } from "./ExchangePanel";
import { ExchangeHistory } from "./ExchangeHistory"; import { ExchangeHistory } from "./ExchangeHistory";
import type { ExchangeQuery } from "./__generated__/ExchangeQuery.graphql"; import type { ExchangeQuery } from "./__generated__/ExchangeQuery.graphql";
export const Exchange = () => { export const Exchange = () => {
const [modelOpen] = useState<boolean>(false);
const data = useLazyLoadQuery<ExchangeQuery>( const data = useLazyLoadQuery<ExchangeQuery>(
graphql` graphql`
query ExchangeQuery { query ExchangeQuery {
fiatBalances { fiatBalances {
...CreateExchangeOrderModal_fiatBalances ...ExchangePanel_fiatBalances
} }
balances { balances {
...CreateExchangeOrderModal_balances ...ExchangePanel_balances
} }
buyCryptoOrders { buyCryptoOrders {
...ExchangeHistory_buyCryptoOrders ...ExchangeHistory_buyCryptoOrders
@@ -32,16 +30,15 @@ export const Exchange = () => {
return ( return (
<div className="w-full"> <div className="w-full">
<ExchangePanel
balancesRefs={data.balances}
fiatBalancesRefs={data.fiatBalances}
/>
<ExchangeHistory <ExchangeHistory
sellCryptoOrdersRefs={data.sellCryptoOrders} sellCryptoOrdersRefs={data.sellCryptoOrders}
buyCryptoOrdersRefs={data.buyCryptoOrders} buyCryptoOrdersRefs={data.buyCryptoOrders}
/> />
{modelOpen && (
<CreateExchangeOrderModal
balancesRefs={data.balances}
fiatBalancesRefs={data.fiatBalances}
/>
)}
</div> </div>
); );
}; };

View File

@@ -83,8 +83,8 @@ export const ExchangeHistory: FC<Props> = ({
const allResultsOrdeneds = allResults.sort((item1, item2) => { const allResultsOrdeneds = allResults.sort((item1, item2) => {
return ( return (
new Date(item1.node.createdAt as string).getTime() - new Date(item2.node.createdAt as string).getTime() -
new Date(item2.node.createdAt as string).getTime() new Date(item1.node.createdAt as string).getTime()
); );
}) as SellOrBuyOrder[]; }) as SellOrBuyOrder[];
@@ -117,6 +117,8 @@ export const ExchangeHistory: FC<Props> = ({
return null; return null;
}); });
if (!orderRows.length) return null;
return ( return (
<div className="container mx-auto px-4 sm:px-8"> <div className="container mx-auto px-4 sm:px-8">
<div className="py-8"> <div className="py-8">

View File

@@ -1,14 +1,16 @@
import React, { useState } from "react"; import React, { useState } from "react";
import type { FC } from "react"; import type { FC } from "react";
import { graphql } from "babel-plugin-relay/macro"; import { graphql } from "babel-plugin-relay/macro";
import { useFragment } from "react-relay"; import { useFragment, useRelayEnvironment } from "react-relay";
import { BigNumber } from "bignumber.js"; import { BigNumber } from "bignumber.js";
import cx from "classnames"; import cx from "classnames";
import { useCurrentUser } from "../../../../contexts/UserProvider"; import { useCurrentUser } from "../../../../contexts/UserProvider";
import { Unauthenticated } from "../../../../messages/Unauthenticated"; import { Unauthenticated } from "../../../../messages/Unauthenticated";
import type { CreateExchangeOrderModal_fiatBalances$key } from "./__generated__/CreateExchangeOrderModal_fiatBalances.graphql"; import type { ExchangePanel_fiatBalances$key } from "./__generated__/ExchangePanel_fiatBalances.graphql";
import type { CreateExchangeOrderModal_balances$key } from "./__generated__/CreateExchangeOrderModal_balances.graphql"; import type { ExchangePanel_balances$key } from "./__generated__/ExchangePanel_balances.graphql";
import { commitCreateSellCryptoOrderMutation } from "./createSellCryptoOrder";
import { commitCreateBuyCryptoOrderMutation } from "./createBuyCryptoOrder";
const tabBaseStyles = const tabBaseStyles =
"w-full text-base font-bold text-black px-4 py-2 focus:ring-blue-500"; "w-full text-base font-bold text-black px-4 py-2 focus:ring-blue-500";
@@ -20,22 +22,23 @@ const inputBaseStyles =
"rounded-lg border-transparent flex-1 appearance-none border border-gray-300 w-full py-2 px-4 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-blue-600 focus:border-transparent mb-3"; "rounded-lg border-transparent flex-1 appearance-none border border-gray-300 w-full py-2 px-4 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-blue-600 focus:border-transparent mb-3";
type Props = { type Props = {
fiatBalancesRefs: CreateExchangeOrderModal_fiatBalances$key; fiatBalancesRefs: ExchangePanel_fiatBalances$key;
balancesRefs: CreateExchangeOrderModal_balances$key; balancesRefs: ExchangePanel_balances$key;
}; };
export const CreateExchangeOrderModal: FC<Props> = ({ export const ExchangePanel: FC<Props> = ({
fiatBalancesRefs, fiatBalancesRefs,
balancesRefs, balancesRefs,
}) => { }) => {
const { isAuthenticated } = useCurrentUser(); const { isAuthenticated } = useCurrentUser();
const environment = useRelayEnvironment();
const [exchangeOption, setExchangeOption] = useState<"BUY" | "SELL">("BUY"); const [exchangeOption, setExchangeOption] = useState<"BUY" | "SELL">("BUY");
const [cryptoDock, setCryptoDock] = useState<string>("0"); const [cryptoDock, setCryptoDock] = useState<string>("0");
const [fiatDock, setFiatDock] = useState<string>("0.00"); const [fiatDock, setFiatDock] = useState<string>("0.00");
const fiatBalances = useFragment<CreateExchangeOrderModal_fiatBalances$key>( const fiatBalances = useFragment<ExchangePanel_fiatBalances$key>(
graphql` graphql`
fragment CreateExchangeOrderModal_fiatBalances on FiatBalanceConnection { fragment ExchangePanel_fiatBalances on FiatBalanceConnection {
edges { edges {
node { node {
amountCents amountCents
@@ -46,12 +49,15 @@ export const CreateExchangeOrderModal: FC<Props> = ({
fiatBalancesRefs fiatBalancesRefs
); );
const balances = useFragment<CreateExchangeOrderModal_balances$key>( const balances = useFragment<ExchangePanel_balances$key>(
graphql` graphql`
fragment CreateExchangeOrderModal_balances on BalanceConnection { fragment ExchangePanel_balances on BalanceConnection {
edges { edges {
node { node {
amount amount
currency {
id
}
} }
} }
} }
@@ -60,6 +66,7 @@ export const CreateExchangeOrderModal: FC<Props> = ({
); );
if (!isAuthenticated) return <Unauthenticated />; if (!isAuthenticated) return <Unauthenticated />;
const [crypto] = balances.edges; const [crypto] = balances.edges;
const [fiat] = fiatBalances.edges; const [fiat] = fiatBalances.edges;
@@ -83,7 +90,10 @@ export const CreateExchangeOrderModal: FC<Props> = ({
}: React.ChangeEvent<HTMLInputElement>) => { }: React.ChangeEvent<HTMLInputElement>) => {
const newCryptoAmount = new BigNumber(value); const newCryptoAmount = new BigNumber(value);
if (newCryptoAmount.isLessThanOrEqualTo(avaliableCrypto)) { if (
newCryptoAmount.isLessThanOrEqualTo(avaliableCrypto) &&
newCryptoAmount.isGreaterThanOrEqualTo(0)
) {
setCryptoDock(value); setCryptoDock(value);
} }
}; };
@@ -91,9 +101,10 @@ export const CreateExchangeOrderModal: FC<Props> = ({
const handleFiatAmountChange = ({ const handleFiatAmountChange = ({
currentTarget: { value }, currentTarget: { value },
}: React.ChangeEvent<HTMLInputElement>) => { }: React.ChangeEvent<HTMLInputElement>) => {
const newFiatAmount = Number(value); const newFiatAmount = parseInt(value, 10);
const avaliableFiatAmount = parseInt(avaliableFiat, 10);
if (Number(avaliableFiat) >= newFiatAmount) { if (newFiatAmount <= avaliableFiatAmount && newFiatAmount >= 0) {
setFiatDock(value); setFiatDock(value);
} }
}; };
@@ -106,8 +117,33 @@ export const CreateExchangeOrderModal: FC<Props> = ({
setCryptoDock(avaliableCrypto.toString()); setCryptoDock(avaliableCrypto.toString());
}; };
const onSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (exchangeOption === "SELL") {
commitCreateSellCryptoOrderMutation(environment, {
amount: cryptoDock,
currencyId: crypto.node.currency.id,
});
}
if (exchangeOption === "BUY") {
const [amountCents] = fiatDock.split(".");
commitCreateBuyCryptoOrderMutation(environment, {
amountCents: parseInt(amountCents, 10),
currencyId: crypto.node.currency.id,
});
}
};
const submitDisabled =
(exchangeOption === "BUY" && parseInt(fiatDock, 10) <= 0) ||
(exchangeOption === "SELL" &&
new BigNumber(cryptoDock).isLessThanOrEqualTo(0));
return ( return (
<div className="max-w-lg"> <div className="max-w-lg mx-auto mt-16">
<div className="flex items-center bg-white rounded-full border border-gray-200 mb-3"> <div className="flex items-center bg-white rounded-full border border-gray-200 mb-3">
<button <button
type="button" type="button"
@@ -132,7 +168,10 @@ export const CreateExchangeOrderModal: FC<Props> = ({
Vender Vender
</button> </button>
</div> </div>
<form className="bg-white p-4 rounded-2xl border border-gray-200"> <form
onSubmit={onSubmit}
className="bg-white p-4 rounded-2xl border border-gray-200"
>
<span className="mb-2"> <span className="mb-2">
{exchangeOption === "SELL" ? "CAKE" : "BRL"} disponível:{" "} {exchangeOption === "SELL" ? "CAKE" : "BRL"} disponível:{" "}
{exchangeOption === "SELL" ? crypto.node.amount : avaliableFiat} {exchangeOption === "SELL" ? crypto.node.amount : avaliableFiat}
@@ -176,8 +215,9 @@ export const CreateExchangeOrderModal: FC<Props> = ({
</div> </div>
<button <button
className="cursor-pointer py-2 px-4 bg-blue-600 hover:bg-blue-700 focus:ring-blue-500 focus:ring-offset-blue-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg" className="cursor-pointer py-2 px-4 disabled:opacity-50 disabled:cursor-default bg-blue-600 hover:bg-blue-700 focus:ring-blue-500 focus:ring-offset-blue-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg"
type="submit" type="submit"
disabled={submitDisabled}
> >
{exchangeOption === "BUY" ? "Comprar" : "Vender"} CAKE {exchangeOption === "BUY" ? "Comprar" : "Vender"} CAKE
</button> </button>

View File

@@ -4,18 +4,21 @@
import { ReaderFragment } from "relay-runtime"; import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type CreateExchangeOrderModal_balances = { export type ExchangePanel_balances = {
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
readonly amount: string; readonly amount: string;
readonly currency: {
readonly id: string;
};
}; };
}>; }>;
readonly " $refType": "CreateExchangeOrderModal_balances"; readonly " $refType": "ExchangePanel_balances";
}; };
export type CreateExchangeOrderModal_balances$data = CreateExchangeOrderModal_balances; export type ExchangePanel_balances$data = ExchangePanel_balances;
export type CreateExchangeOrderModal_balances$key = { export type ExchangePanel_balances$key = {
readonly " $data"?: CreateExchangeOrderModal_balances$data; readonly " $data"?: ExchangePanel_balances$data;
readonly " $fragmentRefs": FragmentRefs<"CreateExchangeOrderModal_balances">; readonly " $fragmentRefs": FragmentRefs<"ExchangePanel_balances">;
}; };
@@ -24,7 +27,7 @@ const node: ReaderFragment = {
"argumentDefinitions": [], "argumentDefinitions": [],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "CreateExchangeOrderModal_balances", "name": "ExchangePanel_balances",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -48,6 +51,24 @@ const node: ReaderFragment = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "amount", "name": "amount",
"storageKey": null "storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
}
],
"storageKey": null
} }
], ],
"storageKey": null "storageKey": null
@@ -59,5 +80,5 @@ const node: ReaderFragment = {
"type": "BalanceConnection", "type": "BalanceConnection",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = '42aad1bd63f1135b4d99ec236cd945b5'; (node as any).hash = '3be851ad99a353609459a7edc960f272';
export default node; export default node;

View File

@@ -4,18 +4,18 @@
import { ReaderFragment } from "relay-runtime"; import { ReaderFragment } from "relay-runtime";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type CreateExchangeOrderModal_fiatBalances = { export type ExchangePanel_fiatBalances = {
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
readonly amountCents: number; readonly amountCents: number;
}; };
}>; }>;
readonly " $refType": "CreateExchangeOrderModal_fiatBalances"; readonly " $refType": "ExchangePanel_fiatBalances";
}; };
export type CreateExchangeOrderModal_fiatBalances$data = CreateExchangeOrderModal_fiatBalances; export type ExchangePanel_fiatBalances$data = ExchangePanel_fiatBalances;
export type CreateExchangeOrderModal_fiatBalances$key = { export type ExchangePanel_fiatBalances$key = {
readonly " $data"?: CreateExchangeOrderModal_fiatBalances$data; readonly " $data"?: ExchangePanel_fiatBalances$data;
readonly " $fragmentRefs": FragmentRefs<"CreateExchangeOrderModal_fiatBalances">; readonly " $fragmentRefs": FragmentRefs<"ExchangePanel_fiatBalances">;
}; };
@@ -24,7 +24,7 @@ const node: ReaderFragment = {
"argumentDefinitions": [], "argumentDefinitions": [],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "CreateExchangeOrderModal_fiatBalances", "name": "ExchangePanel_fiatBalances",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
@@ -59,5 +59,5 @@ const node: ReaderFragment = {
"type": "FiatBalanceConnection", "type": "FiatBalanceConnection",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = 'b3a734bd9e34e02aacfa42b6b95776a5'; (node as any).hash = '14b79d15c8353d856f3e74bb7c181cf7';
export default node; export default node;

View File

@@ -0,0 +1,160 @@
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from "relay-runtime";
export type createBuyCryptoOrderMutationVariables = {
currencyId: string;
amountCents: number;
};
export type createBuyCryptoOrderMutationResponse = {
readonly createBuyCryptoOrder: {
readonly errors: ReadonlyArray<{
readonly messages: ReadonlyArray<string> | null;
}> | null;
readonly order: {
readonly id: string;
} | null;
} | null;
};
export type createBuyCryptoOrderMutation = {
readonly response: createBuyCryptoOrderMutationResponse;
readonly variables: createBuyCryptoOrderMutationVariables;
};
/*
mutation createBuyCryptoOrderMutation(
$currencyId: ID!
$amountCents: Int!
) {
createBuyCryptoOrder(input: {order: {currencyId: $currencyId, amountCents: $amountCents}}) {
errors {
messages
}
order {
id
}
}
}
*/
const node: ConcreteRequest = (function(){
var v0 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "amountCents"
},
v1 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "currencyId"
},
v2 = [
{
"alias": null,
"args": [
{
"fields": [
{
"fields": [
{
"kind": "Variable",
"name": "amountCents",
"variableName": "amountCents"
},
{
"kind": "Variable",
"name": "currencyId",
"variableName": "currencyId"
}
],
"kind": "ObjectValue",
"name": "order"
}
],
"kind": "ObjectValue",
"name": "input"
}
],
"concreteType": "CreateBuyCryptoOrderPayload",
"kind": "LinkedField",
"name": "createBuyCryptoOrder",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "RecordInvalid",
"kind": "LinkedField",
"name": "errors",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "messages",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "BuyCryptoOrder",
"kind": "LinkedField",
"name": "order",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
];
return {
"fragment": {
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment",
"metadata": null,
"name": "createBuyCryptoOrderMutation",
"selections": (v2/*: any*/),
"type": "Mutation",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation",
"name": "createBuyCryptoOrderMutation",
"selections": (v2/*: any*/)
},
"params": {
"cacheID": "d7cc0c483d893b14f46781408d9d3f2f",
"id": null,
"metadata": {},
"name": "createBuyCryptoOrderMutation",
"operationKind": "mutation",
"text": "mutation createBuyCryptoOrderMutation(\n $currencyId: ID!\n $amountCents: Int!\n) {\n createBuyCryptoOrder(input: {order: {currencyId: $currencyId, amountCents: $amountCents}}) {\n errors {\n messages\n }\n order {\n id\n }\n }\n}\n"
}
};
})();
(node as any).hash = 'a272ce6d5ae676a9cdc4e38eb7cc3cbe';
export default node;

View File

@@ -0,0 +1,160 @@
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck
import { ConcreteRequest } from "relay-runtime";
export type createSellCryptoOrderMutationVariables = {
currencyId: string;
amount: string;
};
export type createSellCryptoOrderMutationResponse = {
readonly createSellCryptoOrder: {
readonly errors: ReadonlyArray<{
readonly messages: ReadonlyArray<string> | null;
}> | null;
readonly order: {
readonly id: string;
} | null;
} | null;
};
export type createSellCryptoOrderMutation = {
readonly response: createSellCryptoOrderMutationResponse;
readonly variables: createSellCryptoOrderMutationVariables;
};
/*
mutation createSellCryptoOrderMutation(
$currencyId: ID!
$amount: String!
) {
createSellCryptoOrder(input: {order: {currencyId: $currencyId, amount: $amount}}) {
errors {
messages
}
order {
id
}
}
}
*/
const node: ConcreteRequest = (function(){
var v0 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "amount"
},
v1 = {
"defaultValue": null,
"kind": "LocalArgument",
"name": "currencyId"
},
v2 = [
{
"alias": null,
"args": [
{
"fields": [
{
"fields": [
{
"kind": "Variable",
"name": "amount",
"variableName": "amount"
},
{
"kind": "Variable",
"name": "currencyId",
"variableName": "currencyId"
}
],
"kind": "ObjectValue",
"name": "order"
}
],
"kind": "ObjectValue",
"name": "input"
}
],
"concreteType": "CreateSellCryptoOrderPayload",
"kind": "LinkedField",
"name": "createSellCryptoOrder",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"concreteType": "RecordInvalid",
"kind": "LinkedField",
"name": "errors",
"plural": true,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "messages",
"storageKey": null
}
],
"storageKey": null
},
{
"alias": null,
"args": null,
"concreteType": "SellCryptoOrder",
"kind": "LinkedField",
"name": "order",
"plural": false,
"selections": [
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
}
],
"storageKey": null
}
],
"storageKey": null
}
];
return {
"fragment": {
"argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/)
],
"kind": "Fragment",
"metadata": null,
"name": "createSellCryptoOrderMutation",
"selections": (v2/*: any*/),
"type": "Mutation",
"abstractKey": null
},
"kind": "Request",
"operation": {
"argumentDefinitions": [
(v1/*: any*/),
(v0/*: any*/)
],
"kind": "Operation",
"name": "createSellCryptoOrderMutation",
"selections": (v2/*: any*/)
},
"params": {
"cacheID": "2c81ae5adf76b4fa157bc5453df40fcc",
"id": null,
"metadata": {},
"name": "createSellCryptoOrderMutation",
"operationKind": "mutation",
"text": "mutation createSellCryptoOrderMutation(\n $currencyId: ID!\n $amount: String!\n) {\n createSellCryptoOrder(input: {order: {currencyId: $currencyId, amount: $amount}}) {\n errors {\n messages\n }\n order {\n id\n }\n }\n}\n"
}
};
})();
(node as any).hash = '073e3f84d5921279ded3149dd9ec7db9';
export default node;

View File

@@ -0,0 +1,37 @@
import { graphql } from "babel-plugin-relay/macro";
import type { Environment } from "react-relay";
import { commitMutation } from "react-relay";
import type { createBuyCryptoOrderMutationVariables } from "./__generated__/createBuyCryptoOrderMutation.graphql";
export const commitCreateBuyCryptoOrderMutation = (
environment: Environment,
variables: createBuyCryptoOrderMutationVariables
) => {
return commitMutation(environment, {
mutation: graphql`
mutation createBuyCryptoOrderMutation(
$currencyId: ID!
$amountCents: Int!
) {
createBuyCryptoOrder(
input: {
order: { currencyId: $currencyId, amountCents: $amountCents }
}
) {
errors {
messages
}
order {
id
}
}
}
`,
variables: { ...variables },
onCompleted: (_response) => {
window.location.reload();
},
onError: (_error) => {},
});
};

View File

@@ -0,0 +1,35 @@
import { graphql } from "babel-plugin-relay/macro";
import type { Environment } from "react-relay";
import { commitMutation } from "react-relay";
import type { createSellCryptoOrderMutationVariables } from "./__generated__/createSellCryptoOrderMutation.graphql";
export const commitCreateSellCryptoOrderMutation = (
environment: Environment,
variables: createSellCryptoOrderMutationVariables
) => {
return commitMutation(environment, {
mutation: graphql`
mutation createSellCryptoOrderMutation(
$currencyId: ID!
$amount: String!
) {
createSellCryptoOrder(
input: { order: { currencyId: $currencyId, amount: $amount } }
) {
errors {
messages
}
order {
id
}
}
}
`,
variables: { ...variables },
onCompleted: (_response) => {
window.location.reload();
},
onError: (_error) => {},
});
};

View File

@@ -0,0 +1 @@
export * from "./ExchangePanel";

View File

@@ -7,10 +7,10 @@ import { FragmentRefs } from "relay-runtime";
export type ExchangeQueryVariables = {}; export type ExchangeQueryVariables = {};
export type ExchangeQueryResponse = { export type ExchangeQueryResponse = {
readonly fiatBalances: { readonly fiatBalances: {
readonly " $fragmentRefs": FragmentRefs<"CreateExchangeOrderModal_fiatBalances">; readonly " $fragmentRefs": FragmentRefs<"ExchangePanel_fiatBalances">;
}; };
readonly balances: { readonly balances: {
readonly " $fragmentRefs": FragmentRefs<"CreateExchangeOrderModal_balances">; readonly " $fragmentRefs": FragmentRefs<"ExchangePanel_balances">;
}; };
readonly buyCryptoOrders: { readonly buyCryptoOrders: {
readonly " $fragmentRefs": FragmentRefs<"ExchangeHistory_buyCryptoOrders">; readonly " $fragmentRefs": FragmentRefs<"ExchangeHistory_buyCryptoOrders">;
@@ -29,10 +29,10 @@ export type ExchangeQuery = {
/* /*
query ExchangeQuery { query ExchangeQuery {
fiatBalances { fiatBalances {
...CreateExchangeOrderModal_fiatBalances ...ExchangePanel_fiatBalances
} }
balances { balances {
...CreateExchangeOrderModal_balances ...ExchangePanel_balances
} }
buyCryptoOrders { buyCryptoOrders {
...ExchangeHistory_buyCryptoOrders ...ExchangeHistory_buyCryptoOrders
@@ -42,24 +42,6 @@ query ExchangeQuery {
} }
} }
fragment CreateExchangeOrderModal_balances on BalanceConnection {
edges {
node {
amount
id
}
}
}
fragment CreateExchangeOrderModal_fiatBalances on FiatBalanceConnection {
edges {
node {
amountCents
id
}
}
}
fragment ExchangeHistory_buyCryptoOrders on BuyCryptoOrderConnection { fragment ExchangeHistory_buyCryptoOrders on BuyCryptoOrderConnection {
edges { edges {
node { node {
@@ -93,6 +75,27 @@ fragment ExchangeHistory_sellCryptoOrders on SellCryptoOrderConnection {
} }
} }
} }
fragment ExchangePanel_balances on BalanceConnection {
edges {
node {
amount
currency {
id
}
id
}
}
}
fragment ExchangePanel_fiatBalances on FiatBalanceConnection {
edges {
node {
amountCents
id
}
}
}
*/ */
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
@@ -161,7 +164,7 @@ return {
{ {
"args": null, "args": null,
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "CreateExchangeOrderModal_fiatBalances" "name": "ExchangePanel_fiatBalances"
} }
], ],
"storageKey": null "storageKey": null
@@ -177,7 +180,7 @@ return {
{ {
"args": null, "args": null,
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "CreateExchangeOrderModal_balances" "name": "ExchangePanel_balances"
} }
], ],
"storageKey": null "storageKey": null
@@ -296,6 +299,18 @@ return {
"name": "amount", "name": "amount",
"storageKey": null "storageKey": null
}, },
{
"alias": null,
"args": null,
"concreteType": "Currency",
"kind": "LinkedField",
"name": "currency",
"plural": false,
"selections": [
(v0/*: any*/)
],
"storageKey": null
},
(v0/*: any*/) (v0/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -413,14 +428,14 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "ddb6670ea93a9fdc62c7627c3ed09925", "cacheID": "424352bbffec52284c44f109ce54a441",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ExchangeQuery", "name": "ExchangeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query ExchangeQuery {\n fiatBalances {\n ...CreateExchangeOrderModal_fiatBalances\n }\n balances {\n ...CreateExchangeOrderModal_balances\n }\n buyCryptoOrders {\n ...ExchangeHistory_buyCryptoOrders\n }\n sellCryptoOrders {\n ...ExchangeHistory_sellCryptoOrders\n }\n}\n\nfragment CreateExchangeOrderModal_balances on BalanceConnection {\n edges {\n node {\n amount\n id\n }\n }\n}\n\nfragment CreateExchangeOrderModal_fiatBalances on FiatBalanceConnection {\n edges {\n node {\n amountCents\n id\n }\n }\n}\n\nfragment ExchangeHistory_buyCryptoOrders on BuyCryptoOrderConnection {\n edges {\n node {\n id\n status\n createdAt\n paidAmountCents\n receivedAmount\n currency {\n name\n id\n }\n __typename\n }\n }\n}\n\nfragment ExchangeHistory_sellCryptoOrders on SellCryptoOrderConnection {\n edges {\n node {\n id\n status\n paidAmount\n receivedAmountCents\n createdAt\n currency {\n name\n id\n }\n __typename\n }\n }\n}\n" "text": "query ExchangeQuery {\n fiatBalances {\n ...ExchangePanel_fiatBalances\n }\n balances {\n ...ExchangePanel_balances\n }\n buyCryptoOrders {\n ...ExchangeHistory_buyCryptoOrders\n }\n sellCryptoOrders {\n ...ExchangeHistory_sellCryptoOrders\n }\n}\n\nfragment ExchangeHistory_buyCryptoOrders on BuyCryptoOrderConnection {\n edges {\n node {\n id\n status\n createdAt\n paidAmountCents\n receivedAmount\n currency {\n name\n id\n }\n __typename\n }\n }\n}\n\nfragment ExchangeHistory_sellCryptoOrders on SellCryptoOrderConnection {\n edges {\n node {\n id\n status\n paidAmount\n receivedAmountCents\n createdAt\n currency {\n name\n id\n }\n __typename\n }\n }\n}\n\nfragment ExchangePanel_balances on BalanceConnection {\n edges {\n node {\n amount\n currency {\n id\n }\n id\n }\n }\n}\n\nfragment ExchangePanel_fiatBalances on FiatBalanceConnection {\n edges {\n node {\n amountCents\n id\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = 'cc0eaddc68f5bd14d39ce9e148876535'; (node as any).hash = '3d09bb5b003cac17750666dc76088801';
export default node; export default node;

View File

@@ -18,7 +18,10 @@ module.exports = {
}, },
}, },
variants: { variants: {
extend: {}, extend: {
opacity: ["disabled"],
cursor: ["disabled"],
},
}, },
plugins: [], plugins: [],
}; };

View File

@@ -6,7 +6,7 @@
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# paid_amount_cents :integer default(0), not null # paid_amount_cents :integer default(0), not null
# received_amount :decimal(20, 10) # received_amount :decimal(20, 10) default(0.0), not null
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null

View File

@@ -6,7 +6,7 @@
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# paid_amount :decimal(20, 10) default(0.0), not null # paid_amount :decimal(20, 10) default(0.0), not null
# received_amount_cents :integer # received_amount_cents :integer default(0), not null
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null

View File

@@ -32,7 +32,7 @@ pt-BR:
fiat_balance: fiat_balance:
amount_formatted: Quantia amount_formatted: Quantia
amount_cents: Quantia amount_cents: Quantia em centavos
currency: currency:
name: Nome name: Nome
@@ -42,8 +42,8 @@ pt-BR:
balance: balance:
attributes: attributes:
amount: amount:
greater_than_or_equal_to: "saldo insuficiente" greater_than_or_equal_to: saldo insuficiente
fiat_balance: fiat_balance:
attributes: attributes:
amount_cents: amount_cents:
greater_than_or_equal_to: "saldo insuficiente" greater_than_or_equal_to: saldo insuficiente

View File

@@ -0,0 +1,14 @@
# frozen_string_literal: true
class AddDefaultValueToSellCryptoOrderRecivedAmountCents < ActiveRecord::Migration[6.1]
def change
# rubocop:disable Rails/ReversibleMigration
execute(<<-SQL.squish)
UPDATE sell_crypto_orders
SET received_amount_cents = 0
WHERE received_amount_cents IS NULL
SQL
change_column_default(:sell_crypto_orders, :received_amount_cents, from: nil, to: 0)
change_column_null(:sell_crypto_orders, :received_amount_cents, false)
end
end

View File

@@ -0,0 +1,14 @@
# frozen_string_literal: true
class AddDefaultValueToBuyCriptoPaidAmountCents < ActiveRecord::Migration[6.1]
def change
# rubocop:disable Rails/ReversibleMigration
execute(<<-SQL.squish)
UPDATE buy_crypto_orders
SET received_amount = 0
WHERE received_amount IS NULL
SQL
change_column_default(:buy_crypto_orders, :received_amount, from: nil, to: 0)
change_column_null(:buy_crypto_orders, :received_amount, false)
end
end

6
db/schema.rb generated
View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_08_14_194513) do ActiveRecord::Schema.define(version: 2021_08_16_015156) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@@ -70,7 +70,7 @@ ActiveRecord::Schema.define(version: 2021_08_14_194513) do
t.bigint "currency_id", null: false t.bigint "currency_id", null: false
t.string "status", null: false t.string "status", null: false
t.integer "paid_amount_cents", default: 0, null: false t.integer "paid_amount_cents", default: 0, null: false
t.decimal "received_amount", precision: 20, scale: 10 t.decimal "received_amount", precision: 20, scale: 10, default: "0.0", null: false
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.index ["currency_id"], name: "index_buy_crypto_orders_on_currency_id" t.index ["currency_id"], name: "index_buy_crypto_orders_on_currency_id"
@@ -97,7 +97,7 @@ ActiveRecord::Schema.define(version: 2021_08_14_194513) do
t.bigint "currency_id", null: false t.bigint "currency_id", null: false
t.string "status", null: false t.string "status", null: false
t.decimal "paid_amount", precision: 20, scale: 10, default: "0.0", null: false t.decimal "paid_amount", precision: 20, scale: 10, default: "0.0", null: false
t.integer "received_amount_cents" t.integer "received_amount_cents", default: 0, null: false
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.index ["currency_id"], name: "index_sell_crypto_orders_on_currency_id" t.index ["currency_id"], name: "index_sell_crypto_orders_on_currency_id"

211
erd.svg
View File

@@ -1,178 +1,179 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by graphviz version 2.40.1 (20161225.0304) <!-- Generated by graphviz version 2.48.0 (0)
--> -->
<!-- Title: XStake Pages: 1 --> <!-- Title: XStake Pages: 1 -->
<svg width="423pt" height="606pt" <svg width="426pt" height="606pt"
viewBox="0.00 0.00 422.60 605.60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> viewBox="0.00 0.00 425.60 605.60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(28.8 576.8)"> <g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(28.8 576.8)">
<title>XStake</title> <title>XStake</title>
<polygon fill="#ffffff" stroke="transparent" points="-28.8,28.8 -28.8,-576.8 393.8,-576.8 393.8,28.8 -28.8,28.8"/> <polygon fill="white" stroke="transparent" points="-28.8,28.8 -28.8,-576.8 396.8,-576.8 396.8,28.8 -28.8,28.8"/>
<text text-anchor="middle" x="182.5" y="-533.6" font-family="Arial Bold" font-size="13.00" fill="#000000">XStake domain model</text> <text text-anchor="middle" x="184" y="-533.6" font-family="Arial Bold" font-size="13.00">XStake domain model</text>
<!-- m_AdminUser --> <!-- m_AdminUser -->
<g id="node1" class="node"> <g id="node1" class="node">
<title>m_AdminUser</title> <title>m_AdminUser</title>
<path fill="none" stroke="#000000" d="M12,-.5C12,-.5 149,-.5 149,-.5 155,-.5 161,-6.5 161,-12.5 161,-12.5 161,-83.5 161,-83.5 161,-89.5 155,-95.5 149,-95.5 149,-95.5 12,-95.5 12,-95.5 6,-95.5 0,-89.5 0,-83.5 0,-83.5 0,-12.5 0,-12.5 0,-6.5 6,-.5 12,-.5"/> <path fill="none" stroke="black" d="M12,-0.5C12,-0.5 150,-0.5 150,-0.5 156,-0.5 162,-6.5 162,-12.5 162,-12.5 162,-83.5 162,-83.5 162,-89.5 156,-95.5 150,-95.5 150,-95.5 12,-95.5 12,-95.5 6,-95.5 0,-89.5 0,-83.5 0,-83.5 0,-12.5 0,-12.5 0,-6.5 6,-0.5 12,-0.5"/>
<text text-anchor="start" x="48.5" y="-82.7" font-family="Arial Bold" font-size="11.00" fill="#000000">AdminUser</text> <text text-anchor="start" x="49" y="-82.7" font-family="Arial Bold" font-size="11.00">AdminUser</text>
<polyline fill="none" stroke="#000000" points="0,-75.5 161,-75.5 "/> <polyline fill="none" stroke="black" points="0,-75.5 162,-75.5 "/>
<text text-anchor="start" x="7.5" y="-62" font-family="Arial" font-size="10.00" fill="#000000">email </text> <text text-anchor="start" x="7" y="-62" font-family="Arial" font-size="10.00">email </text>
<text text-anchor="start" x="34.5" y="-62" font-family="Arial Italic" font-size="10.00" fill="#999999">string U</text> <text text-anchor="start" x="34" y="-62" font-family="Arial Italic" font-size="10.00" fill="#999999">string U</text>
<text text-anchor="start" x="7.5" y="-49" font-family="Arial" font-size="10.00" fill="#000000">encrypted_password </text> <text text-anchor="start" x="7" y="-49" font-family="Arial" font-size="10.00">encrypted_password </text>
<text text-anchor="start" x="100.5" y="-49" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="101" y="-49" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="7.5" y="-36" font-family="Arial" font-size="10.00" fill="#000000">remember_created_at </text> <text text-anchor="start" x="7" y="-36" font-family="Arial" font-size="10.00">remember_created_at </text>
<text text-anchor="start" x="105.5" y="-36" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text> <text text-anchor="start" x="105" y="-36" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text>
<text text-anchor="start" x="7.5" y="-23" font-family="Arial" font-size="10.00" fill="#000000">reset_password_sent_at </text> <text text-anchor="start" x="7" y="-23" font-family="Arial" font-size="10.00">reset_password_sent_at </text>
<text text-anchor="start" x="116.5" y="-23" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text> <text text-anchor="start" x="117" y="-23" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text>
<text text-anchor="start" x="7.5" y="-10" font-family="Arial" font-size="10.00" fill="#000000">reset_password_token </text> <text text-anchor="start" x="7" y="-10" font-family="Arial" font-size="10.00">reset_password_token </text>
<text text-anchor="start" x="108.5" y="-10" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="109" y="-10" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
</g> </g>
<!-- m_Balance --> <!-- m_Balance -->
<g id="node2" class="node"> <g id="node2" class="node">
<title>m_Balance</title> <title>m_Balance</title>
<path fill="none" stroke="#000000" d="M221,-441.5C221,-441.5 341,-441.5 341,-441.5 347,-441.5 353,-447.5 353,-453.5 353,-453.5 353,-498.5 353,-498.5 353,-504.5 347,-510.5 341,-510.5 341,-510.5 221,-510.5 221,-510.5 215,-510.5 209,-504.5 209,-498.5 209,-498.5 209,-453.5 209,-453.5 209,-447.5 215,-441.5 221,-441.5"/> <path fill="none" stroke="black" d="M223,-441.5C223,-441.5 343,-441.5 343,-441.5 349,-441.5 355,-447.5 355,-453.5 355,-453.5 355,-498.5 355,-498.5 355,-504.5 349,-510.5 343,-510.5 343,-510.5 223,-510.5 223,-510.5 217,-510.5 211,-504.5 211,-498.5 211,-498.5 211,-453.5 211,-453.5 211,-447.5 217,-441.5 223,-441.5"/>
<text text-anchor="start" x="257.5" y="-497.7" font-family="Arial Bold" font-size="11.00" fill="#000000">Balance</text> <text text-anchor="start" x="259.5" y="-497.7" font-family="Arial Bold" font-size="11.00">Balance</text>
<polyline fill="none" stroke="#000000" points="209,-490.5 353,-490.5 "/> <polyline fill="none" stroke="black" points="211,-490.5 355,-490.5 "/>
<text text-anchor="start" x="216" y="-477" font-family="Arial" font-size="10.00" fill="#000000">amount </text> <text text-anchor="start" x="218" y="-477" font-family="Arial" font-size="10.00">amount </text>
<text text-anchor="start" x="252" y="-477" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text> <text text-anchor="start" x="254" y="-477" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text>
<text text-anchor="start" x="216" y="-464" font-family="Arial" font-size="10.00" fill="#000000">currency_id </text> <text text-anchor="start" x="218" y="-464" font-family="Arial" font-size="10.00">currency_id </text>
<text text-anchor="start" x="270" y="-464" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="272" y="-464" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
<text text-anchor="start" x="216" y="-451" font-family="Arial" font-size="10.00" fill="#000000">user_id </text> <text text-anchor="start" x="218" y="-451" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="251" y="-451" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="253" y="-451" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g> </g>
<!-- m_BuyCryptoOrder --> <!-- m_BuyCryptoOrder -->
<g id="node3" class="node"> <g id="node3" class="node">
<title>m_BuyCryptoOrder</title> <title>m_BuyCryptoOrder</title>
<path fill="none" stroke="#000000" d="M209,-316.5C209,-316.5 353,-316.5 353,-316.5 359,-316.5 365,-322.5 365,-328.5 365,-328.5 365,-399.5 365,-399.5 365,-405.5 359,-411.5 353,-411.5 353,-411.5 209,-411.5 209,-411.5 203,-411.5 197,-405.5 197,-399.5 197,-399.5 197,-328.5 197,-328.5 197,-322.5 203,-316.5 209,-316.5"/> <path fill="none" stroke="black" d="M210,-316.5C210,-316.5 356,-316.5 356,-316.5 362,-316.5 368,-322.5 368,-328.5 368,-328.5 368,-399.5 368,-399.5 368,-405.5 362,-411.5 356,-411.5 356,-411.5 210,-411.5 210,-411.5 204,-411.5 198,-405.5 198,-399.5 198,-399.5 198,-328.5 198,-328.5 198,-322.5 204,-316.5 210,-316.5"/>
<text text-anchor="start" x="235" y="-398.7" font-family="Arial Bold" font-size="11.00" fill="#000000">BuyCryptoOrder</text> <text text-anchor="start" x="237" y="-398.7" font-family="Arial Bold" font-size="11.00">BuyCryptoOrder</text>
<polyline fill="none" stroke="#000000" points="197,-391.5 365,-391.5 "/> <polyline fill="none" stroke="black" points="198,-391.5 368,-391.5 "/>
<text text-anchor="start" x="204" y="-378" font-family="Arial" font-size="10.00" fill="#000000">currency_id </text> <text text-anchor="start" x="205" y="-378" font-family="Arial" font-size="10.00">currency_id </text>
<text text-anchor="start" x="258" y="-378" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="259" y="-378" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
<text text-anchor="start" x="204" y="-365" font-family="Arial" font-size="10.00" fill="#000000">paid_amount_cents </text> <text text-anchor="start" x="205" y="-365" font-family="Arial" font-size="10.00">paid_amount_cents </text>
<text text-anchor="start" x="292" y="-365" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text> <text text-anchor="start" x="293" y="-365" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text>
<text text-anchor="start" x="204" y="-352" font-family="Arial" font-size="10.00" fill="#000000">received_amount </text> <text text-anchor="start" x="205" y="-352" font-family="Arial" font-size="10.00">received_amount </text>
<text text-anchor="start" x="282" y="-352" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text> <text text-anchor="start" x="283" y="-352" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text>
<text text-anchor="start" x="204" y="-339" font-family="Arial" font-size="10.00" fill="#000000">status </text> <text text-anchor="start" x="205" y="-339" font-family="Arial" font-size="10.00">status </text>
<text text-anchor="start" x="235" y="-339" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="236" y="-339" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="204" y="-326" font-family="Arial" font-size="10.00" fill="#000000">user_id </text> <text text-anchor="start" x="205" y="-326" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="239" y="-326" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="240" y="-326" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g> </g>
<!-- m_Currency --> <!-- m_Currency -->
<g id="node4" class="node"> <g id="node4" class="node">
<title>m_Currency</title> <title>m_Currency</title>
<path fill="none" stroke="#000000" d="M20.5,-342.5C20.5,-342.5 140.5,-342.5 140.5,-342.5 146.5,-342.5 152.5,-348.5 152.5,-354.5 152.5,-354.5 152.5,-373.5 152.5,-373.5 152.5,-379.5 146.5,-385.5 140.5,-385.5 140.5,-385.5 20.5,-385.5 20.5,-385.5 14.5,-385.5 8.5,-379.5 8.5,-373.5 8.5,-373.5 8.5,-354.5 8.5,-354.5 8.5,-348.5 14.5,-342.5 20.5,-342.5"/> <path fill="none" stroke="black" d="M21,-342.5C21,-342.5 141,-342.5 141,-342.5 147,-342.5 153,-348.5 153,-354.5 153,-354.5 153,-373.5 153,-373.5 153,-379.5 147,-385.5 141,-385.5 141,-385.5 21,-385.5 21,-385.5 15,-385.5 9,-379.5 9,-373.5 9,-373.5 9,-354.5 9,-354.5 9,-348.5 15,-342.5 21,-342.5"/>
<text text-anchor="start" x="54" y="-372.7" font-family="Arial Bold" font-size="11.00" fill="#000000">Currency</text> <text text-anchor="start" x="54.5" y="-372.7" font-family="Arial Bold" font-size="11.00">Currency</text>
<polyline fill="none" stroke="#000000" points="8.5,-365.5 152.5,-365.5 "/> <polyline fill="none" stroke="black" points="9,-365.5 153,-365.5 "/>
<text text-anchor="start" x="15.5" y="-352" font-family="Arial" font-size="10.00" fill="#000000">name </text> <text text-anchor="start" x="16" y="-352" font-family="Arial" font-size="10.00">name </text>
<text text-anchor="start" x="43.5" y="-352" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="44" y="-352" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
</g> </g>
<!-- m_Currency&#45;&gt;m_Balance --> <!-- m_Currency&#45;&gt;m_Balance -->
<g id="edge8" class="edge"> <g id="edge8" class="edge">
<title>m_Currency&#45;&gt;m_Balance</title> <title>m_Currency&#45;&gt;m_Balance</title>
<path fill="none" stroke="#000000" d="M119.1584,-385.5947C145.169,-400.1243 180.2111,-419.699 211.0368,-436.9183"/> <path fill="none" stroke="black" d="M120.56,-385.59C146.51,-400.12 181.46,-419.7 212.21,-436.92"/>
<polygon fill="#000000" stroke="#000000" points="209.7968,-439.8338 219.1903,-441.4729 212.8692,-434.3337 209.7968,-439.8338"/> <polygon fill="black" stroke="black" points="210.95,-439.82 220.34,-441.47 214.03,-434.33 210.95,-439.82"/>
</g> </g>
<!-- m_Currency&#45;&gt;m_BuyCryptoOrder --> <!-- m_Currency&#45;&gt;m_BuyCryptoOrder -->
<g id="edge5" class="edge"> <g id="edge5" class="edge">
<title>m_Currency&#45;&gt;m_BuyCryptoOrder</title> <title>m_Currency&#45;&gt;m_BuyCryptoOrder</title>
<path fill="none" stroke="#000000" d="M152.6018,-364C164.0532,-364 176.0378,-364 187.8887,-364"/> <path fill="none" stroke="black" d="M153.08,-364C164.62,-364 176.72,-364 188.7,-364"/>
<polygon fill="#000000" stroke="#000000" points="187.914,-367.1501 196.914,-364 187.914,-360.8501 187.914,-367.1501"/> <polygon fill="black" stroke="black" points="188.82,-367.15 197.82,-364 188.82,-360.85 188.82,-367.15"/>
</g> </g>
<!-- m_SellCryptoOrder --> <!-- m_SellCryptoOrder -->
<g id="node6" class="node"> <g id="node6" class="node">
<title>m_SellCryptoOrder</title> <title>m_SellCryptoOrder</title>
<path fill="none" stroke="#000000" d="M213,-191.5C213,-191.5 349,-191.5 349,-191.5 355,-191.5 361,-197.5 361,-203.5 361,-203.5 361,-274.5 361,-274.5 361,-280.5 355,-286.5 349,-286.5 349,-286.5 213,-286.5 213,-286.5 207,-286.5 201,-280.5 201,-274.5 201,-274.5 201,-203.5 201,-203.5 201,-197.5 207,-191.5 213,-191.5"/> <path fill="none" stroke="black" d="M214.5,-191.5C214.5,-191.5 351.5,-191.5 351.5,-191.5 357.5,-191.5 363.5,-197.5 363.5,-203.5 363.5,-203.5 363.5,-274.5 363.5,-274.5 363.5,-280.5 357.5,-286.5 351.5,-286.5 351.5,-286.5 214.5,-286.5 214.5,-286.5 208.5,-286.5 202.5,-280.5 202.5,-274.5 202.5,-274.5 202.5,-203.5 202.5,-203.5 202.5,-197.5 208.5,-191.5 214.5,-191.5"/>
<text text-anchor="start" x="235.5" y="-273.7" font-family="Arial Bold" font-size="11.00" fill="#000000">SellCryptoOrder</text> <text text-anchor="start" x="238" y="-273.7" font-family="Arial Bold" font-size="11.00">SellCryptoOrder</text>
<polyline fill="none" stroke="#000000" points="201,-266.5 361,-266.5 "/> <polyline fill="none" stroke="black" points="202.5,-266.5 363.5,-266.5 "/>
<text text-anchor="start" x="208" y="-253" font-family="Arial" font-size="10.00" fill="#000000">currency_id </text> <text text-anchor="start" x="210" y="-253" font-family="Arial" font-size="10.00">currency_id </text>
<text text-anchor="start" x="262" y="-253" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="264" y="-253" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
<text text-anchor="start" x="208" y="-240" font-family="Arial" font-size="10.00" fill="#000000">paid_amount </text> <text text-anchor="start" x="210" y="-240" font-family="Arial" font-size="10.00">paid_amount </text>
<text text-anchor="start" x="267" y="-240" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text> <text text-anchor="start" x="269" y="-240" font-family="Arial Italic" font-size="10.00" fill="#999999">decimal (20,10)</text>
<text text-anchor="start" x="208" y="-227" font-family="Arial" font-size="10.00" fill="#000000">received_amount_cents </text> <text text-anchor="start" x="210" y="-227" font-family="Arial" font-size="10.00">received_amount_cents </text>
<text text-anchor="start" x="315" y="-227" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text> <text text-anchor="start" x="317" y="-227" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text>
<text text-anchor="start" x="208" y="-214" font-family="Arial" font-size="10.00" fill="#000000">status </text> <text text-anchor="start" x="210" y="-214" font-family="Arial" font-size="10.00">status </text>
<text text-anchor="start" x="239" y="-214" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="241" y="-214" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="208" y="-201" font-family="Arial" font-size="10.00" fill="#000000">user_id </text> <text text-anchor="start" x="210" y="-201" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="243" y="-201" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="245" y="-201" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g> </g>
<!-- m_Currency&#45;&gt;m_SellCryptoOrder --> <!-- m_Currency&#45;&gt;m_SellCryptoOrder -->
<g id="edge7" class="edge"> <g id="edge7" class="edge">
<title>m_Currency&#45;&gt;m_SellCryptoOrder</title> <title>m_Currency&#45;&gt;m_SellCryptoOrder</title>
<path fill="none" stroke="#000000" d="M115.4244,-342.2267C137.8839,-328.2245 168.0914,-309.3919 196.5551,-291.6464"/> <path fill="none" stroke="black" d="M116.84,-342.23C139.24,-328.22 169.37,-309.39 197.77,-291.65"/>
<polygon fill="#000000" stroke="#000000" points="198.5584,-294.1096 204.5292,-286.6751 195.2253,-288.7635 198.5584,-294.1096"/> <polygon fill="black" stroke="black" points="199.76,-294.12 205.72,-286.68 196.42,-288.77 199.76,-294.12"/>
</g> </g>
<!-- m_FiatBalance --> <!-- m_FiatBalance -->
<g id="node5" class="node"> <g id="node5" class="node">
<title>m_FiatBalance</title> <title>m_FiatBalance</title>
<path fill="none" stroke="#000000" d="M221,-6.5C221,-6.5 341,-6.5 341,-6.5 347,-6.5 353,-12.5 353,-18.5 353,-18.5 353,-63.5 353,-63.5 353,-69.5 347,-75.5 341,-75.5 341,-75.5 221,-75.5 221,-75.5 215,-75.5 209,-69.5 209,-63.5 209,-63.5 209,-18.5 209,-18.5 209,-12.5 215,-6.5 221,-6.5"/> <path fill="none" stroke="black" d="M223,-6.5C223,-6.5 343,-6.5 343,-6.5 349,-6.5 355,-12.5 355,-18.5 355,-18.5 355,-63.5 355,-63.5 355,-69.5 349,-75.5 343,-75.5 343,-75.5 223,-75.5 223,-75.5 217,-75.5 211,-69.5 211,-63.5 211,-63.5 211,-18.5 211,-18.5 211,-12.5 217,-6.5 223,-6.5"/>
<text text-anchor="start" x="248" y="-62.7" font-family="Arial Bold" font-size="11.00" fill="#000000">FiatBalance</text> <text text-anchor="start" x="250" y="-62.7" font-family="Arial Bold" font-size="11.00">FiatBalance</text>
<polyline fill="none" stroke="#000000" points="209,-55.5 353,-55.5 "/> <polyline fill="none" stroke="black" points="211,-55.5 355,-55.5 "/>
<text text-anchor="start" x="216" y="-42" font-family="Arial" font-size="10.00" fill="#000000">amount_cents </text> <text text-anchor="start" x="218" y="-42" font-family="Arial" font-size="10.00">amount_cents </text>
<text text-anchor="start" x="281" y="-42" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text> <text text-anchor="start" x="283" y="-42" font-family="Arial Italic" font-size="10.00" fill="#999999">integer</text>
<text text-anchor="start" x="216" y="-29" font-family="Arial" font-size="10.00" fill="#000000">amount_currency </text> <text text-anchor="start" x="218" y="-29" font-family="Arial" font-size="10.00">amount_currency </text>
<text text-anchor="start" x="295" y="-29" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="297" y="-29" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="216" y="-16" font-family="Arial" font-size="10.00" fill="#000000">user_id </text> <text text-anchor="start" x="218" y="-16" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="251" y="-16" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="253" y="-16" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g> </g>
<!-- m_User --> <!-- m_User -->
<g id="node7" class="node"> <g id="node7" class="node">
<title>m_User</title> <title>m_User</title>
<path fill="none" stroke="#000000" d="M12,-125.5C12,-125.5 149,-125.5 149,-125.5 155,-125.5 161,-131.5 161,-137.5 161,-137.5 161,-234.5 161,-234.5 161,-240.5 155,-246.5 149,-246.5 149,-246.5 12,-246.5 12,-246.5 6,-246.5 0,-240.5 0,-234.5 0,-234.5 0,-137.5 0,-137.5 0,-131.5 6,-125.5 12,-125.5"/> <path fill="none" stroke="black" d="M12,-125.5C12,-125.5 150,-125.5 150,-125.5 156,-125.5 162,-131.5 162,-137.5 162,-137.5 162,-234.5 162,-234.5 162,-240.5 156,-246.5 150,-246.5 150,-246.5 12,-246.5 12,-246.5 6,-246.5 0,-240.5 0,-234.5 0,-234.5 0,-137.5 0,-137.5 0,-131.5 6,-125.5 12,-125.5"/>
<text text-anchor="start" x="66" y="-233.7" font-family="Arial Bold" font-size="11.00" fill="#000000">User</text> <text text-anchor="start" x="66.5" y="-233.7" font-family="Arial Bold" font-size="11.00">User</text>
<polyline fill="none" stroke="#000000" points="0,-226.5 161,-226.5 "/> <polyline fill="none" stroke="black" points="0,-226.5 162,-226.5 "/>
<text text-anchor="start" x="7.5" y="-213" font-family="Arial" font-size="10.00" fill="#000000">email </text> <text text-anchor="start" x="7" y="-213" font-family="Arial" font-size="10.00">email </text>
<text text-anchor="start" x="34.5" y="-213" font-family="Arial Italic" font-size="10.00" fill="#999999">string U</text> <text text-anchor="start" x="34" y="-213" font-family="Arial Italic" font-size="10.00" fill="#999999">string U</text>
<text text-anchor="start" x="7.5" y="-200" font-family="Arial" font-size="10.00" fill="#000000">encrypted_password </text> <text text-anchor="start" x="7" y="-200" font-family="Arial" font-size="10.00">encrypted_password </text>
<text text-anchor="start" x="100.5" y="-200" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="101" y="-200" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="7.5" y="-187" font-family="Arial" font-size="10.00" fill="#000000">first_name </text> <text text-anchor="start" x="7" y="-187" font-family="Arial" font-size="10.00">first_name </text>
<text text-anchor="start" x="56.5" y="-187" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="56" y="-187" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="7.5" y="-174" font-family="Arial" font-size="10.00" fill="#000000">last_name </text> <text text-anchor="start" x="7" y="-174" font-family="Arial" font-size="10.00">last_name </text>
<text text-anchor="start" x="56.5" y="-174" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="56" y="-174" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="7.5" y="-161" font-family="Arial" font-size="10.00" fill="#000000">remember_created_at </text> <text text-anchor="start" x="7" y="-161" font-family="Arial" font-size="10.00">remember_created_at </text>
<text text-anchor="start" x="105.5" y="-161" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text> <text text-anchor="start" x="105" y="-161" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text>
<text text-anchor="start" x="7.5" y="-148" font-family="Arial" font-size="10.00" fill="#000000">reset_password_sent_at </text> <text text-anchor="start" x="7" y="-148" font-family="Arial" font-size="10.00">reset_password_sent_at </text>
<text text-anchor="start" x="116.5" y="-148" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text> <text text-anchor="start" x="117" y="-148" font-family="Arial Italic" font-size="10.00" fill="#999999">datetime</text>
<text text-anchor="start" x="7.5" y="-135" font-family="Arial" font-size="10.00" fill="#000000">reset_password_token </text> <text text-anchor="start" x="7" y="-135" font-family="Arial" font-size="10.00">reset_password_token </text>
<text text-anchor="start" x="108.5" y="-135" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="109" y="-135" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
</g> </g>
<!-- m_User&#45;&gt;m_Balance --> <!-- m_User&#45;&gt;m_Balance -->
<g id="edge2" class="edge"> <g id="edge2" class="edge">
<title>m_User&#45;&gt;m_Balance</title> <title>m_User&#45;&gt;m_Balance</title>
<path fill="none" stroke="#000000" d="M117.8604,-246.6822C132.3012,-271.4162 148.3569,-300.5952 161,-328 180.613,-370.5127 166.9911,-391.063 197,-427 201.3286,-432.1836 206.3552,-436.9437 211.7562,-441.286"/> <path fill="none" stroke="black" d="M119.1,-246.71C133.45,-271.44 149.41,-300.62 162,-328 181.56,-370.54 167.99,-391.06 198,-427 200.43,-429.92 203.09,-432.7 205.91,-435.35"/>
<polygon fill="black" stroke="black" points="203.89,-437.77 212.76,-441.29 208.02,-433.01 203.89,-437.77"/>
</g> </g>
<!-- m_User&#45;&gt;m_BuyCryptoOrder --> <!-- m_User&#45;&gt;m_BuyCryptoOrder -->
<g id="edge4" class="edge"> <g id="edge4" class="edge">
<title>m_User&#45;&gt;m_BuyCryptoOrder</title> <title>m_User&#45;&gt;m_BuyCryptoOrder</title>
<path fill="none" stroke="#000000" d="M138.1489,-246.7611C156.4296,-265.0999 177.0785,-284.8928 197,-302 200.2659,-304.8045 203.6488,-307.6223 207.0989,-310.4268"/> <path fill="none" stroke="black" d="M139.37,-246.78C157.57,-265.12 178.14,-284.91 198,-302 201.26,-304.81 204.64,-307.63 208.09,-310.44"/>
<polygon fill="#000000" stroke="#000000" points="205.2637,-312.9926 214.259,-316.156 209.1997,-308.0735 205.2637,-312.9926"/> <polygon fill="black" stroke="black" points="206.25,-313 215.25,-316.17 210.19,-308.08 206.25,-313"/>
</g> </g>
<!-- m_User&#45;&gt;m_FiatBalance --> <!-- m_User&#45;&gt;m_FiatBalance -->
<g id="edge3" class="edge"> <g id="edge3" class="edge">
<title>m_User&#45;&gt;m_FiatBalance</title> <title>m_User&#45;&gt;m_FiatBalance</title>
<path fill="none" stroke="#000000" d="M150.2329,-125.4832C165.3085,-113.274 181.4114,-100.8639 197,-90 203.9257,-85.1734 211.3503,-80.363 218.8149,-75.7466"/> <path fill="none" stroke="black" d="M151.41,-125.47C166.42,-113.26 182.46,-100.85 198,-90 204.92,-85.17 212.34,-80.35 219.8,-75.73"/>
</g> </g>
<!-- m_User&#45;&gt;m_SellCryptoOrder --> <!-- m_User&#45;&gt;m_SellCryptoOrder -->
<g id="edge6" class="edge"> <g id="edge6" class="edge">
<title>m_User&#45;&gt;m_SellCryptoOrder</title> <title>m_User&#45;&gt;m_SellCryptoOrder</title>
<path fill="none" stroke="#000000" d="M161.1843,-207.328C171.2838,-209.9977 181.6589,-212.7403 191.8779,-215.4415"/> <path fill="none" stroke="black" d="M162.2,-207.25C172.55,-210 183.21,-212.82 193.69,-215.6"/>
<polygon fill="#000000" stroke="#000000" points="191.3009,-218.5471 200.8071,-217.8019 192.911,-212.4563 191.3009,-218.5471"/> <polygon fill="black" stroke="black" points="192.93,-218.66 202.44,-217.92 194.55,-212.57 192.93,-218.66"/>
</g> </g>
<!-- m_UserDocument --> <!-- m_UserDocument -->
<g id="node8" class="node"> <g id="node8" class="node">
<title>m_UserDocument</title> <title>m_UserDocument</title>
<path fill="none" stroke="#000000" d="M221,-105C221,-105 341,-105 341,-105 347,-105 353,-111 353,-117 353,-117 353,-149 353,-149 353,-155 347,-161 341,-161 341,-161 221,-161 221,-161 215,-161 209,-155 209,-149 209,-149 209,-117 209,-117 209,-111 215,-105 221,-105"/> <path fill="none" stroke="black" d="M223,-105C223,-105 343,-105 343,-105 349,-105 355,-111 355,-117 355,-117 355,-149 355,-149 355,-155 349,-161 343,-161 343,-161 223,-161 223,-161 217,-161 211,-155 211,-149 211,-149 211,-117 211,-117 211,-111 217,-105 223,-105"/>
<text text-anchor="start" x="239.5" y="-148.2" font-family="Arial Bold" font-size="11.00" fill="#000000">UserDocument</text> <text text-anchor="start" x="241.5" y="-148.2" font-family="Arial Bold" font-size="11.00">UserDocument</text>
<polyline fill="none" stroke="#000000" points="209,-141 353,-141 "/> <polyline fill="none" stroke="black" points="211,-141 355,-141 "/>
<text text-anchor="start" x="216" y="-128" font-family="Arial" font-size="10.00" fill="#000000">status </text> <text text-anchor="start" x="218" y="-128" font-family="Arial" font-size="10.00">status </text>
<text text-anchor="start" x="247" y="-128" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text> <text text-anchor="start" x="249" y="-128" font-family="Arial Italic" font-size="10.00" fill="#999999">string</text>
<text text-anchor="start" x="216" y="-115" font-family="Arial" font-size="10.00" fill="#000000">user_id </text> <text text-anchor="start" x="218" y="-115" font-family="Arial" font-size="10.00">user_id </text>
<text text-anchor="start" x="251" y="-115" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text> <text text-anchor="start" x="253" y="-115" font-family="Arial Italic" font-size="10.00" fill="#999999">integer (8) FK</text>
</g> </g>
<!-- m_User&#45;&gt;m_UserDocument --> <!-- m_User&#45;&gt;m_UserDocument -->
<g id="edge1" class="edge"> <g id="edge1" class="edge">
<title>m_User&#45;&gt;m_UserDocument</title> <title>m_User&#45;&gt;m_UserDocument</title>
<path fill="none" stroke="#000000" d="M161.1843,-164.672C174.0042,-161.2832 187.2682,-157.777 200.0932,-154.3868"/> <path fill="none" stroke="black" d="M162.2,-164.75C175.26,-161.29 188.8,-157.7 201.87,-154.23"/>
<polygon fill="#000000" stroke="#000000" points="200.9949,-157.4068 208.891,-152.0612 199.3848,-151.316 200.9949,-157.4068"/> <polygon fill="black" stroke="black" points="202.93,-157.21 210.83,-151.86 201.32,-151.12 202.93,-157.21"/>
</g> </g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -6,7 +6,7 @@
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# paid_amount_cents :integer default(0), not null # paid_amount_cents :integer default(0), not null
# received_amount :decimal(20, 10) # received_amount :decimal(20, 10) default(0.0), not null
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null

View File

@@ -6,7 +6,7 @@
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# paid_amount :decimal(20, 10) default(0.0), not null # paid_amount :decimal(20, 10) default(0.0), not null
# received_amount_cents :integer # received_amount_cents :integer default(0), not null
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null

View File

@@ -6,7 +6,7 @@
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# paid_amount_cents :integer default(0), not null # paid_amount_cents :integer default(0), not null
# received_amount :decimal(20, 10) # received_amount :decimal(20, 10) default(0.0), not null
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null

View File

@@ -6,7 +6,7 @@
# #
# id :bigint not null, primary key # id :bigint not null, primary key
# paid_amount :decimal(20, 10) default(0.0), not null # paid_amount :decimal(20, 10) default(0.0), not null
# received_amount_cents :integer # received_amount_cents :integer default(0), not null
# status :string not null # status :string not null
# created_at :datetime not null # created_at :datetime not null
# updated_at :datetime not null # updated_at :datetime not null