Selcan Yukcu commited on
Commit
2eb8d6d
·
1 Parent(s): 35a0431

refactor: dm schema

Browse files
gradio_app.py CHANGED
@@ -4,6 +4,7 @@ import gradio as gr
4
  import asyncio
5
  from postgre_mcp_client import pg_mcp_exec
6
  from postgre_smolagent_clinet import pg_mcp_smolagent_exec
 
7
 
8
 
9
  def load_db_configs():
 
4
  import asyncio
5
  from postgre_mcp_client import pg_mcp_exec
6
  from postgre_smolagent_clinet import pg_mcp_smolagent_exec
7
+ from postgre_smolagent_clinet import pg_mcp_smolagent_exec
8
 
9
 
10
  def load_db_configs():
postgre_mcp_server.py CHANGED
@@ -135,6 +135,14 @@ async def base_prompt_query() -> str:
135
  - Last SQL queries: {last_queries}
136
  - Last result preview: {last_results}
137
 
 
 
 
 
 
 
 
 
138
  ---
139
 
140
  ==========================
 
135
  - Last SQL queries: {last_queries}
136
  - Last result preview: {last_results}
137
 
138
+ ---
139
+
140
+ ==========================
141
+ # Database Description
142
+ ==========================
143
+
144
+ {descriptions}
145
+
146
  ---
147
 
148
  ==========================
postgre_smolagent_clinet.py CHANGED
@@ -42,7 +42,7 @@ async def pg_mcp_smolagent_exec(request: str) -> str:
42
  tools = await load_and_enrich_tools(session, table_summary)
43
  past_data = get_memory_snapshot(memory)
44
 
45
- prompt = await build_prompt(session, intent, request, tools, past_data)
46
  agent_response = agent.run(task=prompt, stream=False)
47
 
48
  # TODO: add a smolagent output parser
@@ -76,8 +76,8 @@ async def load_or_create_memory() -> ConversationMemory:
76
 
77
  async def load_and_enrich_tools(session: ClientSession, summary: str):
78
  tools = await load_mcp_tools(session)
79
- for tool in tools:
80
- tool.description += f" {summary}"
81
  return tools
82
 
83
  def get_memory_snapshot(memory: ConversationMemory) -> dict:
@@ -95,7 +95,7 @@ def get_memory_snapshot(memory: ConversationMemory) -> dict:
95
  "past_requests": "No requests found"
96
  }
97
 
98
- async def build_prompt(session, intent, request, tools, past_data):
99
  superset_prompt = await session.read_resource("resource://last_prompt")
100
  conversation_prompt = await session.read_resource("resource://base_prompt")
101
  # TODO: add uri's from config
@@ -106,7 +106,8 @@ async def build_prompt(session, intent, request, tools, past_data):
106
  past_tools=past_data["past_tools"],
107
  last_queries=past_data["past_queries"],
108
  last_results=past_data["past_results"],
109
- new_request=request
 
110
  )
111
  else:
112
  template = conversation_prompt.contents[0].text
 
42
  tools = await load_and_enrich_tools(session, table_summary)
43
  past_data = get_memory_snapshot(memory)
44
 
45
+ prompt = await build_prompt(session, intent, request, tools, past_data, table_summary)
46
  agent_response = agent.run(task=prompt, stream=False)
47
 
48
  # TODO: add a smolagent output parser
 
76
 
77
  async def load_and_enrich_tools(session: ClientSession, summary: str):
78
  tools = await load_mcp_tools(session)
79
+ #for tool in tools:
80
+ # tool.description += f" {summary}"
81
  return tools
82
 
83
  def get_memory_snapshot(memory: ConversationMemory) -> dict:
 
95
  "past_requests": "No requests found"
96
  }
97
 
98
+ async def build_prompt(session, intent, request, tools, past_data, summary):
99
  superset_prompt = await session.read_resource("resource://last_prompt")
100
  conversation_prompt = await session.read_resource("resource://base_prompt")
101
  # TODO: add uri's from config
 
106
  past_tools=past_data["past_tools"],
107
  last_queries=past_data["past_queries"],
108
  last_results=past_data["past_results"],
109
+ new_request=request,
110
+ descriptions = summary
111
  )
112
  else:
113
  template = conversation_prompt.contents[0].text
table_summary.txt CHANGED
@@ -1,3 +1,342 @@
1
- The users table stores information about the individuals who use the application. Each user is assigned a unique, auto-incrementing id that serves as the primary key. The username field holds the user's chosen display name and cannot be null, while the email field stores the user’s unique email address, also required and constrained to be unique to avoid duplicates. To track when a user was added to the system, the created_at column records the timestamp of their creation, with a default value set to the current time.
2
 
3
- The posts table represents content created by users, such as blog posts or messages. Like the users table, each entry has a unique, auto-incrementing id as the primary key. The user_id field links each post to its author by referencing the id field in the users table, establishing a one-to-many relationship between users and posts. The title column holds a brief summary or headline of the post, while the content field contains the full text. A created_at timestamp is also included to record when each post was created, with a default value of the current time.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Table: `dim_agreement`
2
 
3
+ ### Schema: `dm`
4
+
5
+ ### All Columns and their Descriptions:
6
+ - `agreement_id` (text): Unique identifier for the agreement. This is likely the primary key.
7
+ - `customer_id` (text): Identifier for the customer associated with the agreement. This is likely a foreign key referencing a customer table.
8
+ - `agreement_type` (text): The type of agreement (e.g., Service Level Agreement, Sales Agreement).
9
+ - `agreement_name` (text): The name or title of the agreement.
10
+ - `agreement_status` (text): The current status of the agreement (e.g., Active, Inactive, Expired).
11
+ - `description` (text): A textual description of the agreement.
12
+ - `document_number` (text): The document number associated with the agreement.
13
+ - `statement_of_intent` (text): Indicates whether a statement of intent is associated with the agreement.
14
+ - `version` (text): The version number of the agreement.
15
+ - `initial_date` (timestamp without time zone): The date the agreement was initially created.
16
+ - `agreement_period_start_date` (timestamp without time zone): The start date of the agreement period.
17
+ - `agreement_period_end_date` (timestamp without time zone): The end date of the agreement period.
18
+ - `completion_date_start_date` (timestamp without time zone): The start date of the completion date.
19
+ - `completion_date_end_date` (text): The end date of the completion date.
20
+ - `auto_renewal` (text): Indicates whether the agreement has auto-renewal enabled.
21
+ - `commitment_unit` (text): The unit for the commitment amount (e.g., USD, hours).
22
+ - `rating_type` (text): The type of rating associated with the agreement.
23
+ - `commitment_amount` (text): The committed amount associated with the agreement.
24
+ - `remaining_payment_cycle` (text): The remaining payment cycle.
25
+ - `termination_date` (text): The date the agreement was terminated.
26
+
27
+ ### Relationships with Other Tables (Foreign Keys):
28
+ - `customer_id` (FK) references a `customer` table (likely `dim_customer` or similar) on the `customer_id` column. This links the agreement to a specific customer.
29
+
30
+ ### Cardinality of Relationships:
31
+ - Relationship with `dim_customer` (or similar) is one-to-many. One customer can have multiple agreements.
32
+
33
+ ### Common Use Cases/Example Queries:
34
+ - Describe all active agreements for a specific customer.
35
+ - Analyze agreements by type or status.
36
+ - Track agreement start and end dates.
37
+ - Example SQL Snippet: `SELECT * FROM dim_agreement WHERE customer_id = 'customer_id_value' AND agreement_status = 'Active';`
38
+
39
+ ### Data Constraints and Business Rules:
40
+ - `agreement_id` is likely unique and a primary key.
41
+ - `agreement_status` might have a controlled vocabulary (e.g., Active, Inactive).
42
+ - Date fields should be validated for data integrity.
43
+ - Business rules may dictate agreement approval processes or renewal cycles.
44
+
45
+ ### Data Update Frequency/Volatility:
46
+ - Data is likely updated when agreements are created, modified, or terminated.
47
+ - Update frequency would depend on the business processes.
48
+
49
+ ### Potential Pitfalls/Things to Avoid When Querying:
50
+ - Ensure correct date ranges when filtering by agreement period or completion dates.
51
+ - Be aware of potential data quality issues in text fields.
52
+
53
+ ### Important Notes/Considerations for Querying:
54
+ - Join with the `dim_customer` table to retrieve customer information.
55
+ - Consider indexing frequently queried columns (e.g., `customer_id`, `agreement_status`, `agreement_type`).
56
+
57
+ ---
58
+
59
+ ## Table: `dim_customer`
60
+
61
+ ### Schema: `dm`
62
+
63
+ ### All Columns and their Descriptions:
64
+ - `customer_id` (text): Likely the primary identifier for a customer. This is probably the primary key, although not explicitly stated.
65
+ - `customer_name` (text): The name of the customer.
66
+ - `customer_start_date` (timestamp without time zone): The date the customer record became active.
67
+ - `customer_end_date` (timestamp without time zone): The date the customer record became inactive.
68
+ - `customer_status` (text): The status of the customer (e.g., Active, Inactive).
69
+ - `is_customer_active` (integer): Indicates whether the customer is currently active (1 or 0).
70
+ - `customer_status_reason` (text): Reason for the customer's status.
71
+ - `market_segment` (text): The market segment the customer belongs to.
72
+ - `customer_segment` (text): The customer segment the customer belongs to.
73
+ - `is_individual_customer` (integer): Indicates whether the customer is an individual (1 or 0).
74
+ - `organization_name` (text): The name of the organization, if the customer is an organization.
75
+ - `trading_name` (text): The trading name of the customer.
76
+ - `organization_type_id` (text): The ID of the organization type.
77
+ - `is_head_office` (boolean): Indicates if the customer is a head office.
78
+ - `is_legal_entity` (boolean): Indicates if the customer is a legal entity.
79
+ - `organization_start_date` (timestamp without time zone): The date the organization record became active.
80
+ - `organization_end_date` (timestamp without time zone): The date the organization record became inactive.
81
+ - `birth_date` (timestamp without time zone): The birth date of the customer, if an individual.
82
+ - `death_date` (timestamp without time zone): The death date of the customer, if an individual.
83
+ - `country_of_birth` (text): The country of birth of the customer, if an individual.
84
+ - `party_status` (text): The status of the party.
85
+ - `title` (text): The title of the customer, if an individual.
86
+ - `generation` (text): The generation of the customer, if an individual.
87
+ - `preferred_given_name` (text): The preferred given name of the customer, if an individual.
88
+ - `given_name` (text): The given name of the customer, if an individual.
89
+ - `middle_name` (text): The middle name of the customer, if an individual.
90
+ - `family_name` (text): The family name of the customer, if an individual.
91
+ - `family_name_prefix` (text): The family name prefix of the customer, if an individual.
92
+ - `formatted_name` (text): The formatted name of the customer.
93
+ - `full_name` (text): The full name of the customer.
94
+ - `legal_name` (text): The legal name of the customer.
95
+ - `gender` (text): The gender of the customer, if an individual.
96
+ - `location` (text): The location of the customer.
97
+ - `marital_status` (text): The marital status of the customer, if an individual.
98
+ - `nationality` (text): The nationality of the customer, if an individual.
99
+ - `place_of_birth` (text): The place of birth of the customer, if an individual.
100
+ - `juridical_info` (text): Juridical information of the customer.
101
+ - `latitude` (text): The latitude of the customer's location.
102
+ - `longitude` (text): The longitude of the customer's location.
103
+ - `number_of_employees` (text): The number of employees for the customer, if an organization.
104
+ - `tax_exempt` (text): Indicates if the customer is tax-exempt.
105
+ - `dunning_level` (text): The dunning level for the customer.
106
+ - `contact_verified` (text): Indicates if the contact information is verified.
107
+ - `customer_number` (text): The customer number.
108
+ - `communication_method` (text): The communication method for the customer.
109
+ - `sales_agent_id` (text): The ID of the sales agent. Likely a foreign key to a `sales_agent` table.
110
+ - `account_manager_id` (text): The ID of the account manager. Likely a foreign key to an `account_manager` table.
111
+ - `sales_partner_id` (text): The ID of the sales partner. Likely a foreign key to a `sales_partner` table.
112
+ - `party_identifier` (text): The party identifier.
113
+ - `customer_revision` (bigint): The customer revision number.
114
+ - `party_revision` (bigint): The party revision number.
115
+
116
+ ### Relationships with Other Tables (Foreign Keys):
117
+ - Based on the column names, it is *highly likely* that the table has foreign keys to tables such as: `sales_agent`, `account_manager`, and `sales_partner`. Without the ability to see the foreign key constraints, this is an educated guess.
118
+
119
+ ### Cardinality of Relationships:
120
+ - Relationship with `sales_agent`, `account_manager`, and `sales_partner` is likely one-to-many. One sales agent/account manager/sales partner can be associated with multiple customers.
121
+
122
+ ### Common Use Cases/Example Queries:
123
+ - Describe common use cases:
124
+ * Reporting on customer demographics.
125
+ * Analyzing customer sales by segment.
126
+ * Tracking customer status and activity.
127
+ * Identifying customers by sales agent or account manager.
128
+ - Example SQL Snippet:
129
+ ```sql
130
+ SELECT customer_name, market_segment, customer_status
131
+ FROM dim_customer
132
+ WHERE sales_agent_id = 'XYZ123';
133
+ ```
134
+
135
+ ### Data Constraints and Business Rules:
136
+ - `customer_id` is likely the primary key and should be unique and not null.
137
+ - `customer_start_date` should be before or equal to `customer_end_date`.
138
+ - `is_customer_active` should reflect the status of the customer based on `customer_start_date`, `customer_end_date`, and `customer_status`.
139
+ - Data quality checks should be in place to ensure the accuracy of demographic data (e.g., valid gender, valid countries).
140
+
141
+ ### Data Update Frequency/Volatility:
142
+ - The data is likely updated frequently as customer information changes.
143
+ - The volatility of the data will vary depending on the specific attributes (e.g., contact information will be more volatile than birthdate).
144
+
145
+ ### Potential Pitfalls/Things to Avoid When Querying:
146
+ - Joining to other tables without properly understanding the relationships, especially the role of `sales_agent_id`, `account_manager_id`, and `sales_partner_id`.
147
+ - Incorrectly filtering on date ranges. Consider using `customer_start_date` and `customer_end_date` to filter for active customers.
148
+ - Not considering the impact of customer status when analyzing customer data.
149
+
150
+ ### Important Notes/Considerations for Querying:
151
+ - Always check `is_customer_active` or `customer_status` when querying to ensure you are getting the correct set of customers.
152
+ - Be mindful of the date ranges when analyzing customer data over time.
153
+ - Use the appropriate join conditions when joining with other tables.
154
+ - Consider the impact of null values in fields such as `birth_date`, `death_date`, etc.
155
+
156
+
157
+ ---
158
+
159
+
160
+ ## Table: `dim_product`
161
+
162
+ ### Schema: `dm`
163
+
164
+ ### All Columns and their Descriptions:
165
+
166
+ * **product\_id (text):** Likely the primary identifier for the product. It's a text field. It is likely the primary key, though I don't have FK information.
167
+ * **customer\_id (text):** The identifier for the customer associated with the product. Foreign key to the `dim_customer` table (inferred, as I lack foreign key info).
168
+ * **agreement\_id (text):** An identifier for the agreement related to the product. Foreign key to the `dim_agreement` table (inferred).
169
+ * **agreement\_name (text):** The name of the agreement related to the product.
170
+ * **product\_offering\_id (text):** An identifier for the product offering. Potentially a foreign key to a `dim_product_offering` table (inferred).
171
+ * **product\_offering\_name (text):** The name of the product offering.
172
+ * **product\_name (text):** The name of the product.
173
+ * **place\_id (text):** An identifier related to the product's location or place. Foreign key to `dim_place` (inferred).
174
+ * **product\_class (text):** Categorization of the product (e.g., service, hardware).
175
+ * **product\_status (text):** The current status of the product (e.g., active, inactive).
176
+ * **is\_product\_active (integer):** Indicates if the product is active (1) or not (0).
177
+ * **is\_product\_suspended (integer):** Indicates if the product is suspended (1) or not (0).
178
+ * **is\_product\_in\_active (integer):** Indicates if the product is inactive (1) or not (0).
179
+ * **is\_bundle (boolean):** Indicates if the product is part of a bundle (true) or not (false).
180
+ * **order\_date (timestamp without time zone):** The date the product was ordered.
181
+ * **start\_date (timestamp without time zone):** The date the product service started.
182
+ * **price\_type (text):** The type of pricing associated with the product (e.g., recurring, one-time).
183
+ * **price\_type\_value (text):** The value associated with the price type.
184
+ * **recurring\_charge\_period (text):** The period for recurring charges (e.g., monthly, annually).
185
+ * **tax\_rate (double precision):** The tax rate applied to the product.
186
+ * **duty\_free\_amount (double precision):** The duty-free amount for the product.
187
+ * **tax\_included\_amount (double precision):** The amount of tax included in the product price.
188
+ * **add\_product\_order\_item\_id (text):** Identifier for adding a product to an order item.
189
+ * **delete\_product\_order\_item\_id (text):** Identifier for deleting a product from an order item.
190
+ * **sales\_agent\_id (text):** The identifier of the sales agent. Foreign key to `dim_sales_agent` (inferred).
191
+ * **sales\_partner\_id (text):** The identifier of the sales partner. Foreign key to `dim_sales_partner` (inferred).
192
+ * **commitment\_duration\_units (text):** The units for the commitment duration (e.g., months, years).
193
+ * **commitment\_duration (double precision):** The duration of the commitment.
194
+ * **commitment\_term\_name (text):** The name of the commitment term.
195
+ * **commitment\_term\_type (text):** The type of commitment term.
196
+ * **usage\_duration\_units (text):** The units for the usage duration.
197
+ * **usage\_duration (double precision):** The duration of the product usage.
198
+ * **usage\_term\_name (text):** The name of the usage term.
199
+ * **usage\_term\_type (text):** The type of usage term.
200
+ * **guarantee\_amount (text):** The amount of guarantee associated with the product.
201
+ * **device\_type (text):** The type of device associated with the product.
202
+ * **gl\_code (text):** General Ledger code associated with the product.
203
+ * **infrastructure (text):** The infrastructure associated with the product.
204
+ * **ip\_address (text):** The IP address associated with the product.
205
+ * **mac\_address (text):** The MAC address associated with the product.
206
+ * **oss\_code (text):** OSS code associated with the product.
207
+ * **smart\_card\_serialnumber (text):** The serial number of the smart card associated with the product.
208
+ * **sla (text):** Service Level Agreement associated with the product.
209
+ * **spec\_type (text):** Specification type of the product.
210
+ * **specsub\_type (text):** Specification subtype of the product.
211
+ * **resource\_model (text):** The resource model associated with the product.
212
+ * **rating\_type (text):** The type of rating associated with the product.
213
+ * **postpaid\_type (text):** The postpaid type associated with the product.
214
+ * **brand\_name (text):** The brand name of the product.
215
+ * **tv\_infrastructure (text):** The TV infrastructure associated with the product.
216
+ * **revision (bigint):** Revision number of the product.
217
+ * **href (text):** Hypertext reference (URL) associated with the product.
218
+
219
+ ### Relationships with Other Tables (Foreign Keys):
220
+
221
+ * **customer\_id:** Foreign key referencing `dim_customer`.
222
+ * **agreement\_id:** Foreign key referencing `dim_agreement`.
223
+ * **product\_offering\_id:** Foreign key referencing `dim_product_offering`.
224
+ * **place\_id:** Foreign key referencing `dim_place`.
225
+ * **sales\_agent\_id:** Foreign key referencing `dim_sales_agent`.
226
+ * **sales\_partner\_id:** Foreign key referencing `dim_sales_partner`.
227
+
228
+ ### Cardinality of Relationships:
229
+
230
+ * Relationship with `dim_customer` is likely one-to-many (one customer can have many products).
231
+ * Relationship with `dim_agreement` is likely one-to-many (one agreement can have many products).
232
+ * Relationship with `dim_product_offering` is likely one-to-many (one product offering can be associated with many products).
233
+ * Relationship with `dim_place` is likely one-to-many (one place can have many products).
234
+ * Relationship with `dim_sales_agent` is likely one-to-many (one sales agent can be associated with many products).
235
+ * Relationship with `dim_sales_partner` is likely one-to-many (one sales partner can be associated with many products).
236
+
237
+ ### Common Use Cases/Example Queries:
238
+
239
+ * **Tracking Product Details:** Retrieving detailed information about a specific product.
240
+ * Example SQL Snippet: `SELECT * FROM dm.dim_product WHERE product_id = 'your_product_id';`
241
+ * **Customer Product Overview:** Listing all products associated with a specific customer.
242
+ * Example SQL Snippet: `SELECT * FROM dm.dim_product WHERE customer_id = 'your_customer_id';`
243
+ * **Aggregating product counts:** Calculating the number of products per product offering.
244
+ * Example SQL Snippet: `SELECT product_offering_name, count(*) FROM dm.dim_product GROUP BY product_offering_name;`
245
+
246
+ ### Data Constraints and Business Rules:
247
+
248
+ * `product_id` is likely unique and not null.
249
+ * `is_product_active`, `is_product_suspended`, and `is_product_in_active` should be mutually exclusive (only one can be true at a time).
250
+ * Date fields (order\_date, start\_date) should be consistent with business timelines.
251
+
252
+ ### Data Update Frequency/Volatility:
253
+
254
+ * Data is likely updated frequently, with changes reflecting product status, customer associations, and order information.
255
+
256
+ ### Potential Pitfalls/Things to Avoid When Querying:
257
+
258
+ * Ensure proper joins when querying across related tables (e.g., `dim_customer`, `dim_agreement`).
259
+ * Be aware of product lifecycle (status) when filtering data. Consider `is_product_active` and other status flags.
260
+ * Performance can suffer if large datasets are queried without appropriate indexes.
261
+
262
+ ### Important Notes/Considerations for Querying:
263
+
264
+ * Always join to other dimension tables (e.g., `dim_customer`, `dim_agreement`) to get a complete view of the product's context.
265
+ * Use appropriate date ranges when analyzing product activity over time.
266
+ * Consider the business rules related to product states when building queries.
267
+
268
+ ---
269
+
270
+
271
+ ## Table: `dim_product_order_item`
272
+
273
+ ### Schema: `dm`
274
+
275
+ ### All Columns and their Descriptions:
276
+
277
+ - `product_order_item_id` (text): Unique identifier for a product order item. Likely the primary key.
278
+ - `product_order_id` (text): Likely a foreign key referencing a table containing product order information (e.g., `dim_product_order`).
279
+ - `customer_id` (text): Likely a foreign key referencing the `dim_customer` table.
280
+ - `agreement_id` (text): Likely a foreign key referencing the `dim_agreement` table.
281
+ - `agreement_name` (text): Name of the agreement.
282
+ - `order_item_agreement_id` (text): Identifier for the order item agreement.
283
+ - `order_item_agreement_name` (text): Name of the order item agreement.
284
+ - `billing_account_id` (text): Identifier for the billing account.
285
+ - `sales_channel` (text): The sales channel through which the order was placed.
286
+ - `order_date` (timestamp without time zone): The date the order was placed.
287
+ - `order_status` (text): The status of the order (e.g., 'Pending', 'Shipped', 'Delivered').
288
+ - `order_item_status` (text): The status of the order item.
289
+ - `order_description` (text): Description of the order.
290
+ - `order_revision` (bigint): The revision number of the order.
291
+ - `order_class` (text): The class of the order.
292
+ - `order_href` (text): Hyperlink related to the order.
293
+ - `order_item_type` (text): The type of the order item (e.g., 'Product', 'Service').
294
+ - `quantity` (bigint): The quantity of the product ordered.
295
+ - `order_item_price_type` (text): The price type of the order item (e.g., 'Recurring', 'One-time').
296
+ - `order_item_recurring_charge_period` (text): The recurring charge period if applicable.
297
+ - `order_item_tax_rate` (double precision): The tax rate applied to the order item.
298
+ - `order_item_duty_free_amount` (double precision): The duty-free amount of the order item.
299
+ - `order_item_tax_included_amount` (double precision): The tax-included amount of the order item.
300
+ - `order_item_action` (text): The action performed on the order item (e.g., 'Add', 'Update', 'Delete').
301
+
302
+ ### Relationships with Other Tables (Foreign Keys):
303
+
304
+ - `customer_id` (FK) references `dim_customer`: Links the order item to a specific customer.
305
+ - `agreement_id` (FK) references `dim_agreement`: Links the order item to a specific agreement.
306
+ - `product_order_id`: Likely references a table containing product order information (e.g., `dim_product_order`).
307
+
308
+ ### Cardinality of Relationships:
309
+
310
+ - Relationship with `dim_customer` is one-to-many. One customer can have multiple order items.
311
+ - Relationship with `dim_agreement` is one-to-many. One agreement can have multiple order items.
312
+ - Relationship with the product order table is one-to-many. One product order can have multiple order items.
313
+
314
+ ### Common Use Cases/Example Queries:
315
+
316
+ - Track sales and revenue by customer, product, and agreement.
317
+ - Analyze order item status and trends.
318
+ - Calculate total revenue and taxes.
319
+ - Example SQL Snippet: `SELECT sum(quantity * order_item_tax_included_amount) FROM dim_product_order_item WHERE customer_id = 'customer123';`
320
+
321
+ ### Data Constraints and Business Rules:
322
+
323
+ - `product_order_item_id` should be unique.
324
+ - `order_date` should be a valid date.
325
+ - `quantity` should be a non-negative number.
326
+ - `order_item_tax_rate`, `order_item_duty_free_amount`, and `order_item_tax_included_amount` should be valid numeric values.
327
+
328
+ ### Data Update Frequency/Volatility:
329
+
330
+ - Data is likely updated frequently, reflecting new orders, order updates, and cancellations.
331
+
332
+ ### Potential Pitfalls/Things to Avoid When Querying:
333
+
334
+ - Ensure correct join conditions when joining with other tables.
335
+ - Be mindful of the `order_item_status` to filter for relevant order items.
336
+ - Consider time-based filtering using `order_date` for trend analysis.
337
+
338
+ ### Important Notes/Considerations for Querying:
339
+
340
+ - This table is central to understanding product order details.
341
+ - Join with `dim_customer` and `dim_agreement` for customer and agreement details.
342
+ - The table containing product order information (e.g. `dim_product_order`) will be crucial to join.