← Back to skill
# merchmix-ai-usage-dashboard A small Flask dashboard that queries Azure Monitor metrics for an Azure OpenAI resource and presents recent daily token usage by model deployment. It uses configured per-million-token prices to support usage and cost reporting, with an in-process cache to reduce repeated Azure Monitor queries. The application is packaged as a single-worker Gunicorn container and deployed to Azure Container Apps. ## Business Summary This internal dashboard helps Merchmix staff see how much AI usage the product has generated over recent days. It breaks usage down by AI model and distinguishes input from output tokens, helping teams monitor consumption and estimate costs without manually reviewing Azure monitoring data. ## Capabilities | Capability | Category | Status | Access | Exposure | |---|---|---|---|---| | AI Usage Reporting | Reporting | `production` | `read` | user_facing, agent_facing | | AI Cost Estimation | Reporting | `production` | `read` | user_facing, agent_facing | | Usage Dashboard Health Monitoring | Reporting | `production` | `read` | internal | **AI Usage Reporting** — Shows recent daily AI token consumption, separated by model deployment and by input versus output usage. **AI Cost Estimation** — Estimates AI consumption cost using configured list prices for supported model deployments. **Usage Dashboard Health Monitoring** — Provides a lightweight health check so the deployed dashboard can be monitored by its hosting platform. ## Workflows **View AI usage report** — A user opens the dashboard and retrieves aggregated Azure OpenAI usage data. 1. Load the dashboard at GET /. 2. Request usage data from GET /api/usage. 3. Reuse the in-process cached result when it is within the configured cache period. 4. Otherwise query Azure Monitor for daily InputTokens and OutputTokens metrics. 5. Group metric values by date and model deployment and return the report to the dashboard. **Deploy dashboard** — The master branch pipeline builds and deploys the dashboard as an Azure Container Apps image. 1. Authenticate the Bitbucket pipeline to Azure using secured pipeline variables. 2. Build the Docker image in Azure Container Registry. 3. Tag the image with the Bitbucket commit. 4. Update the pre-provisioned Azure Container App to use the new image. ## Architecture A single-process Flask web application serves a static dashboard and a JSON usage endpoint. It queries Azure Monitor directly through the Azure SDK, performs aggregation and pricing calculations in memory, and caches the resulting report in an in-process dictionary protected by a thread lock. **Components:** Flask application in app.py, Static dashboard at static/index.html, Azure Monitor MetricsQueryClient integration, DefaultAzureCredential integration using the hosting Container App identity, In-process usage cache with configurable expiration, Gunicorn container runtime, Bitbucket Pipelines deployment to Azure Container Apps **Patterns:** Single service application, Read-only reporting API, Direct cloud metrics query, In-memory caching, Managed identity authentication, Single Gunicorn worker with multiple threads ## Interfaces | Kind | Identifier | Description | |---|---|---| | `http` | `GET /` | Serves the dashboard entry point, backed by the static file in static/index.html. | | `http` | `GET /api/usage` | Returns the computed Azure OpenAI usage report, including daily and model-level token data and, based on the configured pricing table, cost-related calculations. | | `http` | `GET /healthz` | Health-check endpoint for the deployed application. | ## Screens | Route | Name | Purpose | |---|---|---| | `/` | AI Usage Dashboard | Displays recent Azure OpenAI usage information retrieved from the usage API. | ## Data | Entity | Ownership | Description | |---|---|---| | Azure OpenAI token metrics | `reads` | Daily InputTokens and OutputTokens metrics queried from Azure Monitor for the configured Azure OpenAI resource. | | Model deployment usage | `owns` | Transient report data grouped by model deployment name, date, input tokens, and output tokens. | | Model pricing configuration | `owns` | Hardcoded per-one-million-token input and output prices for the supported model deployments. | | Usage report cache | `owns` | In-process cached report data and its fetch timestamp; it is not persisted in an external database. | ## Dependencies | Name | Kind | Relationship | Criticality | |---|---|---|---| | Azure Monitor | `external_service` | `reads` | `critical` | | Azure OpenAI resource | `external_service` | `reads` | `critical` | | Azure managed identity | `other` | `authenticates_through` | `critical` | | Flask | `library` | `uses` | `critical` | | Gunicorn | `library` | `uses` | `required` | | azure-identity | `library` | `uses` | `critical` | | azure-monitor-query | `library` | `uses` | `critical` | | Azure Container Registry | `external_service` | `writes` | `required` | | Azure Container Apps | `external_service` | `writes` | `required` | ## Technology Python, Flask 3.0.3, Gunicorn 22.0.0, Azure Identity 1.17.1, Azure Monitor Query 1.4.0, Docker, Azure Container Apps, Azure Container Registry, Bitbucket Pipelines ## Limitations - The supplied app.py source is truncated after the initial usage-row construction, so the exact JSON schema, cost calculation implementation, error handling, and cache response behavior cannot be fully verified. - No persistent database, queue, or write-oriented business API is present in the scanner evidence. - Pricing is hardcoded in app.py and is not fetched dynamically; estimates may become stale when Azure pricing or deployments change. - The scanner lists several environment variable names, while the source explicitly reads OPENAI_RESOURCE_ID, USAGE_DAYS_BACK, and USAGE_CACHE_SECONDS. The effective deployment configuration should be verified separately. - The dashboard is an internal reporting tool, not an AI inference service and not a general-purpose Azure OpenAI administration interface. - The single-worker cache is process-local; the deployment deliberately uses one worker so multiple independent cache copies are not created. ## Agent Instructions Use this repository for questions about internal Azure OpenAI usage, token consumption, model-level reporting, and configured cost estimates. Do not route product planning, assortment, inventory, allocation, or transactional retail operations to it. - For current usage, call GET /api/usage rather than relying on previously cached values. - Interpret results as Azure Monitor-derived metrics over the configured USAGE_DAYS_BACK period, aggregated daily. - Treat pricing and cost figures as estimates based on the in-code PRICING table. - Do not assume the service can modify Azure OpenAI resources or usage data; the evidenced interfaces are read-only reporting endpoints. - Use GET /healthz for service availability checks. - When debugging missing or stale data, check OPENAI_RESOURCE_ID, Azure Monitor access through the Container App managed identity, the configured lookback and cache periods, and Azure Monitor metric availability. - Do not search this repository for API keys or credentials; authentication is intended to come from Azure managed identity and deployment configuration. ## Source | Field | Value | |---|---| | Repository | `merchmix-ai-usage-dashboard` | | Branch | `master` | | Commit | `bc88e68c459a` | | Generated by | `gpt-5.6-luna` | *Generated by the Merchmix Skills Platform from the current codebase.*