Bronze Layer · Data Source

Tamarac

Portfolio management report API with PFX certificate authentication. 33 tables across two target databases — PostgreSQL and Azure SQL — covering holdings, transactions, performance, billing, models, and households.

33Tables
1 PM / 2:30 PMUTC Daily
PG + Azure SQLTarget DBs
NoneArchive
I

Data Source

PropertyValue
Source TypePortfolio management report system — REST API
Delivery MethodHTTPS API — report generation + download
AuthenticationPFX certificate (redwood-tamarac-prod-cert-pfx) + API config (redwood-tamarac-api-config)
Output FormatZIP → CSV per report template
Intermediate StorageAzure Blob Storage (tamarac container, hot tier)
Target DatabasesPostgreSQL · Azure SQL (dbo schema)
DAGsredwood_tamarac_sync_v2 (PG) · redwood_tamarac_azuresql_sync (AzureSQL)
Blob reuse window4 hours — AzureSQL uploads blob at 1 PM, PG reuses it at 2:30 PM
Row validation gateRejects load if new CSV row count < 95% of current table size

Task Pipeline per Template

generate
Queue report or reuse blob
download
Wait & download binary
upload_blob
Upload ZIP to hot storage
extract
Unzip CSV
import_tmp
Load → __tmp_{table}
validate
Row count >= 95%
promote
TRUNCATE + INSERT
cleanup
Remove temp dir

Airflow pools limit concurrency: generate_pool (3 slots — API rate limiting) · import_pool (1 slot — memory pressure). Max active tasks: 20 across all templates.

II

Objects Being Synced

Standard Tamarac Tables (11)

tamarac_templates
Report template definitions and configuration
tamarac_account_information
Account master — entity type, custodian, household
tamarac_account_holdings_current
Current position holdings per account
tamarac_household_information
Household data — address, managed value, net worth
tamarac_group_members
Group-to-account membership
tamarac_billing_groups
Billing group definitions
tamarac_billing_history
Historical billing records
tamarac_security_information
Security master data
tamarac_reports
Report run definitions
tamarac_aum_previous_quarter
Prior quarter AUM snapshot
tamarac_manual_security_snapshot_ytd
Manual YTD security snapshot

Tableau CRM (Tamarac Analytics) Tables (22)

tableau_crm_tamarac_holdings
Current holdings with pricing
tableau_crm_tamarac_holdings_prior_month_end
Prior month-end holdings snapshot
tableau_crm_tamarac_transactions
Transaction records
tableau_crm_tamarac_transactions_2
Supplemental transactions
tableau_crm_tamarac_transactions_history
Full transaction history
tableau_crm_tamarac_transactions_large
Large/complex transactions (separate for performance)
tableau_crm_tamarac_households
Household-level data
tableau_crm_tamarac_financial_accounts
Financial account records
tableau_crm_tamarac_group_members
Group membership
tableau_crm_tamarac_aum_capital_flow_transactions
AUM & capital flow transactions
tableau_crm_tamarac_performance_data
TWR, IRR, benchmark comparisons
tableau_crm_tamarac_billing_groups
Billing group data
tableau_crm_tamarac_billing_payment_details
Billing payment detail
tableau_crm_tamarac_model_properties
Investment model properties
tableau_crm_tamarac_model_security
Model-to-security mapping
tableau_crm_tamarac_security_level_model
Security-level model data
tableau_crm_tamarac_account_excluded_securities
Excluded securities per account
tableau_crm_tamarac_account_security_information
Per-account security info
tableau_crm_tamarac_account_security_restrictions
Security restrictions
tableau_crm_tamarac_cash_reserves
Cash reserve settings
tableau_crm_tamarac_custom_input_symbols
Custom symbol mappings
tableau_crm_tamarac_substitute_securities
Substitute security rules
III

Config, Logs, Monitoring & Schedule

Configuration Table — tamarac_templates

ColumnTypeDescription
template_idINTEGER PKInternal template identifier
template_nameTEXTTamarac report name
destination_tableTEXTTarget PostgreSQL/AzureSQL table
is_enabledBOOLEANActive flag — only enabled templates are synced
API parametersReport generation configuration (filters, date ranges, etc.)

Feature Flags

FlagPG ValueAzureSQL ValuePurpose
ENABLE_BLOB_UPLOADTrueTrueUpload downloaded ZIP to Azure Blob
ENABLE_BLOB_REUSETrueTrueReuse recent blob instead of re-downloading
BLOB_REUSE_MAX_AGE_HOURS42Max blob age before re-download required
ENABLE_ROW_VALIDATIONTrueTrueReject load if rows drop >5% vs current table

Monitoring & Alerting

PropertyValue
Notifierairflow_email_notifier — success + failure callbacks
Subject prefix[Redwood]
On success / failureYes / Yes
Execution timeout4 hours
Max active tasks20 (across all templates)
generate_pool3 slots (API rate limiting)
import_pool1 slot (memory pressure — OOM prevention)
Retry callbacksvalidate_records / import_tmp_table failures clear upstream tasks for fresh download

Email recipients: prashant.surana@collation.ai · monitor@collation.ai · mschwartz@sequoia-financial.com · handerson@sequoia-financial.com · vzivich@sequoia-financial.com · hpatel@sequoia-financial.com · karishni.mehta@collation.ai

DAG Schedule

Pipeline ordering: AzureSQL DAG runs at 1:00 PM UTC and uploads blob. PG DAG runs at 2:30 PM UTC and reuses that blob (within the 4-hour reuse window) — avoiding duplicate Tamarac API calls.
1:00 PM UTC
0 13 * * * · Daily · Azure SQL
2:30 PM UTC
30 14 * * * · Daily · PostgreSQL

Max active runs: 1 · Catchup: disabled · AzureSQL start date: 2024-01-01 · PG start date: 2026-03-20

IV

Bronze Layer — Database Schema

Schema: PostgreSQL tables reside in the public schema. Azure SQL tables use the dbo schema. All tables include imported_at TIMESTAMP and last_sync_at TIMESTAMP. Staging tables are named __tmp_{table_name} and are dropped after atomic promotion.

tamarac_templates

CREATE TABLE public.tamarac_templates (
    template_id       INTEGER,
    template_name     TEXT,
    destination_table TEXT,
    is_enabled        BOOLEAN
    -- Additional API generation parameters...
);

tamarac_account_information

CREATE TABLE public.tamarac_account_information (
    account_number    TEXT,
    account_name      TEXT,
    entity_type       TEXT,
    custodian_code    TEXT,
    household_id      TEXT,
    household_name    TEXT,
    tax_id            TEXT,
    open_date         DATE,
    close_date        DATE,
    is_excluded       BOOLEAN,
    managed_value     NUMERIC,
    upload_account_id TEXT,
    imported_at       TIMESTAMP,
    last_sync_at      TIMESTAMP
);

tamarac_household_information

CREATE TABLE public.tamarac_household_information (
    household_id          TEXT,
    household_name        TEXT,
    primary_contact_name  TEXT,
    address_line1         TEXT,
    address_line2         TEXT,
    city                  TEXT,
    state                 TEXT,
    postal_code           TEXT,
    country               TEXT,
    phone                 TEXT,
    email                 TEXT,
    total_managed_value   NUMERIC,
    net_worth             NUMERIC,
    upload_household_id   TEXT,
    imported_at           TIMESTAMP,
    last_sync_at          TIMESTAMP
);

tamarac_security_information

CREATE TABLE public.tamarac_security_information (
    security_id        TEXT,
    ticker             TEXT,
    cusip              TEXT,
    security_name      TEXT,
    asset_class        TEXT,
    sector             TEXT,
    upload_security_id TEXT,
    imported_at        TIMESTAMP
);

Tableau CRM Tables

All tableau_crm_tamarac_* tables are populated directly from Tamarac report CSV output. Column schemas are derived from report headers and vary per template. Key fields across tables:

TableKey Fields
…_holdingsaccount_number, security_id, cusip, ticker, quantity, price, market_value, cost_basis, unrealized_gain_loss
…_transactionsaccount_number, security_id, transaction_type, trade_date, settle_date, quantity, price, amount, fees
…_transactions_historySame as transactions — full historical set
…_performance_dataaccount_number, period, twr, irr, benchmark_return, inception_date
…_aum_capital_flow_transactionsaccount_number, date, flow_type, amount, beginning_value, ending_value
…_householdshousehold_id, household_name, managed_value, net_worth, primary_advisor
…_financial_accountsaccount_number, account_name, custodian, registration_type, household_id
…_billing_groupsgroup_id, group_name, fee_schedule, accounts
…_billing_payment_detailsaccount_number, billing_date, amount, fee_type, period
…_model_propertiesmodel_id, model_name, asset_class, benchmark, risk_level
…_model_securitymodel_id, security_id, ticker, target_weight, min_weight, max_weight
…_account_excluded_securitiesaccount_number, security_id, exclusion_reason, start_date
…_account_security_restrictionsaccount_number, security_id, restriction_type, constraint_value
…_cash_reservesaccount_number, reserve_amount, reserve_type, effective_date
…_substitute_securitiesoriginal_security_id, substitute_security_id, account_number, reason
…_custom_input_symbolssymbol_name, mapped_ticker, asset_class, price_source
V

Archiving Policy

No dedicated file archival DAG for Tamarac. Tamarac does not maintain source files in long-term storage. The blob storage in the tamarac container serves as a short-term intermediate layer for blob reuse between the AzureSQL and PostgreSQL DAGs. Database-level archival may be configured via redwood_database_archive.

Blob Reuse Mechanism

SettingValue
Containertamarac (Azure Blob hot tier)
PG reuse windowBLOB_REUSE_MAX_AGE_HOURS = 4
AzureSQL reuse windowBLOB_REUSE_MAX_AGE_HOURS = 2
PurposeAzureSQL DAG (1:00 PM) uploads blob → PG DAG (2:30 PM) reuses it — avoids duplicate API calls
Feature flagENABLE_BLOB_REUSE = True
Blob naming{safe_template_name}.zip

Database Table Archiving (via redwood_database_archive)

SettingValue
Schedule0 2 * * * — Daily 2:00 AM UTC
Cold storage path{blob_container}/{prefix}/{YYYYMMDD}/{table}_{timestamp}.zip
Config tabledatabase_archive_config — tables must be explicitly enabled
Log tabledatabase_archive_log
Cold storage secretredwood-cold-storage-config