cashless2ecash

cashless2ecash: pay with cards for digital cash (experimental)
Log | Files | Refs | README

commit b02fedd6450abefe883565c7205e55a3b8f2932f
parent 59d26fbea663abc3becdf1f8f45010e079a57e00
Author: Joel-Haeberli <haebu@rubigen.ch>
Date:   Tue, 12 Mar 2024 18:54:41 +0100

review: add fields and comments on sql

Diffstat:
Mdata/nonce2ecash_schema.sql | 110++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Mnonce2ecash/pkg/common/http-util.go | 31+++++++++++++++++++------------
2 files changed, 103 insertions(+), 38 deletions(-)

diff --git a/data/nonce2ecash_schema.sql b/data/nonce2ecash_schema.sql @@ -1,35 +1,93 @@ -DROP TABLE IF EXISTS withdrawal; -DROP TABLE IF EXISTS terminal; -DROP TABLE IF EXISTS terminal_provider; -DROP TYPE WITHDRAWAL_OPERATION_STATUS; +-- => proper versioning.sql nehmen (siehe exchange.git), +DROP SCHEMA IF EXISTS nonce2ecash CASCADE; -CREATE TYPE WITHDRAWAL_OPERATION_STATUS AS ENUM ( - 'pending', - 'selected', - 'aborted', - 'confirmed' +-- The schema nonce2ecash contains all +CREATE SCHEMA nonce2ecash; + +-- The enumeration contains the states which a withdrawal can be in. +-- The states are the same as in the bank-integration API: +-- pending : the operation is pending parameters selection (exchange and reserve public key) +-- selected : the operations has been selected and is pending confirmation +-- aborted : the operation has been aborted +-- confirmed: the transfer has been confirmed and registered by the bank +CREATE TYPE nonce2ecash.withdrawal_operation_status AS ENUM ( + 'pending', + 'selected', + -- => bound? -> I wanted to stick to the same terms as the bank-integration API + 'aborted', + 'confirmed' ); -CREATE TABLE IF NOT EXISTS terminal_provider ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - name VARCHAR(50), - remarks VARCHAR(255) +-- copied from https://git.taler.net/merchant.git/tree/src/backenddb/merchant-0001.sql +CREATE TYPE nonce2ecash.taler_amount_currency + AS (val INT8, frac INT4 , curr VARCHAR(12)); +COMMENT ON TYPE nonce2ecash.taler_amount_currency + IS 'Stores an amount, fraction is in units of 1/100000000 of the base value'; + +-- The terminal_provider table describes a specific provider of a cashless2ecash +-- terminal provider. +CREATE TABLE IF NOT EXISTS nonce2ecash.terminal_provider ( + -- Uniquely identifies a provider. + provider_terminal_id INT8 GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + -- Name of the provider. Must be unique, because used to choose the process + -- proofing the transaction. + name TEXT NOT NULL UNIQUE, + -- The url of the providers backend, used to proof the transaction. + backend_base_url TEXT NOT NULL, + -- Credentials used to access the backend of the provider. + backend_credentials TEXT NOT NULL ); -CREATE TABLE IF NOT EXISTS terminal ( - id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, - access_token BYTEA CHECK (LENGTH(access_token)=32), - active BOOLEAN DEFAULT TRUE, - remarks VARCHAR(255), - provider_id BIGINT NOT NULL REFERENCES terminal_provider(id) -) +-- The terminal table contains information about terminals of providers. +-- This includes the information if they are active (allowed to do transactions) +-- and their credentials. +CREATE TABLE IF NOT EXISTS nonce2ecash.terminal ( + -- Uniquely identifies a terminal. + terminal_id INT8 GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + -- The access token of the terminal. The access token is used to + -- authenticate against the nonce2ecash API. + access_token BYTEA CHECK (LENGTH(access_token)=32) NOT NULL, + -- A terminal may be deactivated. This MUST be checked at each request of + -- the terminal. This allows to immediately block any terminal from the + -- withdrawal process if necessary. + active BOOLEAN DEFAULT TRUE NOT NULL, + -- The description is thought to help humans to identify a terminal. + -- This may include the location and an identifier of the terminal. + description TEXT, + -- Each terminal belongs to a specific terminal provider. The terminal + -- provider indicates which process is used by nonce2ecash to proof a + -- transaction. + provider_id INT8 NOT NULL REFERENCES terminal_provider(provider_terminal_id) +); -CREATE TABLE IF NOT EXISTS withdrawal ( +-- A withdrawal represents a withdrawal process initiated by one terminal. +CREATE TABLE IF NOT EXISTS nonce2ecash.withdrawal ( + -- The withdrawal id is a nonce generated by the terminal requesting a + -- withdrawal. withdrawal_id BYTEA PRIMARY KEY CHECK (LENGTH(withdrawal_id)=32), - reserve_pub_key BYTEA CHECK (LENGTH(reserve_pub_key)=32), - registration_ts INT8, - amount VARCHAR(50), - withdrawal_status WITHDRAWAL_OPERATION_STATUS NOT NULL, + -- The reserve public key which will hold the amount of the withdrawal + -- after completion. + reserve_pub_key BYTEA CHECK (LENGTH(reserve_pub_key)=32) NOT NULL, + -- The timestamp, when the withdrawal request was initially issued. + registration_ts INT8 NOT NULL, + -- The amount of the withdrawal. This amount is the effective amount to be + -- put into the reserve. Fees are stored in the fees field. + amount nonce2ecash.taler_amount_currency NOT NULL, + -- The fees of the withdrawal. This includes the fees of the exchange and the + -- fees of the provider. + fees nonce2ecash.taler_amount_currency NOT NULL, + -- The status of the withdrawal. Indicates in which step of the process + -- the withdrawal currently is. + withdrawal_status withdrawal_operation_status NOT NULL, + -- The terminal id indicates at which terminal the withdrawal was initiated. terminal_id BIGINT NOT NULL REFERENCES terminal(id) + -- Stores a transaction identifiers supplied by the provider which helps to + -- request information about it at the providers backend. + provider_transaction_id TEXT, + -- Timestamp allowing to remember when we asked last about this transaction. + -- This helps us controlling retries. + last_retry_ts INT8, + -- stores proof of transaction upon final completion delivered by the + -- providers system + completion_proof BLOB ); - diff --git a/nonce2ecash/pkg/common/http-util.go b/nonce2ecash/pkg/common/http-util.go @@ -43,19 +43,20 @@ func HttpPostOrError[T any, R any]( responseCodec Codec[R], ) (*R, int, error) { - encodedBody, err := requestCodec.encode(body) - if err != nil { - return nil, -1, err - } - var res *http.Response if body == nil { if requestCodec == nil { - res, err = http.Post( + res, err := http.Post( formatUrl(req, pathParams, queryParams), "", - encodedBody, + nil, ) + + if err != nil { + return nil, -1, err + } + + return nil, res.StatusCode, nil } else { return nil, -1, errors.New("invalid arguments - body was not present but codec was defined") } @@ -63,20 +64,26 @@ func HttpPostOrError[T any, R any]( if requestCodec == nil { return nil, -1, errors.New("invalid arguments - body was present but no codec was defined") } else { + + encodedBody, err := requestCodec.encode(body) + if err != nil { + return nil, -1, err + } + res, err = http.Post( formatUrl(req, pathParams, queryParams), requestCodec.httpApplicationContentHeader(), encodedBody, ) - } - } - if err != nil { - return nil, -1, err + if err != nil { + return nil, -1, err + } + } } if responseCodec == nil { - return nil, res.StatusCode, err + return nil, res.StatusCode, nil } resBody, err := responseCodec.decode(res.Body)