Git Product home page Git Product logo

systemaccounting / mxfactorial Goto Github PK

View Code? Open in Web Editor NEW
44.0 13.0 26.0 6.71 MB

a payment application intended for deployment by the united states treasury that replaces banking with accounting

Home Page: https://www.systemaccounting.org

HTML 0.05% JavaScript 0.12% CSS 0.06% HCL 8.12% Shell 12.05% Makefile 4.55% Jupyter Notebook 0.87% Dockerfile 1.14% PLpgSQL 1.86% TypeScript 2.91% Svelte 6.09% Rust 62.20%
capital game-theory fintech bivector combinatorial-optimization economics combinatorial-game finance price-discovery mathematical-physics

mxfactorial's People

Contributors

bryantcj5691 avatar chrismagscode avatar dependabot[bot] avatar kishanj918 avatar klishevich avatar krishnal avatar mxfactorial avatar nstfkc avatar oozywaters avatar ryanjamesdeveloper avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mxfactorial's Issues

Create a Drawing Layer to submit queries geometrically

Add a Drawing Layer so that queries are executed with coordinate-ranges returned by the getPath() & getPaths() methods (see third-party demo).

If a box is drawn around the U.S. while "Los Angeles" is specified as a literal argument (noun), accept "Los Angeles" as a Where clause and visualize Los Angeles, only. If a box exists above California while "Fast Food" is the noun, query for "Fast Food" within the coordinate ranges of California. If a box exists above New York while "Los Angeles" exists as a literal argument, return 0.

Flash a 3 second reminder above the input fields to clear the noun box if a filter is not intended, "Clear any names from the noun box if you intend a purely geographic query."

Create a delete shape button (see third party answer & demo).
Create a reset button.

Add /rule endpoint and update /transact to support rule-dependent transactions

  1. Client builds initial transaction object by identifying direction, account, and extemporaneous transaction_item(s)
  2. Client requests GET /rule/transaction?=db_author=Sandy&cr_author=DannysMarket&transaction_item… using qs.stringify() to identify user-generated values for properties and nested array of objects in query string
  3. To reconstruct the object created on the client, GET /rule initializes transactionFromClient object using qs.parse() to parse properties and nested array of objects in query string request
  4. GET /rule queries for rule_instance.cr_author
  5. GET /rule executes rule_instance.trs of matching rule_instance.cr_author record(s) to modify newly-initialized transaction object
  6. GET /rule queries for rule_instance.db_author
  7. GET /rule executes rule_instance.trs of matching rule_instance.db_author record(s) to further modify transaction object
  8. GET /rule responds to client with modified transaction object per user rules
  9. Client requests POST /transact of user-initialized, rule-modified transaction object
  10. /transact authenticates user requesting POST
  11. IF password = TRUE, POST /transact tests authenticated user == db_author
  12. IF authenticated user = db_author, skip to next step, ELSE POST /transact tests authenticated user == cr_author
  13. IF authenticated user = db_author OR cr_author (only passes objects where authenticated user is involved), POST /transact tests cr_author == db_author to avoid transactions where users are paying themselves
  14. IF cr_author == db_author = FALSE, then POST /transact tests IF transaction_item.length > 0 (blocking objects with empty transaction_item array)
  15. IF transaction_item.length > 0, POST /transact tests if db_author, cr_author, expiration_time along with rule_instance_id, db_account, cr_account, quantity, value, and name for ALL transaction_item(s) EXIST (value.length >= 0)
  16. IF required properties EXIST, POST /transact tests if db_author, cr_author, expiration_time along with db_account, cr_account, quantity, value, and name for ALL transaction_item(s) are NON-EMPTY (i.e. value.length > 0, empty rule_instance_id(s) are passed because they identify extemporaneous transaction_item(s))
  17. IF required properties are NON-EMPTY, POST /transact tests IF ALL transaction_item(s) with an EMPTY rule_instance_id (NOT rule-generated) has db_account = db_author to block transaction involving non-authenticated user
  18. IF ALL transaction_item(s) with an EMPTY rule_instance_id has db_account = db_author, POST /transact tests IF ALL transaction_item(s) with an EMPTY `rule_instance_id’ has cr_account = cr_author
  19. IF ALL transaction_item(s) with an EMPTY `rule_instance_id’ has cr_account = cr_author AND authenticated user = db_author, POST /transact stores the object received from client in memory as transactionUnderTestFromDebitor with ONLY db_latlng, expiration_time, and transaction_item objects, ELSE IF authenticated user = cr_author, POST /transact stores the object received from client in memory as transactionUnderTestFromCreditor with ONLY cr_latlng, expiration_time, and transaction_item objects to prepare testing of client object against /rule object
  20. /transact requests GET /rule/transaction?=cr_author,db_author
  21. /rule responds to /transact with same modified transaction object it initially returned to the client
  22. /transact stores object received from /rule in memory as transactionFromRule
  23. /transact tests IF transactionFromRule is a subset of transactionUnderTestFromDebitor OR transactionUnderTestFromCreditor
  24. IF transactionFromRule is a subset of transactionUnderTestFromDebitor OR transactionUnderTestFromCreditor, POST /transact copies cr_latlng OR db_latlng, expiration_time, and all transaction_item(s) with an EMPTY rule_instance_id (NOT rule-generated) from transactionUnderTestFromDebitor OR transactionUnderTestFromCreditor to transactionFromRule
  25. POST /transact adds cr_time OR db_time value of authenticated db_author OR cr_author requesting POST
  26. /transact stores rule-initialized, user-modified, and rule-tested transactionFromRule object in database
  27. /transact returns 200 to client requesting POST

Add /notify service

Add a /notify service that manages delivery of multiple notification types through multiple methods:

{
  "key": "",
  "sender_account": "STRING",
  "receiver_account": "STRING",
  "type": "STRING",
  "method": "STRING",
  "payload": "STRING",
  "sent_time": "DATETIME",
  "received_time": "DATETIME",
}

sender & receiver properties record accounts for their values.

Example values for type:
bid200
ask200
bidReceived200
askReceived200
transact200
accountCreateVerify200
accountCreate200
passwordChangeVerify200
passwordChange200
bidReject200
askReject200

Values for method:
webclient
email
sms
apns
fcm
api

*Note: GCM is replaced by FCM; also https://firebase.google.com/support/faq/#messaging-difference

convert s3 and lambda to terraform modules

  1. convert s3 and lambda to terraform modules
    EXCEPTION: the aws_s3_bucket.www_mxfactorial_react resource remains in workspace config because not applicable to all environments; prod only

add terraform/modules/cloudfront

  1. add terraform/modules/cloudfront
  2. add main.tf, outputs.tf and variables.tf to terraform/modules/cloudfront
  3. duplicate contents of terraform/workspaces/api-gateway.tf into terraform/modules/api-gateway/main.tf
  4. replace contents of terraform/workspaces/api-gateway.tf with module referencing terraform/modules/api-gateway/main.tf as source
  5. terraform apply to dev first, then prod when bugs = 0

storing credit and debit requests

  1. sign in to set current authenticated user = author
  2. create credit request on client, author = creditor
  3. client tests transactions against /rules
  4. /rules returns tested transactions
  5. client sends /rules-tested transactions to /transact
  6. /transact tests transactions against /rules
  7. /transact stores /rules-tested transactions received from client in db

expected
transactions added with creditor_approval_time and NOT debitor_approval_time


  1. sign in to set current authenticated user = author
  2. create debit request on client, author = debitor
  3. client tests transactions against /rules
  4. /rules returns tested transactions
  5. client sends /rules-tested transactions to /transact
  6. /transact tests items against /rules
  7. /transact stores /rules-tested transactions received from client in db

expected
transactions added with debtor_approval_time and NOT creditor_approval_time


*Estimations will include unit and e2e test coverage of requirements. New screens will include an e2e inventory test (example).

Add mock GraphQL rules query endpoint

  1. add rules query to graphql-faas accepting transactions array type
  2. in new resolvers/rules.js, add resolver mocking call to new /rules service returning transaction modification function:
    temporarily hardcode in resolver an updated Transaction Rule Script (trs) that adds a 9% sales tax transaction item to any array (see old addNinePercentPerItemCaliforniaStateSalesTax.js example containing deprecated key names and payload structure; refer to transactions array of bread, milk and honey as current requirement). new mock sales tax trs will return a new array with a sales tax transaction object added for any user instead of matching on single account, e.g. DannysMarket in old version
  3. in react client, add milk to item input field
  4. removing cursor from item input field sends transaction array to /rules query endpoint
  5. 0 additional transaction objects returned
  6. add 5.00 to milk price input field
  7. removing cursor from price input field sends transaction array to /rules query endpoint
  8. with client assuming 1 quantity default, 1 additional transaction object returned from /rules containing "9% state sales tax" and price = 1 quantity x 1.09 x 5.00 milk price
  9. new sales tax object has rule_instance_id populated with mock value
  10. if (rule_instance_id), new sales tax object displays below all user-generated transaction items in client
  11. if (rule_instance_id), new sales tax object displays WITHOUT transactionClear button (rule-generated objects not removable)
  12. add 3 to milk quantity input field
  13. removing cursor from quantity input field sends transaction array to /rules query endpoint
  14. updated transaction object returned from /rules containing 3 x 1.09 x price sales tax
  15. add bread item with price and quantity
  16. sales tax transaction object increments by quantity x 1.09 x price

i. exclude test coverage from estimation this task; new test coverage task issued after to avoid excessive changes during feature r&d
ii. send GET /rules (graphql) onblur from all transaction input fields except where rule_instance_id not populated; user-generated

requestDetailScreen

References

  1. transaction model
  2. 2,3,4 in wireframe

camelCase data-id values copied from requirements

  1. Set data-id to camelCase values from requirements.

Expected
End to end tests select on data-id values copied from requirements (reduces work fixing tests when UI improvements added later).


requestDetailScreen

  1. Sign in to display homeScreen.
  2. Select navigation button to display mobile nav menu.
  3. Select "Requests" button on mobile nav menu to display requestScreen.
  4. Select requestItemIndicator on requestScreen.

Expected

  1. requestDetailScreen displays:
  2. backButton
  3. "Request" screen title copy
  4. emailCopyButton
  5. requestingAccountIndicator (!currentAccount)
  6. sumTransactionItemIndicator ([price x quantity, ....].reduce())
  7. requestTimeIndicator with "Time of request {Day, Month Date, Year @ Time}" copy
  8. expirationTimeIndicator with "Time of expiration {Day, Month Date, Year @ Time}" copy
  9. transactButton
  10. rejectButton
  11. transactionItemIndicator(s) with "quantity x price name" copy
  12. "Transaction ID" copy
  13. transactionIdIndicator
  14. "Rule Instance IDs" copy
  15. ruleInstanceIdsIndicator
  16. "Pre-transaction balance"
  17. preTransactionBalanceIndicator

passwordApproveTransactionPopUp

  1. Select transactButton on requestDetailScreen.

Expected

  1. passwordApproveTransactionPopUp displays:
  2. sumTransactionItemIndicator
  3. "Enter password" copy
  4. passwordInputField
  5. cancelButton
  6. okButton

Dismiss passwordApproveTransactionPopUp

  1. Select transactButton on requestDetailScreen to display passwordApproveTransactionPopUp.
  2. Select cancelButton on passwordApproveTransactionPopUp.

Expected

  1. passwordApproveTransactionPopUp dismissed.
  2. requestDetailScreen displays.

transactionSuccessPopup

  1. Add TRUE password to passwordInputField on passwordApproveTransactionPopUp.
  2. Select okButton on passwordApproveTransactionPopUp.

Expected

  1. transactionSuccessPopup displays:
  2. newButton
  3. okButton

*Note: transactionSuccessPopup will display above historyScreen in future requirement.


Invalid styling and Incorrect Password copy on passwordApproveTransactionPopUp

  1. Add FALSE password to passwordInputField on passwordApproveTransactionPopUp.
  2. Select okButton on passwordApproveTransactionPopUp.

Expected

  1. passwordInputField displays empty with :invalid styling.
  2. Red "Incorrect Password" appears inside :invalid styled passwordInputField.

Remove Incorrect Password copy and invalid styling from passwordInputField

  1. Add FALSE password to passwordInputField on passwordApproveTransactionPopUp.
  2. Select okButton on passwordApproveTransactionPopUp.
  3. Select invalid styled passwordInputField to attempt another password.

Expected

  1. Initial passwordInputField styling displays.

homeScreen from transactionSuccessPopup

  1. Add password to passwordInputField on passwordApproveTransactionPopUp.
  2. Select okButton on passwordApproveTransactionPopUp to display transactionSuccessPopup.
  3. Select newButton on transactionSuccessPopup.

Expected

  1. homeScreen displays.

Cursor position locked in all but last transaction inputs

Branch: private-routes
Client: Chrome Version 68.0.3440.106 (Official Build) (64-bit)
OS: Mac OS 10.12.6 (16G1408)

Steps

  1. Navigate to / to display landingScreen.
  2. Sign In to display homeScreen.
  3. Select addItemButton 3 times to display 3 empty input groups.
  4. Insert cursor into first input[name="transaction-add-name"].
  5. Type bread.

Observed: Cursor position locked.

Expected: bread displays.

Note: Changing step 4 to "Insert cursor into second input...." produces same result. Cursor only moves in last input group. Please review "draft transaction" code. After fixing, please add test('empty transaction inputs in multiple groups receive values',... in e2e.

cache initial GET /rule response, then set onBlur to diff check

client: 0.1.6
server: 1.0.0
browser: Version 71.0.3578.98 (Official Build) (64-bit)

  1. add account with active 9.5% sales tax rule to recipientAccountInputField
  2. add milk, 2.00, 3
  3. add honey 4, 4
  4. add pasta 5, 5
  5. delete milk

expected
sumTransactionItemValueDisplayCell updates instantly

observed
visible delay in sumTransactionItemValueDisplayCell value update

2019-01-30 21 14 00

Print version and build details

general change

print version on landingScreen

  1. navigate to /

expected
similarly styled <IntroStyled>{process.env.REACT_APP_VERSION}</IntroStyled> displayed at bottom of LandingScreen.js (increase top margin)


changes for acceptance builds only

expose build and version to react app

  1. Add to .env.development.local:
REACT_APP_TEST_ENV=dev
REACT_APP_TEST_VERSION=$npm_package_version
REACT_APP_TEST_BRANCH=$(git branch | grep \* | cut -d ' ' -f2)
REACT_APP_TEST_DEVELOPER=
REACT_APP_TEST_PR_NUMBER=
REACT_APP_TEST_BUILD_NUMBER=
REACT_APP_PR_URL=
REACT_APP_BUILD_URL=

expected
variables accessible to react app

note:
last 2 exclude TEST substring


conditionally display build and version values in main nav menu

  1. add if (REACT_APP_HOST_ENV)... condition to display test build values
  2. select main nav hamburger menu button

expected

  1. only nonempty REACT_APP_TEST_* values added as items to bottom of main nav menu; set alternative background coloring for items, and list scrollable if too long
  2. if nonempty, display PR ${process.env.REACT_APP_TEST_PR_NUMBER} linked to REACT_APP_PR_URL in new window
  3. if nonempty, display Build ${process.env.REACT_APP_TEST_BUILD_NUMBER} linked to REACT_APP_BUILD_URL in new window

note:
ci will populate from built-in vars


general notes:

  1. only version displays on landing screen and test menu items NOT displayed e2e test required
  2. unit tests required
  3. remove REACT_APP_TEST_ENV from .env.development.local after finishing development since it will break main nav e2e tests. intended only for CI build and deploy of commits tagged for acceptance testing

Add an Approve All Bids transaction rule to each account during its creation

Transactions are measured when the db_time AND cr_time properties of a transaction record receive datetime values from a pair of debiting & crediting users. Though the right to reject a transaction is a feature in systemaccounting, there are many who have yet to become familiar with how to exercise this preference in detail. Therefore, add an Approve All Bids transaction rule to each account during its creation which, after, may be replaced or removed at the user's discretion.

Transact basic transfer on mobile web client

Produce the transactTransferSequence to enable a simple transfer transaction (non-commercial).

Removing the cursor after inserting the 'danny' user into the recipient input field (crediting account) triggers a GET /trs/public/danny request that returns all the transaction_item records (array) the /transact service will require at the time of POST:

"transaction_item": [
  {
    "item": "accounting",
    "quantity": 1,
    "value": 0.001,
    "db_account": "sandy",
    "cr_account": "mxfactorial"
  }
]

Selecting the "+ good or service" button on the client displays a set of transaction_item input fields underneath (item, quantity, value). There is no limit to the number of transaction items that may be added in a transaction. All extemporaneous transaction items (not generated by a transaction rule) are removable. Changing the user in the recipient field will trigger another GET /trs to populate a new set of required transaction items.
After transaction item input fields receive values, Sandy selects the transactButton to display a pop-up showing both 1) the sum of transaction_item values, and 2) a password input field. Inserting the password and selecting the okButton POSTs a transaction record to the /transact service. The /transact service reconciles required transaction items from /trs/danny to confirm they are present in addition to extemporaneous items:

"transaction_item": [
  {
    "item": "transfer",
    "quantity": 1,
    "value": 25.000,
    "db_account": "sandy",
    "cr_account": "danny"
  },
  {
    "item": "accounting",
    "quantity": 1,
    "value": 0.001,
    "db_account": "sandy",
    "cr_account": "mxfactorial"
  }
]

... and ii) if there are any other private transaction rules the danny account requires executing (e.g. "Every time I receive at least 1.00, pay my favorite charity 0.01").

After the /transact service reconciles between objects received from both the user and the /trs/danny service, it will 1) create the transaction_item records, and 2) add a timestamp to the cr_time property of the parent transaction record to identify a member-equilibrium of the time-coordinate's domain.

To enable expedient initial development, secondary & negative paths will be documented after primary positive paths.

Refine the user data model

Summary: Every time an account is created, two objects will be persisted, one of which will remain immutable (account_auth) because historical versions will be persisted over time to support transaction queries.

First, a lexical change: In systemaccounting, there aren’t “users”, but “accounts”.

Secondly, the object currently passed by the client to the new endpoint during account creation must be divided into 2 object ‘kinds’ (https://cloud.google.com/datastore/docs/concepts/entities#ancestor_paths) by the time it reaches the Datastore where they will have an ancestor/child relationship defined as an ‘entity group’ (“When you create an entity, you can optionally designate another entity as its parent; the new entity is a child of the parent entity..., https://cloud.google.com/datastore/docs/concepts/entities#properties_and_value_types).”

The reason for separation is that profile data for an account will change over time and historical versions will remain in storage to support transaction queries. In contrast, historical versions of the account & password properties will not be persisted.

The first object, or root of this entity group is of the ‘account_auth’ kind:

account (key* see Requirement 3 below)
password

The second object, or child of this entity group is of the ‘account_profile’ kind:

first_name
middle_name
last_name
date_of_birth
email_address
street_number
street_name
unit_number
floor_number
city
county
district
state
region
province
territory
postal_code
country
user_home_latlng
telephone_country_code
telephone_area_code
telephone_number
occupation
industry
created_time

Requirement 1: References to ‘user’ within properties & resources are changed to ‘account’ (in web client, too).

Requirement 2: Current object is split into two ‘kinds in the Datastore’: i) account_auth, ii) account_profile.

Requirement 3: Currently, each record is assigned a random numeric ID by the Datastore per https://cloud.google.com/datastore/docs/concepts/entities#ancestor_paths. Instead, assign the value of the account property to be the ‘key name’ for all account_auth entities (in other words, the username will be the key; not some number generated by the Datastore). The account_profile entities will receive a numeric ID.

Requirement 4: Entities of an account_profile kind are always designated as children of entities of account_auth kind.

add terraform/modules/api-gateway

  1. add terraform/modules/api-gateway
  2. add main.tf, outputs.tf and variables.tf to terraform/modules/api-gateway
  3. duplicate terraform/workspaces/api-gateway.tf into terraform/modules/api-gateway/main.tf
  4. replace contents of terraform/workspaces/api-gateway.tf with module referencing terraform/modules/api-gateway/main.tf as source
  5. add cors to new api-gateway module
  6. terraform apply to dev first, then prod when bugs = 0

historyScreen and historyDetailScreen

References:

  1. transaction model
  2. 1,2 in wireframe

camelCase data-id values copied from requirements

  1. Set data-id to camelCase values from requirements.

Expected

  1. End to end tests select on data-id values copied from requirements (reduces work fixing tests when UI improvements added later).

historyScreen

  1. Sign in to display homeScreen.
  2. Select navigation button to display mobile nav menu.
  3. Select "History" button on mobile nav menu.

Expected

  1. historyScreen displays:
  2. currentAccountBalanceIndicator
  3. historyItemIndicator (transaction where credit_time && debit_time)
  4. time of transaction in historyItemIndicator
  5. transaction partner in historyItemIndicator
  6. amount and direction of transaction (positive or negative)

historyDetailScreen

  1. Select historyItemIndicator on historyScreen.

Expected

  1. historyDetailScreen displays:
  2. backButton
  3. "Detail" copy
  4. emailCopyButton
  5. contraAccountIndicator
  6. sumTransactionItemValueIndicator ([price x quantity, ....].reduce())
  7. transactionTimeIndicator with {Day, Month Date, Year @ Time} copy
  8. transactionItemIndicator(s) with "quantity x price name" copy
  9. "Transaction ID" copy
  10. transactionIdIndicator
  11. "Rule Instance IDs" copy
  12. ruleInstanceIdsIndicator
  13. "Pre-transaction balance" copy
  14. preTransactionBalanceIndicator
  15. "Post-transaction balance" copy
  16. postTransactionBalanceIndicator
  17. disputeTransactionButton

historyScreen navigation from historyDetailScreen

  1. Select backButton on historyDetailScreen.

Expected

  1. historyScreen displays.

homeScreen navigation from historyScreen

  1. Select backButton on historyScreen.

Expected

  1. homeScreen displays.

homeIcon

  1. Select homeIcon from any screen.

Expected

  1. homeScreen displays.

*Estimations will include unit and e2e test coverage of requirements. New screens will include an e2e inventory test (example).

sumTransactionItemValueDisplayCell displays .toFixed(3)

client: 0.1.6
server: 1.0.0
browser: Version 71.0.3578.98 (Official Build) (64-bit)

  1. add account with active 9.5% sales tax rule to recipientAccountInputField
  2. add milk, 2.00, 3
  3. add honey 4, 4
  4. add pasta 5, 5

expected
sumTransactionItemValueDisplayCell displays 51.230, where value.toFixed(3)

observed
screen shot 2019-01-30 at 8 47 50 pm

display stored debit and credit requests on client

  1. sign in to display homeScreen
  2. debit and credit requests matching authenticated account fetched from graphql
  3. graphql resolves measure-faas

expected
measure-faas returns to gaphql:

(select *
FROM transactions
WHERE creditor='Person1' OR debitor='Person1'
AND (creditor_approval_time IS NULL OR debitor_approval_time IS NULL)
ORDER BY id desc limit 20) ORDER BY id;
  • note: 20 record limit avoids table scans during development. add more sophisticated querying for request history later.

  1. sign in to display homeScreen
  2. debit and credit requests matching authenticated account fetched from graphql

expected

  1. graphql returns 20 most recent debit and credit requests matching authenticated account

  1. sign in to display homeScreen
  2. debit and credit requests matching authenticated account fetched from graphql

expected

  1. 20 most recent debit and credit requests matching authenticated account stored in client state

  1. sign in to display homeScreen
  2. select mainNavButton to display mainNavMenu
  3. select mainNavRequestButton

expected

  1. debit and credit requests matching authenticated account fetched from graphql (requests fetched on display of homeScreen && requestScreen)
  2. requestScreen displays 20 most recent debit and credit requests matching authenticated account (order by approval timestamp)

  1. navigate Person1 to requestScreen
  2. Person2 sends Person1 debit request
  3. Person1 refreshes requestScreen

expected

  1. debit request from step 2 displays on Person1's request screen

*Estimations will include unit and e2e test coverage of requirements. New screens will include an e2e inventory test (example).

/transact adds debitor_approval_time and creditor_approval_time instead of client

goal: /transact always ignores debitor_approval_time and creditor_approval_time values received from clients. only /transact will set timestamp values in db after auth. auth will come later.

current task: remove all client code assigning debitor_approval_time and creditor_approval_time values. client continues to support debitor_approval_time and creditor_approval_time properties, and can even resend values initially assigned by /transact, but /transact always ignores client versions of debitor_approval_time and creditor_approval_time values


react test

  1. create transaction from client
  2. POST /transact

expected
client POSTs all transaction item values except values for debitor_approval_time and creditor_approval_time


/transact mock test

  1. /transact receives items from client
  2. /transact tests items against rules
  3. /transact adds debitor_approval_time and creditor_approval_time values to all items

expected
transactions stored in db with mysql datetime value


/transact mock test

  1. /transact receives items from client with debitor_approval_time and creditor_approval_time values
  2. /transact tests items against rules
  3. /transact adds debitor_approval_time and creditor_approval_time values to all items

expected
transactions stored in db with mysql datetime values from Step 3


*Estimations will include unit and e2e test coverage of requirements. New screens will include an e2e inventory test (example).

Create user and user_profile models

Create user & user_profile models using the Datastore API.

The username property is the auth_id. user properties list:

  • key (KeyProperty)
  • username (StringProperty)
  • password (StringProperty)

Create a one-to-many relationship between user & user_profile entities.
Multiple user_profile entities referencing a single user is intended to persist historical user_profile records.

Explanation: Transaction records will avoid duplicating the user_profile data of the transacting users. To reduce writes, transactions will simply index the current version of the user_profile records involved. Queries executed on transactions where user_profile data has changed will therefore filter for historically-matching user_profile records.

Example: The SandyDentist user records Los Angeles as her profile city. Sandy earns 1,200.00 for providing a root canal to another user. Sandy changes her profile city to San Francisco the following month after moving. Danny lives in Los Angeles and wishes to know what the average price of a root canal was in Los Angeles the previous month. Unless transaction entities duplicate user_profile data, the SandyDentist root canal transaction record will be excluded from Danny's query. Persisting & indexing historical versions of user_profile entities avoids i) duplicating user_profile data in transactions, and ii) compromising data (entropy).

user_profile properties list:

  • key (KeyProperty)
  • parent_key_ref
  • first_name (StringProperty)
  • middle_name (StringProperty)
  • last_name (StringProperty)
  • date_of_birth (DateProperty)
  • email_address (StringProperty)
  • street_number (FloatProperty)
  • street_name (StringProperty)
  • unit_number (StringProperty)
  • floor_number (IntegerProperty)
  • city (StringProperty)
  • county (StringProperty)
  • district (StringProperty)
  • state (StringProperty)
  • region (StringProperty)
  • province (StringProperty)
  • territory (StringProperty)
  • postal_code (StringProperty)
  • country (StringProperty)
  • user_home_latlng (GeoPtProperty; added by the Google Maps Geocoding API)
  • telephone_country_code (IntegerProperty)
  • telephone_area_code (IntegerProperty)
  • telephone_number (IntegerProperty)
  • occupation (StringProperty)
  • industry (StringProperty)

Extensibility alert: Similar to personal vs. business checking accounts, users will receive the feature to create multiple sub-accounts for whatever commercial interests they wish to pursue. The root user will become the personal account (consumptive), and the sub-users will be commercial (productive). All commerce-related properties located in the current user (occupation, industry) will then be moved to a new sub_user_profile model where they will be expanded to include, automate, and improve upon such services as the Standard Occupation and North American Industry Classification systems.

Add a /transact REST endpoint

Add a /transact REST endpoint to receive & persist transaction data POSTed by clients (e.g. https://docs.google.com/drawings/d/1nt4Kohxm-Gogw7rK_h_dH6Bl8cLmHOUuFpTtJdB0KZk/edit).

Be familiar with
i) https://cloud.google.com/datastore/docs/concepts/overview#comparison_with_traditional_databases
ii) https://cloud.google.com/nodejs/getting-started/using-cloud-datastore,and
iii) https://cloud.google.com/datastore/docs/concepts/entities

Requirements:
a. app.use your CRUD operation in main.js when a request for /systemaccounting/transact is received, similar to https://github.com/systemaccounting/mxfactorial/blob/master/main.js#L34
b. Add /transact/crud.js, similar to https://github.com/systemaccounting/mxfactorial/tree/master/users
c. Transaction objects received from POST requests will be divided into 4 object ‘kinds’ (https://cloud.google.com/datastore/docs/concepts/entities#ancestor_paths) by the time they reach the Datastore where they will form an ancestor/child relationship defined as an ‘entity group’ (“When you create an entity, you can optionally designate another entity as its parent; the new entity is a child of the parent entity..." - https://cloud.google.com/datastore/docs/concepts/entities#properties_and_value_types).

The first object, or “root” & “sole parent” of this entity group is of the ‘transaction’ kind:

(keys for these entities will be numeric IDs automatically assigned by the Datastore*)
db_author
cr_author
rejection_time
expiration_time

The second object, or child of this entity group is of the ‘debitor’ kind:

db_time
db_latlng

The third object, or child of this entity group is of the ‘creditor’ kind:

cr_time
cr_latlng

The fourth object, or child of this entity group is of the ‘transaction_item’ kind:

db_account
cr_account
value
quantity
units_measured
unit_of_measurement
name

d. Creating a transaction entity requires transaction_item entity > 0.
e. Leave Request & Response as a comment in this issue for client engineers.

Type checking will be added later: https://cloud.google.com/datastore/docs/concepts/entities#properties_and_value_types

*Note: Entities are assigned random numeric IDs by the Datastore per https://cloud.google.com/datastore/docs/concepts/entities#ancestor_paths. Alternatively, there is the option to assign property values to serve as keys (e.g., ‘username’ will be the key; not some number generated by the Datastore).

How to configure your environment & deliver code: https://github.com/systemaccounting/mxfactorial/wiki/Code-Delivery-Workflow

Seperation of private and public routes

Currently we have no protection against private routes. Direct access to Auth required paths should be redirected to a public path (e.g /login).


Redirect on direct access to private routes

Steps

1- Do not login or register on / page
2- Navigate /account

Expected

Browser redirect to landing screen


Redirect to 404 on unavailable route

Steps

1- Login with valid credentials
2- Manually edit url /not-a-valid-route

Expected

Browser navigates to 404 route.

404 route should be created.


Loading authenticated user data should be prevented when navigating between private routes for authenticated user

Steps

1- Login with valid credentials
2- See user will be loaded on /accounts
3- Navigate /requests screen
4- Click home link

Expected

Loading user should not be performed again.


@enestufekci Others from draft:

Navigating to requestsScreen without auth redirects to landingScreen

Steps

  1. Do NOT add credentials on /
  2. Navigate browser to /requests

Expected
Browser redirects to /auth


Navigating to historyScreen without auth redirects to landingScreen

Steps

  1. Do NOT add credentials on /
  2. Navigate browser to /history

Expected
Browser redirects to /auth


landingScreen

Steps

  1. Navigate to /

Expected
browser redirects /auth and landingScreen displays


termsOfUseScreenOne

Steps

  1. Navigate to /auth
  2. Select createAccountButton

Expected
redirects to /auth/create-account and termsOfUseScreenOne displays


requestScreen

Steps

  1. Navigate to / ( automatically redirects to /auth)
  2. Sign in
  3. Select menuIcon
  4. Select mainNavRequestButton

Expected
Browser navigate to /requests and displays requestScreen


Implementation Details from @enestufekci

  1. Reduce main route count to 2: private, public
  2. Create sub routes for main routes
  3. Public Routes: /auth, /auth/create-account

Private Routes: /account, /requests, /history

Fix route paths
Public -> /auth
LandingScreen -> /auth
CreateAccount -> /auth/create-account


Private -> /account
HomeScreen -> /account
RequestScreen -> /requests

Create a user context (Context Api) to cache authenticated user data which will feed private routes with user data.

Create a higher order component to bind the context to component.

Create rule and rule_instance models

Transaction rules are user-generated scripts written in TRS, the Transaction Rule Scripting language that automates the work of 'bankers', brokers, lawyers, tax collectors, accountants, and any other intermediary capable of introducing risk into the efficient pricing of opportunity.

Engineering-wise, transaction rules are nothing more than functions that modify or create transaction objects as required by users. Transaction automation empowers users to reference any measurable dimension defined to exist in the future as a parameter. For example, automating taxes, dividends, interest payments, recurring bills, payroll, and other future commitments may be triggered per:

  1. period of time: Every 30 days, my user pays this user some amount
  2. profitability milestone: When my user reaches some profit = revenue - expense, pay other user a fraction of some profit
  3. transaction_item: When the DannysMarket user is measured to be on the seller's side of a transaction, add a single sales tax transaction_item with the StateOfCalifornia user on the seller's side in the amount of 9% per item sold

Composite transaction rules are scripts within scripts that automate script execution. For example, if a business owner wishes to offer investors a portion of future earnings (equity) in exchange for money (capital), they may create a composite transaction rule script that says, "If my user is on the receiving side of a $200,000.00 transaction (rule 1), create a new rule for my user that pays 5% of its profits to the purchasing user every month (rule 2)." Alternatively, if a business owner wishes to offer investors a note (debt) in exchange for money (capital), they may create a composite script that says, "If my user is on the receiving side of a $200,000.00 transaction (rule 1), create a new rule for my user that pays 1.05/12 of the initial transaction amount to the purchasing user every month (rule 2)." Composite rule scripting simultaneously empowers i) business users to expediently shop for capital and ii) finance users to expediently shop for a return by eliminating the financial friction added by transaction-middlers.

To enable initial development, basic transaction rule scripts will be manually written and inserted into rule_instance records. However, a script generator will eventually be published that 1) standardizes script functions & parameters which, in turn, 2) guarantees the scripts generated by users may be reliably parsed for a set of user-defined parameters (committing these standards to memory & regularly applying them will produce a new breed of engineering-savvy financial lawyers who won't require attendance to business or law school).

For example, if parameters are introduced into the rule provided above:

When the DannysMarket user is measured to be on the seller's side of a transaction (cr_author), add a single sales tax transaction_item with the StateOfCalifornia user on the seller's side (cr_account) in the amount of 9% per item sold.

The resulting abstraction may be stored as a rule_instance record containing a JavaScript function in rule_instance.trs that modifies transaction objects when called and executed by opted-in users (see Data Model document for complete example):

{
  "created_time": "2016-06-27T23:42:10.307Z",
  "trs": "function addNinePercentPerItemCaliforniaStateSalesTax(transaction) {var cr_account = arguments.length <= 1 || arguments[1] === undefined ? "DannysMarket" : arguments[1]; var cr_accountNotDefine = false; transaction.transaction_item.forEach(function (item) {if (item.cr_account == null) {cr_accountNotDefine = true;}}); if (cr_accountNotDefine) {return transaction;} var cr_accountItems = transaction.transaction_item.filter(function (item) {return item.name !== "9% state sales tax";}); var salesTaxValue = 0; cr_accountItems.forEach(function (item) {if (item.cr_account == cr_account) {salesTaxValue = salesTaxValue + item.value * item.quantity * 0.09;}}); cr_accountItems.push({db_account: transaction.db_author, cr_account: "StateOfCalifornia", quantity: "1", units_measured: "", unit_of_measurement: "", value: salesTaxValue.toFixed(3), name: "9% state sales tax"}); transaction.transaction_item = cr_accountItems; transaction.transaction_item.forEach(function (item) {if (item.db_account != transaction.db_author) {item.db_account = transaction.db_author;}}); return transaction;};",
  "cr_author": "DannysMarket",
  "cr_author_active": true,
  "cr_author_public": true,
  "cr_account": "StateOfCalifornia",
  "cr_account_active": true,
  "cr_account_public": true,
  "request_expiration_time": "2016-06-27T23:42:10.307Z"
}

Functions will be standardized in a rule model as the service matures, and offered as a free library to the public (in contrast to rule_instance records where transaction property values are stored as arguments for a function's parameters, transaction property keys are stored as arguments for parameters in rule records). Similar to shopping for open-source code, users may adopt transaction rules as open-source legal contracts. The service responsible for creating rule_instance records from a rule will add 'public' and 'active' properties for every user parameter when adopted.

Parameters may identify variables other than users. Isolating tax policy to a single parameter visible to the public enables it to pursue such experiments as direct democracy, e.g. IF "vote" : {"yes" : >10000000} THEN change all "active" records to "inactive", THEN create, instantiate, and set as "active" a new rule where {"percent" : 8}.

Finally, rule_instance records with a time-interval dependency will be held in-memory to timely i) measure the fulfillment or failure of all variables they define, and ii) create new transaction records between the users they involve. When accommodating a large-scale demand for continuous computation becomes a priority, solutions such as Apache Storm and Spark Streaming will be considered.

Implement authentication for web client

image

to log the user in, web client should call the following endpoint.
http://apiurl:8080/systemaccounting/users/authenticate (POST)
(username and password should be sent in request body)

upon successful authentication, endpoint will return the user object an the security token. (see image)

webclient should store this token (in a cookie or browser local storage). Then for each api call, this security token should be appended as the authorization header.

It is recommended to do this (append token to header) in one place rather than manually adding this to the request for each call.

image

it is also better to log the user out (clear the token from the storage) (redirect user to login page) whenever some endpoint return unauthorized.

Add UI theme

Because this project is a data science initiative, it's initial concern for the web client is producing buttons and forms that test positive for passing/receiving data as expected to/from the database. Therefore, the UI hasn't received much attention.

The task of adding a theme to the web client, screen by screen (beginning with the landing page), recognizes that a cosmetic overhaul is likely to attract additional contributors & test users. Current production environment links:
a. landingScreen = https://mxfactorial.io/
b. homeScreen = https://mxfactorial.io/#/home
c. transactionHistoryScreen = https://mxfactorial.io/#/TransactionHistory
d. The rest of the basic UI/UX can be viewed by opening the links to Google Drawing documents inside the Github issues: https://github.com/systemaccounting/mxfactorial/issues

mxfactorial theme: Just as with enough vertical distance a human's perspective is altered to the degree that it must reject a flat earth, mxfactorial offers a similar change in perspective of value & time: "locally flat, globally spherical"*.

  1. Crop the center of a sphere with a mobile-first screen (see mock and normal_surface_illustration.svg for viewer perception).
  2. Add sky-blue background.
  3. Add the equation, then rotate 30 degrees left to give it a 3D orientation inside the sphere.
  4. Conform the input fields, buttons, and forgot password link to the sphere's surface to give user's the experience they're conducting operations on the surface of the sphere.

Assets:
sphere.eps
sphere.jpg
mxfactorial.png

Eventually, the equation will rotate as users select buttons that spin the surface of the sphere to transition between screens (see Affine Connection wiki, the concept of Development, and rolling along a curve). Rotation of the equation is restricted within a fixed 0 < x < 180 boundary for non-transaction activity. The equation completes a full rotation upon completion of a transaction.

Pending approval of final version by @mxfactorial, complimentary-styled buttons, forms, menus, etc., is left to the discretion of the designer.

*_Note_: "globally spherical" admittedly redundant if the domain vs. shape distinction is ignored

POST to /transact from web client

Adding partial completion of #8 now that #34 was merged & deployed.

Requirements:
a. db_author: Paying user authorizing the transaction (user signed into the client; hardcode value termporarily until #27 is complete)
b. cr_author: User authorizing the receipt of payment
c. db_time: datetime db_author approves transaction (stamp issued by /transact; not client)
d. db_latlng: http://www.w3schools.com/html/html5_geolocation.asp from client
e. cr_time: datetime cr_author approves transaction (stamp issued by /transact; not client)
f. cr_latlng: http://www.w3schools.com/html/html5_geolocation.asp from client
g. db_account: Paying user (decreasing account; different from db_author which is only responsible for recording the user responsible for approving a transaction)
h. cr_account: User receiving payment (increasing account)
i. quantity: quantityInputField
j. units_measured: (leave empty; feature will be added later)
k. unit_of_measurement: (leave empty; feature will be added later)
l. valueInputField: value
m. nameInputField: name

Example

{
    "db_author":"Sandy",
    "cr_author":"Danny",
    "db_time":"10:01",
    "db_latlng":"40.7128,74.0059",
    "cr_time":"10:02",
    "cr_latlng":"40.7128,74.0059",
    "transaction_item" : [
        {"db_account":"Sandy",
         "cr_account":"Danny",
         "quantity":1,
         "units_measured":"1",
         "unit_of_measurement":"Ltr",
         "value":10,
         "name":"Milk"
        },{"db_account":"Sandy",
         "cr_account":"Danny",
         "quantity":1,
         "units_measured":"1",
         "unit_of_measurement":"Ltr",
         "value":5,
         "name":"Bread"
        }
    ]
}

n. Selecting the transactButton displays the passwordApproveTransactionPopUp containing a sumTransactionItemsDisplayCell and a passwordInputField
o. Selecting the cancelButton on the passwordApproveTransactionPopUp dismisses the passwordApproveTransactionPopUp
p. Selecting the okButton after inserting a password on the passwordApproveTransactionPopUp requests a POST to /transact
r. Returning a 200 from /transact displays the transactionSuccssfulPopUp on top of the transactionHistoryScreen (continue using hardcoded transactionHistoryItemDisplayCell on transactionHistoryScreen from #30 until a GET /history is available)
s. Returning an error from /transact displays a "Transaction failed" below the passwordInputField on the passwordApproveTransactionPopUp (more error cases will be added later)
t. Selecting the okButton after leaving passwordInputField empty displays a "Password required" indicator inside the passwordInputField
u. Selecting the okButton on the transactionSuccssfulPopUp dismisses the transactionSuccssfulPopUp
v. Selecting the newButton on the transactionSuccssfulPopUp displays the homeScreen

INSERT rules-tested transaction items

/transact service receives transactions items

  1. add milk x 2 x 2, bread x 3 x 3, honey x 4 x 4 items
  2. select request button
  3. POST mutation

expected

  1. /transact service receives milk, bread, honey and tax transactions items

/transact service tests transactions items against /rules

  1. /transact service receives milk, bread, honey and tax items

expected

  1. /transact service assigns recieved items as itemsUnderTestArray, then logs
  2. /transact service POST /rules itemsUnderTestArray
  3. /transact service assigns POST /rules response to itemsStandardArray, then logs
  4. /transact service tests itemsUnderTestArray for equality with itemsStandardArray (use sortBy first if using _.)

INSERT into transactions table

  1. return true from /transact service testing equality of itemsUnderTestArray with itemsStandardArray

expected

  1. /transact service logs EQUALITY message with identical item arrays
  2. /transact service INSERTs itemsUnderTestArray into transactions table

unequal transaction items

  1. send array missing a rules-required item to /transact
  2. return false from /transact service testing equality of itemsUnderTestArray with itemsStandardArray

expected

  1. /transact service logs UNEQUAL message with unidentical item arrays
  2. /transact service returns required items missing error to client
  3. /transact service does NOT INSERT itemsUnderTestArray into transactions table

*Estimations will include unit and e2e test coverage of requirements. New screens will include an e2e inventory test (example).

Add transactionHistory & transactionDetail screens (UI only, no back-end integration)

Add UI only for screens 1 and 2 on https://docs.google.com/drawings/d/1W4KTDjrqXGz7Xvv56529XBKnOoDdwBZzqUyHPuYQGbE/edit?usp=sharing to enable partial completion of #10.
Create mock templates with hardcoded values to enable the convenient addition of values passed from the Datastore in the future. See #2 for transaction data model to anticipate values expected from the Datastore.

  • Selecting the historyMainNavMenuItem displays the transactionHistoryScreen
  • A list of transactionHistoryItemDisplayCell display on the historyScreen. Human-readable display logic for transaction time stamps will be added later to conserve developer time
  • Selecting a transactionHistoryItemDisplayCell displays the transactionDetailScreen
  • The transactionDetailScreen displays:
    • a backButton
    • an emailCopyButton
    • a transactionPartnerDisplayCell
    • a sumTransactionItemsDisplayCell
    • a transactionTimeDisplayCell
    • a list of transactionItemDisplayCell
    • a trsGeneratedTransactionKeyDisplayCell
    • a preTransactionDisplayCell
    • a concurrentTransactionDisplayCell
    • a postTransactionDisplayCell
    • a disputeTransactionButton

Add UI to home screen

Add UI only for screens 0, 1, and 2 on https://docs.google.com/drawings/d/1nt4Kohxm-Gogw7rK_h_dH6Bl8cLmHOUuFpTtJdB0KZk/edit to enable partial completion of #8

  • Center-justify the text inserted into the creditorAccountInputField and add ‘user’ as a placeholder
  • Selecting the plusGoodOrServiceButton (“+ good or service" button) displays a set of input fields responsible for building a transaction_item array. A transaction_item is an array of objects each containing the following properties: i) item, 2) quantity, 3) value, 4) cr_account (see #8 for illustration of object). The transaction_item is an array because transactions are mathematically interpreted as an array of transaction_item records
  • A new empty set of transaction_item input fields appears above the transactButton every time the addGoodOrServiceButton is selected. Extensibility alert: For now, a deleteGoodOrServiceButton (https://drive.google.com/file/d/0B9xlXsaN9dVQREJQOHhYaWp3Z28/view?usp=sharing) will appear with each set of transaction_item input fields, but this logic will change once the transaction rule feature is added, i.e. the appearance of a deleteGoodOrServiceButton will depend on transaction rules
  • Selecting the deleteGoodOrServiceButton deletes its corresponding set of transaction_item input fields
  • The sumTransactionItemsDisplayCell displays the sum of all (value x quantity) transaction_item objects
  • Selecting the transactButton displays the passwordApproveTransactionPopUp
  • Selecting the cancelButton on the passwordApproveTransactionPopUp dismisses the passwordApproveTransactionPopUp

Create data visualization web client

Create a /visualization.html page that embeds a U.S.-centered map using the Google Maps JavaScript API.

Systemaccounting data queried from this page's input fields will be inserted into the GeoJSON objects expected by the Data Layer (click Layers Intro for more information). To serve the Data class its expected GeoJSON objects, a library of various GeoJSON data sources.for cities, states, and any other supported geographical units* must be stored internally to enable the following sequence: wrap queried systemaccounting data in pre-existing GeoJSON objects, then add the GeoJSON object to the Data Class.

Create 4 input fields positioned horizontally to one another above the map with enough room to the right of the last input field for a 'Query' button. The multiple fields will eventually merge into a single field once the public learns how to structure their queries.

In the first input field, insert the following placeholder hint, "name of public user, industry, city, state, etc."

The second input field displays a "measurement" placeholder hint and is a drop-option menu containing revenue, expense, profit (revenue-expense), and profit margin (profit/revenue).

The third & fourth fields are datetime pickers that launch calendars, etc. to specify the desired range between beginning & end datetime measurements.

Underneath the maps object, center the following text in modestly-sized italics, "This is how physics & data science supplies human beings universal access to knowledge about the real-time performance of their economy. Goodbye, Federal Funds Target Rate, LIBOR, Monetary Policy, and whatever else has nothing to do with reality."

*Note: Geographical information formats include Shapefiles, KML (XML), and GeoJSON. If a non-GeoJSON format supplies a useful set of shapes, format conversion is trivial.

Debiting user (buyer) approves a transaction request

Produce the buyerApproveRequestSequence to enable a debiting user's approval of a transaction request created by a crediting user.

Create mock templates with hardcoded values to enable the convenient addition of values passed from the database where necessary.

a. Selecting the requestsMainNavMenuItem displays the transactionRequestScreen containing:
i) a button group featuring a rejectedButton & an activeButton (default)
ii) a list of transactionRequestItemDisplayCell(s) sorted according to most recent request received, and filtered according to rejectedButton & activeButton state
b. Selecting the activeButton filters requests where transaction.rejected_time does NOT exist AND current time < transaction.expiration_time
c. Selecting the rejectedButton filters requests where transaction.rejected_time EXISTS OR current time >= transaction.expiration_time
d. Receiving an askReceived message from the /notify service increases the notificationCounter by 1
e. If the transactionRequestScreen is currently in view, receiving an askReceived message from the /notify service BOTH i) adds a transactionRequestItemDisplayCell to the top of the featured list, and ii) increases the notificationCounter by 1
f. Selecting a transactionRequestItemDisplayCell on the transactionRequestScreen displays the corresponding transactionRequestDetailScreen containing (similar to #30):
i) a backButton linked to the previous screen
ii) an emailCopyButton
iii) a creditorAccountDisplayCell
iv) a sumTransactionItemDisplayCell (sum transaction_item.quantity x transaction_item.value)
v) a requestTimeDisplayCell
vi) an expirationTimeDisplayCell
vii) a transactButton
viii) a rejectButton
ix) a list of transactionItemDisplayCell(s) containing transaction_item.quantity, transaction_item.value, and transaction_item.name
x) a transactionIdDisplayCell
xi) a preTransactionBalanceDisplayCell
g. Displaying a transactionRequestDetailScreen requests an update of its askReceived record to /notify (datetime value of notification.received is server-generated)
h. Returning a 200 from /notify of an askReceived update decreases the notificationCounter by 1 & removes the notificationDropDownMenuItem from the notificationDropDownMenu
i. Selecting the notificationFlag displays a notificationDropDownMenu that contains a scrollable list of notificationDropDownMenuItem(s) (improvise dimensions & color until UI theme is implemented, and print untranslated time stamp in the notificationDropDownMenuItem to save developer time; human-readable translation rules for time stamps will be added later)
j. While the notificationDropDownMenu is displayed, selecting anywhere else on the screen EXCEPT the notificationDropDownMenu dismisses the notificationDropDownMenu
k. Selecting a notificationDropDownMenuItem on the notificationDropDownMenu displays its transactionRequestDetailScreen (as required by "g", displaying a transactionRequestDetailScreen requests an update of an askReceived record to /notify, which decreases the notificationCounter by 1 & removes the notificationDropDownMenuItem from the notificationDropDownMenu IF a 200 is returned from /notify)
l. Selecting the clearAllButton on the notificationDropDownMenu requests /notify to update notification.received of all askReceived records listed in notificationDropDownMenu
m. Returning a 200 from /notify to update each askReceived record referenced by the clearAllButton decreases the notificationCounter by the commensurate number & removes the notificationDropDownMenuItem(s) from the notificationDropDownMenu
n. Selecting the transactButton on the transactionRequestDetailScreen displays the passwordApproveTransactionPopUp that contains:
i) a sumTransactionItemDisplayCell
ii) a passwordInputField
iii) a cancelButton
iv) an okButton
o. Selecting the cancelButton on the passwordApproveTransactionPopUp dismisses the passwordApproveTransactionPopUp
p. Selecting the okButton after inserting a password on the passwordApproveTransactionPopUp requests a POST to /transact
q. Returning a 200 from /transact displays the transactionSuccessfulPopUp on top of the transactionHistoryScreen (continue using hardcoded transactionHistoryItemDisplayCell on transactionHistoryScreen from #30 until a GET /history is available)
r. Returning an error from /transact displays a "Transaction failed" below the passwordInputField on the passwordApproveTransactionPopUp (more error cases will be added later)
s. Selecting the okButton after leaving the passwordInputField empty on the passwordApproveTransactionPopUp displays a "Password required" indicator inside the passwordInputField
t. Selecting the okButton on the transactionSuccessfullPopUp dismisses the transactionSuccessfulPopUp
u. Selecting the newButton on the transactionSuccessfulPopUp displays the homeScreen
m. Selecting the rejectButton displays a light/pastel red areYouCertainPopUp (no mock; please improvise) containing:
i) a cancelButton
ii) a yesButton
v. Selecting the cancelButton on the areYouCertainPopUp dismisses the areYouCertainPopUp
w. Selecting the yesButton i) sends a request to /transact to add a time stamp (server-generated) to transaction.rejection_time
x. Receiving a 200 from /transact displays the transactionRequestScreen sorted according to most recent rejected items

Create transaction and transaction_item models

A systemaccounting function requires persisting time series data in the form of transaction records (see Bigtable & Cassandra documentation on this subject).

A transaction contains nested debitor, creditor, and transaction_item records which the Datastore documentation identifies as forming an ancestor relationship.

transaction
    ├───creditor
    ├───debitor
    └───transaction_items

Furthermore, a one-to-many relationship is necessary since a single transaction contains multiple transaction_item records.

The parent transaction record, a.k.a. the root entity of a group, contains the following properties (hint: db = debit = buyer, cr = credit = seller):

  • key
  • expiration_time (DateTimeProperty; the expiration time of a transaction)
  • rejection_time (DateTimeProperty; the rejection time of a transaction)
  • db_author (key reference to debiting user authorizing the transaction)
  • cr_author (key reference to crediting user authorizing the transaction)

The first child debitor entity contains these properties:

  • db_time (DateTimeProperty; datetime of authorizing debiting user)
  • db_latlng (GeoPtProperty; device generated latitude & longitude of debiting user; getCurrentPosition() Method)

The second child creditor entity contains these properties:

  • cr_time (DateTimeProperty; datetime of authorizing crediting user)
  • cr_latlng (GeoPtProperty; device generated latitude & longitude of crediting user; same)

A 4D null vector of risk-free value is measured when the db_time AND cr_time properties of a transaction receive datetime values from a pair of debiting & crediting users. For security, systemaccounting properties are immutable.

A bid is measured when the db_time property receives a datetime value from a debiting user, but is NOT received by the cr_time property from a crediting user.

An ask is measured when the cr_time property receives a datetime value from a crediting user, but is NOT received by the db_time property from a debiting user.

The third child transaction_item entity contains these properties:

  • key
  • parent_key_ref (transaction)
  • trs_instance_key_ref (key of transaction rule instance requiring an item's inclusion, e.g. tax)
  • db_account (parent key ref or index to current user_profile)
  • cr_account (same)
  • value (FloatProperty: 3-digit decimal-supported price; tenth-pennies)
  • quantity (FloatProperty: 2.0)
  • units_measured (FloatProperty: 1.0)
  • unit_of_measurement (StringProperty: gallons, kilometers, hours, etc.)
  • name (StringProperty: milk)

Single Item Example: A transaction_item record supports the following sentence, "Sandy paid DannysMarket 7.000 for 2 x 1 gallon [bottles of] milk."

db_account cr_account value quantity units_measured unit_of_measurement name
Sandy DannysMarket 3.500 2.0 1.0 gallon milk

Multiple Item Example: A transaction record supports summarizing the following sentences, "Sandy paid DannysMarket $3.500 for 2 x 1 gallon [bottles of] milk + Sandy paid DannysMarket 3.250 for 2 x 22 ounce [loaves of] bread + Sandy paid DannysMarket 9.000 for 1 x 17 ounce [bottle of] honey + Sandy paid StateOfCalifornia $2.03 for $22.05 x 9% x quantity x value state sales tax.

In short, mathematical operations are required (see next paragraph) to produce the total value transacted, i.e. sum(3.500 x 2, 3.250 x 2, 9.00 x 1, 2.03 x 1) = 24.53.

db_account cr_account value quantity units_measured unit_of_measurement name
Sandy DannysMarket 3.500 2.0 1.0 gallon milk
Sandy DannysMarket 3.250 2.0 22.0 ounce bread
Sandy DannysMarket 9.000 1.0 17.0 ounce honey
Sandy StateOfCalifornia 2.030 1.0 22.5 0.09 x item_quantity x value state sales tax

In observance of systemaccounting's inviolable doctrine of supplying the public unmodified scientific feedback (which differs from current pricing policies), only mathematical functions are permitted to produce new objects from user-generated objects:

In functional code, the output value of a function depends only on the arguments that are input to the function, so calling a function f twice with the same value for an argument x will produce the same result f(x) each time. Eliminating side effects, i.e. changes in state that do not depend on the function inputs, can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming. (https://en.wikipedia.org/wiki/Functional_programming 2015-12-25-11-44)

Extensibility alert: The transaction entity will eventually receive additional property-pairs to identify the context of a transaction between buyers & sellers, e.g. db_note,cr_note; db_device,cr_device; etc. A transaction record groups 4 different levels of time-variant property values:

  1. account: invariant; never changes
  2. account_profile: changes infrequently as users change addresses, etc.
  3. transaction: changes less frequently than transaction_item property values since variability of items users transact is more than the variability of context under which transactions occur (location, devices, etc.)
  4. transaction_item: changes frequently; free-market dynamics

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.