# GB5 BI Platform: Reference

Lookup tables and glossary for developers actively working in this code. Keep this file in sync —
add a row every time a new endpoint, dot-code, table, or dataset joins this engine.

## Glossary

| Term | Meaning |
|---|---|
| **`MBICATALOG`** (renamed from `MANALYSISCATALOG`) | The catalog registry — one row per dataset a BI View can point at, identified by `BICatalogId`. `DATASETKIND` distinguishes `0=Warehouse`/`1=AnalysisQuery`/`2=ApiService` — all three real. |
| **`MBIVIEW`** | A saved, reusable Dimension/Measure/WidgetType definition over one catalog, independent of any dashboard placement — one catalog can back many views. `WIDGETTYPE` is the literal `GB5WidgetType` string. `ADAPTERCONFIGJSON` can hold a saved pivot layout override. |
| **`MBIFIELDMAPPING`** (renamed from `MANALYSISFIELDMAPPING`) | The field-mapping registry for ApiService-kind catalogs — one row per `BICatalogId` + source field, classifying it as Dimension/Measure with a data type, default aggregation, and additivity. |
| **`MWAREHOUSEFACT`** | One row per registered fact table backing a Warehouse-kind catalog. |
| **`MWAREHOUSEMEASURE`** | One row per queryable numeric column on a fact table — `AdditivityType`, `DefaultAggregation`, `IsVisible`. |
| **`WarehouseDimensionCatalog`** | Static C# class hardcoding the allowed dimension fields per fact grain — a deliberate v1 simplification, not a DB table. |
| **`IDatasetResolver`** | The one place that resolves any `BICatalogId` + `DatasetKind` combination to something queryable. Never re-derive this logic elsewhere. |
| **`AnalysisQueryDefinition`** | The FE/BE-shared request shape for `RunBIQuery`: `DatasetId`, `Dimensions[]`, `Measures[]`, `Filters[]` (unconsumed server-side), `Rows[]`/`Columns[]` (consumed client-side only, by the pivot-table adapter), `DrillPath[]`, `Sort[]` (unconsumed), `TopN`. |
| **`AnalysisResult`** | The response shape: `Meta` (`DimensionsUsed`, `MeasuresUsed`, `GeneratedAt`, `TenantId`, `RowCount`, `Truncated`, `Insights` — always `null` today) + flat `Data` rows. Always flat, regardless of which widget type ultimately renders it. |
| **`AdditivityType`** | `0 = Additive` (safe to sum anywhere), `1 = SemiAdditive` (safe to sum across some dimensions, not others), `2 = NonAdditive` (never safe to sum client-side, e.g. an average). Same enum, same meaning, for both Warehouse measures and ApiService field mappings. |
| **`GB5WidgetType`** | `'kpi-card' \| 'apex-chart' \| 'table' \| 'pivot-table'` — which `gb5-widget` adapter renders a given result. Auto-picked by `resolvedType()` from dimension count unless an explicit `widgetType` override (or a picked `MBIVIEW`'s own `WidgetType`) wins. |
| **`GB5WidgetAdapterConfig`** | Per-adapter render config (`chartSubType`, `colors`, `height`, and `pivotSlice` — a saved Rows/Columns override for the pivot-table adapter). |
| **`GB5PivotSlice`** | `{ Rows: string[]; Columns: string[] }` — the pivot-table adapter's current or saved row/column arrangement. |
| **`GB5SelectionEvent`** | The generic click/selection payload every adapter emits (`dimension`, `value`, `measureField?`, `rowIndex?`) — dashboard-agnostic. |
| **`ChartAdapter`** | The structural (docs-only, not compiler-enforced) contract every adapter matches — `definition()`/`result()`/`config()`/`select.emit()`. |
| **`SupportedWidgetTypes`** | `MPORTLETTYPE`'s comma-separated `GB5WidgetType` allow-list — declarative FE-side filter, no server-side hard gate (see the Developer Playbook for why). |

## Backend routes

| Route | Method | Purpose | Endpoint file |
|---|---|---|---|
| `/BI/GetSelectListBICatalog` | GET | Catalog picker — entries visible to the tenant | `AnalyticsSL/EndPoints/BI/GetSelectListBICatalog.cs` |
| `/BI/GetDimensionsForDataset?BICatalogId=X` | GET | Dimension picker for one catalog (all 3 kinds) | `AnalyticsSL/EndPoints/BI/GetDimensionsForDataset.cs` |
| `/BI/GetMeasuresForDataset?BICatalogId=X` | GET | Measure picker (visible measures only) for one catalog | `AnalyticsSL/EndPoints/BI/GetMeasuresForDataset.cs` |
| `/BI/RunBIQuery` | POST | Runs an `AnalysisQueryDefinition`, returns an `AnalysisResult` | `AnalyticsSL/EndPoints/BI/RunBIQuery.cs` |
| `/BI/CreateBICatalogFromReportView` | POST | Turns an existing, non-pivoted report into a new ApiService-kind catalog | `AnalyticsSL/EndPoints/BI/CreateBICatalogFromReportView.cs` |
| `/BI/SuggestBIFieldMappings?BICatalogId=X` | GET | Live-samples an ApiService-kind catalog's report and drafts field mappings | `AnalyticsSL/EndPoints/BI/SuggestBIFieldMappings.cs` |
| `/BI/SaveBIFieldMapping` | POST | Saves one reviewed field-mapping draft | `AnalyticsSL/EndPoints/BI/SaveBIFieldMapping.cs` |
| `/BI/SaveBIView` | POST | Create/update a `MBIVIEW` row | `AnalyticsSL/EndPoints/BI/SaveBIView.cs` |
| `/BI/GetBIView?BIViewId=X` | GET | Fetch one saved view | `AnalyticsSL/EndPoints/BI/GetBIView.cs` |
| `/BI/GetSelectListBIView?BICatalogId=X` | GET | List saved views for one catalog | `AnalyticsSL/EndPoints/BI/GetSelectListBIView.cs` |
| `/BI/DeleteBIView?BIViewId=X` | DELETE | Soft-delete a saved view | `AnalyticsSL/EndPoints/BI/DeleteBIView.cs` |
| `/BI/PilotApiServiceTest` | POST | Fixed 3-row test fixture (REGION/REVENUE/AVGDEALSIZE) — used throughout this engine's development and verification, safe to keep reusing | `AnalyticsSL/EndPoints/BI/PilotApiServiceTest.cs` |
| `/Portlet/SavePortlet` | POST | Create/update an `MPORTLET` row (pre-existing, any portlet type, now includes `BIViewId`) | `GB5Framework/FrameworkSL/Endpoints/PortLet/SavePortlet.cs` |
| `/PortletType/GetSelectListPortletType` | POST | Portlet Type picker (pre-existing, now includes `SupportedWidgetTypes`) | `GB5Framework/FrameworkSL/Endpoints/PortletType/GetSelectListPortletType.cs` |

**Renamed from an earlier pass, do not use the old paths**: `/Analysis/GetSelectListAnalysisCatalog` →
`/BI/GetSelectListBICatalog`; `/Analysis/RunAnalysisQuery` → `/BI/RunBIQuery`;
`/Analysis/PilotApiServiceTest` → `/BI/PilotApiServiceTest`. A stale stored reference to the old
`/Analysis/*` prefix silently 404s — see the Developer Playbook's gotcha on this.

## FE dot-codes

| Dot-code | Route | File |
|---|---|---|
| `Analytics.BICatalog.SelectList` | `/BI/GetSelectListBICatalog` | `projects/gbhost/public/api/gb5api/analytics.ts` |
| `Analytics.BICatalog.Dimensions` | `/BI/GetDimensionsForDataset` | same |
| `Analytics.BICatalog.Measures` | `/BI/GetMeasuresForDataset` | same |
| `Analytics.BICatalog.CreateFromReportView` | `/BI/CreateBICatalogFromReportView` | same |
| `Analytics.BIView.Save` | `/BI/SaveBIView` | same |
| `Analytics.BIView.Get` | `/BI/GetBIView` | same |
| `Analytics.BIView.SelectListByCatalog` | `/BI/GetSelectListBIView` | same |
| `Analytics.BIView.Delete` | `/BI/DeleteBIView` | same |
| `Analytics.BIFieldMapping.Suggest` | `/BI/SuggestBIFieldMappings` | same |
| `Analytics.BIFieldMapping.Save` | `/BI/SaveBIFieldMapping` | same |
| `Framework.Portlet.Save` | `/fws/Portlet/SavePortlet` | `projects/gbhost/public/api/gb5api/framework.ts` |
| `Framework.Portlet.SelectList` | `/fws/Portlet/GetSelectListPortlet` | same |
| `Framework.Portlet.Delete` | `/fws/Portlet/DeletePortlet` | same |
| `Framework.PortletType.Picklist` | `/fws/PortletType/GetSelectListPortletType` | same |

## Key files

**Backend (gb5 repo)**
- `GB5Solution/Analytics/AnalyticsBLL/BICatalog/{I}BICatalogBLL.cs` — catalog list, dimension/measure picker across all 3 kinds, `CreateFromReportView` + its `ResolveApiResourcePath` fallback logic.
- `GB5Solution/Analytics/AnalyticsBLL/BIView/{I}BIViewBLL.cs` — saved-view CRUD + save-time trust re-validation.
- `GB5Solution/Analytics/AnalyticsBLL/BIFieldMapping/{I}BIFieldMappingBLL.cs` — `SuggestMappings`/`SaveMapping`.
- `GB5Solution/Analytics/AnalyticsBLL/DatasetResolver/` — `IDatasetResolver`/`DatasetResolver`.
- `GB5Solution/Analytics/AnalyticsBLL/AnalysisAggregation/AnalysisAggregationService.cs` — `RunBIQuery`'s aggregation + trust-validation logic (`ValidateDefinitionAsync`, shared by query time and `BIViewBLL.Save`).
- `GB5Solution/Analytics/AnalyticsDAL/CustomCode/Warehouse/{WarehouseDAL,WarehouseDimensionCatalog}.cs` — fact/measure/dimension SQL, `ResolveDimensionColumn` allowlist.
- `GB5Solution/Analytics/AnalyticsSL/EndPoints/BI/` — every BI-prefixed endpoint.
- `GB5Framework/FrameworkDAL/DTO/Portlet/{PortletDTO,PortletTypePicklistDTO,PortletTypeVersionDTO}.cs` — `BIViewId`/`SupportedWidgetTypes` additions.

**Frontend (gb4.7mfe repo)**
- `features/gb5widget/model/{gb5-analysis,gb5-widget}.model.ts` — shared DTOs, widget-type/event contracts, `BIViewDTO`/`BIFieldMappingDTO`/`GB5PivotSlice`.
- `features/gb5widget/gb5-widget.component.{ts,html}` — the dispatcher (`resolvedType()`), `mode`/`layoutSave` pass-through to the pivot adapter.
- `features/gb5widget/adapters/{kpi-card,apex-charts,table,pivot-table}-adapter/` — the four rendering adapters.
- `features/gb5widget/service/gb5-analysis-aggregation.service.ts` — the FE service calling `RunBIQuery`.
- `features/gb5widget/portlet/gb5-widget-portlet.component.ts` — the dashboard-hosting wrapper; BIViewId-first read, legacy-scalar fallback.
- `features/gbdashboard/service/widgetcomponentmap.ts` — `'Analysis' → Gb5WidgetPortletComponent` dispatch key.
- `projects/framework/master/portlet/portlet/portlet.component.{ts,html,scss}` — the config screen: catalog picker, BI View author/pick, field-mapping review, pivot design-mode preview + save-layout.

## Live GB5DEMO test data

Used throughout this engine's development and verification — safe to reuse for further testing,
not to be deleted (each is clearly labeled and, per its own `REMARKS`/naming, understood to be
disposable test fixture data, not real client content):

| `BICatalogId` | `CatalogCode` | `CatalogName` | `DatasetKind` | Notes |
|---|---|---|---|---|
| 1 | `FSALE_TEST` | Sales (Test) | 0 Warehouse | FactId 1, 15 measures |
| 2 | `FFINANCE_TEST` | Finance (Test) | 0 Warehouse | FactId 2, 18 measures |
| 3 | `PILOT_APISVC_TEST` | Pilot ApiService Test | 2 ApiService | Points at `/BI/PilotApiServiceTest`; 3 field mappings (REGION dimension, REVENUE/AVGDEALSIZE measures — the latter deliberately NonAdditive) |
| `-1399687719` | `BITEST_FROM_RV` | BI Test From ReportView | 2 ApiService | Created live via `CreateBICatalogFromReportView` against the fixture report below, to prove that code path end-to-end |

Dimension fields available for both Warehouse test catalogs (shared grain): `OUID`, `DATEID`, and
the full `DIMOU.*`/`DIMDATE.*` set (`OUCODE`, `OUNAME`, `COMPANYID`, `COMPANYNAME`, `BRANCHID`,
`BRANCHNAME`, `CITYID`, `CITYNAME`, `REGIONID`, `REGIONNAME`, `COUNTRYID`, `COUNTRYNAME`, plus the
full date-part breakdown).

**Fixture report** (`MREPORT`/`MREPORTVIEW`), used to live-test `CreateBICatalogFromReportView`
against a real (if synthetic) report row rather than only a pre-existing catalog: `ReportId`
`-1399688000`, "BI Platform Test Report," `ReportViewId` `-1399688000`, `ReportUri`
`/BI/PilotApiServiceTest`, `REMARKS` says "safe to remove." Left in place, matching this session's
disposable-fixture convention.

**MAUTONUMBER entity codes** (see `AutoNumber-Seed-Pattern.md` in the parent `Docs/` folder for the
general convention) registered for this engine: `BIVIEW`, `BICATALOG`, `BIFIELDMAPPING` — each is
the *first-ever* real app-level insert path for its table (every earlier row across this engine's
history, including the test catalogs above, was seeded via raw migration SQL, bypassing
AutoNumber entirely).

The registered "Analysis" `MPORTLETTYPE` row's id is `-1499999996` (`Code`/`Name` both
`"Analysis"`) — this is the exact string `widgetcomponentmap.ts` and the config screen's
`isAnalysisType()` both key off.
