@gabriel.pereira c08a667ce5 docs: improve architecture PDF layout
Print only the focused architecture view with a single-page layout.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-11 11:01:28 -03:00
2026-09-11 10:49:23 -03:00
2026-09-11 10:36:16 -03:00

Talk-to-Data: Semantic Analytics for Enterprise Quotations

A POC case study in governance-first semantic layer design: SAP → Snowflake → Cortex → Chatbot.


Problem Statement

Sales and operations teams across multiple regions handle thousands of quote requests monthly. Each inquiry requires:

  • Manual research: Discount policy lookups, product classification, customer contract data
  • Cross-system queries: SAP for pricing, internal databases for agreements, email chains with ops
  • Coordination overhead: Sales emails ops, ops researches and replies (5-30 minutes per quote)
  • Scale challenge: 30+ salespersons generating inquiries daily across the sales organization

Result: Quote turnaround times of 5-30 minutes, even for routine requests. Ops team context-switches between email, SAP, and spreadsheets. Sales can't get answers fast enough to close deals.


Solution: Semantic Analytics Layer + Cortex Guardrails

Core insight: Build a semantic layer that serves as the single source of truth for quote logic, then consume it via two interfaces: BI dashboards and an LLM-powered chatbot. Governance lives in the data layer, not in prompts.

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│ SAP ERP (Sales, Pricing, Discounts)                         │
│ Updated daily via batch extract (05:00 UTC)                │
└────────────────────────┬────────────────────────────────────┘
                         │
                    Daily ELT Job
                         │
┌────────────────────────▼────────────────────────────────────┐
│ Snowflake Raw Layer                                         │
│ - raw.quotations (document, line item, amount, ...)      │
│ - raw.discount_conditions (discount tiers, policies)     │
│ - raw.customer_master (customer codes, agreements)       │
└────────────────────────┬────────────────────────────────────┘
                         │
                    dbt Staging
                         │
┌────────────────────────▼────────────────────────────────────┐
│ Staging Layer (STAGING schema)                              │
│ - Column mapping, type casting, null handling              │
│ - No business logic, just data preparation                 │
└────────────────────────┬────────────────────────────────────┘
                         │
                   dbt Transforms
                         │
┌────────────────────────▼────────────────────────────────────┐
│ Transform Layer (TRANSFORM schema)                          │
│ - Join discount conditions, policies, agreements           │
│ - Calculate: discount tiers, totals, exceptions            │
│ - Apply: governance flags, audit columns                   │
│ - Models: trf_quotation, trf_chatbot_quotation            │
└────────────────────────┬────────────────────────────────────┘
                         │
              Semantic Views (DDL)
                         │
┌────────────────────────▼────────────────────────────────────┐
│ Semantic Layer (DISTRIBUTE_DDL schema)                      │
│ - sv_quotation: Full BI consumption                        │
│ - sv_chatbot_quotation: LLM-optimized dimensions           │
│ - Exposes: business logic (discounts, policies)            │
│ - Hides: implementation details (temp tables, keys)        │
└────────────────────────┬────────────────────────────────────┘
                         │
            Cortex Analytics Guardrails
                         │
         ┌───────────────┴───────────────┐
         │                               │
┌────────▼──────────────┐      ┌─────────▼─────────────┐
│  Snowflake UI         │      │  Internal Workspace   │
│  (BI Dashboard)       │      │  (Chatbot + LLM)      │
│                       │      │                       │
│ - Visual analysis     │      │ - Quote Q&A           │
│ - Sales reporting     │      │ - Prompt engineering  │
│ - Ops monitoring      │      │ - Real-time answers   │
└───────────┬──────────┘      └──────────┬────────────┘
            │                            │
            │                    <1 minute turnaround
            │
    End Users (Sales, Ops)

Stack: Why Each Layer?

SAP → Snowflake ELT (Daily Batch)

  • Why: Quotation data lives in SAP; Snowflake is the reporting warehouse
  • How: Daily batch extract (05:00 UTC), once-per-day refresh sufficient for quote workflow (real-time inventory not required)
  • Trade-off: Once-daily freshness OK for most quote requests; could escalate to hourly for real-time dashboard if needed

Staging → Transform → Semantic Layer (dbt)

  • Why dbt?

    • Lineage: Column-level traceability (SAP field → transform → semantic dimension)
    • Testability: Unit tests on discount calculations, data quality checks
    • Team reuse: SQL-first approach, skill portability across data team
    • Governance: Schema.yml documents business logic and access rules
    • Reproducibility: Version-controlled transformations, audit trail of changes
  • Why separate layers?

    • Staging: Decouples source-system brittleness from business logic
    • Transform: Concentrates business rules (discount math, policy flags) in one place
    • Semantic: Exposes curated dimensions to downstream consumers; hides technical debt

Snowflake Semantic Views

  • What: Semantic views (DDL) wrap transform models; define dimensions, facts, and synonyms
  • Why:
    • Define the contract between data and consumers (Sales, Cortex)
    • Synonyms enable natural-language queries ("desconto cliente" → discount_customer_pct)
    • Consistent schema across BI dashboards and LLM consumption
  • Example: A chatbot user asks "What's the customer discount on this quote?" The semantic layer maps "customer discount" (natural language) to discount_customer_pct (column), and Cortex applies guardrails (hides the raw percentage and shows only "within policy" or "requires approval")

Cortex Analytics + Guardrails

  • What: Snowflake's native LLM platform + custom governance policies
  • Why Cortex, not custom LLM?
    • Built-in guardrails: protection of sensitive information, access control, and cost controls
    • Fast prototyping: Cortex agents consume Snowflake semantic views directly (no ETL to another system)
    • Governance-as-code: Policies live alongside data, versioned, audited
    • Security: Data stays in Snowflake; LLM calls don't leak sensitive data
  • Trade-off: Cortex is Snowflake-specific (vs. generic LLM + Anthropic); acceptable for POC, revisit if multi-cloud needed later

Dual Consumption (Snowflake UI + Internal Workspace)

  • Snowflake UI: Native BI dashboards for sales/ops teams. Semantic model feeds Power BI or Tableau directly.
  • Internal Workspace: Existing chatbot environment. Cortex queries the semantic layer + prompt engineering layer refines responses.
  • Why two interfaces? Users consume data differently — dashboards for exploration, chatbot for direct answers. Semantic layer unified the source, reducing maintenance.

Key Decisions & Trade-offs

Decision Rationale Trade-off
Governance-first Discount policies, protection of personal and customer information, and exception escalation built into the data layer Requires upfront effort to define policies; can't skip it for "speed"
Semantic views (DDL) Single contract between data → BI/LLM Requires mapping business terms to columns; initial work to get synonyms right
Once-daily batch Sufficient for quote workflow; reduces ELT complexity Not real-time; acceptable for POC; upgrade to hourly if pilot shows need
Cortex (vs. custom LLM) Fast prototyping, built-in guardrails, stays in Snowflake ecosystem Cortex-only (could integrate with Anthropic later)
Separate transform model per interface trf_quotation for BI, trf_chatbot_quotation for LLM — optimize each Slight duplication; worth it if interfaces have different freshness/cardinality needs

Governance: How We Built Safety In

Governance is not a checklist; it's embedded in the data layer.

1. Discount Policy Guardrails

  • Rule: No discount exceeds the configured policy ceiling
  • Implementation:
    • Transform model calculates discount_above_ceiling flag
    • Cortex policy hides raw discount percentages; shows only "Within Policy" or "Requires Approval"
    • Chatbot escalates flagged quotes to ops team (max 10 escalations/hour to prevent bot spam)
  • Effect: Sales can't accidentally propose an unapproved discount; exceptions are visible and auditable

2. Protection of Personal and Customer Information

  • Rule: The chatbot must not expose customer names, contact details, or negotiated terms unless the user is authorized
  • Implementation:
    • sv_chatbot_quotation includes only aggregated customer data (customer_id, portfolio_code)
    • Cortex policy replaces customer_name with "[Customer information protected]" in chatbot responses
    • Exception: Sales team in authorized role can see unmasked values via dashboard
  • Effect: Chatbot can answer quote questions without leaking customer contracts

3. Access Control & Audit Trail

  • Rule: Different roles see different data
    • Sales: Can query sv_chatbot_quotation (limited fields, no raw discounts)
    • Ops: Can query sv_quotation (full discount details, for policy review)
    • Cortex Agent: Can query sv_chatbot_quotation only (locked down for LLM)
  • Implementation: Snowflake role-based access control (RBAC) + Cortex authorized_teams config
  • Audit: All queries logged; policy violations trigger alerts

4. Data Freshness Contract

  • Rule: Chatbot rejects queries on stale data; warns user if data is > 24 hours old
  • Implementation:
    • dbt model adds load_timestamp column
    • Cortex quality gate checks: current_timestamp() - load_timestamp < 24 hours
    • Failure: Returns "Data unavailable; please retry in 1 hour" (prevents stale-data surprises)

Results: From POC to Impact

Estimated Impact (Based on User Interviews)

  • Quote turnaround: 5-30 min (email + manual lookup) → <1 min (chatbot query)
    • Savings per quote: 5-30 minutes
    • Pilots with 5 sales reps: ~50+ hours/week freed (estimated)
    • Extrapolation: 30+ sales team × 5 hours/week = 150+ hours recovered org-wide
  • Error reduction: Discount exceptions caught by policy guardrails (vs. manually reviewed)
  • Team velocity: POC shipped in weeks (not months), governance patterns established for scale

Why This Matters for Delivery Managers

  1. Governance-first approach: We didn't build a prototype and hope for policy later. Guardrails were baked in from day one.
  2. Reusable patterns: The semantic layer + Cortex + dbt playbook works for any quote/contract/discount domain. Next use cases ship faster.
  3. Measurable before scale: We validated impact with a small pilot; ready to scale to 30+ users with confidence.
  4. Ops visibility: Sales/ops can see what the bot is doing (audit logs, escalation flags); not a black box.

How to Use This Repo

Deliverables

  • dbt/: Anonymized dbt models (staging, transforms, semantic views)
    • models/staging/stg_*.sql — Raw layer transformations
    • models/transform/trf_*.sql — Business logic
    • models/distribute_ddl/sv_*.yml — Semantic views with synonyms
  • cortex/: Governance config (information protection, access control, audit rules)
    • cortex_governance_config.yaml — Guardrails, freshness contracts, LLM policies
  • docs/: Architecture diagrams, decision logs
    • architecture_dag.md — Data flow Mermaid diagram
    • decisions.md — Architecture decision records (ADRs)
  • README.md: This file (the narrative for interviewers/stakeholders)

How to Adapt This to Your Domain

  1. Replace discount logic with your domain (e.g., pricing tiers, contract terms, approval workflows)
  2. Adjust freshness (once-daily to hourly/real-time) based on your use case
  3. Modify semantic dimensions to match your business terminology
  4. Update Cortex policies for your personal-information and governance rules
  5. Test with a small pilot (5-10 users) before org-wide rollout

Lessons Learned

What Worked

Semantic views as the contract: Defining dimensions + synonyms upfront saved rework later. Sales/ops understood the model; Cortex had clear field mappings.

Governance in the data layer: Embedding discount flags and information-protection rules in dbt/Cortex meant the bot couldn't bypass them. No workaround hacks possible.

Once-daily batch sufficient: For this workflow, 24-hour freshness was OK. We didn't need real-time complexity (yet).

dbt for team alignment: SQL-first + schema docs meant the data team and business stakeholders spoke the same language. Onboarding new people was fast.

What We'd Change at Scale

⚠️ Real-time discount updates: If pilot shows sales need <1hr freshness on policy changes, escalate to hourly ELT.

⚠️ Multi-region governance: Current config is single-region (BR). If expanding to US/CA, add region-specific discount tiers and approval workflows.

⚠️ Cortex cost: Monitor Cortex token usage as chatbot volume scales. Current config has cost controls (monthly budget, per-query max tokens); may need aggressive pruning at scale.

⚠️ Semantic view complexity: If adding more dimensions (15→50), consider splitting into focused semantic views (e.g., sv_quote_discounts, sv_quote_compliance) to keep queries fast.


Tech Stack Summary

Component Tool Why
Data Warehouse Snowflake Scalable, built-in Cortex, governance features
Transformations dbt + Jinja SQL lineage, testability, team skill reuse
Semantic Layer Snowflake DDL Data contract, synonyms for NLP, single source of truth
AI/Guardrails Cortex Analytics Native LLM, information protection, access control, cost controls
Consumption 1 Snowflake Native App / BI Tool Dashboard for ops/sales exploration
Consumption 2 Internal Workspace + Prompt Engineering Chatbot for direct question-answering
Infrastructure Cloud-native Snowflake No ops overhead, pay-per-query

FAQ

Q: Can I use this with a different warehouse (e.g., BigQuery, Redshift)? A: Yes. Adapt the dbt dialect (BigQuery: jinja-sql, Redshift: redshift profile). Cortex is Snowflake-native; substitute with your own LLM guardrails (policy enforcement layer).

Q: Is once-daily refresh really enough? A: For quote research, yes. If you need real-time pricing updates, escalate to hourly ELT. The architecture supports it; just change the schedule in your orchestrator.

Q: How do I handle discount exceptions? A: Cortex policy flags them and escalates to a human review queue (max 10/hour). Ops team approves or rejects in Snowflake; bot learns the decision for future similar quotes.

Q: What if I need to scale to 500+ users? A: Semantic layer architecture scales horizontally. Snowflake handles concurrency. Monitor Cortex token usage and partition semantic views if queries slow down. dbt stays the same.

Q: Can I export this as a Snowflake Native App for partners? A: Yes. Package the semantic views + Cortex policies as an app; partners can install it and use the chatbot without seeing raw data.


Next Steps

  1. Expand pilot: Rollout to 30+ sales team over 4 weeks
  2. Measure impact: Track quote turnaround times, bot usage, escalation rates
  3. Iterate on policies: Refine discount rules and information-protection controls based on pilot feedback
  4. Add new domains: Reuse the semantic layer pattern for contracts, serviceability, pricing
  5. Scale LLM: Move from proof-of-concept to production volume (monitor cost, latency)

Contact & Questions

This case study demonstrates:

  • Governance-first architecture for enterprise AI
  • Semantic layer design (SAP → dbt → Snowflake → LLM)
  • Operationalizing guardrails and audit trails
  • Shipping production-ready POCs in weeks

For questions about the design decisions, data flow, or how to adapt this to your domain, reach out.


Co-authored by Copilot

Description
No description provided
Readme 598 KiB
Languages
SQL 100%