digraph G { overlap=false nodesep=2 subgraph client { label = "Client"; node[color=red]; "Customer" "Freelancer" } subgraph endpoints { label = "API Endpoints"; node[color=turquoise] "/" "/customer/$freelancer/template/$templateName" "/customer/$freelancer/template/$templateName/request" "/freelancer/$freelancer/inbox" "/freelancer/$freelancer/requests/$requestID" "/freelancer/$freelancer/requests/$requestID/accept" "/freelancer/$freelancer/requests/$requestID/decline" "/freelancer/$freelancer/createInvoice" "/freelancer/login" "/freelancer/$freelancer/requests/$requestID/finalProduct" } subgraph backend { label = "Backend"; node[color=blue] "Oauth2 Authorization Server" UpFrontPaymentSetup UpFrontPaymentWatcher OnDeliverPaymentSetup OnDeliverPaymentWatcher FreelancerPayOut deliveryHandler "Download Link Maker" } subgraph foreign { node[color=yellow] label = "Foreign APIs"; Stripe } subgraph selfhosted { node[color=orange] label = "Self-Hosted software"; "Email Server" BTCPayServer } subgraph filesystem { node[color=black] label = "Filesystem"; "Freelancer Data" "commission database" } //Customer Interface ////GET "Customer" -> {"/" "/customer/$freelancer/template/$templateName"} [label="GET Request"] {"/" "/customer/$freelancer/template/$templateName"} -> Customer [label="HTML"] ////POST "Customer" -> {"/customer/$freelancer/template/$templateName/request"} [label = "POST Request"] {"/customer/$freelancer/template/$templateName/request"} -> "Customer" [label="HTML"] //Freelancer Interface "Freelancer" -> {"/freelancer/$freelancer/inbox" "/freelancer/$freelancer/requests/$requestID/accept" "/freelancer/$freelancer/requests/$requestID/decline"} [label="GET Request"] {"/freelancer/$freelancer/inbox" "/freelancer/$freelancer/requests/$requestID/accept" "/freelancer/$freelancer/requests/$requestID/decline"} -> "Freelancer" [label="HTML"] //Populating with Freelancer Data "Freelancer Data" -> "/customer/$freelancer/template/$templateName" [label = "Commission Templates"] //Template System "/customer/$freelancer/template/$templateName/request" -> {"commission database"} [label = "store Commission Request Data"] "commission database" -> "/freelancer/$freelancer/requests/$requestID" [label = "read Commission Request Data"] "/freelancer/$freelancer/requests/$requestID/accept" -> "commission database" [label = "change $accepted value to true"] "/freelancer/$freelancer/requests/$requestID/decline" -> "commission database" [label = "change $accepted value to false"] "/freelancer/$freelancer/requests/$requestID/decline" -> "Email Server" -> "Customer" [label = "Declining letter"] //Invoice System Freelancer -> "/freelancer/$freelancer/createInvoice" [label = "POST Request"] "/freelancer/$freelancer/createInvoice" -> "commission database" [label = "store Commission Request Data"] //Log in Freelancer -> "/freelancer/login" "/freelancer/login" -> "Oauth2 Authorization Server" [label = "POST Request"] "Oauth2 Authorization Server" -> "Freelancer" [label = "Authorization Token"] //Payment verification "commission database" -> UpFrontPaymentSetup [label="Periodic queries of new approved commissions"] UpFrontPaymentSetup -> {BTCPayServer Stripe} [label="API request"] {BTCPayServer Stripe} -> UpFrontPaymentSetup [label="Invoice IDs"] UpFrontPaymentSetup -> "commission database" [label="write $invoiceID of commission"] "commission database" -> UpFrontPaymentWatcher [label="periodic queries of $invoiceIDs of unpaid upfront commissions"] {BTCPayServer Stripe} -> UpFrontPaymentWatcher [label="Payment recieved on invoice"] UpFrontPaymentWatcher -> Freelancer [label="Notification that payment for commission has been recieved"] {Stripe BTCPayServer} -> Customer [label = "Email containing invoice data"] //Delivery ////Freelancer Upload Freelancer -> "/freelancer/$freelancer/requests/$requestID/finalProduct" [label="POST Request"] "/freelancer/$freelancer/requests/$requestID/finalProduct" -> deliveryHandler [label="notification to start handling the delivery of the product"] "/freelancer/$freelancer/requests/$requestID/finalProduct" -> "Download Link Maker" [label="Notification to hand the Freelancer a link to his product"] "Download Link Maker" -> "/freelancer/$freelancer/requests/$requestID/finalProduct" -> Freelancer [label="Link to final product"] ////Conditional on delivery handling "commission database" -> deliveryHandler [label="check if delivery is pay-on-deliver or not"] deliveryHandler -> {"Email Server"} -> Customer [label="Final Product delivered directly if not pay-on-deliver"] deliveryHandler -> OnDeliverPaymentSetup [label="notify that this will require payment on deliver"] "commission database" -> OnDeliverPaymentSetup -> {BTCPayServer Stripe}[label="Amount owed and who to invoice"] {BTCPayServer Stripe} -> "Invoice IDs" -> "commission database" [label="write $invoiceID of commission"] "commission database" -> OnDeliverPaymentWatcher [label="periodic queries of $invoiceIDs of unpaid delivery commissions"] {BTCPayServer Stripe} -> OnDeliverPaymentWatcher [label="Payment recieved on invoice"] OnDeliverPaymentWatcher -> Freelancer [label="Notification that payment for commission has been recieved"] OnDeliverPaymentWatcher -> {"Email Server"} -> Customer [label="Final Product delivered"] //Set up system for payouts to users {OnDeliverPaymentWatcher deliveryHandler} -> "FreelancerPayOut" "FreelancerPayOut" -> {Stripe BTCPayServer} [label = "Send a call out to send money to the freelancer"] {Stripe BTCPayServer} -> "FreelancerPayOut" [label = "Confirmed money has been sent to user"] "FreelancerPayOut" -> "Freelancer" [label = "Notification money has been sent"] }