added testing strategy

This commit is contained in:
Mike Stepanovic 2025-02-11 18:08:23 -07:00
parent 6288700af7
commit 8ab094b0c6
75 changed files with 1531 additions and 387 deletions

42
.github/workflows/dbt_test_full.yml vendored Normal file
View File

@ -0,0 +1,42 @@
name: dbt_test_scheduled
run-name: dbt_test_scheduled
on:
workflow_dispatch:
schedule:
- cron: '0 1 * * *'
env:
DBT_PROFILES_DIR: ./
ACCOUNT: "${{ secrets.ACCOUNT }}"
ROLE: "${{ secrets.ROLE }}"
USER: "${{ secrets.USER }}"
PASSWORD: "${{ secrets.PASSWORD }}"
REGION: "${{ secrets.REGION }}"
DATABASE: "${{ secrets.DATABASE }}"
WAREHOUSE: "${{ secrets.WAREHOUSE }}"
SCHEMA: "${{ secrets.SCHEMA }}"
jobs:
run_dbt_jobs:
runs-on: ubuntu-latest
environment:
name: workflow_prod
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.10.x"
cache: "pip"
- name: install dependencies
run: |
pip install -r requirements.txt
dbt deps
- name: Run DBT Jobs
run: |
dbt test -m "stellar_models,models/silver" "stellar_models,models/gold"

54
.github/workflows/dbt_test_recent.yml vendored Normal file
View File

@ -0,0 +1,54 @@
name: dbt_test_recent
run-name: dbt_test_recent
on:
workflow_dispatch:
# schedule:
# # Daily at 8:30am UTC
# - cron: '30 8 * * *'
env:
USE_VARS: "${{ vars.USE_VARS }}"
DBT_PROFILES_DIR: "${{ vars.DBT_PROFILES_DIR }}"
DBT_VERSION: "${{ vars.DBT_VERSION }}"
ACCOUNT: "${{ vars.ACCOUNT }}"
ROLE: "${{ vars.ROLE }}"
USER: "${{ vars.USER }}"
PASSWORD: "${{ secrets.PASSWORD }}"
REGION: "${{ vars.REGION }}"
DATABASE: "${{ vars.DATABASE }}"
WAREHOUSE: "${{ vars.WAREHOUSE }}"
SCHEMA: "${{ vars.SCHEMA }}"
SLACK_WEBHOOK_URL: "${{ secrets.SLACK_WEBHOOK_URL }}"
concurrency:
group: ${{ github.workflow }}
jobs:
run_dbt_jobs:
runs-on: ubuntu-latest
environment:
name: workflow_prod
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "${{ vars.PYTHON_VERSION }}"
cache: "pip"
- name: install dependencies
run: |
pip install -r requirements.txt
dbt deps
- name: Run DBT Jobs
run: |
dbt run -m "stellar_models,tag:recent_test"
dbt test -m "stellar_models,tag:recent_test"
continue-on-error: true
- name: Log test results
run: |
python python/dbt_test_alert.py

View File

@ -27,6 +27,9 @@ There is more information on how to use dbt docs in the last section of this doc
- [core.fact_operations](https://flipsidecrypto.github.io/stellar-models/#!/model/model.stellar_models.core__fact_operations)
- [core.fact_transactions](https://flipsidecrypto.github.io/stellar-models/#!/model/model.stellar_models.core__fact_transactions)
**Convenience Views:**
- [core.ez_operations](https://flipsidecrypto.github.io/stellar-models/#!/model/model.stellar_models.core__ez_operations)
### DeFi Tables (`stellar`.`DEFI`.`<table_name>`)
**Fact Tables:**

View File

@ -0,0 +1,3 @@
{% docs account_muxed_id %}
Record that contains details based on the type of operation executed. Each operation will return its own relevant details, with the rest of the details as null
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs asset %}
The asset available to be claimed in the form of "asset_code:issuing_address". If the claimable balance is in XLM, it is reported as "native"
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs begin_sponsor_muxed %}
If the initiating sponsorship account is multiplexed, the virtual address.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs begin_sponsor_muxed_id %}
If the initiating sponsorship account is multiplexed, the integer representation of the virtual address.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs block_timestamp %}
A clone of closed_at for join convenience.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs claimable_balance_id %}
The balance id of the claimable balance which is no longer sponsored
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs claimant %}
The account address of the account which claimed the claimable balance
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs claimant_muxed %}
If the account is multiplexed, the virtual address of the account which claimed the claimable balance
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs claimant_muxed_id %}
If the account is multiplexed, an integer representation of the muxed account which claimed the balance
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs claimants %}
An unstructured field that lists account addresses eligible to claim a balance and the conditions which must be satisfied to claim the balance (typically time bound conditions)
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs data_account_id %}
The account address of the account whose data entry is no longer sponsored
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs data_name %}
The name of the data entry which is no longer sponsored
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs from_account %}
The account address from which the payment/contract originates (the sender account)
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs from_muxed %}
If the account is multiplexed, the virtual address of the sender account
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs from_muxed_id %}
If the account is multiplexed, the integer representation of the virtual address of the sender account
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs funder_muxed %}
If the account is multiplexed, the virtual address of the account funding the new account
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs funder_muxed_id %}
If the account is multiplexed, the integer representation of the account funding the new account
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs high_threshold %}
The sum of the weight of all signatures that sign a transaction for the high threshold operation. The weight must exceed the set threshold for the operation to succeed.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs inflation_dest %}
The account address specifying where to send inflation funds. The concept of inflation on the network has been discontinued
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs into_muxed %}
If the account is multiplexed, the virtual address of the account receive the deleted account's lumens
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs into_muxed_id %}
If the account is multiplexed, the integer representation of the account receiving the deleted account's lumens
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs ledger_id %}
Unique identifier for the ledger
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs ledger_key_hash %}
Hash of the ledgerKey which is a subset of the ledgerEntry. The subset of ledgerEntry fields depends on ledgerEntryType.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs ledgers_to_expire %}
The number of ledgers after which the operation will expire if its not executed.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs limit_amount %}
The upper bound amount of an asset that an account can hold
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs low_threshold %}
The sum of the weight of all signatures that sign a transaction for the low threshold operation. The weight must exceed the set threshold for the operation to succeed.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs master_key_weight %}
An accounts private key is called the master key. For signing transactions, the account holder can specify a weight for the master key, which contributes to thresholds validation when processing a transaction.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs med_threshold %}
The sum of the weight of all signatures that sign a transaction for the medium threshold operation. The weight must exceed the set threshold for the operation to succeed.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs price_r %}
Precise representation of the buy and sell price of the assets on an offer. The n is the numerator, the d is the denominator. By calculating the ratio of n/d you can calculate the price of the bid or ask.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs signer_account_id %}
The address of the account of the signer no longer sponsored
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs source_account %}
The account that originated the transaction.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs to_muxed %}
If the account is multiplexed, the virtual address of the account receiving the payment
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs to_muxed_id %}
If the account is multiplexed, the integer representation of the virtual address of the recipient account
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs trustee_muxed %}
If the issuing account address is multiplexed, the virtual address of the trustee
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs trustee_muxed_id %}
If the issuing account address is multiplexed, the integer representation of the virtual address of the trustee
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs trustline_account_id %}
The address of the account whose trustline is no longer sponsored
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs trustor_muxed %}
If the trusting account is multiplexed, the virtual address of the account
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs trustor_muxed_id %}
If the trusting account is multiplexed, the integer representation of the virtual address of the account
{% enddocs %}

View File

@ -1,3 +1,3 @@
{% docs txn_account %}
{% docs tx_account %}
Account executing the transaction.
{% enddocs %}

View File

@ -1,3 +1,3 @@
{% docs txn_application_order %}
{% docs tx_application_order %}
Order of transaction application.
{% enddocs %}

View File

@ -1,3 +1,3 @@
{% docs txn_created_at %}
{% docs tx_created_at %}
Creation timestamp of the transaction.
{% enddocs %}

View File

@ -1,3 +1,3 @@
{% docs txn_operation_count %}
{% docs tx_operation_count %}
Number of operations in the transaction.
{% enddocs %}

View File

@ -0,0 +1,3 @@
{% docs type_string %}
The verbose type of operation.
{% enddocs %}

View File

@ -3,40 +3,43 @@ version: 2
models:
- name: core__dim_assets
description: Dimension table containing information about assets on the network.
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- ASSET_TYPE
- ASSET_CODE
- ASSET_ISSUER
columns:
- name: ID
description: '{{ doc("id") }}'
- name: ASSET_ID
description: '{{ doc("asset_id") }}'
tests:
- dbt_expectations.expect_column_to_exist
- not_null
- name: ASSET_TYPE
description: '{{ doc("asset_type") }}'
tests:
- dbt_expectations.expect_column_to_exist
- not_null
- name: ASSET_CODE
description: '{{ doc("asset_code") }}'
tests:
- dbt_expectations.expect_column_to_exist
- not_null:
where: asset_type != 'native'
- name: ASSET_ISSUER
description: '{{ doc("asset_issuer") }}'
tests:
- dbt_expectations.expect_column_to_exist
- not_null:
where: asset_type != 'native'
- name: ASSET_ID
description: '{{ doc("asset_id") }}'
tests:
- dbt_expectations.expect_column_to_exist
- not_null
- unique
- name: ID
description: 'Numeric hash of asset_id, asset_type, and asset_issuer for join operations'
- name: DIM_ASSETS_ID
description: '{{ doc("pk") }}'
tests:
- unique
- not_null
- unique
- name: INSERTED_TIMESTAMP
description: '{{ doc("inserted_timestamp") }}'
@ -47,8 +50,3 @@ models:
description: '{{ doc("modified_timestamp") }}'
tests:
- not_null
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- asset_id

View File

@ -3,6 +3,13 @@ version: 2
models:
- name: core__fact_accounts
description: Core fact table containing all Stellar account information and their current states
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- ACCOUNT_ID
- SEQUENCE_NUMBER
- LEDGER_ENTRY_CHANGE
- LAST_MODIFIED_LEDGER
columns:
- name: ACCOUNT_ID
description: "{{ doc('account_id') }}"
@ -80,15 +87,6 @@ models:
tests:
- not_null
- name: BATCH_ID
description: '{{ doc("batch_id") }}'
- name: BATCH_RUN_DATE
description: '{{ doc("batch_run_date") }}'
- name: BATCH_INSERT_TS
description: '{{ doc("batch_insert_ts") }}'
- name: SPONSOR
description: '{{ doc("sponsor") }}'
@ -117,6 +115,11 @@ models:
tests:
- not_null
- name: BLOCK_TIMESTAMP
description: '{{ doc("block_timestamp") }}'
tests:
- not_null
- name: LEDGER_SEQUENCE
description: '{{ doc("ledger_sequence") }}'
tests:
@ -136,10 +139,4 @@ models:
- name: MODIFIED_TIMESTAMP
description: '{{ doc("modified_timestamp") }}'
tests:
- not_null
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- ACCOUNT_ID
- CLOSED_AT
- not_null

View File

@ -13,115 +13,77 @@ models:
- name: LEDGER_HASH
description: '{{ doc("ledger_hash") }}'
tests:
- dbt_expectations.expect_column_to_exist
- not_null
- name: PREVIOUS_LEDGER_HASH
description: '{{ doc("previous_ledger_hash") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: TRANSACTION_COUNT
description: '{{ doc("transaction_count") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: OPERATION_COUNT
description: '{{ doc("operation_count") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: CLOSED_AT
description: '{{ doc("closed_at") }}'
tests:
- dbt_expectations.expect_column_to_exist
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: day
interval: 1
- name: BLOCK_TIMESTAMP
description: '{{ doc("block_timestamp") }}'
- name: ID
description: '{{ doc("id") }}'
tests:
- dbt_expectations.expect_column_to_exist
- not_null
- name: TOTAL_COINS
description: '{{ doc("total_coins") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: FEE_POOL
description: '{{ doc("fee_pool") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: BASE_FEE
description: '{{ doc("base_fee") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: BASE_RESERVE
description: '{{ doc("base_reserve") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: MAX_TX_SET_SIZE
description: '{{ doc("max_tx_set_size") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: PROTOCOL_VERSION
description: '{{ doc("protocol_version") }}'
tests:
- dbt_expectations.expect_column_to_exist
# - name: LEDGER_HEADER
# description: '{{ doc("ledger_header") }}'
# tests:
# - dbt_expectations.expect_column_to_exist
- name: SUCCESSFUL_TRANSACTION_COUNT
description: '{{ doc("successful_transaction_count") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: FAILED_TRANSACTION_COUNT
description: '{{ doc("failed_transaction_count") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: TX_SET_OPERATION_COUNT
description: '{{ doc("tx_set_operation_count") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: BATCH_ID
description: '{{ doc("batch_id") }}'
- name: BATCH_RUN_DATE
description: '{{ doc("batch_run_date") }}'
- name: BATCH_INSERT_TS
description: '{{ doc("batch_insert_ts") }}'
- name: SOROBAN_FEE_WRITE_1KB
description: '{{ doc("soroban_fee_write_1kb") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: NODE_ID
description: '{{ doc("node_id") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: SIGNATURE
description: '{{ doc("signature") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: TOTAL_BYTE_SIZE_OF_BUCKET_LIST
description: '{{ doc("total_byte_size_of_bucket_list") }}'
tests:
- dbt_expectations.expect_column_to_exist
- name: FACT_LEDGERS_ID
description: '{{ doc("pk") }}'
tests:
- unique
- not_null
- name: INSERTED_TIMESTAMP
description: '{{ doc("inserted_timestamp") }}'
@ -135,8 +97,3 @@ models:
- name: _INVOCATION_ID
description: '{{ doc("invocation_id") }}'
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- SEQUENCE

View File

@ -3,12 +3,28 @@ version: 2
models:
- name: core__fact_operations
description: A comprehensive view of all operations executed on the Stellar network, including transaction details, operation types, and their outcomes.
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- ID
- SOURCE_ACCOUNT
- TRANSACTION_ID
- LEDGER_SEQUENCE
- TYPE
- TYPE_STRING
columns:
- name: ID
description: '{{ doc("op_id") }}'
tests:
- unique
- not_null
- name: CLOSED_AT
description: '{{ doc("closed_at") }}'
tests:
- not_null
- name: BLOCK_TIMESTAMP
description: '{{ doc("block_timestamp") }}'
- name: ACCOUNT
description: '{{ doc("account") }}'
@ -88,11 +104,8 @@ models:
- name: PRICE
description: '{{ doc("price") }}'
- name: D
description: '{{ doc("d") }}'
- name: N
description: '{{ doc("n") }}'
- name: PRICE_R
description: '{{ doc("price_r") }}'
- name: SELLING_ASSET_CODE
description: '{{ doc("selling_asset_code") }}'
@ -111,6 +124,9 @@ models:
- name: SET_FLAGS_S
description: '{{ doc("set_flags_s") }}'
- name: SIGNER_ACCOUNT_ID
description: '{{ doc("signer_account_id") }}'
- name: SIGNER_KEY
description: '{{ doc("signer_key") }}'
@ -219,22 +235,19 @@ models:
- name: RESERVE_B_DEPOSIT_AMOUNT
description: '{{ doc("reserve_b_deposit_amount") }}'
- name: MIN_PRICE
description: '{{ doc("min_price") }}'
- name: MIN_PRICE_R
description: '{{ doc("min_price_r") }}'
- name: MAX_PRICE
description: '{{ doc("max_price") }}'
- name: MAX_PRICE_R
description: '{{ doc("max_price_r") }}'
- name: SHARES_RECEIVED
description: '{{ doc("shares_received") }}'
- name: RESERVE_A_MIN_AMOUNT
description: '{{ doc("reserve_a_min_amount") }}'
- name: RESERVE_B_MIN_AMOUNT
description: '{{ doc("reserve_b_min_amount") }}'
- name: SHARES
description: '{{ doc("shares") }}'
@ -244,194 +257,159 @@ models:
- name: RESERVE_B_WITHDRAW_AMOUNT
description: '{{ doc("reserve_b_withdraw_amount") }}'
- name: OP_SOURCE_ACCOUNT
description: '{{ doc("op_source_account") }}'
- name: SOURCE_ACCOUNT
description: '{{ doc("source_account") }}'
tests:
- not_null
- name: OP_SOURCE_ACCOUNT_MUXED
description: '{{ doc("op_source_account_muxed") }}'
- name: TRANSACTION_ID
description: '{{ doc("transaction_id") }}'
tests:
- not_null
- name: TYPE
description: '{{ doc("type") }}'
- name: TRANSACTION_HASH
description: '{{ doc("transaction_hash") }}'
tests:
- not_null
- name: TYPE_STRING
description: '{{ doc("type_string") }}'
tests:
- not_null
- name: LEDGER_SEQUENCE
description: '{{ doc("ledger_sequence") }}'
- name: TXN_ACCOUNT
description: '{{ doc("txn_account") }}'
- name: ACCOUNT_SEQUENCE
description: '{{ doc("account_sequence") }}'
- name: MAX_FEE
description: '{{ doc("max_fee") }}'
- name: TXN_OPERATION_COUNT
description: '{{ doc("txn_operation_count") }}'
- name: TXN_CREATED_AT
description: '{{ doc("txn_created_at") }}'
- name: MEMO_TYPE
description: '{{ doc("memo_type") }}'
- name: MEMO
description: '{{ doc("memo") }}'
- name: TIME_BOUNDS
description: '{{ doc("time_bounds") }}'
- name: SUCCESSFUL
description: '{{ doc("successful") }}'
- name: FEE_CHARGED
description: '{{ doc("fee_charged") }}'
- name: FEE_ACCOUNT
description: '{{ doc("fee_account") }}'
- name: NEW_MAX_FEE
description: '{{ doc("new_max_fee") }}'
- name: ACCOUNT_MUXED
tests:
- not_null
- name: OP_ACCOUNT_MUXED
description: '{{ doc("account_muxed") }}'
- name: FEE_ACCOUNT_MUXED
description: '{{ doc("fee_account_muxed") }}'
- name: LEDGER_HASH
description: '{{ doc("ledger_hash") }}'
- name: PREVIOUS_LEDGER_HASH
description: '{{ doc("previous_ledger_hash") }}'
- name: TRANSACTION_COUNT
description: '{{ doc("transaction_count") }}'
- name: LEDGER_OPERATION_COUNT
description: '{{ doc("ledger_operation_count") }}'
- name: CLOSED_AT
description: '{{ doc("closed_at") }}'
- name: TOTAL_COINS
description: '{{ doc("total_coins") }}'
- name: FEE_POOL
description: '{{ doc("fee_pool") }}'
- name: BASE_FEE
description: '{{ doc("base_fee") }}'
- name: BASE_RESERVE
description: '{{ doc("base_reserve") }}'
- name: MAX_TX_SET_SIZE
description: '{{ doc("max_tx_set_size") }}'
- name: PROTOCOL_VERSION
description: '{{ doc("protocol_version") }}'
- name: SUCCESSFUL_TRANSACTION_COUNT
description: '{{ doc("successful_transaction_count") }}'
- name: FAILED_TRANSACTION_COUNT
description: '{{ doc("failed_transaction_count") }}'
- name: OP_ACCOUNT_MUXED_ID
description: '{{ doc("account_muxed_id") }}'
- name: LEDGER_KEY_HASH
description: '{{ doc("ledger_key_hash") }}'
- name: BATCH_ID
description: '{{ doc("batch_id") }}'
- name: BATCH_RUN_DATE
description: '{{ doc("batch_run_date") }}'
description: '{{ doc("batch_run_date") }}'
- name: BATCH_INSERT_TS
description: '{{ doc("batch_insert_ts") }}'
- name: LEDGER_BOUNDS
description: '{{ doc("ledger_bounds") }}'
- name: MIN_ACCOUNT_SEQUENCE
description: '{{ doc("min_account_sequence") }}'
- name: MIN_ACCOUNT_SEQUENCE_AGE
description: '{{ doc("min_account_sequence_age") }}'
- name: MIN_ACCOUNT_SEQUENCE_LEDGER_GAP
description: '{{ doc("min_account_sequence_ledger_gap") }}'
- name: EXTRA_SIGNERS
description: '{{ doc("extra_signers") }}'
- name: ASSET_BALANCE_CHANGES
description: '{{ doc("asset_balance_changes") }}'
- name: PARAMETERS
description: '{{ doc("parameters") }}'
- name: PARAMETERS_DECODED
description: '{{ doc("parameters_decoded") }}'
description: '{{ doc("parameters_decoded") }}'
- name: FUNCTION
description: '{{ doc("function") }}'
- name: ADDRESS
description: '{{ doc("address") }}'
- name: SOROBAN_OPERATION_TYPE
description: '{{ doc("soroban_operation_type") }}'
- name: EXTEND_TO
description: '{{ doc("extend_to") }}'
- name: CONTRACT_ID
description: '{{ doc("contract_id") }}'
- name: CONTRACT_CODE_HASH
description: '{{ doc("contract_code_hash") }}'
- name: RESOURCE_FEE
description: '{{ doc("resource_fee") }}'
- name: SOROBAN_RESOURCES_INSTRUCTIONS
description: '{{ doc("soroban_resources_instructions") }}'
- name: SOROBAN_RESOURCES_READ_BYTES
description: '{{ doc("soroban_resources_read_bytes") }}'
- name: SOROBAN_RESOURCES_WRITE_BYTES
description: '{{ doc("soroban_resources_write_bytes") }}'
- name: TRANSACTION_RESULT_CODE
description: '{{ doc("transaction_result_code") }}'
- name: INCLUSION_FEE_BID
description: '{{ doc("inclusion_fee_bid") }}'
- name: INCLUSION_FEE_CHARGED
description: '{{ doc("inclusion_fee_charged") }}'
- name: RESOURCE_FEE_REFUND
description: '{{ doc("resource_fee_refund") }}'
- name: OPERATION_RESULT_CODE
description: '{{ doc("operation_result_code") }}'
- name: OPERATION_TRACE_CODE
description: '{{ doc("operation_trace_code") }}'
- name: BEGIN_SPONSOR_MUXED
description: '{{ doc("begin_sponsor_muxed") }}'
- name: OP_APPLICATION_ORDER
description: '{{ doc("op_application_order") }}'
- name: BEGIN_SPONSOR_MUXED_ID
description: '{{ doc("begin_sponsor_muxed_id") }}'
- name: TXN_APPLICATION_ORDER
description: '{{ doc("txn_application_order") }}'
- name: CLAIMABLE_BALANCE_ID
description: '{{ doc("claimable_balance_id") }}'
- name: _INSERTED_TIMESTAMP
description: '{{ doc("inserted_timestamp") }}'
- name: CLAIMANT
description: '{{ doc("claimant") }}'
- name: CLAIMANTS
description: '{{ doc("claimants") }}'
- name: CLAIMANT_MUXED
description: '{{ doc("claimant_muxed") }}'
- name: CLAIMANT_MUXED_ID
description: '{{ doc("claimant_muxed_id") }}'
- name: DATA_ACCOUNT_ID
description: '{{ doc("data_account_id") }}'
- name: DATA_NAME
description: '{{ doc("data_name") }}'
- name: DETAILS_JSON
description: '{{ doc("details_json") }}'
- name: FROM_MUXED
description: '{{ doc("from_muxed") }}'
- name: FROM_MUXED_ID
description: '{{ doc("from_muxed_id") }}'
- name: FUNDER_MUXED
description: '{{ doc("funder_muxed") }}'
- name: FUNDER_MUXED_ID
description: '{{ doc("funder_muxed_id") }}'
- name: INTO_MUXED
description: '{{ doc("into_muxed") }}'
- name: INTO_MUXED_ID
description: '{{ doc("into_muxed_id") }}'
- name: LEDGERS_TO_EXPIRE
description: '{{ doc("ledgers_to_expire") }}'
- name: OP_ACCOUNT_ID
description: '{{ doc("account_id") }}'
- name: TO_MUXED
description: '{{ doc("to_muxed") }}'
- name: TO_MUXED_ID
description: '{{ doc("to_muxed_id") }}'
- name: TRUSTEE_MUXED
description: '{{ doc("trustee_muxed") }}'
- name: TRUSTEE_MUXED_ID
description: '{{ doc("trustee_muxed_id") }}'
- name: TRUSTLINE_ACCOUNT_ID
description: '{{ doc("trustline_account_id") }}'
- name: TRUSTOR_MUXED
description: '{{ doc("trustor_muxed") }}'
- name: TRUSTOR_MUXED_ID
description: '{{ doc("trustor_muxed_id") }}'
- name: FACT_OPERATIONS_ID
description: '{{ doc("pk") }}'
@ -443,7 +421,4 @@ models:
description: '{{ doc("modified_timestamp") }}'
- name: _INVOCATION_ID
description: '{{ doc("invocation_id") }}'
- name: DETAILS_JSON
description: '{{ doc("details_json") }}'
description: '{{ doc("invocation_id") }}'

View File

@ -4,190 +4,159 @@ models:
- name: core__fact_transactions
description: Fact table containing transaction details from the Stellar network.
columns:
# - name: id
# description: '{{ doc("pk") }}'
# tests:
# - unique
# - not_null
- name: id
- name: ID
description: Unique identifier for the transaction
tests:
- not_null
- unique
- name: transaction_hash
- name: TRANSACTION_HASH
description: '{{ doc("transaction_hash") }}'
tests:
- not_null
- name: ledger_sequence
- name: LEDGER_SEQUENCE
description: '{{ doc("ledger_sequence") }}'
tests:
- not_null
- name: CLOSED_AT
description: '{{ doc("closed_at") }}'
tests:
- not_null
- name: BLOCK_TIMESTAMP
description: '{{ doc("block_timestamp") }}'
- name: account
- name: ACCOUNT
description: '{{ doc("account") }}'
tests:
- not_null
- name: account_sequence
- name: ACCOUNT_SEQUENCE
description: '{{ doc("account_sequence") }}'
tests:
- not_null
- name: max_fee
- name: MAX_FEE
description: '{{ doc("max_fee") }}'
tests:
- not_null
- name: operation_count
- name: OPERATION_COUNT
description: '{{ doc("operation_count") }}'
tests:
- not_null
- name: created_at
description: '{{ doc("txn_created_at") }}'
tests:
- not_null
- name: CREATED_AT
description: '{{ doc("tx_created_at") }}'
- name: memo_type
- name: MEMO_TYPE
description: '{{ doc("memo_type") }}'
- name: memo
- name: MEMO
description: '{{ doc("memo") }}'
- name: time_bounds
- name: TIME_BOUNDS
description: '{{ doc("time_bounds") }}'
- name: successful
- name: SUCCESSFUL
description: '{{ doc("successful") }}'
# tests:
# - not_null
- name: fee_charged
- name: FEE_CHARGED
description: '{{ doc("fee_charged") }}'
tests:
- not_null
- name: inner_transaction_hash
- name: INNER_TRANSACTION_HASH
description: '{{ doc("inner_transaction_hash") }}'
- name: fee_account
- name: FEE_ACCOUNT
description: '{{ doc("fee_account") }}'
- name: new_max_fee
- name: NEW_MAX_FEE
description: '{{ doc("new_max_fee") }}'
- name: account_muxed
- name: ACCOUNT_MUXED
description: '{{ doc("account_muxed") }}'
- name: fee_account_muxed
- name: FEE_ACCOUNT_MUXED
description: '{{ doc("fee_account_muxed") }}'
- name: batch_id
- name: BATCH_ID
description: '{{ doc("batch_id") }}'
tests:
- not_null
- name: batch_run_date
- name: BATCH_RUN_DATE
description: '{{ doc("batch_run_date") }}'
tests:
- not_null
- name: batch_insert_ts
- name: BATCH_INSERT_TS
description: '{{ doc("batch_insert_ts") }}'
tests:
- not_null
- name: ledger_bounds
- name: LEDGER_BOUNDS
description: '{{ doc("ledger_bounds") }}'
- name: min_account_sequence
- name: MIN_ACCOUNT_SEQUENCE
description: '{{ doc("min_account_sequence") }}'
- name: min_account_sequence_age
- name: MIN_ACCOUNT_SEQUENCE_AGE
description: '{{ doc("min_account_sequence_age") }}'
- name: min_account_sequence_ledger_gap
- name: MIN_ACCOUNT_SEQUENCE_LEDGER_GAP
description: '{{ doc("min_account_sequence_ledger_gap") }}'
- name: tx_envelope
- name: TX_ENVELOPE
description: '{{ doc("tx_envelope") }}'
- name: tx_result
- name: TX_RESULT
description: '{{ doc("tx_result") }}'
- name: tx_meta
- name: TX_META
description: '{{ doc("tx_meta") }}'
- name: tx_fee_meta
- name: TX_FEE_META
description: '{{ doc("tx_fee_meta") }}'
- name: extra_signers
- name: EXTRA_SIGNERS
description: '{{ doc("extra_signers") }}'
- name: resource_fee
- name: RESOURCE_FEE
description: '{{ doc("resource_fee") }}'
- name: soroban_resources_instructions
- name: SOROBAN_RESOURCES_INSTRUCTIONS
description: '{{ doc("soroban_resources_instructions") }}'
- name: soroban_resources_read_bytes
- name: SOROBAN_RESOURCES_READ_BYTES
description: '{{ doc("soroban_resources_read_bytes") }}'
- name: soroban_resources_write_bytes
- name: SOROBAN_RESOURCES_WRITE_BYTES
description: '{{ doc("soroban_resources_write_bytes") }}'
- name: closed_at
description: '{{ doc("closed_at") }}'
tests:
- not_null
- name: transaction_result_code
- name: TRANSACTION_RESULT_CODE
description: '{{ doc("transaction_result_code") }}'
- name: inclusion_fee_bid
- name: INCLUSION_FEE_BID
description: '{{ doc("inclusion_fee_bid") }}'
- name: inclusion_fee_charged
- name: INCLUSION_FEE_CHARGED
description: '{{ doc("inclusion_fee_charged") }}'
- name: resource_fee_refund
- name: RESOURCE_FEE_REFUND
description: '{{ doc("resource_fee_refund") }}'
- name: non_refundable_resource_fee_charged
- name: NON_REFUNDABLE_RESOURCE_FEE_CHARGED
description: '{{ doc("non_refundable_resource_fee_charged") }}'
- name: refundable_resource_fee_charged
- name: REFUNDABLE_RESOURCE_FEE_CHARGED
description: '{{ doc("refundable_resource_fee_charged") }}'
- name: rent_fee_charged
- name: RENT_FEE_CHARGED
description: '{{ doc("rent_fee_charged") }}'
- name: tx_signers
- name: TX_SIGNERS
description: '{{ doc("tx_signers") }}'
- name: refundable_fee
- name: REFUNDABLE_FEE
description: '{{ doc("refundable_fee") }}'
- name: fact_transactions_id
- name: FACT_TRANSACTIONS_ID
description: '{{ doc("pk") }}'
tests:
- not_null
- unique
- name: inserted_timestamp
- name: INSERTED_TIMESTAMP
description: '{{ doc("inserted_timestamp") }}'
tests:
- not_null
- name: modified_timestamp
- name: MODIFIED_TIMESTAMP
description: '{{ doc("modified_timestamp") }}'
tests:
- not_null
- name: _invocation_id
- name: _INVOCATION_ID
description: '{{ doc("invocation_id") }}'
tests:
- not_null

View File

@ -3,113 +3,525 @@ version: 2
models:
- name: core__ez_operations
description: A comprehensive view combining operations with their associated transaction and ledger data.
config:
tags: ["core"]
columns:
- name: fact_operations_id
description: '{{ doc("pk") }}'
tests:
- unique
- not_null
- name: op_id
- name: OP_ID
description: '{{ doc("op_id") }}'
tests:
- not_null
- name: transaction_id
description: '{{ doc("transaction_id") }}'
- name: OP_SOURCE_ACCOUNT
description: '{{ doc("op_source_account") }}'
- name: type
description: '{{ doc("type") }}'
- name: OP_SOURCE_ACCOUNT_MUXED
description: '{{ doc("op_source_account_muxed") }}'
- name: account
description: '{{ doc("account") }}'
- name: OP_ACCOUNT_ID
description: '{{ doc("account_id") }}'
- name: amount
- name: AMOUNT
description: '{{ doc("amount") }}'
- name: asset_code
- name: ASSET
description: '{{ doc("asset") }}'
- name: ASSET_CODE
description: '{{ doc("asset_code") }}'
- name: asset_issuer
- name: ASSET_ISSUER
description: '{{ doc("asset_issuer") }}'
- name: asset_type
- name: ASSET_TYPE
description: '{{ doc("asset_type") }}'
- name: transaction_hash
description: '{{ doc("transaction_hash") }}'
- name: AUTHORIZE
description: '{{ doc("authorize") }}'
- name: ledger_sequence
description: '{{ doc("ledger_sequence") }}'
- name: BALANCE_ID
description: '{{ doc("balance_id") }}'
- name: closed_at
description: '{{ doc("closed_at") }}'
- name: CLAIMANT
description: '{{ doc("claimant") }}'
- name: successful
description: '{{ doc("successful") }}'
- name: CLAIMANT_MUXED
description: '{{ doc("claimant_muxed") }}'
- name: operation_result_code
description: '{{ doc("operation_result_code") }}'
- name: CLAIMANT_MUXED_ID
description: '{{ doc("claimant_muxed_id") }}'
- name: operation_trace_code
description: '{{ doc("operation_trace_code") }}'
- name: CLAIMANTS
description: '{{ doc("claimants") }}'
- name: details_json
description: '{{ doc("details_json") }}'
- name: DATA_ACCOUNT_ID
description: '{{ doc("data_account_id") }}'
- name: asset_balance_changes
- name: DATA_NAME
description: '{{ doc("data_name") }}'
- name: BUYING_ASSET_CODE
description: '{{ doc("buying_asset_code") }}'
- name: BUYING_ASSET_ISSUER
description: '{{ doc("buying_asset_issuer") }}'
- name: BUYING_ASSET_TYPE
description: '{{ doc("buying_asset_type") }}'
- name: FROM_ACCOUNT
description: '{{ doc("from_account") }}'
- name: FROM_MUXED
description: '{{ doc("from_muxed") }}'
- name: FROM_MUXED_ID
description: '{{ doc("from_muxed_id") }}'
- name: FUNDER
description: '{{ doc("funder") }}'
- name: FUNDER_MUXED
description: '{{ doc("funder_muxed") }}'
- name: FUNDER_MUXED_ID
description: '{{ doc("funder_muxed_id") }}'
- name: HIGH_THRESHOLD
description: '{{ doc("high_threshold") }}'
- name: HOME_DOMAIN
description: '{{ doc("home_domain") }}'
- name: INFLATION_DEST
description: '{{ doc("inflation_dest") }}'
- name: INTO_ACCOUNT
description: '{{ doc("into") }}'
- name: INTO_MUXED
description: '{{ doc("into_muxed") }}'
- name: INTO_MUXED_ID
description: '{{ doc("into_muxed_id") }}'
- name: LIMIT_AMOUNT
description: '{{ doc("limit_amount") }}'
- name: LOW_THRESHOLD
description: '{{ doc("low_threshold") }}'
- name: MASTER_KEY_WEIGHT
description: '{{ doc("master_key_weight") }}'
- name: MED_THRESHOLD
description: '{{ doc("med_threshold") }}'
- name: NAME
description: '{{ doc("name") }}'
- name: OFFER_ID
description: '{{ doc("offer_id") }}'
- name: PATH
description: '{{ doc("path") }}'
- name: PRICE
description: '{{ doc("price") }}'
- name: PRICE_R
description: '{{ doc("price_r") }}'
- name: SELLING_ASSET_CODE
description: '{{ doc("selling_asset_code") }}'
- name: SELLING_ASSET_ISSUER
description: '{{ doc("selling_asset_issuer") }}'
- name: SELLING_ASSET_TYPE
description: '{{ doc("selling_asset_type") }}'
- name: SET_FLAGS
description: '{{ doc("set_flags") }}'
- name: SET_FLAGS_S
description: '{{ doc("set_flags_s") }}'
- name: SIGNER_ACCOUNT_ID
description: '{{ doc("signer_account_id") }}'
- name: SIGNER_KEY
description: '{{ doc("signer_key") }}'
- name: SIGNER_WEIGHT
description: '{{ doc("signer_weight") }}'
- name: SOURCE_AMOUNT
description: '{{ doc("source_amount") }}'
- name: SOURCE_ASSET_CODE
description: '{{ doc("source_asset_code") }}'
- name: SOURCE_ASSET_ISSUER
description: '{{ doc("source_asset_issuer") }}'
- name: SOURCE_ASSET_TYPE
description: '{{ doc("source_asset_type") }}'
- name: SOURCE_MAX
description: '{{ doc("source_max") }}'
- name: STARTING_BALANCE
description: '{{ doc("starting_balance") }}'
- name: TO_ACCOUNT
description: '{{ doc("to") }}'
- name: TO_MUXED
description: '{{ doc("to_muxed") }}'
- name: TO_MUXED_ID
description: '{{ doc("to_muxed_id") }}'
- name: TRUSTEE
description: '{{ doc("trustee") }}'
- name: TRUSTEE_MUXED
description: '{{ doc("trustee_muxed") }}'
- name: TRUSTEE_MUXED_ID
description: '{{ doc("trustee_muxed_id") }}'
- name: TRUSTOR
description: '{{ doc("trustor") }}'
- name: TRUSTOR_MUXED
description: '{{ doc("trustor_muxed") }}'
- name: TRUSTOR_MUXED_ID
description: '{{ doc("trustor_muxed_id") }}'
- name: TRUSTLINE_ACCOUNT_ID
description: '{{ doc("trustline_account_id") }}'
- name: TRUSTLINE_ASSET
description: '{{ doc("trustline_asset") }}'
- name: VALUE
description: '{{ doc("value") }}'
- name: CLEAR_FLAGS
description: '{{ doc("clear_flags") }}'
- name: CLEAR_FLAGS_S
description: '{{ doc("clear_flags_s") }}'
- name: DESTINATION_MIN
description: '{{ doc("destination_min") }}'
- name: BUMP_TO
description: '{{ doc("bump_to") }}'
- name: SPONSOR
description: '{{ doc("sponsor") }}'
- name: SPONSORED_ID
description: '{{ doc("sponsored_id") }}'
- name: BEGIN_SPONSOR
description: '{{ doc("begin_sponsor") }}'
- name: BEGIN_SPONSOR_MUXED
description: '{{ doc("begin_sponsor_muxed") }}'
- name: BEGIN_SPONSOR_MUXED_ID
description: '{{ doc("begin_sponsor_muxed_id") }}'
- name: AUTHORIZE_TO_MAINTAIN_LIABILITIES
description: '{{ doc("authorize_to_maintain_liabilities") }}'
- name: CLAWBACK_ENABLED
description: '{{ doc("clawback_enabled") }}'
- name: LIQUIDITY_POOL_ID
description: '{{ doc("liquidity_pool_id") }}'
- name: RESERVE_A_ASSET_TYPE
description: '{{ doc("reserve_a_asset_type") }}'
- name: RESERVE_A_ASSET_CODE
description: '{{ doc("reserve_a_asset_code") }}'
- name: RESERVE_A_ASSET_ISSUER
description: '{{ doc("reserve_a_asset_issuer") }}'
- name: RESERVE_A_MAX_AMOUNT
description: '{{ doc("reserve_a_max_amount") }}'
- name: RESERVE_A_DEPOSIT_AMOUNT
description: '{{ doc("reserve_a_deposit_amount") }}'
- name: RESERVE_B_ASSET_TYPE
description: '{{ doc("reserve_b_asset_type") }}'
- name: RESERVE_B_ASSET_CODE
description: '{{ doc("reserve_b_asset_code") }}'
- name: RESERVE_B_ASSET_ISSUER
description: '{{ doc("reserve_b_asset_issuer") }}'
- name: RESERVE_B_MAX_AMOUNT
description: '{{ doc("reserve_b_max_amount") }}'
- name: RESERVE_B_DEPOSIT_AMOUNT
description: '{{ doc("reserve_b_deposit_amount") }}'
- name: MIN_PRICE
description: '{{ doc("min_price") }}'
- name: MIN_PRICE_R
description: '{{ doc("min_price_r") }}'
- name: MAX_PRICE
description: '{{ doc("max_price") }}'
- name: MAX_PRICE_R
description: '{{ doc("max_price_r") }}'
- name: SHARES_RECEIVED
description: '{{ doc("shares_received") }}'
- name: RESERVE_A_MIN_AMOUNT
description: '{{ doc("reserve_a_min_amount") }}'
- name: RESERVE_B_MIN_AMOUNT
description: '{{ doc("reserve_b_min_amount") }}'
- name: SHARES
description: '{{ doc("shares") }}'
- name: RESERVE_A_WITHDRAW_AMOUNT
description: '{{ doc("reserve_a_withdraw_amount") }}'
- name: RESERVE_B_WITHDRAW_AMOUNT
description: '{{ doc("reserve_b_withdraw_amount") }}'
- name: TX_ID
description: '{{ doc("transaction_id") }}'
- name: TYPE
description: '{{ doc("type") }}'
- name: TYPE_STRING
description: '{{ doc("type_string") }}'
- name: BATCH_ID
description: '{{ doc("batch_id") }}'
- name: BATCH_RUN_DATE
description: '{{ doc("batch_run_date") }}'
- name: ASSET_BALANCE_CHANGES
description: '{{ doc("asset_balance_changes") }}'
- name: parameters
- name: PARAMETERS
description: '{{ doc("parameters") }}'
- name: parameters_decoded
- name: PARAMETERS_DECODED
description: '{{ doc("parameters_decoded") }}'
- name: function
- name: FUNCTION
description: '{{ doc("function") }}'
- name: contract_id
- name: ADDRESS
description: '{{ doc("address") }}'
- name: SOROBAN_OPERATION_TYPE
description: '{{ doc("soroban_operation_type") }}'
- name: EXTEND_TO
description: '{{ doc("extend_to") }}'
- name: CONTRACT_ID
description: '{{ doc("contract_id") }}'
- name: contract_code_hash
- name: CONTRACT_CODE_HASH
description: '{{ doc("contract_code_hash") }}'
- name: resource_fee
- name: OPERATION_RESULT_CODE
description: '{{ doc("operation_result_code") }}'
- name: OPERATION_TRACE_CODE
description: '{{ doc("operation_trace_code") }}'
- name: DETAILS_JSON
description: '{{ doc("details_json") }}'
- name: CLOSED_AT
description: '{{ doc("closed_at") }}'
- name: BLOCK_TIMESTAMP
description: '{{ doc("block_timestamp") }}'
- name: TRANSACTION_HASH
description: '{{ doc("transaction_hash") }}'
- name: LEDGER_SEQUENCE
description: '{{ doc("ledger_sequence") }}'
- name: TX_ACCOUNT
description: '{{ doc("tx_account") }}'
- name: ACCOUNT_SEQUENCE
description: '{{ doc("account_sequence") }}'
- name: MAX_FEE
description: '{{ doc("max_fee") }}'
- name: TX_OPERATION_COUNT
description: '{{ doc("tx_operation_count") }}'
- name: TX_CREATED_AT
description: '{{ doc("tx_created_at") }}'
- name: MEMO_TYPE
description: '{{ doc("memo_type") }}'
- name: MEMO
description: '{{ doc("memo") }}'
- name: TIME_BOUNDS
description: '{{ doc("time_bounds") }}'
- name: SUCCESSFUL
description: '{{ doc("successful") }}'
- name: FEE_CHARGED
description: '{{ doc("fee_charged") }}'
- name: FEE_ACCOUNT
description: '{{ doc("fee_account") }}'
- name: NEW_MAX_FEE
description: '{{ doc("new_max_fee") }}'
- name: ACCOUNT_MUXED
description: '{{ doc("account_muxed") }}'
- name: FEE_ACCOUNT_MUXED
description: '{{ doc("fee_account_muxed") }}'
- name: LEDGER_BOUNDS
description: '{{ doc("ledger_bounds") }}'
- name: MIN_ACCOUNT_SEQUENCE
description: '{{ doc("min_account_sequence") }}'
- name: MIN_ACCOUNT_SEQUENCE_AGE
description: '{{ doc("min_account_sequence_age") }}'
- name: MIN_ACCOUNT_SEQUENCE_LEDGER_GAP
description: '{{ doc("min_account_sequence_ledger_gap") }}'
- name: EXTRA_SIGNERS
description: '{{ doc("extra_signers") }}'
- name: RESOURCE_FEE
description: '{{ doc("resource_fee") }}'
- name: soroban_resources_instructions
- name: SOROBAN_RESOURCES_INSTRUCTIONS
description: '{{ doc("soroban_resources_instructions") }}'
- name: soroban_resources_read_bytes
- name: SOROBAN_RESOURCES_READ_BYTES
description: '{{ doc("soroban_resources_read_bytes") }}'
- name: soroban_resources_write_bytes
- name: SOROBAN_RESOURCES_WRITE_BYTES
description: '{{ doc("soroban_resources_write_bytes") }}'
- name: non_refundable_resource_fee_charged
- name: TRANSACTION_RESULT_CODE
description: '{{ doc("transaction_result_code") }}'
- name: INCLUSION_FEE_BID
description: '{{ doc("inclusion_fee_bid") }}'
- name: INCLUSION_FEE_CHARGED
description: '{{ doc("inclusion_fee_charged") }}'
- name: RESOURCE_FEE_REFUND
description: '{{ doc("resource_fee_refund") }}'
- name: LEDGER_HASH
description: '{{ doc("ledger_hash") }}'
- name: PREVIOUS_LEDGER_HASH
description: '{{ doc("previous_ledger_hash") }}'
- name: TRANSACTION_COUNT
description: '{{ doc("transaction_count") }}'
- name: LEDGER_OPERATION_COUNT
description: '{{ doc("ledger_operation_count") }}'
- name: LEDGER_ID
description: '{{ doc("ledger_id") }}'
- name: TOTAL_COINS
description: '{{ doc("total_coins") }}'
- name: FEE_POOL
description: '{{ doc("fee_pool") }}'
- name: BASE_FEE
description: '{{ doc("base_fee") }}'
- name: BASE_RESERVE
description: '{{ doc("base_reserve") }}'
- name: MAX_TX_SET_SIZE
description: '{{ doc("max_tx_set_size") }}'
- name: PROTOCOL_VERSION
description: '{{ doc("protocol_version") }}'
- name: SUCCESSFUL_TRANSACTION_COUNT
description: '{{ doc("successful_transaction_count") }}'
- name: FAILED_TRANSACTION_COUNT
description: '{{ doc("failed_transaction_count") }}'
- name: SOROBAN_FEE_WRITE_1KB
description: '{{ doc("soroban_fee_write_1kb") }}'
- name: NODE_ID
description: '{{ doc("node_id") }}'
- name: SIGNATURE
description: '{{ doc("signature") }}'
- name: TOTAL_BYTE_SIZE_OF_BUCKET_LIST
description: '{{ doc("total_byte_size_of_bucket_list") }}'
- name: NON_REFUNDABLE_RESOURCE_FEE_CHARGED
description: '{{ doc("non_refundable_resource_fee_charged") }}'
- name: refundable_resource_fee_charged
- name: REFUNDABLE_RESOURCE_FEE_CHARGED
description: '{{ doc("refundable_resource_fee_charged") }}'
- name: rent_fee_charged
- name: RENT_FEE_CHARGED
description: '{{ doc("rent_fee_charged") }}'
- name: tx_signers
- name: TX_SIGNERS
description: '{{ doc("tx_signers") }}'
- name: refundable_fee
- name: REFUNDABLE_FEE
description: '{{ doc("refundable_fee") }}'
- name: inserted_timestamp
- name: FACT_OPERATIONS_ID
description: '{{ doc("pk") }}'
- name: INSERTED_TIMESTAMP
description: '{{ doc("inserted_timestamp") }}'
- name: modified_timestamp
- name: MODIFIED_TIMESTAMP
description: '{{ doc("modified_timestamp") }}'
- name: _invocation_id
- name: _INVOCATION_ID
description: '{{ doc("invocation_id") }}'

View File

@ -0,0 +1,39 @@
version: 2
models:
- name: silver__accounts
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- ACCOUNT_ID
- SEQUENCE_NUMBER
- LEDGER_ENTRY_CHANGE
- LAST_MODIFIED_LEDGER
columns:
- name: ACCOUNT_ID
description: "{{ doc('account_id') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- VARCHAR
- name: SEQUENCE_NUMBER
description: "{{ doc('sequence_number') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER
- name: LEDGER_ENTRY_CHANGE
description: "{{ doc('ledger_entry_change') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER
- name: LAST_MODIFIED_LEDGER
description: "{{ doc('last_modified_ledger') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER

View File

@ -0,0 +1,31 @@
version: 2
models:
- name: silver__assets
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- ASSET_TYPE
- ASSET_CODE
- ASSET_ISSUER
columns:
- name: ASSET_TYPE
description: "{{ doc('asset_type') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- VARCHAR
- name: ASSET_CODE
description: "{{ doc('asset_code') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- VARCHAR
- name: ASSET_ISSUER
description: "{{ doc('asset_issuer') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- VARCHAR

View File

@ -0,0 +1,9 @@
version: 2
models:
- name: silver__ledgers
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- SEQUENCE
- fsc_utils.sequence_gaps:
column_name: SEQUENCE

View File

@ -0,0 +1,31 @@
version: 2
models:
- name: silver__liquidity_pools
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- LIQUIDITY_POOL_ID
- LEDGER_ENTRY_CHANGE
- LAST_MODIFIED_LEDGER
columns:
- name: LIQUIDITY_POOL_ID
description: "{{ doc('liquidity_pool_id') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- VARCHAR
- name: LEDGER_ENTRY_CHANGE
description: "{{ doc('ledger_entry_change') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER
- name: LAST_MODIFIED_LEDGER
description: "{{ doc('last_modified_ledger') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER

View File

@ -0,0 +1,55 @@
version: 2
models:
- name: silver__operations
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- ID
- SOURCE_ACCOUNT
- TRANSACTION_ID
- LEDGER_SEQUENCE
- TYPE
- TYPE_STRING
columns:
- name: ID
description: "{{ doc('id') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER
- name: SOURCE_ACCOUNT
description: "{{ doc('source_account') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- VARCHAR
- name: TRANSACTION_ID
description: "{{ doc('transaction_id') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER
- name: LEDGER_SEQUENCE
description: "{{ doc('ledger_sequence') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER
- name: TYPE
description: "{{ doc('type') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER
- name: TYPE_STRING
description: "{{ doc('type_string') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- VARCHAR

View File

@ -0,0 +1,23 @@
version: 2
models:
- name: silver__trades
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- HISTORY_OPERATION_ID
- '"order"'
columns:
- name: HISTORY_OPERATION_ID
description: "{{ doc('history_operation_id') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER
- name: '"order"'
description: "{{ doc('order') }}"
tests:
- not_null
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER

View File

@ -0,0 +1,12 @@
version: 2
models:
- name: silver__transactions
columns:
- name: ID
description: "{{ doc('id') }}"
tests:
- not_null
- unique
- dbt_expectations.expect_column_values_to_be_in_type_list:
column_type_list:
- NUMBER

View File

@ -0,0 +1,27 @@
{{ config (
materialized = "ephemeral",
unique_key = "closed_at",
) }}
WITH base AS (
SELECT
closed_at :: DATE AS closed_at,
MAX(sequence) AS sequence
FROM
{{ ref("silver__ledgers") }}
GROUP BY
closed_at :: DATE
)
SELECT
closed_at,
sequence
FROM
base
WHERE
closed_at <> (
SELECT
MAX(closed_at)
FROM
base
)

View File

@ -0,0 +1,27 @@
{{ config (
materialized = 'view',
tags = ['recent_test']
) }}
WITH last_3_days AS (
SELECT
closed_at
FROM
{{ ref("_max_ledger_by_date") }}
qualify ROW_NUMBER() over (
ORDER BY
closed_at DESC
) = 3
)
SELECT
*
FROM
{{ ref('core__fact_accounts') }}
WHERE
closed_at :: DATE >= (
SELECT
closed_at
FROM
last_3_days
)

View File

@ -0,0 +1,11 @@
version: 2
models:
- name: test_core__accounts_recent
columns:
- name: BLOCK_TIMESTAMP
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: hour
interval: 3

View File

@ -0,0 +1,27 @@
{{ config (
materialized = 'view',
tags = ['recent_test']
) }}
WITH last_3_days AS (
SELECT
closed_at
FROM
{{ ref("_max_ledger_by_date") }}
qualify ROW_NUMBER() over (
ORDER BY
closed_at DESC
) = 3
)
SELECT
*
FROM
{{ ref('core__ez_operations') }}
WHERE
closed_at :: DATE >= (
SELECT
closed_at
FROM
last_3_days
)

View File

@ -0,0 +1,11 @@
version: 2
models:
- name: test_core__ez_operations_recent
columns:
- name: BLOCK_TIMESTAMP
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: hour
interval: 3

View File

@ -0,0 +1,27 @@
{{ config (
materialized = 'view',
tags = ['recent_test']
) }}
WITH last_3_days AS (
SELECT
closed_at
FROM
{{ ref("_max_ledger_by_date") }}
qualify ROW_NUMBER() over (
ORDER BY
closed_at DESC
) = 3
)
SELECT
*
FROM
{{ ref('core__fact_ledgers') }}
WHERE
closed_at :: DATE >= (
SELECT
closed_at
FROM
last_3_days
)

View File

@ -0,0 +1,11 @@
version: 2
models:
- name: test_core__ledgers_recent
columns:
- name: BLOCK_TIMESTAMP
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: hour
interval: 3

View File

@ -0,0 +1,27 @@
{{ config (
materialized = 'view',
tags = ['recent_test']
) }}
WITH last_3_days AS (
SELECT
closed_at
FROM
{{ ref("_max_ledger_by_date") }}
qualify ROW_NUMBER() over (
ORDER BY
closed_at DESC
) = 3
)
SELECT
*
FROM
{{ ref('core__fact_operations') }}
WHERE
closed_at :: DATE >= (
SELECT
closed_at
FROM
last_3_days
)

View File

@ -0,0 +1,11 @@
version: 2
models:
- name: test_core__operations_recent
columns:
- name: BLOCK_TIMESTAMP
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: hour
interval: 3

View File

@ -0,0 +1,27 @@
{{ config (
materialized = 'view',
tags = ['recent_test']
) }}
WITH last_3_days AS (
SELECT
closed_at
FROM
{{ ref("_max_ledger_by_date") }}
qualify ROW_NUMBER() over (
ORDER BY
closed_at DESC
) = 3
)
SELECT
*
FROM
{{ ref('core__fact_transactions') }}
WHERE
closed_at :: DATE >= (
SELECT
closed_at
FROM
last_3_days
)

View File

@ -0,0 +1,11 @@
version: 2
models:
- name: test_core__transactions_recent
columns:
- name: BLOCK_TIMESTAMP
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: hour
interval: 3

View File

@ -0,0 +1,27 @@
{{ config (
materialized = 'view',
tags = ['recent_test']
) }}
WITH last_3_days AS (
SELECT
closed_at
FROM
{{ ref("_max_ledger_by_date") }}
qualify ROW_NUMBER() over (
ORDER BY
closed_at DESC
) = 3
)
SELECT
*
FROM
{{ ref('defi__fact_liquidity_pools') }}
WHERE
closed_at :: DATE >= (
SELECT
closed_at
FROM
last_3_days
)

View File

@ -0,0 +1,11 @@
version: 2
models:
- name: test_defi__fact_liquidity_pools
columns:
- name: BLOCK_TIMESTAMP
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: hour
interval: 3

View File

@ -0,0 +1,27 @@
{{ config (
materialized = 'view',
tags = ['recent_test']
) }}
WITH last_3_days AS (
SELECT
closed_at
FROM
{{ ref("_max_ledger_by_date") }}
qualify ROW_NUMBER() over (
ORDER BY
closed_at DESC
) = 3
)
SELECT
*
FROM
{{ ref('defi__fact_trades') }}
WHERE
ledger_closed_at :: DATE >= (
SELECT
closed_at
FROM
last_3_days
)

View File

@ -0,0 +1,11 @@
version: 2
models:
- name: test_defi__trades_recent
columns:
- name: BLOCK_TIMESTAMP
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: hour
interval: 3

127
python/dbt_test_alert.py Normal file
View File

@ -0,0 +1,127 @@
import datetime
import requests
import json
import sys
import os
def log_test_result():
"""Reads the run_results.json file and returns a dictionary of targeted test results"""
filepath = "target/run_results.json"
with open(filepath) as f:
run = json.load(f)
logs = []
messages = {
"fail": [],
"warn": []
}
test_count = 0
warn_count = 0
fail_count = 0
for test in run["results"]:
test_count += 1
if test["status"] != "pass":
logs.append(test)
message = f"{test['failures']} record failure(s) in {test['unique_id']}"
if test["status"] == "warn":
messages["warn"].append(message)
warn_count += 1
elif test["status"] == "fail":
messages["fail"].append(message)
fail_count += 1
dbt_test_result = {
"logs": logs,
"messages": messages,
"test_count": test_count,
"warn_count": warn_count,
"fail_count": fail_count,
"elapsed_time": str(datetime.timedelta(seconds=run["elapsed_time"]))
}
return dbt_test_result
def create_message(**kwargs):
messageBody = {
"text": f"Hey{' <!here>' if len(kwargs['messages']['fail']) > 0 else ''}, new DBT test results for :{os.environ.get('DATABASE').split('_DEV')[0]}: {os.environ.get('DATABASE')}",
"attachments": [
{
"color": kwargs["color"],
"fields": [
{
"title": "Total Tests Run",
"value": kwargs["test_count"],
"short": True
},
{
"title": "Total Time Elapsed",
"value": kwargs["elapsed_time"],
"short": True
},
{
"title": "Number of Unsuccessful Tests",
"value": f"Fail: {kwargs['fail_count']}, Warn: {kwargs['warn_count']}",
"short": True
},
{
"title": "Failed Tests:",
"value": "\n".join(kwargs["messages"]["fail"]) if len(kwargs["messages"]["fail"]) > 0 else "None :)",
"short": False
}
],
"actions": [
{
"type": "button",
"text": "View Warnings",
"style": "primary",
"url": "https://github.com/FlipsideCrypto/stellar-models/actions/workflows/dbt_test_recent.yml",
"confirm": {
"title": f"{kwargs['warn_count']} Warnings",
"text": "\n".join(kwargs["messages"]["warn"]) if len(kwargs["messages"]["warn"]) > 0 else "None :)",
"ok_text": "Continue to GHA",
"dismiss_text": "Dismiss"
}
}
]
}
]
}
return messageBody
def send_alert(webhook_url):
"""Sends a message to a slack channel"""
url = webhook_url
data = log_test_result()
send_message = create_message(
fail_count=data["fail_count"],
warn_count=data["warn_count"],
test_count=data["test_count"],
messages=data["messages"],
elapsed_time=data["elapsed_time"],
color="#f44336" if data["fail_count"] > 0 else "#4CAF50"
)
x = requests.post(url, json=send_message)
# test config to continue on error in workflow, so we want to exit with a non-zero code if there are any failures
if data['fail_count'] > 0:
sys.exit(1)
if __name__ == '__main__':
webhook_url = os.environ.get("SLACK_WEBHOOK_URL")
send_alert(webhook_url)