Build a contract analytics dashboard with Box Query Insights API
Use the Box Query Insights API to aggregate metadata across Box content and power dashboards with counts, sums, averages, and grouped breakdowns.
Sales, legal, and procurement teams often store contracts in Box with structured metadata, for example, contract type, value, effective dates, and status. Listing every file to compute totals in your application is slow, expensive, and hard to keep current as content grows.The Box Query Insights API solves this by returning aggregated metrics directly from Box. You filter items with the same predicate syntax as Box Query API, optionally group results, and request metrics such as count, sum, avg, min, and max in a single API call.This tutorial builds a contract analytics dashboard with total, average, minimum, and maximum contract value for sales contracts in a date range.
Clone the working sample
Prefer to start from running code? The complete app built in this tutorial is on GitHub. Clone it, add your Box credentials, and run.
The Box Query Insights API fits any workflow where you need summary numbers instead of individual file lists.
Use case
What you compute
Example metrics
Executive dashboard
Portfolio totals and breakdowns by category
sum of contract value grouped by contractType
Compliance reporting
How many documents match a template in a period
count with box:item:created_at filters
Procurement analytics
Typical and outlier deal sizes
avg, min, and max on a currency field
Department scorecards
Metrics scoped to a team folder
ancestors set to a department root folder
Data quality checks
Volume of tagged content before a migration
Empty metrics object for default totalResultCount
The Box Query Insights API applies filters first, then grouping, then metric calculation. It does not return individual items. When you need file-level results, use Box Query API or metadata queries and compute aggregates in your app, or call both APIs for drill-down views.
The agent expects a metadata template, a contracts folder, and tagged sample files to already exist in Box. If you don’t have them yet, complete the first three steps of Build by hand, through Create a metadata template and sample data, and then return here.Get these values from the sample data generated by the script setup_test_data.py or from the metadata template and folder you created:
Template key - from the template you created (for example, sales)
Folder ID - from the folder you created (for example, 1234567890)
Enterprise ID - from the Developer Console (for example, 1234567890)
Choose your stack and copy the prompt. It already lists these as prerequisites, so the agent reads them from environment variables instead of trying to create them. Replace the <TEMPLATE_KEY>, <FOLDER_ID>, and <ENTERPRISE_ID> placeholders if you want the agent to pre-fill .env; otherwise leave them and fill .env yourself after scaffolding.
Python + Script
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse Python as a command-line script. Target Python 3.11+, use pip and a virtual environment. Install exactly one Box package: boxsdk (do NOT also install box-sdk-gen — both ship the box_sdk_gen module and conflict). Import Box APIs with `from box_sdk_gen import ...`. Also install python-dotenv, and pytest for tests.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxCall the API exactly as the tutorial does: client.query.create_query_insight_v2026_r0(query, metrics), passing CreateQueryInsightV2026R0Query (predicate, params, ancestors with QueryAncestorReferenceV2026R0, group_by with QueryInsightsGroupByV2026R0) and a dict of metric aliases to QueryInsightsMetricDefinitionV2026R0 (its type field takes the QueryInsightsMetricDefinitionV2026R0TypeField enum). The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Compare entry.type against QueryInsightEntryV2026R0TypeField. Errors raise BoxAPIError, which carries the status as error.response_info.status_code and the Box code as error.response_info.code. In tests, turn recorded payloads into typed models with box_sdk_gen.deserialize(payload, QueryInsightsV2026R0) instead of hand-building objects; if you also need to raise a BoxAPIError, its RequestInfo and ResponseInfo live in box_sdk_gen.box.errors. Confirm the symbol names against the installed SDK's query manager and schema modules before writing code. Build the client with BoxCCGAuth and CCGConfig as the tutorial shows. Print a console report; do not add a web server.The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- box_client.py (CCG client), reports.py (count, value statistics, and grouped queries with response parsing), dashboard.py that prints the report, and pytest.ini with pythonpath = .- a flat script layout matching the tutorial (no unnecessary packages)- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Add pytest.ini with pythonpath = . so pytest can import reports and box_client from the project root. Without it, pytest fails with ModuleNotFoundError: No module named 'reports'- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
Python + Flask
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse Python with Flask. Target Python 3.11+, use pip and a virtual environment. Install exactly one Box package: boxsdk (do NOT also install box-sdk-gen — both ship the box_sdk_gen module and conflict). Import Box APIs with `from box_sdk_gen import ...`. Also install flask, python-dotenv, and pytest for tests.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxCall the API exactly as the tutorial does: client.query.create_query_insight_v2026_r0(query, metrics), passing CreateQueryInsightV2026R0Query (predicate, params, ancestors with QueryAncestorReferenceV2026R0, group_by with QueryInsightsGroupByV2026R0) and a dict of metric aliases to QueryInsightsMetricDefinitionV2026R0 (its type field takes the QueryInsightsMetricDefinitionV2026R0TypeField enum). The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Compare entry.type against QueryInsightEntryV2026R0TypeField. Errors raise BoxAPIError, which carries the status as error.response_info.status_code and the Box code as error.response_info.code. In tests, turn recorded payloads into typed models with box_sdk_gen.deserialize(payload, QueryInsightsV2026R0) instead of hand-building objects; if you also need to raise a BoxAPIError, its RequestInfo and ResponseInfo live in box_sdk_gen.box.errors. Confirm the symbol names against the installed SDK's query manager and schema modules before writing code. Build the client with BoxCCGAuth and CCGConfig as the tutorial shows. Add only a thin Flask layer that returns the aggregates as JSON, and listen on port 5000 so the endpoints can be tested with curl.The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- box_client.py, reports.py (the Box query logic), app.py exposing GET /dashboard plus GET /healthz, and pytest.ini with pythonpath = .- a flat Flask layout; keep the Box modules separate from the HTTP layer- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Add pytest.ini with pythonpath = . so pytest can import reports and box_client from the project root. Without it, pytest fails with ModuleNotFoundError: No module named 'reports'- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
Python + FastAPI
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse Python with FastAPI. Target Python 3.11+, use pip and a virtual environment. Install exactly one Box package: boxsdk (do NOT also install box-sdk-gen — both ship the box_sdk_gen module and conflict). Import Box APIs with `from box_sdk_gen import ...`. Also install fastapi, uvicorn, python-dotenv, and pytest for tests.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxCall the API exactly as the tutorial does: client.query.create_query_insight_v2026_r0(query, metrics), passing CreateQueryInsightV2026R0Query (predicate, params, ancestors with QueryAncestorReferenceV2026R0, group_by with QueryInsightsGroupByV2026R0) and a dict of metric aliases to QueryInsightsMetricDefinitionV2026R0 (its type field takes the QueryInsightsMetricDefinitionV2026R0TypeField enum). The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Compare entry.type against QueryInsightEntryV2026R0TypeField. Errors raise BoxAPIError, which carries the status as error.response_info.status_code and the Box code as error.response_info.code. In tests, turn recorded payloads into typed models with box_sdk_gen.deserialize(payload, QueryInsightsV2026R0) instead of hand-building objects; if you also need to raise a BoxAPIError, its RequestInfo and ResponseInfo live in box_sdk_gen.box.errors. Confirm the symbol names against the installed SDK's query manager and schema modules before writing code. Build the client with BoxCCGAuth and CCGConfig as the tutorial shows. Adapt the HTTP layer to FastAPI and uvicorn. The Box Python SDK is synchronous — use plain def route handlers (or run the sync Box calls in a threadpool); do not await sync SDK methods. Listen on port 5000 so the endpoints can be tested with curl.The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- box_client.py, reports.py (the Box query logic), a FastAPI app module exposing GET /dashboard plus GET /healthz with Pydantic response models, and pytest.ini with pythonpath = .- an idiomatic FastAPI layout; keep the Box modules separate from the HTTP layer- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Add pytest.ini with pythonpath = . so pytest can import reports and box_client from the project root. Without it, pytest fails with ModuleNotFoundError: No module named 'reports'- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
TypeScript + Express
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse TypeScript with Express on Node.js 20+. Use npm and exactly one Box package: box-node-sdk@10 (do NOT also install box-typescript-sdk-gen). Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import Query Insights types and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — they are not on the package root. Also install express, dotenv, tsx (or tsc), and a test runner such as node:test or vitest.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxThe tutorial's samples are Python; use the TypeScript equivalent of the same call. Call await client.query.createQueryInsightV2026R0({ query, metrics }), where query holds predicate, params, ancestors, and groupBy — note the camelCase groupBy and bucketLimit, unlike the snake_case JSON body. Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import QueryInsightsV2026R0, QueryInsightsMetricDefinitionV2026R0, QueryInsightsGroupByV2026R0, QueryAncestorReferenceV2026R0, and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — the package root does not re-export those symbols. Build CcgConfig with camelCase clientId, clientSecret, and enterpriseId. The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Errors are BoxApiError; read error.responseInfo.statusCode and error.responseInfo.code. In tests, turn recorded payloads into typed models with deserializeQueryInsightsV2026R0(payload) instead of hand-building objects. Confirm the schema and manager names against the installed SDK's typings before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID. Use tsconfig module ES2022, moduleResolution bundler, esModuleInterop, and strict. Do not set moduleResolution to node — TypeScript 7 removed it (TS5108). Run with npx tsx app.ts. Listen on port 5000 so the endpoints can be tested with curl.The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- boxClient.ts, reports.ts (count, value statistics, and grouped queries with response parsing), app.ts exposing GET /dashboard plus GET /healthz, and tsconfig.json- a flat Express + TypeScript layout; keep the Box modules separate from the HTTP layer- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Add a test script such as tsx --test tests/*.test.ts so local modules resolve from the project root without extra NODE_PATH flags. If you keep CommonJS output, resolve fixture paths with __dirname, not import.meta.url. Run the tests before you finish- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
TypeScript + Fastify
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse TypeScript with Fastify on Node.js 20+. Use npm and exactly one Box package: box-node-sdk@10 (do NOT also install box-typescript-sdk-gen). Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import Query Insights types and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — they are not on the package root. Also install fastify, dotenv, tsx (or tsc), and a test runner such as node:test or vitest.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxThe tutorial's samples are Python; use the TypeScript equivalent of the same call. Call await client.query.createQueryInsightV2026R0({ query, metrics }), where query holds predicate, params, ancestors, and groupBy — note the camelCase groupBy and bucketLimit, unlike the snake_case JSON body. Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import QueryInsightsV2026R0, QueryInsightsMetricDefinitionV2026R0, QueryInsightsGroupByV2026R0, QueryAncestorReferenceV2026R0, and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — the package root does not re-export those symbols. Build CcgConfig with camelCase clientId, clientSecret, and enterpriseId. The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Errors are BoxApiError; read error.responseInfo.statusCode and error.responseInfo.code. In tests, turn recorded payloads into typed models with deserializeQueryInsightsV2026R0(payload) instead of hand-building objects. Confirm the schema and manager names against the installed SDK's typings before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID. Use tsconfig module ES2022, moduleResolution bundler, esModuleInterop, and strict. Do not set moduleResolution to node — TypeScript 7 removed it (TS5108). Keep the Box modules framework-agnostic and adapt only the HTTP layer to Fastify. Listen on port 5000 so the endpoints can be tested with curl.The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- boxClient.ts, reports.ts (the Box query logic), a Fastify app module exposing GET /dashboard plus GET /healthz, and tsconfig.json- an idiomatic Fastify + TypeScript layout; keep the Box modules separate from the HTTP layer- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Add a test script such as tsx --test tests/*.test.ts so local modules resolve from the project root without extra NODE_PATH flags. If you keep CommonJS output, resolve fixture paths with __dirname, not import.meta.url. Run the tests before you finish- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
Node + Express
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse Node.js 20+ with JavaScript (not TypeScript) and Express. Use npm and exactly one Box package: box-node-sdk@10 (do NOT also install box-typescript-sdk-gen). Load BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError with require("box-node-sdk"). Also install express, dotenv, and a test runner such as node:test.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxThe tutorial's samples are Python; use the Node.js equivalent of the same call. Call await client.query.createQueryInsightV2026R0({ query, metrics }), where query holds predicate, params, ancestors, and groupBy — note the camelCase groupBy and bucketLimit, unlike the snake_case JSON body. npm init defaults to CommonJS: write const { BoxClient, BoxCcgAuth, CcgConfig, BoxApiError } = require("box-node-sdk") and const { deserializeQueryInsightsV2026R0 } = require("box-node-sdk/schemas"). Do not write import statements unless you also set "type": "module" in package.json — otherwise Node throws SyntaxError: Cannot use import statement outside a module. The package root does not re-export Query Insights helpers. Build CcgConfig with camelCase clientId, clientSecret, and enterpriseId. Read entry.type, entry.key, and entry.metrics[alias].values off the returned model rather than parsing raw JSON. Errors are BoxApiError; read error.responseInfo.statusCode and error.responseInfo.code. In tests, turn recorded payloads into models with deserializeQueryInsightsV2026R0(payload). Confirm the symbol names against the installed SDK before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID. Write plain JavaScript with JSDoc comments instead of type annotations, and listen on port 5000 so the endpoints can be tested with curl.The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- boxClient.js, reports.js (count, value statistics, and grouped queries with response parsing), and app.js exposing GET /dashboard plus GET /healthz- a flat Express + JavaScript layout; keep the Box modules separate from the HTTP layer- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Add a test script such as node --test tests/*.test.js so require("../reports") resolves from the tests folder. Use __dirname for fixture paths. Run the tests before you finish- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
Node + NestJS
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse Node.js 20+ with NestJS. NestJS projects use TypeScript by default. Use npm and exactly one Box package: box-node-sdk@10 (do NOT also install box-typescript-sdk-gen). Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import Query Insights types and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — they are not on the package root. Also install @nestjs/core, @nestjs/common, @nestjs/platform-express, dotenv, and a test runner such as Jest.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxThe tutorial's samples are Python; use the TypeScript equivalent of the same call. Call await client.query.createQueryInsightV2026R0({ query, metrics }), where query holds predicate, params, ancestors, and groupBy — note the camelCase groupBy and bucketLimit, unlike the snake_case JSON body. Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import QueryInsightsV2026R0, QueryInsightsMetricDefinitionV2026R0, QueryInsightsGroupByV2026R0, QueryAncestorReferenceV2026R0, and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — the package root does not re-export those symbols. Build CcgConfig with camelCase clientId, clientSecret, and enterpriseId. The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Errors are BoxApiError; read error.responseInfo.statusCode and error.responseInfo.code. In tests, turn recorded payloads into typed models with deserializeQueryInsightsV2026R0(payload) instead of hand-building objects. Confirm the schema and manager names against the installed SDK's typings before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID, and expose it as an injectable provider. Use tsconfig module ES2022, moduleResolution bundler, esModuleInterop, and strict. Do not set moduleResolution to node — TypeScript 7 removed it (TS5108). Listen on port 5000 so the endpoints can be tested with curl.The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- a Box client provider, a reports provider (the Box query logic), and a dashboard controller exposing GET /dashboard plus GET /healthz- an idiomatic NestJS layout (module, controller, providers); keep the Box client and report logic in dedicated providers separate from the HTTP controller- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Configure Jest so Nest providers import without extra path flags. Use moduleResolution bundler so box-node-sdk/schemas resolves. Keep parsing tests as plain unit tests (do not start a Nest testing module that constructs BoxClient) so they pass without BOX_* environment variables. Run the tests before you finish- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
Java + Spring Boot
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse Java 17+ with Spring Boot 3. Use Maven or Gradle and exactly one Box artifact: com.box:box-java-sdk version 10 or later (do NOT also add box-java-sdk-gen). Use BoxClient, BoxCCGAuth, CCGConfig, BoxAPIError, and the generated query types from that SDK (packages under com.box.sdkgen.schemas.v2026r0, lowercase r0). Also use spring-boot-starter-web, a test starter such as spring-boot-starter-test, and me.paulschwarz:spring-dotenv so a tutorial .env file is loaded — Spring Boot does not read .env by itself.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxThe tutorial's samples are Python; use the Java equivalent of the same call. Call client.getQuery().createQueryInsightV2026R0(new QueryInsightsRequestBodyV2026R0(query, metrics)). That request body has no builder — pass the query and metrics map to the constructor. Build the query with new QueryInsightsRequestBodyV2026R0QueryField.Builder(predicate).params(...).ancestors(...).groupBy(...).build(). Ancestors are new QueryAncestorReferenceV2026R0(folderId, "folder"). Group-by is new QueryInsightsGroupByV2026R0.Builder(field).bucketLimit(n).build(). Each metric is new QueryInsightsMetricDefinitionV2026R0(QueryInsightsMetricDefinitionV2026R0TypeField.AVG, field) — that class also has no builder. Import these types from their generated packages under com.box.sdkgen.schemas.v2026r0 (lowercase r0), for example com.box.sdkgen.schemas.v2026r0.queryinsightsrequestbodyv2026r0. Entry types are EnumWrapper values: compare entry.getType().getEnumValue() to QueryInsightEntryV2026R0TypeField.OVERALL, GROUP, or OTHER, and read metrics with getMetrics().get(alias).getValues().get(metricType). Build auth with new BoxCCGAuth(new CCGConfig.Builder(clientId, clientSecret).enterpriseId(enterpriseId).build()) and new BoxClient(auth). Errors are BoxAPIError; read getResponseInfo().getStatusCode() and getResponseInfo().getCode(). In tests, deserialize with JsonManager.deserialize(JsonManager.jsonToSerializedData(json), QueryInsightsV2026R0.class) — deserialize takes a JsonNode, not a raw String. Confirm the builder and getter names against the installed SDK before writing code. Build the client with BoxCCGAuth and CCGConfig using the enterprise ID. Catch BoxAPIError and check getResponseInfo().getStatusCode() to distinguish the documented status codes. Adapt the HTTP layer to Spring Web (@RestController) and keep the server on port 5000 (server.port=5000).The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- a Box client configuration/bean, a ReportService with the count, value statistics, and grouped queries, and a dashboard controller exposing GET /dashboard plus GET /healthz- an idiomatic Spring Boot layout; keep Box client configuration and the report logic in dedicated classes separate from the HTTP controller- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Use the default Maven or Gradle test classpath so ReportService tests compile and run. Keep parsing tests as plain unit tests (do not start a Spring context) so they pass without BOX_* environment variables. Run the tests before you finish- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
Java + Quarkus
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse Java 17+ with Quarkus. Use Maven or Gradle and exactly one Box artifact: com.box:box-java-sdk version 10 or later (do NOT also add box-java-sdk-gen). Use BoxClient, BoxCCGAuth, CCGConfig, BoxAPIError, and the generated query types from that SDK (packages under com.box.sdkgen.schemas.v2026r0, lowercase r0). Also use quarkus-rest-jackson (or quarkus-resteasy-jackson) and quarkus-junit5 for tests. Quarkus loads a project .env file natively — keep the tutorial variable names.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxThe tutorial's samples are Python; use the Java equivalent of the same call. Call client.getQuery().createQueryInsightV2026R0(new QueryInsightsRequestBodyV2026R0(query, metrics)). That request body has no builder — pass the query and metrics map to the constructor. Build the query with new QueryInsightsRequestBodyV2026R0QueryField.Builder(predicate).params(...).ancestors(...).groupBy(...).build(). Ancestors are new QueryAncestorReferenceV2026R0(folderId, "folder"). Group-by is new QueryInsightsGroupByV2026R0.Builder(field).bucketLimit(n).build(). Each metric is new QueryInsightsMetricDefinitionV2026R0(QueryInsightsMetricDefinitionV2026R0TypeField.AVG, field) — that class also has no builder. Import these types from their generated packages under com.box.sdkgen.schemas.v2026r0 (lowercase r0), for example com.box.sdkgen.schemas.v2026r0.queryinsightsrequestbodyv2026r0. Entry types are EnumWrapper values: compare entry.getType().getEnumValue() to QueryInsightEntryV2026R0TypeField.OVERALL, GROUP, or OTHER, and read metrics with getMetrics().get(alias).getValues().get(metricType). Build auth with new BoxCCGAuth(new CCGConfig.Builder(clientId, clientSecret).enterpriseId(enterpriseId).build()) and new BoxClient(auth). Errors are BoxAPIError; read getResponseInfo().getStatusCode() and getResponseInfo().getCode(). In tests, deserialize with JsonManager.deserialize(JsonManager.jsonToSerializedData(json), QueryInsightsV2026R0.class) — deserialize takes a JsonNode, not a raw String. Confirm the builder and getter names against the installed SDK before writing code. Build the client with BoxCCGAuth and CCGConfig using the enterprise ID. Catch BoxAPIError and check getResponseInfo().getStatusCode() to distinguish the documented status codes. Adapt the HTTP layer to Quarkus REST and keep the server on port 5000 (quarkus.http.port=5000).The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- a Box client producer/bean, a ReportService with the count, value statistics, and grouped queries, and a JAX-RS resource exposing GET /dashboard plus GET /healthz- an idiomatic Quarkus layout; keep the Box client and report logic in dedicated beans separate from the JAX-RS resource- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Use the default Maven or Gradle test classpath so ReportService tests compile and run. Keep parsing tests as plain unit tests (do not start a Quarkus test profile that constructs BoxClient) so they pass without BOX_* environment variables. Run the tests before you finish- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
.NET + ASP.NET Core
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse .NET 8+ with ASP.NET Core controllers. Use NuGet and exactly one Box package: Box.V2.Core version 10 or later (do NOT also install Box.Sdk.Gen — v10 of Box.V2.Core already ships the generated client). Use BoxClient, BoxCcgAuth, CcgConfig, and BoxApiException from Box.Sdk.Gen. Also add xUnit and DotNetEnv — ASP.NET Core does not load a tutorial .env file by itself.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxThe tutorial's samples are Python; use the .NET equivalent of the same call. Call await client.Query.CreateQueryInsightV2026R0Async(new QueryInsightsRequestBodyV2026R0(query, metrics)). Build the query with new QueryInsightsRequestBodyV2026R0QueryField(predicate) { Parameters = ..., Ancestors = ..., GroupBy = ... }. The predicate params map is Parameters because params is a C# keyword. Group-by is new QueryInsightsGroupByV2026R0(field) { BucketLimit = n }. Each metric is new QueryInsightsMetricDefinitionV2026R0(QueryInsightsMetricDefinitionV2026R0TypeField.Avg, field). Ancestors are new QueryAncestorReferenceV2026R0(folderId, "folder"). Types live in Box.Sdk.Gen and Box.Sdk.Gen.Schemas and ship inside Box.V2.Core — do not add a second Box.Sdk.Gen package. Entry types are StringEnum values: compare entry.Type.Value to QueryInsightEntryV2026R0TypeField.Overall, Group, or Other, and read metrics with entry.Metrics[alias].Values[metricType]. Build auth with new BoxCcgAuth(new CcgConfig(clientId, clientSecret) { EnterpriseId = enterpriseId }) and new BoxClient(auth). The CcgConfig third constructor argument is tokenStorage, not the enterprise ID. Errors are BoxApiException; read ResponseInfo.StatusCode and ResponseInfo.Code. In tests, deserialize with System.Text.Json.JsonSerializer.Deserialize<QueryInsightsV2026R0>(json) — SimpleJsonSerializer is internal. Qualify System.IO.File because Box.Sdk.Gen.Schemas.File conflicts with it. Confirm the property names against the installed SDK before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID. All SDK calls are async — await them and keep controller actions async. Call DotNetEnv.Env.Load() at startup, bind with builder.WebHost.UseUrls("http://127.0.0.1:5000"), skip UseHttpsRedirection, and run with --no-launch-profile (or edit launchSettings.json). The webapi template otherwise listens on 5020/7060 and enables HTTPS, so curl to port 5000 fails.The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- a Box client factory/service, a ReportService with the count, value statistics, and grouped queries, and a dashboard controller exposing GET /dashboard plus GET /healthz- an idiomatic ASP.NET Core layout; keep the Box client and report logic in dedicated services separate from the HTTP controller- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Reference the app project from the test project so ReportService tests build. Keep parsing tests as plain xUnit tests (do not start a WebApplicationFactory that constructs BoxClient) so they pass without BOX_* environment variables. Copy fixture files to the test output directory. Run the tests before you finish- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
.NET + Minimal APIs
Build a production-minded contract analytics dashboard by following this Box tutorial:https://developer.box.com/tutorials/query-insightsUse .NET 8+ with ASP.NET Core Minimal APIs. Use NuGet and exactly one Box package: Box.V2.Core version 10 or later (do NOT also install Box.Sdk.Gen — v10 of Box.V2.Core already ships the generated client). Use BoxClient, BoxCcgAuth, CcgConfig, and BoxApiException from Box.Sdk.Gen. Also add xUnit and DotNetEnv — ASP.NET Core does not load a tutorial .env file by itself.Prerequisites already done in Box (see 'Before you start' in the tutorial).Do NOT try to create these; read their values from environment variables:- Enterprise metadata template key: <TEMPLATE_KEY> (fields contractType as enum with Sales and Renewal, contractValue as float). If a template with that key already exists and contractType is a string, group_by returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.- Contracts folder ID: <FOLDER_ID>. CCG stores this folder in the app service account root, not the developer's personal All Files. The service account must be able to read it (Viewer or higher). Do not fail the project if the developer cannot see the folder in their own Box web app.- Enterprise ID: <ENTERPRISE_ID>- CCG app scopes enabled: Read and write all files and folders stored in BoxThe tutorial's samples are Python; use the .NET equivalent of the same call. Call await client.Query.CreateQueryInsightV2026R0Async(new QueryInsightsRequestBodyV2026R0(query, metrics)). Build the query with new QueryInsightsRequestBodyV2026R0QueryField(predicate) { Parameters = ..., Ancestors = ..., GroupBy = ... }. The predicate params map is Parameters because params is a C# keyword. Group-by is new QueryInsightsGroupByV2026R0(field) { BucketLimit = n }. Each metric is new QueryInsightsMetricDefinitionV2026R0(QueryInsightsMetricDefinitionV2026R0TypeField.Avg, field). Ancestors are new QueryAncestorReferenceV2026R0(folderId, "folder"). Types live in Box.Sdk.Gen and Box.Sdk.Gen.Schemas and ship inside Box.V2.Core — do not add a second Box.Sdk.Gen package. Entry types are StringEnum values: compare entry.Type.Value to QueryInsightEntryV2026R0TypeField.Overall, Group, or Other, and read metrics with entry.Metrics[alias].Values[metricType]. Build auth with new BoxCcgAuth(new CcgConfig(clientId, clientSecret) { EnterpriseId = enterpriseId }) and new BoxClient(auth). The CcgConfig third constructor argument is tokenStorage, not the enterprise ID. Errors are BoxApiException; read ResponseInfo.StatusCode and ResponseInfo.Code. In tests, deserialize with System.Text.Json.JsonSerializer.Deserialize<QueryInsightsV2026R0>(json) — SimpleJsonSerializer is internal. Qualify System.IO.File because Box.Sdk.Gen.Schemas.File conflicts with it. Confirm the property names against the installed SDK before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID. All SDK calls are async — await them inside the endpoint delegates. Call DotNetEnv.Env.Load() at startup, bind with builder.WebHost.UseUrls("http://127.0.0.1:5000"), skip UseHttpsRedirection, and run with --no-launch-profile (or edit launchSettings.json). The webapi template otherwise listens on 5020/7060 and enables HTTPS, so curl to port 5000 fails.The app must:1. Authenticate to Box with Client Credentials Grant (enterprise / service account). Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.2. Call the Box Query Insights API through the SDK's query manager method named above. That method targets the v2026.0 API and sends the required box-version: 2026.0 header for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do not manage access tokens — the SDK's CCG auth handles refresh and retries.3. Build fully qualified field references from the template key and enterprise ID: template ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY> and a field ref is enterprise_<ENTERPRISE_ID>:<TEMPLATE_KEY>:<fieldKey>. Read TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set; otherwise derive them from the field keys contractType and contractValue.4. Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the template ref, ancestors set to the folder ID with type folder, and an empty metrics map. An empty metrics map returns the default totalResultCount metric.5. Expose a value statistics query: avg, min, and max metrics on the contract value field, filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND box:item:created_at < :endDate. Accept the date range as input; use RFC 3339 timestamps.6. Expose a grouped query for charts: group by the contract type enum field with a bucket limit, plus a sum metric on contract value and a count metric on contract type. Do not group on a free-text string field — Query Insights returns 400 Invalid query request. Present the buckets in the order the API returns them; do not re-sort them client-side, because re-sorting would misrepresent which buckets the other rollup excluded.7. Parse the response by entry type, not by array position. Each entry has a type of overall, group, or other: - overall: read metric values directly; the key is always empty - group: use the first key value as the bucket label - other: read the count from the totalCountBeyondTopGroups alias, not your own alias Each metric value is nested under values and keyed by the metric type, so an avg metric exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by document count descending; that order cannot be customized.8. Check the documented API limits before sending a request and fail fast with a clear message, so a bad request never reaches Box: - only one group-by field per request - bucket limit defaults to 5, maximum 10 - maximum 10 metrics per request - each metric alias must start with a letter and contain only letters, digits, underscores, hyphens, and periods (maximum 256 characters) Document, but do not try to validate, the guidance that grouped fields should stay below 10,000 distinct values — cardinality is a server-side property you cannot check locally.9. Catch the SDK's Box API error type, read the HTTP status off it, and report 400 BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429 RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes expired tokens, and a second layer would multiply the wait.10. Fetch each aggregate once per report run and reuse the result rather than calling the API again for every panel. Add a short-TTL cache only if your stack serves repeated requests (a web layer or a refresh loop); a script that exits after printing does not need one. Note in the README that Box Query Insights API reads a metadata index that updates shortly after content is tagged, so a metric can return 0 immediately after tagging.Read configuration from the same environment variables the tutorial uses, so a .env filewritten for one path works for the other:BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, andoptionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.Create a complete runnable project with:- a Box client factory, a ReportService with the count, value statistics, and grouped queries, and Program.cs with MapGet("/dashboard", ...) plus MapGet("/healthz", ...)- an idiomatic Minimal APIs layout (MapGet in Program.cs); keep the Box client and report logic in dedicated classes separate from endpoint mapping- dependency and run commands- .env.example and .gitignore files- a sample console or JSON report that shows the total contract count, the average, minimum, and maximum contract value, and the top contract types with the total value and count of each. The other rollup carries only a count, so leave its value column empty rather than reporting a total for it.- focused unit tests that assert response parsing for the overall, group, and other entry types against recorded sample payloads (do not call Box in tests)- Reference the app project from the test project so ReportService tests build. Keep parsing tests as plain xUnit tests (do not start a WebApplicationFactory that constructs BoxClient) so they pass without BOX_* environment variables. Copy fixture files to the test output directory. Run the tests before you finish- a README with setup, run, and test steps. State that CCG content lives in the service account root, that Query Insights can return 0 until the metadata index updates, and that group_by requires an enum contractTypeAfter you write the files, run the test command and fix any import or parse failuresbefore you stop. Do not call Box from tests. Do not require a filled .env for teststo pass.Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.
Review generated code before using it in production. Never paste Box credentials into your
coding agent.
When the agent finishes, copy .env.example to .env and fill in your client ID, client secret, enterprise ID, metadata template key, and folder ID. Use a template whose contractType is an enum. Grouping on a free-text string field returns 400 Invalid query request. A CCG app stores the contracts folder in the service account root, so the folder does not display in your personal All Files. Then skip ahead to Run and verify.Prefer to write the code yourself? See Build by hand below.
Create a project directory and virtual environment:
mkdir contract-insights && cd contract-insightspython3 -m venv .venvsource .venv/bin/activate
Install the required packages:
pip install boxsdk python-dotenv
Create a .env file with your application credentials. Fill in the first three Client Credentials Grant values now – you add the folder and template values in the next step:
BoxCCGAuth fetches and refreshes the access token for you, so you never manage the token endpoint directly.
BOX_ENTERPRISE_ID must be the numeric enterprise ID from Developer Console > Configuration > App Details. Pasting a client ID or client secret here fails with invalid_grant: Grant credentials are invalid.
The remaining steps call client.query.create_query_insight_v2026_r0, which sends POST https://api.box.com/2.0/query_insights with the box-version: 2026.0 header. Because the method is generated from the API spec, you pass typed request objects and read a typed QueryInsightsV2026R0 result instead of assembling JSON by hand.
3
Create a metadata template and sample data
Create setup_test_data.py to create the sales metadata template, a folder, and a few tagged sample contracts. It reuses get_box_client from the previous step:
import ioimport osfrom box_sdk_gen import ( BoxAPIError, BoxClient, CreateFileMetadataByIdScope, CreateFolderParent, CreateMetadataTemplateFields, CreateMetadataTemplateFieldsOptionsField, CreateMetadataTemplateFieldsTypeField, GetMetadataTemplateScope, UpdateFileMetadataByIdRequestBody, UpdateFileMetadataByIdRequestBodyOpField, UpdateFileMetadataByIdScope, UpdateMetadataTemplateRequestBody, UpdateMetadataTemplateRequestBodyOpField, UpdateMetadataTemplateScope, UploadFileAttributes, UploadFileAttributesParentField,)from dotenv import load_dotenvfrom box_client import get_box_clientload_dotenv()TEMPLATE_KEY = os.environ.get("TEMPLATE_KEY") or "sales"ENUM_FIELD_KEY = "contractType"ENUM_FALLBACK_KEY = "contractTypeEnum"FOLDER_NAME = "Sales Contracts"SAMPLE_CONTRACTS = [ {"name": "Contract 1", "contractType": "Sales", "contractValue": 100000}, {"name": "Contract 2", "contractType": "Sales", "contractValue": 200000}, {"name": "Contract 3", "contractType": "Renewal", "contractValue": 150000}, {"name": "Contract 4", "contractType": "Renewal", "contractValue": 45000},]def _enum_field_key(template) -> str | None: fields = {field.key: field for field in (template.fields or [])} for key in (ENUM_FIELD_KEY, ENUM_FALLBACK_KEY): field = fields.get(key) if field and str(getattr(field.type, "value", field.type)) == "enum": return key return Nonedef _add_enum_field(client: BoxClient) -> None: client.metadata_templates.update_metadata_template( UpdateMetadataTemplateScope.ENTERPRISE, TEMPLATE_KEY, [ UpdateMetadataTemplateRequestBody( op=UpdateMetadataTemplateRequestBodyOpField.ADDFIELD, data={ "type": "enum", "key": ENUM_FALLBACK_KEY, "displayName": "Contract type", "options": [{"key": "Sales"}, {"key": "Renewal"}], }, ) ], )def ensure_template(client: BoxClient) -> str: """Create the template if needed, then return the field to group on.""" try: client.metadata_templates.create_metadata_template( scope="enterprise", display_name="Sales Contracts", template_key=TEMPLATE_KEY, fields=[ CreateMetadataTemplateFields( type=CreateMetadataTemplateFieldsTypeField.ENUM, key=ENUM_FIELD_KEY, display_name="Contract type", options=[ CreateMetadataTemplateFieldsOptionsField(key="Sales"), CreateMetadataTemplateFieldsOptionsField(key="Renewal"), ], ), CreateMetadataTemplateFields( type=CreateMetadataTemplateFieldsTypeField.FLOAT, key="contractValue", display_name="Contract value", ), ], ) return ENUM_FIELD_KEY except BoxAPIError: pass # The template already exists. Box Query Insights API groups on enum # fields only, so reuse an existing enum or add one now. Otherwise the # grouped query fails later with 400 Invalid query request. template = client.metadata_templates.get_metadata_template( GetMetadataTemplateScope.ENTERPRISE, TEMPLATE_KEY ) type_field = _enum_field_key(template) if type_field is None: _add_enum_field(client) type_field = ENUM_FALLBACK_KEY print( f"'{TEMPLATE_KEY}.{ENUM_FIELD_KEY}' is not an enum. " f"Added enum field '{ENUM_FALLBACK_KEY}' to group on." ) elif type_field != ENUM_FIELD_KEY: print( f"'{TEMPLATE_KEY}.{ENUM_FIELD_KEY}' is not an enum. " f"Grouping on existing enum field '{type_field}'." ) return type_fielddef ensure_folder(client: BoxClient) -> str: for item in client.folders.get_folder_items("0").entries: if item.type == "folder" and item.name == FOLDER_NAME: return item.id folder = client.folders.create_folder( name=FOLDER_NAME, parent=CreateFolderParent(id="0") ) return folder.iddef existing_files(client: BoxClient, folder_id: str) -> dict[str, str]: files: dict[str, str] = {} offset = 0 limit = 1000 while True: items = client.folders.get_folder_items( folder_id, limit=limit, offset=offset ) entries = items.entries or [] for item in entries: if item.type == "file": files[item.name] = item.id if len(entries) < limit: break offset += limit return filesdef apply_metadata(client: BoxClient, file_id: str, payload: dict) -> None: try: client.file_metadata.create_file_metadata_by_id( file_id, CreateFileMetadataByIdScope.ENTERPRISE, TEMPLATE_KEY, payload, ) except BoxAPIError as error: if error.response_info.status_code != 409: raise client.file_metadata.update_file_metadata_by_id( file_id, UpdateFileMetadataByIdScope.ENTERPRISE, TEMPLATE_KEY, [ UpdateFileMetadataByIdRequestBody( op=UpdateFileMetadataByIdRequestBodyOpField.ADD, path=f"/{key}", value=value, ) for key, value in payload.items() ], )def _metadata_payload(contract: dict, type_field: str) -> dict: payload = { type_field: contract["contractType"], "contractValue": contract["contractValue"], } if type_field != ENUM_FIELD_KEY: # Keep the original string field populated so both stay in sync. payload[ENUM_FIELD_KEY] = contract["contractType"] return payloaddef upload_contracts(client: BoxClient, folder_id: str, type_field: str) -> None: existing = existing_files(client, folder_id) for contract in SAMPLE_CONTRACTS: filename = f"{contract['name']}.txt" payload = _metadata_payload(contract, type_field) file_id = existing.get(filename) if file_id is None: uploaded = client.uploads.upload_file( attributes=UploadFileAttributes( name=filename, parent=UploadFileAttributesParentField(id=folder_id), ), file=io.BytesIO(b"Sample contract for Box Query Insights API."), ) file_id = uploaded.entries[0].id apply_metadata(client, file_id, payload)if __name__ == "__main__": client = get_box_client() enterprise_id = os.environ["BOX_ENTERPRISE_ID"] type_field = ensure_template(client) folder_id = ensure_folder(client) upload_contracts(client, folder_id, type_field) template_ref = f"enterprise_{enterprise_id}:{TEMPLATE_KEY}" print("Add these values to your .env file:") print(f"FOLDER_ID={folder_id}") print(f"TEMPLATE_KEY={TEMPLATE_KEY}") print(f"TEMPLATE_REF={template_ref}") print(f"FIELD_CONTRACT_TYPE={template_ref}:{type_field}") print(f"FIELD_CONTRACT_VALUE={template_ref}:contractValue")
Run the script, then copy the printed values into your .env file:
python setup_test_data.py
Alternatively, you can point the tutorial at an existing template.The Box Query Insights API can group on enum fields, not free-text string fields:
contractType (enum, for example, Sales and Renewal)
contractValue (float)
The script is safe to run more than once. It reuses the template and folder, skips uploading a sample file whose name already exists, and falls back to a JSON-Patch update when a file already carries the template. Box Query Insights API reads a metadata index that updates shortly after you tag content. If a metric returns 0 right after setup, wait a minute and run the reporting steps again.
If a sales template already exists whose contractType is a free-text string, the script adds an enum field named contractTypeEnum and prints it as your FIELD_CONTRACT_TYPE. Copy whichever field key the script prints. Grouping on a string field returns 400 Invalid query request.
A Client Credentials Grant app acts as a service account with its own folder tree, so Sales Contracts does not display in your personal All Files. To see it, collaborate yourself on the folder using the service account email from Developer Console > App Details, or open the content as an admin in Content Manager.
4
Count matching contracts
Create reports.py with the queries that power your dashboard. Pass an empty metrics map to get the default totalResultCount metric across all items that match your filter.Every metric result nests its value under values, keyed by the metric type, so metric.values[metric.type] reads the value without hard-coding the type. The remaining steps use the same pattern.
The box-version: 2026.0 header is required. The SDK method sets it for you, so you only pass it when you call the endpoint directly.
5
Compute overall contract value statistics
Add this function to reports.py, below count_contracts. It requests multiple metrics in one call to populate summary cards – average, minimum, and maximum deal size for contracts created in a date range.
Because each metric result is keyed by its own type, the same metric.values[metric.type] lookup reads avg, min, and max without a branch per metric. The underlying response looks like this:
Add this last function to reports.py. Grouping by a metadata field powers bar or pie charts. The API returns the top buckets ordered by document count (descending). Remaining groups are rolled into an other entry.
Only one group_by field is supported per request, and bucket_limit defaults to 5 with a maximum of 10. Group on an enum field such as contractType. A free-text string field returns 400 Invalid query request. Avoid grouping on high-cardinality fields – cardinality of 10,000 or above can cause errors.
7
Combine metrics in a dashboard function
Create dashboard.py to wire the helpers together and print a console report you can adapt for a web dashboard or business intelligence export.
import osfrom box_client import get_box_clientfrom reports import contract_value_stats, count_contracts, top_contract_typesdef _format_cell(value) -> str: if value is None: return "—" if isinstance(value, float) and value.is_integer(): value = int(value) if isinstance(value, int): return f"{value:,}" if isinstance(value, float): return f"{value:,.2f}" return str(value)def _print_table(headers: list[str], rows: list[list]) -> None: str_rows = [[_format_cell(cell) for cell in row] for row in rows] widths = [len(header) for header in headers] for row in str_rows: for index, cell in enumerate(row): widths[index] = max(widths[index], len(cell)) def format_row(cells: list[str]) -> str: parts = [] for index, cell in enumerate(cells): # Labels stay left-aligned; numeric columns stay right-aligned. aligned = ( cell.ljust(widths[index]) if index == 0 else cell.rjust(widths[index]) ) parts.append(aligned) return " ".join(parts) print(format_row(headers)) print(" ".join("-" * width for width in widths)) for row in str_rows: print(format_row(row))def print_contract_dashboard( template_ref: str, type_field: str, value_field: str,) -> None: client = get_box_client() folder_id = os.environ["FOLDER_ID"] total = count_contracts(client, template_ref, folder_id) stats = contract_value_stats( client, template_ref, folder_id, value_field, "2020-01-01T00:00:00Z", "2030-01-01T00:00:00Z", ) groups = top_contract_types( client, template_ref, folder_id, type_field, value_field ) print("Contract analytics dashboard") print() _print_table( ["Metric", "Value"], [ ["Total contracts", total], ["Average value", stats["avgContractValue"]], ["Minimum value", stats["minContractValue"]], ["Maximum value", stats["maxContractValue"]], ], ) print() # Buckets arrive ordered by document count, so print them as returned. print("Top contract types") _print_table( ["Type", "Total value", "Count"], [ [row.get("contract_type"), row.get("total_value"), row.get("count")] for row in groups ], )if __name__ == "__main__": print_contract_dashboard( template_ref=os.environ["TEMPLATE_REF"], type_field=os.environ["FIELD_CONTRACT_TYPE"], value_field=os.environ["FIELD_CONTRACT_VALUE"], )
Run the report against your own content to confirm that authentication, the template reference, and response parsing all work.
Confirm your environment values. Your .env file needs the three Client Credentials Grant values plus FOLDER_ID, TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE. The setup script in Create a metadata template and sample data prints the last four values for you.
Run the report. Activate your virtual environment first, then use the command for your path:
cd contract-insightssource .venv/bin/activatepython dashboard.py
# Console script: run the entry point the agent createdcd contract-insightssource .venv/bin/activatepython dashboard.py# Flask, FastAPI, Express, Fastify, Spring Boot, or ASP.NET Core: start the server, then query it from a second terminalcurl http://127.0.0.1:5000/dashboard
If you built with an agent, check the README it generated for the exact module and run command.
Check the output. With the four sample contracts from the setup step, the console report looks like this:
Contract analytics dashboardMetric Value--------------- -------Total contracts 4Average value 123,750Minimum value 45,000Maximum value 200,000Top contract typesType Total value Count------- ----------- -----Sales 300,000 2Renewal 195,000 2
Buckets are ordered by document count in descending order, so your group order varies with your own data.
Cross-check one number in Box. Open the contracts folder in Box and count the files that carry your metadata template. That count matches Total contracts from step 3, which confirms your ancestors filter and template reference point at the content you expect.
A metric of 0 right after you tag content usually means the metadata index has not caught up yet. Wait a minute and run the report again. For other symptoms, see Troubleshooting.
Dashboard widgets rarely need real-time precision. Refresh aggregates on a schedule, for example, every 15 minutes or hourly, instead of calling the Box Query Insights API on every page load. Store results in your app cache or a data warehouse. The SDK already retries 429 RATE_LIMIT_EXCEEDED and 5xx responses with backoff, so cache to reduce the number of calls rather than adding a retry loop of your own.
Scope queries with ancestors
Pass department or program folder IDs in ancestors so each team sees only its content. This reduces result set size, keeps dashboards tenant-aware, and aligns with how Box enforces folder-level access for the service account.
Pair insights with Box Query API for drill-down
Use the Box Query Insights API for summary tiles and charts, then call Box Query API when you select a bucket to load the underlying files. The Box Query Insights API returns aggregates only. Box Query API returns individual items with the same predicate syntax.
Validate group_by field cardinality
Make sure the bucket_limit is set to 10 or less. Prefer low-cardinality dimensions for chart axes. Cardinality of 10,000 or above can cause errors, though that threshold is rarely reached in practice.
Last modified on October 26, 2026
Was this page helpful?
{"docsConfig":{"theme":"aspen","$schema":"https://mintlify.com/docs.json","name":"Box Dev Docs","description":"Box for Developers: guides, API reference, SDKs, and tutorials for building content management, Box AI, and enterprise integrations.","colors":{"primary":"#0061d5","light":"#f6fafd","dark":"#002947"},"logo":{"light":"https://mintcdn.com/box/lJLw9z7FWORNWMcq/logo/boxdev-light.png?fit=max\u0026auto=format\u0026n=lJLw9z7FWORNWMcq\u0026q=85\u0026s=a11710b698ff59d24426f9ecec6c7e9c","dark":"https://mintcdn.com/box/siVVIgx7pBuvW4ua/logo/boxdev-dark.svg?fit=max\u0026auto=format\u0026n=siVVIgx7pBuvW4ua\u0026q=85\u0026s=0e34af393abb1b8c024258d684bb7732"},"favicon":"https://mintcdn.com/box/T2hwpVFBJMA4eeDs/favicon.ico?fit=max\u0026auto=format\u0026n=T2hwpVFBJMA4eeDs\u0026q=85\u0026s=2a2efcc60e46eca7ee3ebbe650c47350","api":{"examples":{"languages":["curl","python","node","swift","java",".Net"],"autogenerate":false}},"seo":{"metatags":{"google-site-verification":"fuelbNhVR1kQluNBJjYt4K1Hj5HvJLhLnIq0o9CAY9E"}},"fonts":{"family":"Inter"},"contextual":{"options":[{"title":"Install Box Agent Skills","description":"Add Box plugins to your AI assistants","icon":"sparkles","href":"/ai/agent-skills"},"cursor","vscode","mcp","chatgpt","claude","perplexity","copy","view"],"display":"header"},"metadata":{"timestamp":true},"styling":{"latex":false},"navigation":{"languages":[{"language":"en","banner":{"content":"Join BoxWorks Dev Summit on Nov 5-6, San Francisco and dive into AI agents and unstructured content. [See agenda](https://boxworks.box.com/series/boxworks-2026-dev-summit/landing_page).","dismissible":true},"footer":{"socials":{"x":"https://x.com/box","github":"https://github.com/box-community","linkedin":"https://linkedin.com/company/box","youtube":"https://www.youtube.com/user/box","facebook":"https://www.facebook.com/box"},"links":[{"header":"Resources","items":[{"label":"Newsletter unsubscribe","href":"https://go.box.com/preferences.html"},{"label":"Terms of Use","href":"https://cloud.app.box.com/s/rmwxu64h1ipr41u49w3bbuvbsa29wku9"},{"label":"Privacy Policy","href":"https://www.box.com/en-gb/legal/privacypolicy?url_redirect=direct"},{"label":"Cookie Notification","href":"https://www.box.com/en-gb/legal/cookie-notification?url_redirect=direct"},{"label":"llms.txt","href":"https://developer.box.com/llms.txt"}]}]},"navbar":{"links":[{"href":"https://account.box.com/developers/console","label":"Log in","type":"button"}],"primary":{"type":"button","label":"Get started for free","href":"https://account.box.com/signup/developer"}},"href":""},{"language":"ja","banner":{"content":"Join live webinar on Sept 29: See how to give agents a computer and enterprise content to work on with Box and Daytona. [Register now](https://events.zoom.us/ev/Amkp36LSSk_TxOQbBytoLoHa_Ztg7quKlJv2u74NRvSZJtlnbG5L~AqO7fnFo-ePaTqEcPrKs4jSfhxq3pMVK52ut69Q2zfn9jOr70vx5DQVJaeNF1dDZE9_0N33jMcY1yE9LoHDL5Oamqg).","dismissible":true},"footer":{"socials":{"x":"https://x.com/box","github":"https://github.com/box-community","linkedin":"https://linkedin.com/company/box","youtube":"https://www.youtube.com/user/box","facebook":"https://www.facebook.com/box"},"links":[{"header":"リソース","items":[{"label":"ニュースレターの登録解除","href":"https://go.box.com/preferences.html"},{"label":"利用規約","href":"https://cloud.app.box.com/s/rmwxu64h1ipr41u49w3bbuvbsa29wku9"},{"label":"個人情報保護方針","href":"https://www.box.com/en-gb/legal/privacypolicy?url_redirect=direct"},{"label":"Cookieに関する通知","href":"https://www.box.com/en-gb/legal/cookie-notification?url_redirect=direct"},{"label":"llms.txt","href":"https://developer.box.com/llms.txt"}]}]},"navbar":{"links":[{"href":"https://account.box.com/developers/console","label":"ログイン","type":"button"}],"primary":{"type":"button","label":"今すぐ無料で開始","href":"https://account.box.com/signup/developer"}},"href":"ja"}]}},"deployment":{"deploymentMetadataValue":{"subdomain":"box","hasAudioNarration":false,"actualSubdomain":"box","customDomains":["developer.box.com"],"gitSource":{"type":"github","owner":"box","repo":"box-mintlify","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6adf7f5c808b7de584522819","collectionId":"8dc826db-3576-4d84-aa0d-15e2dbd23887","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6adf7f5c808b7de584522819"},"feedback":{"thumbs":true,"issues":false},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"REMOVE_BRANDING":{"status":"ENABLED"},"CONTEXTUAL_FEEDBACK":{"status":"ENABLED"},"CODE_SNIPPET_FEEDBACK":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6adf81bea6cc13f54c03378c","clientVersion":"0.0.3971","searchFilterCounts":[{"language":"en","tag":"API reference","count":680},{"language":"ja","tag":"ホーム","count":368},{"language":"ja","tag":"APIリファレンス","count":339},{"language":"en","tag":"Home","count":302},{"language":"ja","tag":"AI","count":187},{"language":"en","tag":"AI","count":173},{"language":"ja","tag":"コラボレーション","count":81},{"language":"ja","tag":"ツール","count":76},{"language":"ja","tag":"開発ツール","count":76},{"language":"ja","tag":"メタデータと検索","count":67},{"language":"en","tag":"Tools","count":62},{"language":"en","tag":"Dev tools","count":62},{"language":"ja","tag":"コンテンツ","count":58},{"language":"en","tag":"Metadata \u0026 search","count":56},{"language":"en","tag":"Collaboration","count":50},{"language":"en","tag":"Content","count":49},{"language":"ja","tag":"メタデータ","count":49},{"language":"en","tag":"v2026.0","count":47},{"language":"en","tag":"Supported AI models","count":46},{"language":"ja","tag":"サポートされているAIモデル","count":44}]},"assistantConfig":{"enableAskAiButton":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[{"filePath":"styles.css","content":"a code{border-bottom-color:none!important}.prose :where(a code):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)){color:inherit;font-weight:inherit;text-decoration:none;text-decoration-color:rgb(var(--primary));text-underline-offset:0;text-decoration-thickness:1px}#consent_blackbar{position:relative;z-index:9999999!important}#sidebar,.left-0.right-0.sticky.sm\\:px-4.pb-4.sm\\:pb-6.bottom-0.pt-1.flex.flex-col.items-center.w-full.overflow-hidden.z-20{z-index:1}#footer>div,#sidebar-content{z-index:0}a.nav-anchor img[src$=\"/images/sidebar/box.svg\"]{background-color:transparent!important}#truste-consent-track{z-index:9999999!important;position:fixed!important}.dark #truste-consent-track{background-color:#151f26!important;border-color:#1a1a1a}.dark #truste-show-consent{background-color:#fff;color:#151f26}.dark #truste-consent-text{color:#fff}#truste-consent-content{max-width:1400px}.homepage_container .card img{max-height:200px}.homepage_container h1 span,.homepage_container h2 span{margin:auto}#navbar .max-w-8xl.mx-auto.relative button .ml-4.flex.text-sm.leading-6.whitespace-nowrap.min-w-0.space-x-3.overflow-hidden,header#header .eyebrow{display:none!important}.sidebar-group-header:has(+.sidebar-group>li:is(\n [id=\"/reference\"],\n [id=\"/ja/reference\"],\n [id=\"/ja/reference/v2025.0\"],\n [id=\"/ja/reference/v2026.0\"]\n))>.sidebar-title{display:none}footer div.flex.gap-4.flex-col.md\\:flex-row.md\\:items-center.md\\:gap-8.md\\:justify-center{flex-wrap:wrap}footer div.flex.gap-4.flex-col.md\\:flex-row.md\\:items-center.md\\:gap-8.md\\:justify-center a{white-space:nowrap;text-overflow:clip;overflow:visible;align-self:start;flex-shrink:0;cursor:pointer!important}#google-preferred-source-column{display:flex;flex-direction:column;align-items:flex-end;flex:0 0 auto;width:max-content;max-width:100%}#google-preferred-source{display:flex;justify-content:flex-end;width:auto;margin:0;padding-top:16px}.google-preferred-source-button{appearance:none;margin:0;padding:0;border:0;background:0 0;line-height:0;cursor:pointer}.google-preferred-source-badge{display:block;width:140px;max-width:100%;height:auto}.dark .google-preferred-source-badge--light,.google-preferred-source-badge--dark{display:none}.dark .google-preferred-source-badge--dark{display:block}.nav-logo{min-width:109px}.badge-guide,.badge-quickstart,.badge-tutorial,.dark .badge-guide,.dark .badge-quickstart,.dark .badge-tutorial{background-color:#1f2937;color:#fff}.badge-get{background-color:rgb(74 222 128/.2);color:#15803d}.dark .badge-get{color:#4ade80}.badge-post{background-color:rgb(96 165 250/.2);color:#1d4ed8}.dark .badge-post{color:#60a5fa}.badge-patch,.badge-put{background-color:rgb(250 204 21/.2);color:#a16207}.dark .badge-patch,.dark .badge-put{color:#facc15}.badge-delete{background-color:rgb(248 113 113/.2);color:#b91c1c}.dark .badge-delete{color:#f87171}.badge-api{background-color:#e3f2fd;color:#0d47a1}.dark .badge-api{background-color:#0d47a1;color:#bbdefb}.badge-documentation,.badge-reference,.dark .badge-documentation,.dark .badge-reference{background-color:#000;color:#fff}.badge-default{background-color:#f5f5f5;color:#424242}.badge-group{display:inline-flex;gap:.5rem;flex-wrap:wrap}.dark .badge-default{background-color:#424242;color:#e0e0e0}.update>div:first-child>div:nth-child(3){padding:0;order:4}.update>div:first-child>div:nth-child(3)>span{display:flex;padding:.25rem .75rem;align-items:center;border-radius:9999px;font-size:.875rem;line-height:1.25rem;color:#374151;background-color:#f3f4f6}.dark .update>div:first-child>div:nth-child(3)>span{color:#cecece;background-color:#161616}.update>div:first-child>div:nth-child(4){order:3}div#banner a{text-decoration:none!important;color:#fff;font-weight:600}nav ul #topbar-cta-button a span,nav ul .navbar-link a{border-radius:50px!important}nav ul #topbar-cta-button a span{background-color:#0061d5}#topbar-cta-button a:hover span{opacity:1!important;background-color:#146bd5}.dark #topbar-cta-button a:hover span{opacity:1!important;background-color:#0058c3}.signup-cta-button,.signup-cta-button:active,.signup-cta-button:focus,.signup-cta-button:hover{background-color:#0061d5;border-radius:50px!important;transition:background-color .2s!important;box-shadow:none!important;transform:none!important;border:0!important;border-bottom:none!important;text-decoration:none!important;outline:0!important}.signup-cta-button:hover{background-color:#146bd5!important;opacity:1!important}.dark .signup-cta-button:hover{background-color:#0058c3!important;opacity:1!important}.homepage-secondary-button,.homepage-secondary-button:active,.homepage-secondary-button:focus,.homepage-secondary-button:hover{border-radius:50px!important;border:1px solid #d1d5db!important;background-color:transparent!important;color:#1f2937!important;transition:background-color .2s!important;box-shadow:none!important;transform:none!important;text-decoration:none!important;outline:0!important}.homepage-secondary-button:hover{background-color:#f9fafb!important}.dark .homepage-secondary-button,.dark .homepage-secondary-button:active,.dark .homepage-secondary-button:focus{border-color:#4b5563!important;color:#e5e7eb!important}.dark .homepage-secondary-button:hover{background-color:#1f2937!important}.signup-cta-login,.signup-cta-login:active,.signup-cta-login:focus,.signup-cta-login:hover{text-decoration:none!important;border-bottom:none!important}#content-area h1,#content-area h2,#content-area h3,#content-area h4,#content-area h5,#content-area h6{font-weight:600!important}#content-area h1{font-size:32px!important}.dark img[src*=\"guides-box-ai-ai-models/claude.svg\"],.dark img[src*=\"guides-box-ai-ai-models/gemini.svg\"],.dark img[src*=\"guides-box-ai-ai-models/grok.svg\"],.dark img[src*=\"guides-box-ai-ai-models/meta.svg\"],.dark img[src*=\"guides-box-ai-ai-models/mistral.svg\"],.dark img[src*=\"guides-box-ai-ai-models/openai.svg\"]{filter:invert(1)}.homepage_h2{font-size:28px!important}.chat-assistant-floating-input{z-index:1!important}"}],"page":{"pagePath":"tutorials/query-insights","slug":"/tutorials/query-insights","pageMetadata":{"title":"Build a contract analytics dashboard with Box Query Insights API","sidebarTitle":"Contract analytics dashboard","description":"Use the Box Query Insights API to aggregate metadata across Box content and power dashboards with counts, sums, averages, and grouped breakdowns.","href":"/tutorials/query-insights"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Use the Box Query Insights API to aggregate metadata across Box content and power dashboards with counts, sums, averages, and grouped breakdowns.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];const{useState:__snippet_useState_1h1agm2,useEffect:__snippet_useEffect_1h1agm2}=React;const AgentPromptBuilder=({stacks=[],rootId=`agent-prompt-root`})=>{const{Icon}=_provideComponents()||{};if(!Icon)_missingMdxReference(`Icon`,true);const languages=Array.isArray(stacks)?stacks:[];const[language,setLanguage]=__snippet_useState_1h1agm2(languages[0]?.language||``);const[framework,setFramework]=__snippet_useState_1h1agm2(languages[0]?.frameworks?.[0]?.name||``);const activeLanguage=languages.find(entry=>entry.language===language)||languages[0];const frameworks=activeLanguage?.frameworks||[];const activeFramework=frameworks.find(entry=>entry.name===framework)?.name||frameworks[0]?.name||``;__snippet_useEffect_1h1agm2(()=>{if(!activeLanguage?.language||!activeFramework)return;const root=document.getElementById(rootId);if(!root)return;const key=`${activeLanguage.language}||${activeFramework}`;const panels=root.querySelectorAll(`[data-agent-stack]`);panels.forEach(panel=>{const match=panel.getAttribute(`data-agent-stack`)===key;panel.hidden=!match;panel.style.display=match?``:`none`})},[activeLanguage?.language,activeFramework,rootId]);if(languages.length===0){return _jsxs(`div`,{className:`mint-mb-4 mint-rounded-xl mint-border mint-border-red-200 mint-bg-red-50 mint-px-4 mint-py-3 mint-text-sm mint-text-red-800 dark:mint-border-red-900 dark:mint-bg-red-600/20 dark:mint-text-red-300`,children:[`AgentPromptBuilder needs a non-empty `,_jsx(`code`,{children:`stacks`}),` prop.`]})}const selectClassName=`w-full min-w-[10rem] appearance-none rounded-lg border border-gray-200 bg-white px-3 py-2 pr-9 text-sm font-medium text-gray-900 transition-colors focus:outline-none focus:ring-2 focus:ring-gray-400/30 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:focus:ring-gray-500/30`;const handleLanguageChange=event=>{const next=languages.find(entry=>entry.language===event.target.value)||languages[0];setLanguage(next.language);setFramework(next.frameworks?.[0]?.name||``)};return _jsxs(_Fragment,{children:[_jsx(`div`,{\"aria-hidden\":`true`,className:`mint-text-gray-500 dark:mint-text-gray-400`,children:_jsx(Icon,{icon:`sparkles`,size:24})}),_jsx(`h3`,{className:`mint-mt-4 mint-mb-0 mint-text-base mint-font-semibold mint-text-gray-900 dark:mint-text-white`,children:`Build this tutorial with your coding agent`}),_jsx(`p`,{className:`mint-mt-1 mint-mb-0 mint-text-base mint-leading-6 mint-text-gray-600 dark:mint-text-gray-400`,children:`Choose your stack, then copy this ready-to-use prompt into Codex, Claude Code, Cursor, or another coding agent.`}),_jsxs(`div`,{className:`mint-mt-5 mint-flex mint-flex-col mint-gap-4 sm:mint-flex-row`,children:[_jsxs(`div`,{className:`mint-min-w-0 mint-flex-1`,children:[_jsx(`label`,{htmlFor:`agent-prompt-language`,className:`mint-mb-2 mint-block mint-text-sm mint-font-medium mint-text-gray-900 dark:mint-text-gray-200`,children:`Programming language`}),_jsxs(`div`,{className:`mint-relative`,children:[_jsx(`select`,{id:`agent-prompt-language`,value:activeLanguage.language,onChange:handleLanguageChange,className:`mint-w-full mint-min-w-[10rem] mint-appearance-none mint-rounded-lg mint-border mint-border-gray-200 mint-bg-white mint-px-3 mint-py-2 mint-pr-9 mint-text-sm mint-font-medium mint-text-gray-900 mint-transition-colors focus:mint-outline-none focus:mint-ring-2 focus:mint-ring-gray-400/30 dark:mint-border-gray-700 dark:mint-bg-gray-900 dark:mint-text-gray-100 dark:focus:mint-ring-gray-500/30`,children:languages.map(entry=>_jsx(`option`,{value:entry.language,children:entry.language},entry.language))}),_jsx(`span`,{\"aria-hidden\":`true`,className:`mint-pointer-events-none mint-absolute mint-inset-y-0 mint-right-3 mint-flex mint-items-center mint-text-gray-500 dark:mint-text-gray-400`,children:_jsx(Icon,{icon:`chevron-down`,size:16})})]})]}),_jsxs(`div`,{className:`mint-min-w-0 mint-flex-1`,children:[_jsx(`label`,{htmlFor:`agent-prompt-framework`,className:`mint-mb-2 mint-block mint-text-sm mint-font-medium mint-text-gray-900 dark:mint-text-gray-200`,children:`Framework`}),_jsxs(`div`,{className:`mint-relative`,children:[_jsx(`select`,{id:`agent-prompt-framework`,value:activeFramework,onChange:event=>setFramework(event.target.value),className:`mint-w-full mint-min-w-[10rem] mint-appearance-none mint-rounded-lg mint-border mint-border-gray-200 mint-bg-white mint-px-3 mint-py-2 mint-pr-9 mint-text-sm mint-font-medium mint-text-gray-900 mint-transition-colors focus:mint-outline-none focus:mint-ring-2 focus:mint-ring-gray-400/30 dark:mint-border-gray-700 dark:mint-bg-gray-900 dark:mint-text-gray-100 dark:focus:mint-ring-gray-500/30`,children:frameworks.map(entry=>_jsx(`option`,{value:entry.name,children:entry.name},entry.name))}),_jsx(`span`,{\"aria-hidden\":`true`,className:`mint-pointer-events-none mint-absolute mint-inset-y-0 mint-right-3 mint-flex mint-items-center mint-text-gray-500 dark:mint-text-gray-400`,children:_jsx(Icon,{icon:`chevron-down`,size:16})})]})]})]})]})};const RelatedLinks=({title,items=[]})=>{const _components={a:`a`,..._provideComponents()};const getBadgeClass=badge=>{if(!badge)return`badge-default`;const badgeType=badge.toLowerCase().replace(/\\s+/g,`-`);return`badge-${badge===`ガイド`?`guide`:badgeType}`};if(!items||items.length===0){return null}return _jsxs(`div`,{className:`mint-my-8`,children:[_jsx(`h3`,{className:`mint-text-sm mint-font-bold mint-uppercase mint-tracking-wider mint-mb-4`,children:title}),_jsx(`div`,{className:`mint-flex mint-flex-col mint-gap-3`,children:items.map((item,index)=>_jsxs(_components.a,{href:item.href,className:`mint-py-2 mint-px-3 mint-rounded related_link hover:mint-bg-[#f2f2f2] dark:hover:mint-bg-[#111827] mint-flex mint-items-center mint-gap-3 group mint-no-underline hover:mint-no-underline mint-border-b-0`,children:[_jsx(`span`,{className:`mint-px-2 mint-py-1 mint-rounded-full mint-text-xs mint-font-semibold mint-uppercase mint-tracking-wide mint-flex-shrink-0 ${getBadgeClass(item.badge)}`,children:item.badge}),_jsx(`span`,{className:`mint-text-base`,children:item.label})]},index))})]})};const SignupCTA=({children})=>{return _jsxs(`div`,{className:`mint-flex mint-flex-wrap mint-items-center mint-gap-4 mint-p-5 mint-rounded-lg mint-border mint-border-gray-200 dark:mint-border-gray-700 mint-my-6`,style:{background:`linear-gradient(135deg, rgba(0, 97, 213, 0.06), rgba(0, 97, 213, 0.02))`},children:[_jsx(`div`,{className:`mint-flex-1 mint-text-sm mint-leading-relaxed mint-text-gray-700 dark:mint-text-gray-300`,style:{minWidth:`280px`},children}),_jsxs(`div`,{className:`mint-flex mint-flex-col mint-items-center mint-gap-2`,children:[_jsx(`a`,{href:`https://account.box.com/signup/developer`,className:`signup-cta-button mint-inline-flex mint-items-center mint-whitespace-nowrap mint-px-5 mint-py-2 mint-text-sm mint-font-semibold mint-text-white mint-no-underline`,children:translate(`Get started for free`)}),_jsx(`a`,{href:`https://account.box.com/developers/console`,className:`signup-cta-login mint-text-xs mint-text-gray-500 dark:mint-text-gray-400 mint-no-underline mint-whitespace-nowrap`,children:translate(`Already have an account? Log in`)})]})]})};function _createMdxContent(props){const _components={a:`a`,code:`code`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,tbody:`tbody`,td:`td`,th:`th`,thead:`thead`,tr:`tr`,ul:`ul`,..._provideComponents(),...props.components},{Accordion,AccordionGroup,Card,CodeBlock,CodeGroup,Heading,Note,Step,Steps,Table,Tip,Warning,_MdxComponentBoundary}=_components;if(!Accordion)_missingMdxReference(`Accordion`,true);if(!AccordionGroup)_missingMdxReference(`AccordionGroup`,true);if(!Card)_missingMdxReference(`Card`,true);if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!CodeGroup)_missingMdxReference(`CodeGroup`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Note)_missingMdxReference(`Note`,true);if(!Step)_missingMdxReference(`Step`,true);if(!Steps)_missingMdxReference(`Steps`,true);if(!Table)_missingMdxReference(`Table`,true);if(!Tip)_missingMdxReference(`Tip`,true);if(!Warning)_missingMdxReference(`Warning`,true);if(!_MdxComponentBoundary)_missingMdxReference(`_MdxComponentBoundary`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`Sales, legal, and procurement teams often store contracts in Box with structured metadata, for example, contract type, value, effective dates, and status. Listing every file to compute totals in your application is slow, expensive, and hard to keep current as content grows.`}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.a,{href:`/guides/query/insights`,children:`Box Query Insights API`}),` solves this by returning aggregated metrics directly from Box. You filter items with the same predicate syntax as `,_jsx(_components.a,{href:`/guides/query/box-query`,children:`Box Query API`}),`, optionally group results, and request metrics such as `,_jsx(_components.code,{children:`count`}),`, `,_jsx(_components.code,{children:`sum`}),`, `,_jsx(_components.code,{children:`avg`}),`, `,_jsx(_components.code,{children:`min`}),`, and `,_jsx(_components.code,{children:`max`}),` in a single API call.`]}),`\n`,_jsx(_components.p,{children:`This tutorial builds a contract analytics dashboard with total, average, minimum, and maximum contract value for sales contracts in a date range.`}),`\n`,_jsx(Card,{title:`Clone the working sample`,href:`https://github.com/box-community/query-insights-dashboard`,icon:`github`,arrow:`true`,children:_jsx(_components.p,{children:`Prefer to start from running code? The complete app built in this tutorial is on GitHub. Clone it, add your Box credentials, and run.`})}),`\n`,_jsx(Heading,{level:`2`,id:`use-cases`,children:`Use cases`}),`\n`,_jsx(_components.p,{children:`The Box Query Insights API fits any workflow where you need summary numbers instead of individual file lists.`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Use case`}),_jsx(_components.th,{children:`What you compute`}),_jsx(_components.th,{children:`Example metrics`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Executive dashboard`})}),_jsx(_components.td,{children:`Portfolio totals and breakdowns by category`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`sum`}),` of contract value grouped by `,_jsx(_components.code,{children:`contractType`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Compliance reporting`})}),_jsx(_components.td,{children:`How many documents match a template in a period`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`count`}),` with `,_jsx(_components.code,{children:`box:item:created_at`}),` filters`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Procurement analytics`})}),_jsx(_components.td,{children:`Typical and outlier deal sizes`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`avg`}),`, `,_jsx(_components.code,{children:`min`}),`, and `,_jsx(_components.code,{children:`max`}),` on a currency field`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Department scorecards`})}),_jsx(_components.td,{children:`Metrics scoped to a team folder`}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`ancestors`}),` set to a department root folder`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.strong,{children:`Data quality checks`})}),_jsx(_components.td,{children:`Volume of tagged content before a migration`}),_jsxs(_components.td,{children:[`Empty `,_jsx(_components.code,{children:`metrics`}),` object for default `,_jsx(_components.code,{children:`totalResultCount`})]})]})]})]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`The Box Query Insights API applies filters first, then grouping, then metric calculation. It does not return individual items. When you need file-level results, use `,_jsx(_components.a,{href:`/guides/query/box-query`,children:`Box Query API`}),` or `,_jsx(_components.a,{href:`/guides/metadata/queries`,children:`metadata queries`}),` and compute aggregates in your app, or call both APIs for drill-down views.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`before-you-start`,children:`Before you start`}),`\n`,_jsx(_components.p,{children:`You need:`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`A free `,_jsx(_components.a,{href:`https://account.box.com/signup/developer`,children:`Box developer account`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`A `,_jsx(_components.a,{href:`https://cloud.app.box.com/developers/console`,children:`Box application`}),` configured with `,_jsx(_components.strong,{children:`Client Credentials Grant (CCG)`}),` authentication.`]}),`\n`,_jsxs(_components.li,{children:[`The `,_jsx(_components.strong,{children:`Read and write all files and folders stored in Box`}),` scope enabled on your app.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Client Credentials Grant authorized`}),` for your enterprise in the `,_jsx(_components.strong,{children:`Developer Console`}),` and `,_jsx(_components.a,{href:`https://app.box.com/master/settings/openbox`,children:`Admin Console`}),`.`]}),`\n`,_jsx(_components.li,{children:`Python 3.10 or later.`}),`\n`,_jsxs(_components.li,{children:[`Admin permissions to create a metadata template, or an existing template you can use instead. See `,_jsx(_components.a,{href:`/guides/metadata/templates/create`,children:`Create a metadata template`}),`.`]}),`\n`]}),`\n`,_jsx(_MdxComponentBoundary,{name:`SignupCTA`,children:_jsx(SignupCTA,{children:_jsx(_components.p,{children:`A free Box developer account gives you a Developer Console, API access, and a test environment for building metadata-driven reporting workflows.`})})}),`\n`,_jsx(Heading,{level:`2`,id:`build-with-an-agent`,children:`Build with an agent`}),`\n`,_jsxs(_components.p,{children:[`The agent expects a metadata template, a contracts folder, and tagged sample files to already exist in Box. If you don’t have them yet, complete the first three steps of `,_jsx(_components.a,{href:`#build-by-hand`,children:`Build by hand`}),`, through `,_jsx(_components.strong,{children:`Create a metadata template and sample data`}),`, and then return here.`]}),`\n`,_jsxs(_components.p,{children:[`Get these values from the sample data generated by the script `,_jsx(_components.code,{children:`setup_test_data.py`}),` or from the metadata template and folder you created:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Template key`}),` - from the template you created (for example, `,_jsx(_components.code,{children:`sales`}),`)`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Folder ID`}),` - from the folder you created (for example, `,_jsx(_components.code,{children:`1234567890`}),`)`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Enterprise ID`}),` - from the `,_jsx(_components.a,{href:`https://app.box.com/developers/console`,children:`Developer Console`}),` (for example, `,_jsx(_components.code,{children:`1234567890`}),`)`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Choose your stack and copy the prompt. It already lists these as prerequisites, so the agent reads them from environment variables instead of trying to create them. Replace the `,_jsx(_components.code,{children:`\u003cTEMPLATE_KEY>`}),`, `,_jsx(_components.code,{children:`\u003cFOLDER_ID>`}),`, and `,_jsx(_components.code,{children:`\u003cENTERPRISE_ID>`}),` placeholders if you want the agent to pre-fill `,_jsx(_components.code,{children:`.env`}),`; otherwise leave them and fill `,_jsx(_components.code,{children:`.env`}),` yourself after scaffolding.`]}),`\n`,_jsxs(`div`,{id:`query-insights-agent-prompt-root`,className:`mint-my-6 mint-w-full mint-rounded-2xl mint-border mint-border-gray-200 mint-bg-white mint-px-6 mint-py-5 dark:mint-border-white/10 dark:mint-bg-transparent`,children:[_jsx(_MdxComponentBoundary,{name:`AgentPromptBuilder`,children:_jsx(AgentPromptBuilder,{rootId:`query-insights-agent-prompt-root`,stacks:[{\"language\":`Python`,\"frameworks\":[{\"name\":`Script`},{\"name\":`Flask`},{\"name\":`FastAPI`}]},{\"language\":`TypeScript`,\"frameworks\":[{\"name\":`Express`},{\"name\":`Fastify`}]},{\"language\":`Node`,\"frameworks\":[{\"name\":`Express`},{\"name\":`NestJS`}]},{\"language\":`Java`,\"frameworks\":[{\"name\":`Spring Boot`},{\"name\":`Quarkus`}]},{\"language\":`.NET`,\"frameworks\":[{\"name\":`ASP.NET Core`},{\"name\":`Minimal APIs`}]}]})}),_jsxs(`div`,{className:`mint-mt-5`,children:[_jsx(`div`,{\"data-agent-stack\":`Python||Script`,children:_jsx(CodeBlock,{filename:`Python + Script`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use Python as a command-line script. Target Python 3.11+, use pip and a virtual environment. Install exactly one Box package: boxsdk (do NOT also install box-sdk-gen — both ship the box_sdk_gen module and conflict). Import Box APIs with `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#CE9178`},children:\"`from box_sdk_gen import ...`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Also install python-dotenv, and pytest for tests.`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Call the API exactly as the tutorial does: client.query.create_query_insight_v2026_r0(query, metrics), passing CreateQueryInsightV2026R0Query (predicate, params, ancestors with QueryAncestorReferenceV2026R0, group_by with QueryInsightsGroupByV2026R0) and a dict of metric aliases to QueryInsightsMetricDefinitionV2026R0 (its type field takes the QueryInsightsMetricDefinitionV2026R0TypeField enum). The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Compare entry.type against QueryInsightEntryV2026R0TypeField. Errors raise BoxAPIError, which carries the status as error.response_info.status_code and the Box code as error.response_info.code. In tests, turn recorded payloads into typed models with box_sdk_gen.deserialize(payload, QueryInsightsV2026R0) instead of hand-building objects; if you also need to raise a BoxAPIError, its RequestInfo and ResponseInfo live in box_sdk_gen.box.errors. Confirm the symbol names against the installed SDK's query manager and schema modules before writing code. Build the client with BoxCCGAuth and CCGConfig as the tutorial shows. Print a console report; do not add a web server.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box_client.py (CCG client), reports.py (count, value statistics, and grouped queries with response parsing), dashboard.py that prints the report, and pytest.ini with pythonpath = .`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a flat script layout matching the tutorial (no unnecessary packages)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Add pytest.ini with pythonpath = . so pytest can import reports and box_client from the project root. Without it, pytest fails with ModuleNotFoundError: No module named 'reports'`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})}),_jsx(`div`,{\"data-agent-stack\":`Python||Flask`,hidden:true,children:_jsx(CodeBlock,{filename:`Python + Flask`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use Python with Flask. Target Python 3.11+, use pip and a virtual environment. Install exactly one Box package: boxsdk (do NOT also install box-sdk-gen — both ship the box_sdk_gen module and conflict). Import Box APIs with `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#CE9178`},children:\"`from box_sdk_gen import ...`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Also install flask, python-dotenv, and pytest for tests.`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Call the API exactly as the tutorial does: client.query.create_query_insight_v2026_r0(query, metrics), passing CreateQueryInsightV2026R0Query (predicate, params, ancestors with QueryAncestorReferenceV2026R0, group_by with QueryInsightsGroupByV2026R0) and a dict of metric aliases to QueryInsightsMetricDefinitionV2026R0 (its type field takes the QueryInsightsMetricDefinitionV2026R0TypeField enum). The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Compare entry.type against QueryInsightEntryV2026R0TypeField. Errors raise BoxAPIError, which carries the status as error.response_info.status_code and the Box code as error.response_info.code. In tests, turn recorded payloads into typed models with box_sdk_gen.deserialize(payload, QueryInsightsV2026R0) instead of hand-building objects; if you also need to raise a BoxAPIError, its RequestInfo and ResponseInfo live in box_sdk_gen.box.errors. Confirm the symbol names against the installed SDK's query manager and schema modules before writing code. Build the client with BoxCCGAuth and CCGConfig as the tutorial shows. Add only a thin Flask layer that returns the aggregates as JSON, and listen on port 5000 so the endpoints can be tested with curl.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box_client.py, reports.py (the Box query logic), app.py exposing GET /dashboard plus GET /healthz, and pytest.ini with pythonpath = .`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a flat Flask layout; keep the Box modules separate from the HTTP layer`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Add pytest.ini with pythonpath = . so pytest can import reports and box_client from the project root. Without it, pytest fails with ModuleNotFoundError: No module named 'reports'`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})}),_jsx(`div`,{\"data-agent-stack\":`Python||FastAPI`,hidden:true,children:_jsx(CodeBlock,{filename:`Python + FastAPI`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use Python with FastAPI. Target Python 3.11+, use pip and a virtual environment. Install exactly one Box package: boxsdk (do NOT also install box-sdk-gen — both ship the box_sdk_gen module and conflict). Import Box APIs with `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#CE9178`},children:\"`from box_sdk_gen import ...`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Also install fastapi, uvicorn, python-dotenv, and pytest for tests.`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Call the API exactly as the tutorial does: client.query.create_query_insight_v2026_r0(query, metrics), passing CreateQueryInsightV2026R0Query (predicate, params, ancestors with QueryAncestorReferenceV2026R0, group_by with QueryInsightsGroupByV2026R0) and a dict of metric aliases to QueryInsightsMetricDefinitionV2026R0 (its type field takes the QueryInsightsMetricDefinitionV2026R0TypeField enum). The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Compare entry.type against QueryInsightEntryV2026R0TypeField. Errors raise BoxAPIError, which carries the status as error.response_info.status_code and the Box code as error.response_info.code. In tests, turn recorded payloads into typed models with box_sdk_gen.deserialize(payload, QueryInsightsV2026R0) instead of hand-building objects; if you also need to raise a BoxAPIError, its RequestInfo and ResponseInfo live in box_sdk_gen.box.errors. Confirm the symbol names against the installed SDK's query manager and schema modules before writing code. Build the client with BoxCCGAuth and CCGConfig as the tutorial shows. Adapt the HTTP layer to FastAPI and uvicorn. The Box Python SDK is synchronous — use plain def route handlers (or run the sync Box calls in a threadpool); do not await sync SDK methods. Listen on port 5000 so the endpoints can be tested with curl.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box_client.py, reports.py (the Box query logic), a FastAPI app module exposing GET /dashboard plus GET /healthz with Pydantic response models, and pytest.ini with pythonpath = .`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` an idiomatic FastAPI layout; keep the Box modules separate from the HTTP layer`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Add pytest.ini with pythonpath = . so pytest can import reports and box_client from the project root. Without it, pytest fails with ModuleNotFoundError: No module named 'reports'`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})}),_jsx(`div`,{\"data-agent-stack\":`TypeScript||Express`,hidden:true,children:_jsx(CodeBlock,{filename:`TypeScript + Express`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use TypeScript with Express on Node.js 20+. Use npm and exactly one Box package: box-node-sdk@10 (do NOT also install box-typescript-sdk-gen). Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import Query Insights types and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — they are not on the package root. Also install express, dotenv, tsx (or tsc), and a test runner such as node:test or vitest.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`The tutorial's samples are Python; use the TypeScript equivalent of the same call. Call await client.query.createQueryInsightV2026R0({ query, metrics }), where query holds predicate, params, ancestors, and groupBy — note the camelCase groupBy and bucketLimit, unlike the snake_case JSON body. Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import QueryInsightsV2026R0, QueryInsightsMetricDefinitionV2026R0, QueryInsightsGroupByV2026R0, QueryAncestorReferenceV2026R0, and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — the package root does not re-export those symbols. Build CcgConfig with camelCase clientId, clientSecret, and enterpriseId. The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Errors are BoxApiError; read error.responseInfo.statusCode and error.responseInfo.code. In tests, turn recorded payloads into typed models with deserializeQueryInsightsV2026R0(payload) instead of hand-building objects. Confirm the schema and manager names against the installed SDK's typings before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID. Use tsconfig module ES2022, moduleResolution bundler, esModuleInterop, and strict. Do not set moduleResolution to node — TypeScript 7 removed it (TS5108). Run with npx tsx app.ts. Listen on port 5000 so the endpoints can be tested with curl.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` boxClient.ts, reports.ts (count, value statistics, and grouped queries with response parsing), app.ts exposing GET /dashboard plus GET /healthz, and tsconfig.json`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a flat Express + TypeScript layout; keep the Box modules separate from the HTTP layer`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Add a test script such as tsx --test tests/*.test.ts so local modules resolve from the project root without extra NODE_PATH flags. If you keep CommonJS output, resolve fixture paths with __dirname, not import.meta.url. Run the tests before you finish`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})}),_jsx(`div`,{\"data-agent-stack\":`TypeScript||Fastify`,hidden:true,children:_jsx(CodeBlock,{filename:`TypeScript + Fastify`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use TypeScript with Fastify on Node.js 20+. Use npm and exactly one Box package: box-node-sdk@10 (do NOT also install box-typescript-sdk-gen). Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import Query Insights types and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — they are not on the package root. Also install fastify, dotenv, tsx (or tsc), and a test runner such as node:test or vitest.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`The tutorial's samples are Python; use the TypeScript equivalent of the same call. Call await client.query.createQueryInsightV2026R0({ query, metrics }), where query holds predicate, params, ancestors, and groupBy — note the camelCase groupBy and bucketLimit, unlike the snake_case JSON body. Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import QueryInsightsV2026R0, QueryInsightsMetricDefinitionV2026R0, QueryInsightsGroupByV2026R0, QueryAncestorReferenceV2026R0, and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — the package root does not re-export those symbols. Build CcgConfig with camelCase clientId, clientSecret, and enterpriseId. The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Errors are BoxApiError; read error.responseInfo.statusCode and error.responseInfo.code. In tests, turn recorded payloads into typed models with deserializeQueryInsightsV2026R0(payload) instead of hand-building objects. Confirm the schema and manager names against the installed SDK's typings before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID. Use tsconfig module ES2022, moduleResolution bundler, esModuleInterop, and strict. Do not set moduleResolution to node — TypeScript 7 removed it (TS5108). Keep the Box modules framework-agnostic and adapt only the HTTP layer to Fastify. Listen on port 5000 so the endpoints can be tested with curl.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` boxClient.ts, reports.ts (the Box query logic), a Fastify app module exposing GET /dashboard plus GET /healthz, and tsconfig.json`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` an idiomatic Fastify + TypeScript layout; keep the Box modules separate from the HTTP layer`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Add a test script such as tsx --test tests/*.test.ts so local modules resolve from the project root without extra NODE_PATH flags. If you keep CommonJS output, resolve fixture paths with __dirname, not import.meta.url. Run the tests before you finish`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})}),_jsx(`div`,{\"data-agent-stack\":`Node||Express`,hidden:true,children:_jsx(CodeBlock,{filename:`Node + Express`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use Node.js 20+ with JavaScript (not TypeScript) and Express. Use npm and exactly one Box package: box-node-sdk@10 (do NOT also install box-typescript-sdk-gen). Load BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError with require(\"box-node-sdk\"). Also install express, dotenv, and a test runner such as node:test.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`The tutorial's samples are Python; use the Node.js equivalent of the same call. Call await client.query.createQueryInsightV2026R0({ query, metrics }), where query holds predicate, params, ancestors, and groupBy — note the camelCase groupBy and bucketLimit, unlike the snake_case JSON body. npm init defaults to CommonJS: write const { BoxClient, BoxCcgAuth, CcgConfig, BoxApiError } = require(\"box-node-sdk\") and const { deserializeQueryInsightsV2026R0 } = require(\"box-node-sdk/schemas\"). Do not write import statements unless you also set \"type\": \"module\" in package.json — otherwise Node throws SyntaxError: Cannot use import statement outside a module. The package root does not re-export Query Insights helpers. Build CcgConfig with camelCase clientId, clientSecret, and enterpriseId. Read entry.type, entry.key, and entry.metrics[alias].values off the returned model rather than parsing raw JSON. Errors are BoxApiError; read error.responseInfo.statusCode and error.responseInfo.code. In tests, turn recorded payloads into models with deserializeQueryInsightsV2026R0(payload). Confirm the symbol names against the installed SDK before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID. Write plain JavaScript with JSDoc comments instead of type annotations, and listen on port 5000 so the endpoints can be tested with curl.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` boxClient.js, reports.js (count, value statistics, and grouped queries with response parsing), and app.js exposing GET /dashboard plus GET /healthz`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a flat Express + JavaScript layout; keep the Box modules separate from the HTTP layer`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Add a test script such as node --test tests/*.test.js so require(\"../reports\") resolves from the tests folder. Use __dirname for fixture paths. Run the tests before you finish`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})}),_jsx(`div`,{\"data-agent-stack\":`Node||NestJS`,hidden:true,children:_jsx(CodeBlock,{filename:`Node + NestJS`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use Node.js 20+ with NestJS. NestJS projects use TypeScript by default. Use npm and exactly one Box package: box-node-sdk@10 (do NOT also install box-typescript-sdk-gen). Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import Query Insights types and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — they are not on the package root. Also install @nestjs/core, @nestjs/common, @nestjs/platform-express, dotenv, and a test runner such as Jest.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`The tutorial's samples are Python; use the TypeScript equivalent of the same call. Call await client.query.createQueryInsightV2026R0({ query, metrics }), where query holds predicate, params, ancestors, and groupBy — note the camelCase groupBy and bucketLimit, unlike the snake_case JSON body. Import BoxClient, BoxCcgAuth, CcgConfig, and BoxApiError from box-node-sdk. Import QueryInsightsV2026R0, QueryInsightsMetricDefinitionV2026R0, QueryInsightsGroupByV2026R0, QueryAncestorReferenceV2026R0, and deserializeQueryInsightsV2026R0 from box-node-sdk/schemas — the package root does not re-export those symbols. Build CcgConfig with camelCase clientId, clientSecret, and enterpriseId. The method returns a typed QueryInsightsV2026R0 result, so read entry.type, entry.key, and entry.metrics[alias].values off that model rather than parsing raw JSON. Errors are BoxApiError; read error.responseInfo.statusCode and error.responseInfo.code. In tests, turn recorded payloads into typed models with deserializeQueryInsightsV2026R0(payload) instead of hand-building objects. Confirm the schema and manager names against the installed SDK's typings before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID, and expose it as an injectable provider. Use tsconfig module ES2022, moduleResolution bundler, esModuleInterop, and strict. Do not set moduleResolution to node — TypeScript 7 removed it (TS5108). Listen on port 5000 so the endpoints can be tested with curl.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a Box client provider, a reports provider (the Box query logic), and a dashboard controller exposing GET /dashboard plus GET /healthz`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` an idiomatic NestJS layout (module, controller, providers); keep the Box client and report logic in dedicated providers separate from the HTTP controller`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Configure Jest so Nest providers import without extra path flags. Use moduleResolution bundler so box-node-sdk/schemas resolves. Keep parsing tests as plain unit tests (do not start a Nest testing module that constructs BoxClient) so they pass without BOX_* environment variables. Run the tests before you finish`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})}),_jsx(`div`,{\"data-agent-stack\":`Java||Spring Boot`,hidden:true,children:_jsx(CodeBlock,{filename:`Java + Spring Boot`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use Java 17+ with Spring Boot 3. Use Maven or Gradle and exactly one Box artifact: com.box:box-java-sdk version 10 or later (do NOT also add box-java-sdk-gen). Use BoxClient, BoxCCGAuth, CCGConfig, BoxAPIError, and the generated query types from that SDK (packages under com.box.sdkgen.schemas.v2026r0, lowercase r0). Also use spring-boot-starter-web, a test starter such as spring-boot-starter-test, and me.paulschwarz:spring-dotenv so a tutorial .env file is loaded — Spring Boot does not read .env by itself.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`The tutorial's samples are Python; use the Java equivalent of the same call. Call client.getQuery().createQueryInsightV2026R0(new QueryInsightsRequestBodyV2026R0(query, metrics)). That request body has no builder — pass the query and metrics map to the constructor. Build the query with new QueryInsightsRequestBodyV2026R0QueryField.Builder(predicate).params(...).ancestors(...).groupBy(...).build(). Ancestors are new QueryAncestorReferenceV2026R0(folderId, \"folder\"). Group-by is new QueryInsightsGroupByV2026R0.Builder(field).bucketLimit(n).build(). Each metric is new QueryInsightsMetricDefinitionV2026R0(QueryInsightsMetricDefinitionV2026R0TypeField.AVG, field) — that class also has no builder. Import these types from their generated packages under com.box.sdkgen.schemas.v2026r0 (lowercase r0), for example com.box.sdkgen.schemas.v2026r0.queryinsightsrequestbodyv2026r0. Entry types are EnumWrapper values: compare entry.getType().getEnumValue() to QueryInsightEntryV2026R0TypeField.OVERALL, GROUP, or OTHER, and read metrics with getMetrics().get(alias).getValues().get(metricType). Build auth with new BoxCCGAuth(new CCGConfig.Builder(clientId, clientSecret).enterpriseId(enterpriseId).build()) and new BoxClient(auth). Errors are BoxAPIError; read getResponseInfo().getStatusCode() and getResponseInfo().getCode(). In tests, deserialize with JsonManager.deserialize(JsonManager.jsonToSerializedData(json), QueryInsightsV2026R0.class) — deserialize takes a JsonNode, not a raw String. Confirm the builder and getter names against the installed SDK before writing code. Build the client with BoxCCGAuth and CCGConfig using the enterprise ID. Catch BoxAPIError and check getResponseInfo().getStatusCode() to distinguish the documented status codes. Adapt the HTTP layer to Spring Web (@RestController) and keep the server on port 5000 (server.port=5000).`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a Box client configuration/bean, a ReportService with the count, value statistics, and grouped queries, and a dashboard controller exposing GET /dashboard plus GET /healthz`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` an idiomatic Spring Boot layout; keep Box client configuration and the report logic in dedicated classes separate from the HTTP controller`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use the default Maven or Gradle test classpath so ReportService tests compile and run. Keep parsing tests as plain unit tests (do not start a Spring context) so they pass without BOX_* environment variables. Run the tests before you finish`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})}),_jsx(`div`,{\"data-agent-stack\":`Java||Quarkus`,hidden:true,children:_jsx(CodeBlock,{filename:`Java + Quarkus`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use Java 17+ with Quarkus. Use Maven or Gradle and exactly one Box artifact: com.box:box-java-sdk version 10 or later (do NOT also add box-java-sdk-gen). Use BoxClient, BoxCCGAuth, CCGConfig, BoxAPIError, and the generated query types from that SDK (packages under com.box.sdkgen.schemas.v2026r0, lowercase r0). Also use quarkus-rest-jackson (or quarkus-resteasy-jackson) and quarkus-junit5 for tests. Quarkus loads a project .env file natively — keep the tutorial variable names.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`The tutorial's samples are Python; use the Java equivalent of the same call. Call client.getQuery().createQueryInsightV2026R0(new QueryInsightsRequestBodyV2026R0(query, metrics)). That request body has no builder — pass the query and metrics map to the constructor. Build the query with new QueryInsightsRequestBodyV2026R0QueryField.Builder(predicate).params(...).ancestors(...).groupBy(...).build(). Ancestors are new QueryAncestorReferenceV2026R0(folderId, \"folder\"). Group-by is new QueryInsightsGroupByV2026R0.Builder(field).bucketLimit(n).build(). Each metric is new QueryInsightsMetricDefinitionV2026R0(QueryInsightsMetricDefinitionV2026R0TypeField.AVG, field) — that class also has no builder. Import these types from their generated packages under com.box.sdkgen.schemas.v2026r0 (lowercase r0), for example com.box.sdkgen.schemas.v2026r0.queryinsightsrequestbodyv2026r0. Entry types are EnumWrapper values: compare entry.getType().getEnumValue() to QueryInsightEntryV2026R0TypeField.OVERALL, GROUP, or OTHER, and read metrics with getMetrics().get(alias).getValues().get(metricType). Build auth with new BoxCCGAuth(new CCGConfig.Builder(clientId, clientSecret).enterpriseId(enterpriseId).build()) and new BoxClient(auth). Errors are BoxAPIError; read getResponseInfo().getStatusCode() and getResponseInfo().getCode(). In tests, deserialize with JsonManager.deserialize(JsonManager.jsonToSerializedData(json), QueryInsightsV2026R0.class) — deserialize takes a JsonNode, not a raw String. Confirm the builder and getter names against the installed SDK before writing code. Build the client with BoxCCGAuth and CCGConfig using the enterprise ID. Catch BoxAPIError and check getResponseInfo().getStatusCode() to distinguish the documented status codes. Adapt the HTTP layer to Quarkus REST and keep the server on port 5000 (quarkus.http.port=5000).`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a Box client producer/bean, a ReportService with the count, value statistics, and grouped queries, and a JAX-RS resource exposing GET /dashboard plus GET /healthz`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` an idiomatic Quarkus layout; keep the Box client and report logic in dedicated beans separate from the JAX-RS resource`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use the default Maven or Gradle test classpath so ReportService tests compile and run. Keep parsing tests as plain unit tests (do not start a Quarkus test profile that constructs BoxClient) so they pass without BOX_* environment variables. Run the tests before you finish`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})}),_jsx(`div`,{\"data-agent-stack\":`.NET||ASP.NET Core`,hidden:true,children:_jsx(CodeBlock,{filename:`.NET + ASP.NET Core`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use .NET 8+ with ASP.NET Core controllers. Use NuGet and exactly one Box package: Box.V2.Core version 10 or later (do NOT also install Box.Sdk.Gen — v10 of Box.V2.Core already ships the generated client). Use BoxClient, BoxCcgAuth, CcgConfig, and BoxApiException from Box.Sdk.Gen. Also add xUnit and DotNetEnv — ASP.NET Core does not load a tutorial .env file by itself.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`The tutorial's samples are Python; use the .NET equivalent of the same call. Call await client.Query.CreateQueryInsightV2026R0Async(new QueryInsightsRequestBodyV2026R0(query, metrics)). Build the query with new QueryInsightsRequestBodyV2026R0QueryField(predicate) { Parameters = ..., Ancestors = ..., GroupBy = ... }. The predicate params map is Parameters because params is a C# keyword. Group-by is new QueryInsightsGroupByV2026R0(field) { BucketLimit = n }. Each metric is new QueryInsightsMetricDefinitionV2026R0(QueryInsightsMetricDefinitionV2026R0TypeField.Avg, field). Ancestors are new QueryAncestorReferenceV2026R0(folderId, \"folder\"). Types live in Box.Sdk.Gen and Box.Sdk.Gen.Schemas and ship inside Box.V2.Core — do not add a second Box.Sdk.Gen package. Entry types are StringEnum values: compare entry.Type.Value to QueryInsightEntryV2026R0TypeField.Overall, Group, or Other, and read metrics with entry.Metrics[alias].Values[metricType]. Build auth with new BoxCcgAuth(new CcgConfig(clientId, clientSecret) { EnterpriseId = enterpriseId }) and new BoxClient(auth). The CcgConfig third constructor argument is tokenStorage, not the enterprise ID. Errors are BoxApiException; read ResponseInfo.StatusCode and ResponseInfo.Code. In tests, deserialize with System.Text.Json.JsonSerializer.Deserialize\u003cQueryInsightsV2026R0>(json) — SimpleJsonSerializer is internal. Qualify System.IO.File because Box.Sdk.Gen.Schemas.File conflicts with it. Confirm the property names against the installed SDK before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID. All SDK calls are async — await them and keep controller actions async. Call DotNetEnv.Env.Load() at startup, bind with builder.WebHost.UseUrls(\"http://127.0.0.1:5000\"), skip UseHttpsRedirection, and run with --no-launch-profile (or edit launchSettings.json). The webapi template otherwise listens on 5020/7060 and enables HTTPS, so curl to port 5000 fails.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a Box client factory/service, a ReportService with the count, value statistics, and grouped queries, and a dashboard controller exposing GET /dashboard plus GET /healthz`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` an idiomatic ASP.NET Core layout; keep the Box client and report logic in dedicated services separate from the HTTP controller`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Reference the app project from the test project so ReportService tests build. Keep parsing tests as plain xUnit tests (do not start a WebApplicationFactory that constructs BoxClient) so they pass without BOX_* environment variables. Copy fixture files to the test output directory. Run the tests before you finish`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})}),_jsx(`div`,{\"data-agent-stack\":`.NET||Minimal APIs`,hidden:true,children:_jsx(CodeBlock,{filename:`.NET + Minimal APIs`,numberOfLines:`99`,language:`markdown`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`markdown`,children:_jsxs(_components.code,{language:`markdown`,numberOfLines:`99`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Build a production-minded contract analytics dashboard by following this Box tutorial:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`https://developer.box.com/tutorials/query-insights`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Use .NET 8+ with ASP.NET Core Minimal APIs. Use NuGet and exactly one Box package: Box.V2.Core version 10 or later (do NOT also install Box.Sdk.Gen — v10 of Box.V2.Core already ships the generated client). Use BoxClient, BoxCcgAuth, CcgConfig, and BoxApiException from Box.Sdk.Gen. Also add xUnit and DotNetEnv — ASP.NET Core does not load a tutorial .env file by itself.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Prerequisites already done in Box (see 'Before you start' in the tutorial).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Do NOT try to create these; read their values from environment variables:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise metadata template key: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (fields contractType as enum with Sales and Renewal, contractValue as float).`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` If a template with that key already exists and contractType is a string, group_by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` returns 400 — use a different TEMPLATE_KEY whose contractType is an enum.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Contracts folder ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. CCG stores this folder in the app service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, not the developer's personal All Files. The service account must`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` be able to read it (Viewer or higher). Do not fail the project if the developer`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cannot see the folder in their own Box web app.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Enterprise ID: `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CCG app scopes enabled: Read and write all files and folders stored in Box`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`The tutorial's samples are Python; use the .NET equivalent of the same call. Call await client.Query.CreateQueryInsightV2026R0Async(new QueryInsightsRequestBodyV2026R0(query, metrics)). Build the query with new QueryInsightsRequestBodyV2026R0QueryField(predicate) { Parameters = ..., Ancestors = ..., GroupBy = ... }. The predicate params map is Parameters because params is a C# keyword. Group-by is new QueryInsightsGroupByV2026R0(field) { BucketLimit = n }. Each metric is new QueryInsightsMetricDefinitionV2026R0(QueryInsightsMetricDefinitionV2026R0TypeField.Avg, field). Ancestors are new QueryAncestorReferenceV2026R0(folderId, \"folder\"). Types live in Box.Sdk.Gen and Box.Sdk.Gen.Schemas and ship inside Box.V2.Core — do not add a second Box.Sdk.Gen package. Entry types are StringEnum values: compare entry.Type.Value to QueryInsightEntryV2026R0TypeField.Overall, Group, or Other, and read metrics with entry.Metrics[alias].Values[metricType]. Build auth with new BoxCcgAuth(new CcgConfig(clientId, clientSecret) { EnterpriseId = enterpriseId }) and new BoxClient(auth). The CcgConfig third constructor argument is tokenStorage, not the enterprise ID. Errors are BoxApiException; read ResponseInfo.StatusCode and ResponseInfo.Code. In tests, deserialize with System.Text.Json.JsonSerializer.Deserialize\u003cQueryInsightsV2026R0>(json) — SimpleJsonSerializer is internal. Qualify System.IO.File because Box.Sdk.Gen.Schemas.File conflicts with it. Confirm the property names against the installed SDK before writing code. Build the client with BoxCcgAuth and CcgConfig using the enterprise ID. All SDK calls are async — await them inside the endpoint delegates. Call DotNetEnv.Env.Load() at startup, bind with builder.WebHost.UseUrls(\"http://127.0.0.1:5000\"), skip UseHttpsRedirection, and run with --no-launch-profile (or edit launchSettings.json). The webapi template otherwise listens on 5020/7060 and enables HTTPS, so curl to port 5000 fails.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`The app must:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`1.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Authenticate to Box with Client Credentials Grant (enterprise / service account).`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Use BOX_ENTERPRISE_ID — do NOT authenticate as a managed user.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`2.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Call the Box Query Insights API through the SDK's query manager method named above.`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` That method targets the v2026.0 API and sends the required box-version: 2026.0 header`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` for you. Do not hand-roll the HTTP call, do not set the version header yourself, and do`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` not manage access tokens — the SDK's CCG auth handles refresh and retries.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`3.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Build fully qualified field references from the template key and enterprise ID:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref is enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` and a field ref is`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`fieldKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#808080`},children:`>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`. Read TEMPLATE_REF,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE from the environment when they are set;`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` otherwise derive them from the field keys contractType and contractValue.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`4.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a count query: predicate EXISTS(:templateArg) with params templateArg set to the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template ref, ancestors set to the folder ID with type folder, and an empty metrics map.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` An empty metrics map returns the default totalResultCount metric.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`5.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a value statistics query: avg, min, and max metrics on the contract value field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filtered by EXISTS(:templateArg) AND box:item:created_at >= :startDate AND`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box:item:created_at \u003c :endDate. Accept the date range as input; use RFC 3339 timestamps.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`6.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Expose a grouped query for charts: group by the contract type enum field with a bucket`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit, plus a sum metric on contract value and a count metric on contract type. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group on a free-text string field — Query Insights returns 400 Invalid query request.`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Present the buckets in the order the API returns them; do not re-sort them client-side,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` because re-sorting would misrepresent which buckets the other rollup excluded.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`7.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Parse the response by entry type, not by array position. Each entry has a type of`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall, group, or other:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall: read metric values directly; the key is always empty`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` group: use the first key value as the bucket label`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` other: read the count from the totalCountBeyondTopGroups alias, not your own alias`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Each metric value is nested under values and keyed by the metric type, so an avg metric`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` exposes values.avg and a sum metric exposes values.sum. Buckets are always ordered by`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` document count descending; that order cannot be customized.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`8.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Check the documented API limits before sending a request and fail fast with a clear`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` message, so a bad request never reaches Box:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` only one group-by field per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` bucket limit defaults to 5, maximum 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` maximum 10 metrics per request`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:` -`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` each metric alias must start with a letter and contain only letters, digits,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` underscores, hyphens, and periods (maximum 256 characters)`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Document, but do not try to validate, the guidance that grouped fields should stay below`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` 10,000 distinct values — cardinality is a server-side property you cannot check locally.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`9.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Catch the SDK's Box API error type, read the HTTP status off it, and report 400`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BAD_REQUEST (predicate or param type problem), 403 FORBIDDEN (missing scope or`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` inaccessible ancestor), 404 INSTANCE_NOT_FOUND (wrong template ref), and 429`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` RATE_LIMIT_EXCEEDED distinctly, so the message tells the developer what to fix. Do not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` add your own retry loop: the SDK already retries 429 and 5xx with backoff and refreshes`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` expired tokens, and a second layer would multiply the wait.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`10.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Fetch each aggregate once per report run and reuse the result rather than calling the`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` API again for every panel. Add a short-TTL cache only if your stack serves repeated`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` requests (a web layer or a refresh loop); a script that exits after printing does not`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` need one. Note in the README that Box Query Insights API reads a metadata index that`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` updates shortly after content is tagged, so a metric can return 0 immediately after`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` tagging.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Read configuration from the same environment variables the tutorial uses, so a .env file`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`written for one path works for the other:`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`BOX_CLIENT_ID, BOX_CLIENT_SECRET, BOX_ENTERPRISE_ID, TEMPLATE_KEY, FOLDER_ID, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`optionally TEMPLATE_REF, FIELD_CONTRACT_TYPE, and FIELD_CONTRACT_VALUE.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Create a complete runnable project with:`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a Box client factory, a ReportService with the count, value statistics, and grouped queries, and Program.cs with MapGet(\"/dashboard\", ...) plus MapGet(\"/healthz\", ...)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` an idiomatic Minimal APIs layout (MapGet in Program.cs); keep the Box client and report logic in dedicated classes separate from endpoint mapping`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dependency and run commands`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` .env.example and .gitignore files`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a sample console or JSON report that shows the total contract count, the average,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` minimum, and maximum contract value, and the top contract types with the total value and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count of each. The other rollup carries only a count, so leave its value column empty`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rather than reporting a total for it.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` focused unit tests that assert response parsing for the overall, group, and other entry`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` types against recorded sample payloads (do not call Box in tests)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` Reference the app project from the test project so ReportService tests build. Keep parsing tests as plain xUnit tests (do not start a WebApplicationFactory that constructs BoxClient) so they pass without BOX_* environment variables. Copy fixture files to the test output directory. Run the tests before you finish`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#6796E6`},children:`-`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` a README with setup, run, and test steps. State that CCG content lives in the service`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` account root, that Query Insights can return 0 until the metadata index updates, and`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` that group_by requires an enum contractType`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`After you write the files, run the test command and fix any import or parse failures`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`before you stop. Do not call Box from tests. Do not require a filled .env for tests`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`to pass.`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`Never hard-code credentials. Add concise comments only where the Box-specific behavior is not obvious. Before writing code, summarize the architecture and list the files you will create.`})}),`\n`]})})})})]}),_jsx(`p`,{className:`mint-mt-4 mint-mb-0 mint-text-sm mint-leading-6 mint-text-gray-500 dark:mint-text-gray-400`,children:_jsx(_components.p,{children:`Review generated code before using it in production. Never paste Box credentials into your\ncoding agent.`})})]}),`\n`,_jsxs(_components.p,{children:[`When the agent finishes, copy `,_jsx(_components.code,{children:`.env.example`}),` to `,_jsx(_components.code,{children:`.env`}),` and fill in your client ID, client secret, enterprise ID, metadata template key, and folder ID. Use a template whose `,_jsx(_components.code,{children:`contractType`}),` is an enum. Grouping on a free-text string field returns `,_jsx(_components.code,{children:`400 Invalid query request`}),`. A CCG app stores the contracts folder in the service account root, so the folder does not display in your personal `,_jsx(_components.strong,{children:`All Files`}),`. Then skip ahead to `,_jsx(_components.a,{href:`#run-and-verify`,children:`Run and verify`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Prefer to write the code yourself? See `,_jsx(_components.a,{href:`#build-by-hand`,children:`Build by hand`}),` below.`]}),`\n`,_jsx(Heading,{level:`2`,id:`build-by-hand`,children:`Build by hand`}),`\n`,_jsxs(Steps,{children:[_jsxs(Step,{title:`Set up the development environment`,children:[_jsxs(_components.ol,{children:[`\n`,_jsx(_components.li,{children:`Create a project directory and virtual environment:`}),`\n`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`mkdir`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` contract-insights`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` \u0026\u0026 `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`cd`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` contract-insights`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`python3`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -m`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` venv`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` .venv`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`source`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` .venv/bin/activate`})]}),`\n`]})})}),_jsxs(_components.ol,{start:`2`,children:[`\n`,_jsx(_components.li,{children:`Install the required packages:`}),`\n`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`pip`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` install`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` boxsdk`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` python-dotenv`})]}),`\n`]})})}),_jsxs(_components.ol,{start:`3`,children:[`\n`,_jsxs(_components.li,{children:[`Create a `,_jsx(_components.code,{children:`.env`}),` file with your application credentials. Fill in the first three Client Credentials Grant values now – you add the folder and template values in the next step:`]}),`\n`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`BOX_CLIENT_ID`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`your_client_id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`BOX_CLIENT_SECRET`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`your_client_secret`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`BOX_ENTERPRISE_ID`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`your_enterprise_id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`FOLDER_ID`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`your_folder_id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`sales`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`TEMPLATE_REF`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`your_template_ref`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`FIELD_CONTRACT_TYPE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`your_contract_type_field`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`FIELD_CONTRACT_VALUE`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`your_contract_value_field`})]}),`\n`]})})}),_jsx(Warning,{children:_jsxs(_components.p,{children:[`Add `,_jsx(_components.code,{children:`.env`}),` to `,_jsx(_components.code,{children:`.gitignore`}),`. Never commit credentials to version control.`]})})]}),_jsxs(Step,{title:`Authenticate the Box client`,children:[_jsxs(_components.p,{children:[`Create `,_jsx(_components.code,{children:`box_client.py`}),`. Every other module imports `,_jsx(_components.code,{children:`get_box_client`}),` from here, so the credentials live in one place:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`17`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`17`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` os`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box_sdk_gen `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BoxCCGAuth, BoxClient, CCGConfig`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dotenv `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` load_dotenv`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`load_dotenv()`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` get_box_client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`() -> BoxClient:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` auth `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BoxCCGAuth(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` config`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`CCGConfig(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` client_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`os.environ[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"BOX_CLIENT_ID\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` client_secret`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`os.environ[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"BOX_CLIENT_SECRET\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` enterprise_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`os.environ[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"BOX_ENTERPRISE_ID\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BoxClient(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`auth`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`auth)`})]}),`\n`]})})}),_jsxs(_components.p,{children:[_jsx(_components.code,{children:`BoxCCGAuth`}),` fetches and refreshes the access token for you, so you never manage the token endpoint directly.`]}),_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`BOX_ENTERPRISE_ID`}),` must be the numeric enterprise ID from `,_jsx(_components.strong,{children:`Developer Console > Configuration > App Details`}),`. Pasting a client ID or client secret here fails with `,_jsx(_components.code,{children:`invalid_grant: Grant credentials are invalid`}),`.`]})}),_jsxs(_components.p,{children:[`The remaining steps call `,_jsx(_components.code,{children:`client.query.create_query_insight_v2026_r0`}),`, which sends `,_jsx(_components.code,{children:`POST https://api.box.com/2.0/query_insights`}),` with the `,_jsx(_components.code,{children:`box-version: 2026.0`}),` header. Because the method is generated from the API spec, you pass typed request objects and read a typed `,_jsx(_components.code,{children:`QueryInsightsV2026R0`}),` result instead of assembling JSON by hand.`]})]}),_jsxs(Step,{title:`Create a metadata template and sample data`,children:[_jsxs(_components.p,{children:[`Create `,_jsx(_components.code,{children:`setup_test_data.py`}),` to create the `,_jsx(_components.code,{children:`sales`}),` metadata template, a folder, and a few tagged sample contracts. It reuses `,_jsx(_components.code,{children:`get_box_client`}),` from the previous step:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`214`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`214`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` io`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` os`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box_sdk_gen `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BoxAPIError,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BoxClient,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateFileMetadataByIdScope,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateFolderParent,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateMetadataTemplateFields,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateMetadataTemplateFieldsOptionsField,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateMetadataTemplateFieldsTypeField,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` GetMetadataTemplateScope,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UpdateFileMetadataByIdRequestBody,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UpdateFileMetadataByIdRequestBodyOpField,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UpdateFileMetadataByIdScope,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UpdateMetadataTemplateRequestBody,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UpdateMetadataTemplateRequestBodyOpField,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UpdateMetadataTemplateScope,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UploadFileAttributes,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UploadFileAttributesParentField,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` dotenv `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` load_dotenv`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box_client `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` get_box_client`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`load_dotenv()`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` os.environ.get(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"TEMPLATE_KEY\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`or`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"sales\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM_FIELD_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"contractType\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM_FALLBACK_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"contractTypeEnum\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`FOLDER_NAME`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Sales Contracts\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`SAMPLE_CONTRACTS`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Contract 1\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractType\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Sales\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`100000`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`},`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Contract 2\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractType\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Sales\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`200000`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`},`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Contract 3\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractType\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Renewal\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`150000`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`},`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Contract 4\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractType\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Renewal\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`45000`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`},`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` _enum_field_key`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`template`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` |`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` None`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` fields `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {field.key: field `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` field `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (template.fields `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`or`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [])}`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` key `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM_FIELD_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM_FALLBACK_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`):`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` field `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` fields.get(key)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` field `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`and`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`getattr`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(field.type, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"value\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, field.type)) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`==`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"enum\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` key`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` None`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` _add_enum_field`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: BoxClient) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`None`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.metadata_templates.update_metadata_template(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UpdateMetadataTemplateScope.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENTERPRISE`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UpdateMetadataTemplateRequestBody(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` op`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`UpdateMetadataTemplateRequestBodyOpField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ADDFIELD`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` data`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"enum\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"key\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM_FALLBACK_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"displayName\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Contract type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"options\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [{`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"key\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Sales\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}, {`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"key\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Renewal\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ],`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` ensure_template`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: BoxClient) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"\"\"Create the template if needed, then return the field to group on.\"\"\"`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` try`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.metadata_templates.create_metadata_template(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` scope`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"enterprise\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` display_name`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Sales Contracts\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` template_key`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` fields`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateMetadataTemplateFields(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`CreateMetadataTemplateFieldsTypeField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` key`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM_FIELD_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` display_name`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Contract type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` options`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateMetadataTemplateFieldsOptionsField(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`key`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Sales\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateMetadataTemplateFieldsOptionsField(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`key`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Renewal\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ],`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateMetadataTemplateFields(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`CreateMetadataTemplateFieldsTypeField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`FLOAT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` key`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` display_name`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Contract value\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ],`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` ENUM_FIELD_KEY`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` except`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BoxAPIError:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` pass`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # The template already exists. Box Query Insights API groups on enum`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # fields only, so reuse an existing enum or add one now. Otherwise the`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # grouped query fails later with 400 Invalid query request.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.metadata_templates.get_metadata_template(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` GetMetadataTemplateScope.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENTERPRISE`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`TEMPLATE_KEY`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` type_field `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` _enum_field_key(template)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` type_field `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`is`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` None`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` _add_enum_field(client)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` type_field `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` ENUM_FALLBACK_KEY`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`.`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM_FIELD_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`' is not an enum. \"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Added enum field '`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM_FALLBACK_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`' to group on.\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` elif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` type_field `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` ENUM_FIELD_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"'`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`.`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM_FIELD_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`' is not an enum. \"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Grouping on existing enum field '`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`type_field`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'.\"`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` type_field`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` ensure_folder`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: BoxClient) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` item `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.folders.get_folder_items(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"0\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`).entries:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` item.type `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`==`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"folder\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` and`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` item.name `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`==`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` FOLDER_NAME`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` item.id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` folder `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.folders.create_folder(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` name`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`FOLDER_NAME`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`parent`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`CreateFolderParent(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"0\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` folder.id`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` existing_files`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: BoxClient, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`folder_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> dict[`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` files: dict[`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`] `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {}`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` offset `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 0`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 1000`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` while`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` True`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` items `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.folders.get_folder_items(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` folder_id, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`limit`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`limit, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`offset`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`offset`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` entries `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` items.entries `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`or`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` []`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` item `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` entries:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` item.type `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`==`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"file\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` files[item.name] `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` item.id`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` len`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(entries) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` break`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` offset `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`+=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` limit`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` files`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` apply_metadata`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: BoxClient, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`file_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`payload`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`dict`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`None`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` try`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.file_metadata.create_file_metadata_by_id(`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` file_id,`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateFileMetadataByIdScope.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENTERPRISE`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` payload,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` except`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BoxAPIError `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`as`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` error:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` error.response_info.status_code `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 409`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` raise`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.file_metadata.update_file_metadata_by_id(`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` file_id,`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UpdateFileMetadataByIdScope.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENTERPRISE`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` UpdateFileMetadataByIdRequestBody(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` op`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`UpdateFileMetadataByIdRequestBodyOpField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ADD`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` path`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"/`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`key`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` value`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`value,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` key, value `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` payload.items()`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ],`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` _metadata_payload`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`contract`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`dict`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`type_field`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`dict`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` payload `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` type_field: contract[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractType\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"contractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: contract[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` type_field `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` ENUM_FIELD_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # Keep the original string field populated so both stay in sync.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` payload[`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`ENUM_FIELD_KEY`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`] `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` contract[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contractType\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` payload`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` upload_contracts`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: BoxClient, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`folder_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`type_field`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`None`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` existing `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` existing_files(client, folder_id)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` contract `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:` SAMPLE_CONTRACTS`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` filename `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`contract[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'name'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`.txt\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` payload `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` _metadata_payload(contract, type_field)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` file_id `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` existing.get(filename)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` file_id `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`is`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` None`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` uploaded `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.uploads.upload_file(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` attributes`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`UploadFileAttributes(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` name`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`filename,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` parent`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`UploadFileAttributesParentField(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`folder_id),`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` file`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`io.BytesIO(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`b`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Sample contract for Box Query Insights API.\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` file_id `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` uploaded.entries[`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`].id`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` apply_metadata(client, file_id, payload)`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`if`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` __name__`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ==`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"__main__\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` get_box_client()`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` enterprise_id `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` os.environ[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"BOX_ENTERPRISE_ID\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` type_field `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ensure_template(client)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` folder_id `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ensure_folder(client)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` upload_contracts(client, folder_id, type_field)`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template_ref `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"enterprise_`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`enterprise_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Add these values to your .env file:\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"FOLDER_ID=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`folder_id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"TEMPLATE_KEY=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`TEMPLATE_KEY`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"TEMPLATE_REF=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`template_ref`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"FIELD_CONTRACT_TYPE=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`template_ref`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`type_field`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"FIELD_CONTRACT_VALUE=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`template_ref`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`:contractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`]})})}),_jsxs(_components.p,{children:[`Run the script, then copy the printed values into your `,_jsx(_components.code,{children:`.env`}),` file:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`python`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` setup_test_data.py`})]}),`\n`]})})}),_jsx(_components.p,{children:`Alternatively, you can point the tutorial at an existing template.`}),_jsx(_components.p,{children:`The Box Query Insights API can group on enum fields, not free-text string fields:`}),_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`contractType`}),` (enum, for example, Sales and Renewal)`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`contractValue`}),` (float)`]}),`\n`]}),_jsx(_components.p,{children:`The script is safe to run more than once. It reuses the template and folder, skips uploading a sample file whose name already exists, and falls back to a JSON-Patch update when a file already carries the template. Box Query Insights API reads a metadata index that updates shortly after you tag content. If a metric returns 0 right after setup, wait a minute and run the reporting steps again.`}),_jsx(Warning,{children:_jsxs(_components.p,{children:[`If a `,_jsx(_components.code,{children:`sales`}),` template already exists whose `,_jsx(_components.code,{children:`contractType`}),` is a free-text string, the script adds an enum field named `,_jsx(_components.code,{children:`contractTypeEnum`}),` and prints it as your `,_jsx(_components.code,{children:`FIELD_CONTRACT_TYPE`}),`. Copy whichever field key the script prints. Grouping on a string field returns `,_jsx(_components.code,{children:`400 Invalid query request`}),`.`]})}),_jsx(Note,{children:_jsxs(_components.p,{children:[`A Client Credentials Grant app acts as a service account with its own folder tree, so `,_jsx(_components.code,{children:`Sales Contracts`}),` does not display in your personal `,_jsx(_components.strong,{children:`All Files`}),`. To see it, collaborate yourself on the folder using the service account email from `,_jsx(_components.strong,{children:`Developer Console > App Details`}),`, or open the content as an admin in Content Manager.`]})})]}),_jsxs(Step,{title:`Count matching contracts`,children:[_jsxs(_components.p,{children:[`Create `,_jsx(_components.code,{children:`reports.py`}),` with the queries that power your dashboard. Pass an empty `,_jsx(_components.code,{children:`metrics`}),` map to get the default `,_jsx(_components.code,{children:`totalResultCount`}),` metric across all items that match your filter.`]}),_jsxs(_components.p,{children:[`Every metric result nests its value under `,_jsx(_components.code,{children:`values`}),`, keyed by the metric type, so `,_jsx(_components.code,{children:`metric.values[metric.type]`}),` reads the value without hard-coding the type. The remaining steps use the same pattern.`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`31`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`31`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box_sdk_gen `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` BoxClient,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateQueryInsightV2026R0Query,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` QueryAncestorReferenceV2026R0,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` QueryInsightEntryV2026R0TypeField,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` QueryInsightsGroupByV2026R0,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` QueryInsightsMetricDefinitionV2026R0,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` QueryInsightsMetricDefinitionV2026R0TypeField,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` QueryInsightsV2026R0,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` overall_entry`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`result`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: QueryInsightsV2026R0):`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` next`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` entry`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` entry `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` result.insights`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` entry.type `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`==`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` QueryInsightEntryV2026R0TypeField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`OVERALL`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` count_contracts`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: BoxClient, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`template_ref`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`folder_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`float`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` result `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.query.create_query_insight_v2026_r0(`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateQueryInsightV2026R0Query(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` predicate`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"EXISTS(:templateArg)\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` params`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"templateArg\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: template_ref},`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` ancestors`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[QueryAncestorReferenceV2026R0(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`folder_id, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"folder\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {},`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` metric `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall_entry(result).metrics[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"totalResultCount\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` metric.values[metric.type]`})]}),`\n`]})})}),_jsx(_components.p,{children:`Equivalent cURL request:`}),_jsx(CodeBlock,{filename:``,numberOfLines:`12`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`12`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -X`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` POST`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"https://api.box.com/2.0/query_insights\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Authorization: Bearer `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`$ACCESS_TOKEN`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"box-version: 2026.0\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -H`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"Content-Type: application/json\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -d`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"query\": {`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"predicate\": \"EXISTS(:templateArg)\",`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"params\": { \"templateArg\": \"enterprise_12345678:sales\" },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"ancestors\": [{ \"id\": \"987654321\", \"type\": \"folder\" }]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"metrics\": {}`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` }'`})}),`\n`]})})}),_jsx(Note,{children:_jsxs(_components.p,{children:[`The `,_jsx(_components.code,{children:`box-version: 2026.0`}),` header is required. The SDK method sets it for you, so you only pass it when you call the endpoint directly.`]})})]}),_jsxs(Step,{title:`Compute overall contract value statistics`,children:[_jsxs(_components.p,{children:[`Add this function to `,_jsx(_components.code,{children:`reports.py`}),`, below `,_jsx(_components.code,{children:`count_contracts`}),`. It requests multiple metrics in one call to populate summary cards – average, minimum, and maximum deal size for contracts created in a date range.`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`41`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`41`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` contract_value_stats`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: BoxClient,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` template_ref`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` folder_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` value_field`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` start_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` end_date`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`dict`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` result `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.query.create_query_insight_v2026_r0(`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateQueryInsightV2026R0Query(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` predicate`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"EXISTS(:templateArg) AND \"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"box:item:created_at >= :startDate AND \"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"box:item:created_at \u003c :endDate\"`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` params`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"templateArg\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: template_ref,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"startDate\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: start_date,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"endDate\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: end_date,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` ancestors`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[QueryAncestorReferenceV2026R0(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`folder_id, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"folder\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"avgContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: QueryInsightsMetricDefinitionV2026R0(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`QueryInsightsMetricDefinitionV2026R0TypeField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`AVG`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` field`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`value_field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"minContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: QueryInsightsMetricDefinitionV2026R0(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`QueryInsightsMetricDefinitionV2026R0TypeField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`MIN`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` field`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`value_field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"maxContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: QueryInsightsMetricDefinitionV2026R0(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`QueryInsightsMetricDefinitionV2026R0TypeField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`MAX`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` field`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`value_field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` alias: metric.values[metric.type]`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` alias, metric `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` overall_entry(result).metrics.items()`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`]})})}),_jsxs(_components.p,{children:[`Because each metric result is keyed by its own type, the same `,_jsx(_components.code,{children:`metric.values[metric.type]`}),` lookup reads `,_jsx(_components.code,{children:`avg`}),`, `,_jsx(_components.code,{children:`min`}),`, and `,_jsx(_components.code,{children:`max`}),` without a branch per metric. The underlying response looks like this:`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`13`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`13`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"insights\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"key\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"overall\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"metrics\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"avgContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"avg\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"values\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"avg\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`45055.5`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"minContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"min\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"values\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"min\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`22000`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"maxContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"max\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"values\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"max\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`75000`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } }`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ]`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),_jsxs(_components.p,{children:[`See `,_jsx(_components.a,{href:`/guides/query/insights#overall-average-minimum-maximum-contract-value`,children:`Overall average, minimum, maximum contract value`}),` for the full request and response.`]})]}),_jsxs(Step,{title:`Group results for dashboard charts`,children:[_jsxs(_components.p,{children:[`Add this last function to `,_jsx(_components.code,{children:`reports.py`}),`. Grouping by a metadata field powers bar or pie charts. The API returns the top buckets ordered by document count (descending). Remaining groups are rolled into an `,_jsx(_components.code,{children:`other`}),` entry.`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`49`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`49`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` top_contract_types`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: BoxClient,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` template_ref`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` folder_id`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` type_field`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` value_field`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` bucket_limit`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`int`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 5`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> list[`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`dict`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` result `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client.query.create_query_insight_v2026_r0(`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` CreateQueryInsightV2026R0Query(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` predicate`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"EXISTS(:templateArg)\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` params`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"templateArg\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: template_ref},`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` ancestors`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[QueryAncestorReferenceV2026R0(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`folder_id, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"folder\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` group_by`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`[`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` QueryInsightsGroupByV2026R0(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` field`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`type_field, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`bucket_limit`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`bucket_limit`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ],`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"totalContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: QueryInsightsMetricDefinitionV2026R0(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`QueryInsightsMetricDefinitionV2026R0TypeField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`SUM`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` field`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`value_field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"countByType\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: QueryInsightsMetricDefinitionV2026R0(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` type`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`QueryInsightsMetricDefinitionV2026R0TypeField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`COUNT`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` field`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`type_field,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ),`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` groups `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` []`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` entry `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` result.insights:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` entry.type `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`==`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` QueryInsightEntryV2026R0TypeField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`GROUP`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` groups.append(`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"contract_type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: entry.key[`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"total_value\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: entry.metrics[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"totalContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`].values[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"sum\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"count\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: entry.metrics[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"countByType\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`].values[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"count\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` elif`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` entry.type `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`==`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` QueryInsightEntryV2026R0TypeField.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#D4D4D4`},children:`OTHER`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` groups.append(`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"contract_type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Other\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"count\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: entry.metrics[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"totalCountBeyondTopGroups\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`].values[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"count\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` groups`})]}),`\n`]})})}),_jsx(Tip,{children:_jsxs(_components.p,{children:[`Only one `,_jsx(_components.code,{children:`group_by`}),` field is supported per request, and `,_jsx(_components.code,{children:`bucket_limit`}),` defaults to 5 with a maximum of 10. Group on an enum field such as `,_jsx(_components.code,{children:`contractType`}),`. A free-text string field returns `,_jsx(_components.code,{children:`400 Invalid query request`}),`. Avoid grouping on high-cardinality fields – cardinality of 10,000 or above can cause errors.`]})})]}),_jsxs(Step,{title:`Combine metrics in a dashboard function`,children:[_jsxs(_components.p,{children:[`Create `,_jsx(_components.code,{children:`dashboard.py`}),` to wire the helpers together and print a console report you can adapt for a web dashboard or business intelligence export.`]}),_jsx(CodeBlock,{filename:``,numberOfLines:`93`,language:`python`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`python`,children:_jsxs(_components.code,{language:`python`,numberOfLines:`93`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` os`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` box_client `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` get_box_client`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` reports `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` contract_value_stats, count_contracts, top_contract_types`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` _format_cell`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`value`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` value `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`is`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` None`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"—\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` isinstance`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(value, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`float`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`and`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` value.is_integer():`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` value `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` int`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(value)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` isinstance`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(value, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`int`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`):`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`value`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:,}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` isinstance`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(value, `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`float`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`):`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` f`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`{`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`value`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`:,.2f}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(value)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` _print_table`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`headers`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: list[`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`], `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`rows`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: list[`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`list`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`None`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` str_rows `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [[_format_cell(cell) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cell `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` row] `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` row `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` rows]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` widths `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`len`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(header) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` header `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` headers]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` row `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` str_rows:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` index, cell `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` enumerate`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(row):`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` widths[index] `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` max`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(widths[index], `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`len`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(cell))`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` format_row`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`cells`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: list[`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` parts `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` []`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` index, cell `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` enumerate`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(cells):`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # Labels stay left-aligned; numeric columns stay right-aligned.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` aligned `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cell.ljust(widths[index])`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` if`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` index `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`==`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 0`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` else`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` cell.rjust(widths[index])`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` parts.append(aligned)`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` return`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \" \"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.join(parts)`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(format_row(headers))`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\" \"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.join(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"-\"`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` *`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` width `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` width `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` widths))`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` row `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` str_rows:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(format_row(row))`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`def`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` print_contract_dashboard`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` template_ref`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` type_field`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` value_field`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:`str`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) -> `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`None`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` get_box_client()`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` folder_id `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` os.environ[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"FOLDER_ID\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` total `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` count_contracts(client, template_ref, folder_id)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` stats `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` contract_value_stats(`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` template_ref,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` folder_id,`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` value_field,`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"2020-01-01T00:00:00Z\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"2030-01-01T00:00:00Z\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` groups `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` top_contract_types(`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` client, template_ref, folder_id, type_field, value_field`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Contract analytics dashboard\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` _print_table(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Metric\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Value\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Total contracts\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, total],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Average value\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, stats[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"avgContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Minimum value\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, stats[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"minContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Maximum value\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, stats[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"maxContractValue\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ],`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`()`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # Buckets arrive ordered by document count, so print them as returned.`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:` print`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Top contract types\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` _print_table(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Total value\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Count\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [row.get(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"contract_type\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`), row.get(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"total_value\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`), row.get(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"count\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` for`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` row `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`in`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` groups`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ],`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`if`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#9CDCFE`},children:` __name__`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` ==`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` \"__main__\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` print_contract_dashboard(`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` template_ref`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`os.environ[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"TEMPLATE_REF\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` type_field`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`os.environ[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"FIELD_CONTRACT_TYPE\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:` value_field`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`=`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`os.environ[`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"FIELD_CONTRACT_VALUE\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`],`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` )`})}),`\n`]})})})]})]}),`\n`,_jsx(Heading,{level:`2`,id:`run-and-verify`,children:`Run and verify`}),`\n`,_jsx(_components.p,{children:`Run the report against your own content to confirm that authentication, the template reference, and response parsing all work.`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Confirm your environment values.`}),` Your `,_jsx(_components.code,{children:`.env`}),` file needs the three Client Credentials Grant values plus `,_jsx(_components.code,{children:`FOLDER_ID`}),`, `,_jsx(_components.code,{children:`TEMPLATE_REF`}),`, `,_jsx(_components.code,{children:`FIELD_CONTRACT_TYPE`}),`, and `,_jsx(_components.code,{children:`FIELD_CONTRACT_VALUE`}),`. The setup script in `,_jsx(_components.a,{href:`#build-by-hand`,children:`Create a metadata template and sample data`}),` prints the last four values for you.`]}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Run the report.`}),` Activate your virtual environment first, then use the command for your path:`]}),`\n`,_jsxs(CodeGroup,{children:[_jsx(CodeBlock,{filename:`Build by hand`,numberOfLines:`3`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`cd`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` contract-insights`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`source`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` .venv/bin/activate`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`python`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` dashboard.py`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`Agent`,numberOfLines:`7`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`7`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Console script: run the entry point the agent created`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`cd`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` contract-insights`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#DCDCAA`},children:`source`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` .venv/bin/activate`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`python`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` dashboard.py`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# Flask, FastAPI, Express, Fastify, Spring Boot, or ASP.NET Core: start the server, then query it from a second terminal`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`curl`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` http://127.0.0.1:5000/dashboard`})]}),`\n`]})})})]}),`\n`,_jsx(_components.p,{children:`If you built with an agent, check the README it generated for the exact module and run command.`}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Check the output.`}),` With the four sample contracts from the setup step, the console report looks like this:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`15`,language:`text`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`text`,children:_jsxs(_components.code,{language:`text`,numberOfLines:`15`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Contract analytics dashboard`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Metric Value`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`--------------- -------`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Total contracts 4`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Average value 123,750`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Minimum value 45,000`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Maximum value 200,000`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Top contract types`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Type Total value Count`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`------- ----------- -----`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Sales 300,000 2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{children:`Renewal 195,000 2`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{})})]})})}),`\n`,_jsx(_components.p,{children:`Buckets are ordered by document count in descending order, so your group order varies with your own data.`}),`\n`]}),`\n`,_jsxs(_components.li,{children:[`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Cross-check one number in Box.`}),` Open the contracts folder in Box and count the files that carry your metadata template. That count matches `,_jsx(_components.code,{children:`Total contracts`}),` from step 3, which confirms your `,_jsx(_components.code,{children:`ancestors`}),` filter and template reference point at the content you expect.`]}),`\n`]}),`\n`]}),`\n`,_jsx(Note,{children:_jsxs(_components.p,{children:[`A metric of 0 right after you tag content usually means the metadata index has not caught up yet. Wait a minute and run the report again. For other symptoms, see `,_jsx(_components.a,{href:`#troubleshooting`,children:`Troubleshooting`}),`.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`response-entry-types`,children:`Response entry types`}),`\n`,_jsxs(_components.p,{children:[`Every insight in the response has a `,_jsx(_components.code,{children:`type`}),` that tells you how to interpret it.`]}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Type`}),_jsx(_components.th,{children:`When it displays`}),_jsx(_components.th,{children:`How to use it`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`overall`})}),_jsxs(_components.td,{children:[`No `,_jsx(_components.code,{children:`group_by`}),`, or global metric row`]}),_jsxs(_components.td,{children:[`Read metric values directly from `,_jsx(_components.code,{children:`metrics`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`group`})}),_jsxs(_components.td,{children:[`Top buckets from `,_jsx(_components.code,{children:`group_by`})]}),_jsxs(_components.td,{children:[`Use `,_jsx(_components.code,{children:`key[0]`}),` as the group label (for example, contract type)`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`other`})}),_jsxs(_components.td,{children:[`Groups outside the top `,_jsx(_components.code,{children:`bucket_limit`})]}),_jsxs(_components.td,{children:[`Read `,_jsx(_components.code,{children:`totalCountBeyondTopGroups`}),` for the remaining document count`]})]})]})]}),`\n`,_jsx(_components.p,{children:`For grouped requests, buckets are always sorted by document count in descending order. You cannot customize sort order.`}),`\n`,_jsx(Heading,{level:`2`,id:`troubleshooting`,children:`Troubleshooting`}),`\n`,_jsxs(Table,{children:[_jsx(_components.thead,{children:_jsxs(_components.tr,{children:[_jsx(_components.th,{children:`Symptom`}),_jsx(_components.th,{children:`Likely cause`}),_jsx(_components.th,{children:`What to do`})]})}),_jsxs(_components.tbody,{children:[_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`KeyError`}),` on an environment variable`]}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`.env`}),` not created, or placeholders not replaced`]}),_jsxs(_components.td,{children:[`Fill in the Client Credentials Grant values, then paste the four values printed by `,_jsx(_components.code,{children:`setup_test_data.py`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`invalid_grant: Grant credentials are invalid`})}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`BOX_ENTERPRISE_ID`}),` holds a client ID or secret`]}),_jsxs(_components.td,{children:[`Use the numeric enterprise ID from `,_jsx(_components.strong,{children:`Developer Console > Configuration > App Details`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`unauthorized_client`})}),_jsx(_components.td,{children:`App not authorized, or scopes changed since authorization`}),_jsx(_components.td,{children:`Authorize or re-authorize the app in the Developer Console and Admin Console`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`404 INSTANCE_NOT_FOUND`})}),_jsxs(_components.td,{children:[`Wrong template reference in `,_jsx(_components.code,{children:`EXISTS(:templateArg)`})]}),_jsxs(_components.td,{children:[`Confirm `,_jsx(_components.code,{children:`enterprise_\u003cid>:\u003ctemplateKey>`}),` matches your template`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`403 FORBIDDEN`})}),_jsx(_components.td,{children:`Missing scope or inaccessible ancestors`}),_jsx(_components.td,{children:`Verify app scopes and that the service account can read the folder`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`400 BAD_REQUEST`})}),_jsx(_components.td,{children:`Invalid predicate or parameter types`}),_jsxs(_components.td,{children:[`Check placeholder names match `,_jsx(_components.code,{children:`params`}),` keys and field types`]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`400 Invalid query request`})}),_jsxs(_components.td,{children:[_jsx(_components.code,{children:`group_by`}),` points at a free-text string field`]}),_jsxs(_components.td,{children:[`Re-run `,_jsx(_components.code,{children:`setup_test_data.py`}),` and copy the `,_jsx(_components.code,{children:`FIELD_CONTRACT_TYPE`}),` it prints. On a template with a string `,_jsx(_components.code,{children:`contractType`}),`, that is `,_jsx(_components.code,{children:`contractTypeEnum`})]})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:_jsx(_components.code,{children:`429 RATE_LIMIT_EXCEEDED`})}),_jsx(_components.td,{children:`Too many requests for the enterprise`}),_jsx(_components.td,{children:`Cache dashboard results; the SDK already retries with backoff`})]}),_jsxs(_components.tr,{children:[_jsx(_components.td,{children:`Every metric returns 0`}),_jsx(_components.td,{children:`Index lag, wrong folder, or untagged files`}),_jsxs(_components.td,{children:[`Wait a minute after tagging, then confirm `,_jsx(_components.code,{children:`FOLDER_ID`}),` and the field references`]})]}),_jsxs(_components.tr,{children:[_jsxs(_components.td,{children:[_jsx(_components.code,{children:`Sales Contracts`}),` is missing from Box`]}),_jsx(_components.td,{children:`Files belong to the service account, not your user`}),_jsx(_components.td,{children:`Collaborate yourself on the folder, or open it as an admin in Content Manager`})]})]})]}),`\n`,_jsxs(_components.p,{children:[`See `,_jsx(_components.a,{href:`/guides/query/insights`,children:`Box Query Insights API guide`}),` for the full parameter reference, response fields, and additional examples.`]}),`\n`,_jsx(Heading,{level:`2`,id:`scaling-to-production`,children:`Scaling to production`}),`\n`,_jsxs(AccordionGroup,{children:[_jsx(Accordion,{title:`Cache dashboard results`,id:`cache-dashboard-results`,children:_jsxs(_components.p,{children:[`Dashboard widgets rarely need real-time precision. Refresh aggregates on a schedule, for example, every 15 minutes or hourly, instead of calling the Box Query Insights API on every page load. Store results in your app cache or a data warehouse. The SDK already retries `,_jsx(_components.code,{children:`429 RATE_LIMIT_EXCEEDED`}),` and `,_jsx(_components.code,{children:`5xx`}),` responses with backoff, so cache to reduce the number of calls rather than adding a retry loop of your own.`]})}),_jsx(Accordion,{title:`Scope queries with ancestors`,id:`scope-queries-with-ancestors`,children:_jsxs(_components.p,{children:[`Pass department or program folder IDs in `,_jsx(_components.code,{children:`ancestors`}),` so each team sees only its content. This reduces result set size, keeps dashboards tenant-aware, and aligns with how Box enforces folder-level access for the service account.`]})}),_jsx(Accordion,{title:`Pair insights with Box Query API for drill-down`,id:`pair-insights-with-box-query-api-for-drill-down`,children:_jsxs(_components.p,{children:[`Use the Box Query Insights API for summary tiles and charts, then call `,_jsx(_components.a,{href:`/guides/query/box-query`,children:`Box Query API`}),` when you select a bucket to load the underlying files. The Box Query Insights API returns aggregates only. Box Query API returns individual items with the same predicate syntax.`]})}),_jsx(Accordion,{title:`Validate group_by field cardinality`,id:`validate-group-by-field-cardinality`,children:_jsxs(_components.p,{children:[`Make sure the `,_jsx(_components.code,{children:`bucket_limit`}),` is set to 10 or less. Prefer low-cardinality dimensions for chart axes. Cardinality of 10,000 or above can cause errors, though that threshold is rarely reached in practice.`]})})]}),`\n`,_jsx(_MdxComponentBoundary,{name:`RelatedLinks`,children:_jsx(RelatedLinks,{title:`RELATED GUIDES`,items:[{label:translate(`Box Query Insights API`),href:`/guides/query/insights`,badge:`GUIDE`},{label:translate(`Box Query API`),href:`/guides/query/box-query`,badge:`GUIDE`},{label:translate(`Metadata fields`),href:`/guides/metadata/fields/index`,badge:`GUIDE`},{label:translate(`Customizing metadata templates`),href:`https://support.box.com/hc/en-us/articles/360044194033-Customizing-Metadata-Templates`,badge:`SUPPORT`}]})})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{__snippet_useState_1h1agm2,__snippet_useEffect_1h1agm2,AgentPromptBuilder,RelatedLinks,SignupCTA,default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Build a contract analytics dashboard with Box Query Insights API","sidebarTitle":"Contract analytics dashboard","description":"Use the Box Query Insights API to aggregate metadata across Box content and power dashboards with counts, sums, averages, and grouped breakdowns.","href":"/tutorials/query-insights"}}},"mdxSourceWithNoJs":null,"noJsSplices":[[133,7290," __snippet_useState_1h1agm2=undefined;const __snippet_useEffect_1h1agm2=undefined;const AgentPromptBuilder=()=>null;const RelatedLinks=()=>null;const SignupCTA=()=>null;function _c"],[521593,522018,""]]},"mdxExtracts":{"tableOfContents":[{"title":"Use cases","slug":"use-cases","depth":2,"children":[]},{"title":"Before you start","slug":"before-you-start","depth":2,"children":[]},{"title":"Build with an agent","slug":"build-with-an-agent","depth":2,"children":[]},{"title":"Build by hand","slug":"build-by-hand","depth":2,"children":[]},{"title":"Run and verify","slug":"run-and-verify","depth":2,"children":[]},{"title":"Response entry types","slug":"response-entry-types","depth":2,"children":[]},{"title":"Troubleshooting","slug":"troubleshooting","depth":2,"children":[]},{"title":"Scaling to production","slug":"scaling-to-production","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":["/_mintlify/custom/box/523776d2eff70e58/scripts/cookie-banner.js","/_mintlify/custom/box/e597cec886c1778e/scripts/locale-links.js","/_mintlify/custom/box/37b2f846ed414abc/snippets/choose-choice-simple.js","/_mintlify/custom/box/78fc14bb599966cb/scripts/locale-footer-combined.js","/_mintlify/custom/box/9a429216167d598a/scripts/analitics.js","/_mintlify/custom/box/2f463a090bfcd0e8/snippets/boxIntl.js","/_mintlify/custom/box/d88c3906cf95ec86/snippets/translations.js","/_mintlify/custom/box/d67e74fc334b686a/scripts/preferred-source.js"],"dynamicCss":".mint-pointer-events-none {\n pointer-events: none\n}\n.mint-absolute {\n position: absolute\n}\n.mint-relative {\n position: relative\n}\n.mint-inset-y-0 {\n top: 0px;\n bottom: 0px\n}\n.mint-right-3 {\n right: 0.75rem\n}\n.mint-my-6 {\n margin-top: 1.5rem;\n margin-bottom: 1.5rem\n}\n.mint-my-8 {\n margin-top: 2rem;\n margin-bottom: 2rem\n}\n.mint-mb-0 {\n margin-bottom: 0px\n}\n.mint-mb-2 {\n margin-bottom: 0.5rem\n}\n.mint-mb-4 {\n margin-bottom: 1rem\n}\n.mint-mt-1 {\n margin-top: 0.25rem\n}\n.mint-mt-4 {\n margin-top: 1rem\n}\n.mint-mt-5 {\n margin-top: 1.25rem\n}\n.mint-block {\n display: block\n}\n.mint-flex {\n display: flex\n}\n.mint-inline-flex {\n display: inline-flex\n}\n.mint-w-full {\n width: 100%\n}\n.mint-min-w-0 {\n min-width: 0px\n}\n.mint-min-w-\\[10rem\\] {\n min-width: 10rem\n}\n.mint-flex-1 {\n flex: 1 1 0%\n}\n.mint-flex-shrink-0 {\n flex-shrink: 0\n}\n.mint-appearance-none {\n appearance: none\n}\n.mint-flex-col {\n flex-direction: column\n}\n.mint-flex-wrap {\n flex-wrap: wrap\n}\n.mint-items-center {\n align-items: center\n}\n.mint-gap-2 {\n gap: 0.5rem\n}\n.mint-gap-3 {\n gap: 0.75rem\n}\n.mint-gap-4 {\n gap: 1rem\n}\n.mint-whitespace-nowrap {\n white-space: nowrap\n}\n.mint-rounded {\n border-radius: 0.25rem\n}\n.mint-rounded-2xl {\n border-radius: 1rem\n}\n.mint-rounded-full {\n border-radius: 9999px\n}\n.mint-rounded-lg {\n border-radius: 0.5rem\n}\n.mint-rounded-xl {\n border-radius: 0.75rem\n}\n.mint-border {\n border-width: 1px\n}\n.mint-border-b-0 {\n border-bottom-width: 0px\n}\n.mint-border-gray-200 {\n --tw-border-opacity: 1;\n border-color: rgb(229 231 235 / var(--tw-border-opacity, 1))\n}\n.mint-border-red-200 {\n --tw-border-opacity: 1;\n border-color: rgb(254 202 202 / var(--tw-border-opacity, 1))\n}\n.mint-bg-red-50 {\n --tw-bg-opacity: 1;\n background-color: rgb(254 242 242 / var(--tw-bg-opacity, 1))\n}\n.mint-bg-white {\n --tw-bg-opacity: 1;\n background-color: rgb(255 255 255 / var(--tw-bg-opacity, 1))\n}\n.mint-p-5 {\n padding: 1.25rem\n}\n.mint-px-2 {\n padding-left: 0.5rem;\n padding-right: 0.5rem\n}\n.mint-px-3 {\n padding-left: 0.75rem;\n padding-right: 0.75rem\n}\n.mint-px-4 {\n padding-left: 1rem;\n padding-right: 1rem\n}\n.mint-px-5 {\n padding-left: 1.25rem;\n padding-right: 1.25rem\n}\n.mint-px-6 {\n padding-left: 1.5rem;\n padding-right: 1.5rem\n}\n.mint-py-1 {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem\n}\n.mint-py-2 {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem\n}\n.mint-py-3 {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem\n}\n.mint-py-5 {\n padding-top: 1.25rem;\n padding-bottom: 1.25rem\n}\n.mint-pr-9 {\n padding-right: 2.25rem\n}\n.mint-text-base {\n font-size: 1rem;\n line-height: 1.5rem\n}\n.mint-text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem\n}\n.mint-text-xs {\n font-size: 0.75rem;\n line-height: 1rem\n}\n.mint-font-bold {\n font-weight: 700\n}\n.mint-font-medium {\n font-weight: 500\n}\n.mint-font-semibold {\n font-weight: 600\n}\n.mint-uppercase {\n text-transform: uppercase\n}\n.mint-leading-6 {\n line-height: 1.5rem\n}\n.mint-leading-relaxed {\n line-height: 1.625\n}\n.mint-tracking-wide {\n letter-spacing: 0.025em\n}\n.mint-tracking-wider {\n letter-spacing: 0.05em\n}\n.mint-text-gray-500 {\n --tw-text-opacity: 1;\n color: rgb(107 114 128 / var(--tw-text-opacity, 1))\n}\n.mint-text-gray-600 {\n --tw-text-opacity: 1;\n color: rgb(75 85 99 / var(--tw-text-opacity, 1))\n}\n.mint-text-gray-700 {\n --tw-text-opacity: 1;\n color: rgb(55 65 81 / var(--tw-text-opacity, 1))\n}\n.mint-text-gray-900 {\n --tw-text-opacity: 1;\n color: rgb(17 24 39 / var(--tw-text-opacity, 1))\n}\n.mint-text-red-800 {\n --tw-text-opacity: 1;\n color: rgb(153 27 27 / var(--tw-text-opacity, 1))\n}\n.mint-text-white {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity, 1))\n}\n.mint-no-underline {\n text-decoration-line: none\n}\n.mint-transition-colors {\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n transition-duration: 150ms\n}\n.hover\\:mint-bg-\\[\\#f2f2f2\\]:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(242 242 242 / var(--tw-bg-opacity, 1))\n}\n.hover\\:mint-no-underline:hover {\n text-decoration-line: none\n}\n.focus\\:mint-outline-none:focus {\n outline: 2px solid transparent;\n outline-offset: 2px\n}\n.focus\\:mint-ring-2:focus {\n --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);\n box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)\n}\n.focus\\:mint-ring-gray-400\\/30:focus {\n --tw-ring-color: rgb(156 163 175 / 0.3)\n}\n.dark\\:mint-border-gray-700:is(.dark *) {\n --tw-border-opacity: 1;\n border-color: rgb(55 65 81 / var(--tw-border-opacity, 1))\n}\n.dark\\:mint-border-red-900:is(.dark *) {\n --tw-border-opacity: 1;\n border-color: rgb(127 29 29 / var(--tw-border-opacity, 1))\n}\n.dark\\:mint-border-white\\/10:is(.dark *) {\n border-color: rgb(255 255 255 / 0.1)\n}\n.dark\\:mint-bg-gray-900:is(.dark *) {\n --tw-bg-opacity: 1;\n background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1))\n}\n.dark\\:mint-bg-red-600\\/20:is(.dark *) {\n background-color: rgb(220 38 38 / 0.2)\n}\n.dark\\:mint-bg-transparent:is(.dark *) {\n background-color: transparent\n}\n.dark\\:mint-text-gray-100:is(.dark *) {\n --tw-text-opacity: 1;\n color: rgb(243 244 246 / var(--tw-text-opacity, 1))\n}\n.dark\\:mint-text-gray-200:is(.dark *) {\n --tw-text-opacity: 1;\n color: rgb(229 231 235 / var(--tw-text-opacity, 1))\n}\n.dark\\:mint-text-gray-300:is(.dark *) {\n --tw-text-opacity: 1;\n color: rgb(209 213 219 / var(--tw-text-opacity, 1))\n}\n.dark\\:mint-text-gray-400:is(.dark *) {\n --tw-text-opacity: 1;\n color: rgb(156 163 175 / var(--tw-text-opacity, 1))\n}\n.dark\\:mint-text-red-300:is(.dark *) {\n --tw-text-opacity: 1;\n color: rgb(252 165 165 / var(--tw-text-opacity, 1))\n}\n.dark\\:mint-text-white:is(.dark *) {\n --tw-text-opacity: 1;\n color: rgb(255 255 255 / var(--tw-text-opacity, 1))\n}\n.dark\\:hover\\:mint-bg-\\[\\#111827\\]:hover:is(.dark *) {\n --tw-bg-opacity: 1;\n background-color: rgb(17 24 39 / var(--tw-bg-opacity, 1))\n}\n.dark\\:focus\\:mint-ring-gray-500\\/30:focus:is(.dark *) {\n --tw-ring-color: rgb(107 114 128 / 0.3)\n}\n@media (min-width: 640px) {\n .sm\\:mint-flex-row {\n flex-direction: row\n }\n}","subdomain":"box","siteName":"Box Dev Docs","title":"Build a contract analytics dashboard with Box Query Insights API - Box Dev Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{"en":{"href":"/tutorials/query-insights","matchLevel":0},"ja":{"href":"/ja","matchLevel":4}}},"lastModified":"2026-10-26T08:16:23.719Z","gitLastModified":"2026-10-26T08:14:52.000Z","originalFileLocation":"tutorials/query-insights.mdx","locale":"en"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Use the Box Query Insights API to aggregate metadata across Box content and power dashboards with counts, sums, averages, and grouped breakdowns.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Box Dev Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/box/ZCmC4_xrCUAVE-ZZ/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/box/ZCmC4_xrCUAVE-ZZ/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/box/ZCmC4_xrCUAVE-ZZ/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/box/ZCmC4_xrCUAVE-ZZ/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/box/ZCmC4_xrCUAVE-ZZ/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/box/ZCmC4_xrCUAVE-ZZ/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/box/ZCmC4_xrCUAVE-ZZ/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/box/ZCmC4_xrCUAVE-ZZ/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/box/ZCmC4_xrCUAVE-ZZ/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Build a contract analytics dashboard with Box Query Insights API - Box Dev Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Use the Box Query Insights API to aggregate metadata across Box content and power dashboards with counts, sums, averages, and grouped breakdowns.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Box Dev Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://developer.box.com/tutorials/query-insights\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://box.mintlify.app/_mintlify/api/og/v2?division=Documentation\u0026amp;title=Build+a+contract+analytics+dashboard+with+Box+Query+Insights+API\u0026amp;description=Use+the+Box+Query+Insights+API+to+aggregate+metadata+across+Box+content+and+power+dashboards+with+counts%2C+sums%2C+averages%2C+and+grouped+breakdowns.\u0026amp;theme=7c006b8b877970d319badcf9\u0026amp;signature=08d8baed356358075c5a5d0d61bcb692e4e45bfaaabd905770518ebd6c0b54c5\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Build a contract analytics dashboard with Box Query Insights API - Box Dev Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Use the Box Query Insights API to aggregate metadata across Box content and power dashboards with counts, sums, averages, and grouped breakdowns.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://box.mintlify.app/_mintlify/api/og/v2?division=Documentation\u0026amp;title=Build+a+contract+analytics+dashboard+with+Box+Query+Insights+API\u0026amp;description=Use+the+Box+Query+Insights+API+to+aggregate+metadata+across+Box+content+and+power+dashboards+with+counts%2C+sums%2C+averages%2C+and+grouped+breakdowns.\u0026amp;theme=7c006b8b877970d319badcf9\u0026amp;signature=08d8baed356358075c5a5d0d61bcb692e4e45bfaaabd905770518ebd6c0b54c5\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/box/ZCmC4_xrCUAVE-ZZ/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Box Dev Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0061d5\">\u003cmeta data-mint-head name=\"google-site-verification\" content=\"fuelbNhVR1kQluNBJjYt4K1Hj5HvJLhLnIq0o9CAY9E\">\u003clink data-mint-head rel=\"canonical\" href=\"https://developer.box.com/tutorials/query-insights\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/tutorials/query-insights.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://developer.box.com/#organization\",\"name\":\"Box Dev Docs\",\"url\":\"https://developer.box.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/box/lJLw9z7FWORNWMcq/logo/boxdev-light.png?fit=max\u0026auto=format\u0026n=lJLw9z7FWORNWMcq\u0026q=85\u0026s=a11710b698ff59d24426f9ecec6c7e9c\"}},{\"@type\":\"WebSite\",\"@id\":\"https://developer.box.com#website\",\"name\":\"Box Dev Docs\",\"url\":\"https://developer.box.com\",\"publisher\":{\"@id\":\"https://developer.box.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://developer.box.com/tutorials/query-insights#webpage\",\"url\":\"https://developer.box.com/tutorials/query-insights\",\"name\":\"Build a contract analytics dashboard with Box Query Insights API\",\"description\":\"Use the Box Query Insights API to aggregate metadata across Box content and power dashboards with counts, sums, averages, and grouped breakdowns.\",\"dateModified\":\"2026-10-26T08:14:52.000Z\",\"isPartOf\":{\"@id\":\"https://developer.box.com#website\"}},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://developer.box.com/tutorials/query-insights#article\",\"headline\":\"Build a contract analytics dashboard with Box Query Insights API\",\"name\":\"Build a contract analytics dashboard with Box Query Insights API\",\"description\":\"Use the Box Query Insights API to aggregate metadata across Box content and power dashboards with counts, sums, averages, and grouped breakdowns.\",\"url\":\"https://developer.box.com/tutorials/query-insights\",\"mainEntityOfPage\":{\"@id\":\"https://developer.box.com/tutorials/query-insights#webpage\"},\"dateModified\":\"2026-10-26T08:14:52.000Z\",\"publisher\":{\"@id\":\"https://developer.box.com/#organization\"},\"isPartOf\":{\"@id\":\"https://developer.box.com#website\"}}]}\u003c/script>","siteName":"Box Dev Docs","nav":{"global":null,"languages":[{"language":"en","banner":{"content":"Join BoxWorks Dev Summit on Nov 5-6, San Francisco and dive into AI agents and unstructured content. [See agenda](https://boxworks.box.com/series/boxworks-2026-dev-summit/landing_page).","dismissible":true},"footer":{"socials":{"x":"https://x.com/box","github":"https://github.com/box-community","linkedin":"https://linkedin.com/company/box","youtube":"https://www.youtube.com/user/box","facebook":"https://www.facebook.com/box"},"links":[{"header":"Resources","items":[{"label":"Newsletter unsubscribe","href":"https://go.box.com/preferences.html"},{"label":"Terms of Use","href":"https://cloud.app.box.com/s/rmwxu64h1ipr41u49w3bbuvbsa29wku9"},{"label":"Privacy Policy","href":"https://www.box.com/en-gb/legal/privacypolicy?url_redirect=direct"},{"label":"Cookie Notification","href":"https://www.box.com/en-gb/legal/cookie-notification?url_redirect=direct"},{"label":"llms.txt","href":"https://developer.box.com/llms.txt"}]}]},"navbar":{"links":[{"href":"https://account.box.com/developers/console","label":"Log in","type":"button"}],"primary":{"type":"button","label":"Get started for free","href":"https://account.box.com/signup/developer"}},"tabs":[{"tab":"Home","pages":[{"title":"Home","href":""}]},{"tab":"AI","pages":[{"title":"AI","href":"/ai"}]},{"tab":"API reference","pages":[{"title":"API reference","href":"/reference"}]},{"tab":"Tools","pages":[{"title":"Tools","href":"/sdks-and-tools"}]},{"tab":"Tutorials","pages":[{"title":"Box Tutorials","mode":"wide","href":"/tutorials"},{"title":"Automate invoice intake with Box AI Extract","sidebarTitle":"Invoice intake automation","href":"/tutorials/invoice-intake"},{"title":"Build an AI-powered DAM system with Box","sidebarTitle":"AI-powered DAM","href":"/tutorials/ai-powered-dam"},{"title":"Build an answer bank with Box Hubs and AI","sidebarTitle":"AI-powered answer bank","href":"/tutorials/sales-rfp-answer-bank"},{"title":"Build secure in-app document review with Box View","sidebarTitle":"Secure in-app document review","href":"/tutorials/secure-in-app-document-review"},{"title":"Turn supplier agreements into structured procurement data with Box AI","sidebarTitle":"Supplier agreement extraction","href":"/tutorials/supplier-agreements"},{"title":"Automate new hire onboarding with Box APIs","sidebarTitle":"Automate new hire onboarding","href":"/tutorials/onboarding-workspaces"},{"title":"Automate offer letter creation with Box Doc Gen and Box Sign","sidebarTitle":"Offer letter automation","href":"/tutorials/offer-letter-creation"},{"title":"Build an NDA risk summary with Box AI Extract","sidebarTitle":"NDA risk summary","href":"/tutorials/nda-risk-summary"},{"title":"Build your company brain","sidebarTitle":"Build your company brain","href":"/tutorials/company-brain"},{"title":"Route claims evidence for review with Box Automate","sidebarTitle":"Claims evidence review","href":"/tutorials/claims-evidence-review"},{"title":"Connect an AI agent to Box","href":"/tutorials/connect-an-agent-to-box"},{"title":"Build a document dashboard with the Content Explorer metadata view","sidebarTitle":"Document metadata dashboard","description":"Embed the enhanced metadata view of the Box Content Explorer to browse, filter, and edit documents by their metadata, with a single setup script and one HTML page.","href":"/tutorials/explorer-metadata-view"},{"title":"Build a contract analytics dashboard with Box Query Insights API","sidebarTitle":"Contract analytics dashboard","href":"/tutorials/query-insights"},{"title":"Create a review workflow in Box Automate with Slack notifications","sidebarTitle":"Create workflow Automate and Slack","description":"Build a review workflow with Box Automate that routes files through approval tasks, sends notifications in Box, and posts updates to a Slack channel using HTTPS Request outcomes.","href":"/tutorials/box-automate-review-workflow"},{"title":"Extract EXIF metadata with Box representations","sidebarTitle":"Extract EXIF metadata","href":"/tutorials/extract-exif-metadata"}]},{"tab":"Changelog","pages":[{"title":"Changelog","href":"/changelog/2026"}]}],"global":{"anchors":[{"anchor":"Box","icon":"https://mintlify.s3.us-west-1.amazonaws.com/box/images/sidebar/box.svg","href":"https://www.box.com/home"},{"anchor":"Community","icon":"book-open-cover","href":"https://community.box.com/box-platform-5"},{"anchor":"Developer Blog","icon":"newspaper","href":"https://blog.box.com/developer"},{"anchor":"Box SDKs","icon":"code","href":"https://github.com/box/sdks"},{"anchor":"Box Docs","icon":"file-lines","href":"https://docs.box.com"}]}},{"language":"ja","banner":{"content":"Join live webinar on Sept 29: See how to give agents a computer and enterprise content to work on with Box and Daytona. [Register now](https://events.zoom.us/ev/Amkp36LSSk_TxOQbBytoLoHa_Ztg7quKlJv2u74NRvSZJtlnbG5L~AqO7fnFo-ePaTqEcPrKs4jSfhxq3pMVK52ut69Q2zfn9jOr70vx5DQVJaeNF1dDZE9_0N33jMcY1yE9LoHDL5Oamqg).","dismissible":true},"footer":{"socials":{"x":"https://x.com/box","github":"https://github.com/box-community","linkedin":"https://linkedin.com/company/box","youtube":"https://www.youtube.com/user/box","facebook":"https://www.facebook.com/box"},"links":[{"header":"リソース","items":[{"label":"ニュースレターの登録解除","href":"https://go.box.com/preferences.html"},{"label":"利用規約","href":"https://cloud.app.box.com/s/rmwxu64h1ipr41u49w3bbuvbsa29wku9"},{"label":"個人情報保護方針","href":"https://www.box.com/en-gb/legal/privacypolicy?url_redirect=direct"},{"label":"Cookieに関する通知","href":"https://www.box.com/en-gb/legal/cookie-notification?url_redirect=direct"},{"label":"llms.txt","href":"https://developer.box.com/llms.txt"}]}]},"navbar":{"links":[{"href":"https://account.box.com/developers/console","label":"ログイン","type":"button"}],"primary":{"type":"button","label":"今すぐ無料で開始","href":"https://account.box.com/signup/developer"}},"pages":[{"title":"ja","href":"/ja"}]}]},"title":"Build a contract analytics dashboard with Box Query Insights API - Box Dev Docs","buildId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","deploymentId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","dynamics":["10e4515597"],"chunks":["BannerMarkdown-BVNUlwBc.js","dist-aeztFa9U.js","lib--scc4DXi.js","lib-B8HbPgcC.js","clsx-rL8ZCCw4.js","html-void-elements-mCSPHezU.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js"]}