@fayz-ai/plugin-reports 0.11.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -830,15 +830,11 @@ function AnalyticsModule({ view, cardId, children }) {
830
830
  );
831
831
  }
832
832
  function AnalyticsOverview() {
833
- const { labels, showHeader } = useAnalyticsConfig();
833
+ const { labels } = useAnalyticsConfig();
834
834
  const cards = useOverviewCards();
835
835
  const filters = React6__default.useMemo(() => collectFilters(cards), [cards]);
836
836
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
837
- showHeader ? /* @__PURE__ */ jsxs("div", { children: [
838
- /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold tracking-tight", children: labels.analytics }),
839
- /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: labels.overviewSubtitle })
840
- ] }) : null,
841
- /* @__PURE__ */ jsx(AnalyticsControls, { filters, className: "sticky top-3 z-20" }),
837
+ /* @__PURE__ */ jsx(AnalyticsControls, { filters }),
842
838
  cards.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center justify-center rounded-xl border border-dashed py-16 text-center", children: [
843
839
  /* @__PURE__ */ jsx("div", { className: "mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx(BarChart3, { className: "h-5 w-5 text-muted-foreground" }) }),
844
840
  /* @__PURE__ */ jsx("p", { className: "font-medium", children: labels.emptyOverviewTitle }),
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/data/aggregate.ts","../src/data/analytics-supabase.ts","../src/data/analytics-mock.ts","../src/lib/tenant.ts","../src/locales/en.ts","../src/locales/pt-BR.ts","../src/locales/index.ts","../src/lib/legacy.ts","../src/lib/lastViewed.ts","../src/views/AnalyticsSurface.tsx","../src/views/AnalyticsAssistant.tsx","../src/views/AnalyticsModule.tsx","../src/views/AnalyticsOverview.tsx","../src/views/ReportsListPage.tsx","../src/export/csv.ts","../src/components/ExportDropdown.tsx","../src/components/ReportPagination.tsx","../src/views/AnalyticsReportViewer.tsx","../src/views/LiveViewPage.tsx","../src/data/supabase.ts","../src/data/mock.ts","../src/index.ts"],"names":["data","error","React","jsx","useTranslation","jsxs","useState","useEffect","page","Button","Fragment","DataTable","AnalyticsControls","camelToSnake","snakeToCamel","mapRow","getSupabaseClientOptional"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n AnalyticsCardDef, AnalyticsGrain, AnalyticsQueryState, AnalyticsResult, AnalyticsRow,\n} from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Client-side aggregation.\n//\n// The SQL engine (analytics_run) is the real one; this exists for the two cases\n// that cannot reach it — the mock provider, and cards whose source is an app\n// function rather than a read model. It deliberately mirrors the SQL semantics\n// step for step, because a card must not change meaning depending on which\n// provider answered it.\n// ---------------------------------------------------------------------------\n\nfunction num(value: unknown): number {\n if (value == null) return 0\n const n = typeof value === 'number' ? value : Number(value)\n return Number.isFinite(n) ? n : 0\n}\n\n/** Truncate a timestamp to the start of its bucket — the JS date_trunc. */\nexport function truncate(value: unknown, grain: AnalyticsGrain): string | null {\n const d = new Date(String(value))\n if (Number.isNaN(d.getTime())) return null\n const out = new Date(d)\n switch (grain) {\n case 'hour': out.setMinutes(0, 0, 0); break\n case 'week': {\n // ISO weeks start Monday; getDay() calls Sunday 0, hence the shift.\n const day = (out.getDay() + 6) % 7\n out.setDate(out.getDate() - day)\n out.setHours(0, 0, 0, 0)\n break\n }\n case 'month': out.setDate(1); out.setHours(0, 0, 0, 0); break\n case 'quarter': out.setMonth(Math.floor(out.getMonth() / 3) * 3, 1); out.setHours(0, 0, 0, 0); break\n case 'year': out.setMonth(0, 1); out.setHours(0, 0, 0, 0); break\n default: out.setHours(0, 0, 0, 0); break\n }\n return out.toISOString()\n}\n\nfunction matchesFilters(row: AnalyticsRow, filters: Record<string, unknown>): boolean {\n for (const [key, value] of Object.entries(filters)) {\n if (value == null || value === '') continue\n const actual = row[key]\n if (Array.isArray(value)) {\n if (value.length > 0 && !value.map(String).includes(String(actual))) return false\n } else if (String(actual) !== String(value)) {\n return false\n }\n }\n return true\n}\n\nfunction inRange(row: AnalyticsRow, dateColumn: string, from?: string, to?: string): boolean {\n const raw = row[dateColumn]\n if (raw == null) return true\n const t = new Date(String(raw)).getTime()\n if (Number.isNaN(t)) return true\n // `to` is an inclusive DAY, so the window closes at its final millisecond —\n // comparing against midnight would silently drop everything ordered that day.\n if (from && t < new Date(`${from}T00:00:00`).getTime()) return false\n if (to && t > new Date(`${to}T23:59:59.999`).getTime()) return false\n return true\n}\n\n/** Apply one measure over a bucket of rows. 'ratio' is resolved by the UI layer. */\nfunction applyMeasure(rows: AnalyticsRow[], agg: string, column: string): number | null {\n if (agg === 'count') return rows.length\n const values = rows.map((r) => r[column]).filter((v) => v != null)\n if (agg === 'count_distinct') return new Set(values.map(String)).size\n const numbers = values.map(num)\n if (numbers.length === 0) return agg === 'sum' ? 0 : null\n switch (agg) {\n case 'sum': return numbers.reduce((a, b) => a + b, 0)\n case 'avg': return numbers.reduce((a, b) => a + b, 0) / numbers.length\n case 'min': return Math.min(...numbers)\n case 'max': return Math.max(...numbers)\n default: return null\n }\n}\n\nexport interface AggregateOptions {\n /** Skip pagination and return every group (the export path). */\n all?: boolean\n}\n\n/**\n * Group, aggregate, sort and page a row set exactly as analytics_run does.\n * Returns the same {rows, total, summary} envelope so callers cannot tell which\n * engine answered.\n */\nexport function aggregateRows(\n source: AnalyticsRow[],\n card: AnalyticsCardDef,\n state: AnalyticsQueryState,\n options?: AggregateOptions,\n): AnalyticsResult {\n // dateColumn null ⇒ a snapshot: the range must not apply (see AnalyticsQuery).\n const snapshot = card.query.dateColumn === null\n const dateColumn = card.query.dateColumn ?? 'created_at'\n const dimensions = card.query.dimensions ?? []\n const measures = (card.query.measures ?? []).filter((m) => m.agg !== 'ratio')\n\n const filtered = source\n .filter((row) => snapshot || inRange(row, dateColumn, state.dateRange?.from, state.dateRange?.to))\n .filter((row) => matchesFilters(row, state.filters ?? {}))\n\n // The rollup: same rows, same filters, no grouping. Identical to SQL 8.11.\n const summary: Record<string, number> = {}\n for (const m of measures) {\n const value = applyMeasure(filtered, m.agg, m.column ?? m.key)\n summary[m.key] = value ?? 0\n }\n\n // No measures ⇒ a detail listing; the rows pass through untouched.\n if (measures.length === 0 && dimensions.length === 0) {\n const sorted = sortRows(filtered, state.sortBy ?? card.query.defaultSort, state.sortDir ?? card.query.defaultSortDir)\n return { rows: page(sorted, state, options), total: sorted.length, summary }\n }\n\n const buckets = new Map<string, { key: AnalyticsRow; rows: AnalyticsRow[] }>()\n for (const row of filtered) {\n const keyParts: AnalyticsRow = {}\n for (const d of dimensions) {\n const raw = row[d.key]\n keyParts[d.key] = d.grain && d.grain !== 'auto' ? truncate(raw, d.grain) : (raw ?? null)\n }\n const id = JSON.stringify(dimensions.map((d) => keyParts[d.key]))\n const existing = buckets.get(id)\n if (existing) existing.rows.push(row)\n else buckets.set(id, { key: keyParts, rows: [row] })\n }\n\n let grouped: AnalyticsRow[] = [...buckets.values()].map(({ key, rows }) => {\n const out: AnalyticsRow = { ...key }\n for (const m of measures) out[m.key] = applyMeasure(rows, m.agg, m.column ?? m.key)\n return out\n })\n\n grouped = sortRows(grouped, state.sortBy ?? card.query.defaultSort, state.sortDir ?? card.query.defaultSortDir)\n if (card.query.limit) grouped = grouped.slice(0, card.query.limit)\n\n return { rows: page(grouped, state, options), total: grouped.length, summary }\n}\n\nfunction sortRows(rows: AnalyticsRow[], sortBy?: string, dir?: 'asc' | 'desc'): AnalyticsRow[] {\n if (!sortBy) return rows\n const sign = dir === 'asc' ? 1 : -1\n return [...rows].sort((a, b) => {\n const av = a[sortBy]\n const bv = b[sortBy]\n // Nulls sort last in both directions — matching SQL's NULLS LAST, so a\n // never-shipped order does not top a \"fastest fulfillment\" report.\n if (av == null && bv == null) return 0\n if (av == null) return 1\n if (bv == null) return -1\n if (typeof av === 'number' || typeof bv === 'number') return (num(av) - num(bv)) * sign\n return String(av).localeCompare(String(bv)) * sign\n })\n}\n\nfunction page(rows: AnalyticsRow[], state: AnalyticsQueryState, options?: AggregateOptions): AnalyticsRow[] {\n if (options?.all) return rows\n const size = state.pageSize || 50\n const start = ((state.page || 1) - 1) * size\n return rows.slice(start, start + size)\n}\n","import { getSupabaseClientOptional } from '@fayz-ai/core'\nimport type {\n AnalyticsBatchRequest, AnalyticsCardDef, AnalyticsProvider, AnalyticsQueryState,\n AnalyticsResult, AnalyticsRow,\n} from '@fayz-ai/core'\nimport { aggregateRows } from './aggregate'\n\n// ---------------------------------------------------------------------------\n// The Supabase analytics provider.\n//\n// Everything a card asks for goes through ONE server function, analytics_run:\n// \"orders over time\" and \"sales by product\" are the same call with different\n// dimensions. That is what removes the per-report SQL that made adding a report\n// a database migration.\n//\n// kind 'view' → analytics_run over a registered read model (the normal path)\n// kind 'rpc' → a bespoke function, for the rare card the generic engine\n// cannot express (escape hatch, not the default)\n// kind 'fn' → an app-supplied async function, aggregated client-side\n// ---------------------------------------------------------------------------\n\nfunction snakeToCamel(s: string): string {\n return s.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())\n}\n\n/**\n * Map DB keys to JS keys. Measure and dimension keys are passed through\n * UNTOUCHED — the card named them, the SQL aliased them to exactly that, and\n * silently camelCasing `net_sales` into `netSales` would make every card whose\n * viz references `net_sales` render blank.\n */\nfunction mapRow(row: AnalyticsRow, reserved: Set<string>, columnMap?: Record<string, string>): AnalyticsRow {\n const out: AnalyticsRow = {}\n for (const [key, value] of Object.entries(row)) {\n if (reserved.has(key)) { out[key] = value; continue }\n out[columnMap?.[key] ?? snakeToCamel(key)] = value\n // Keep the raw key too: column definitions written against the read model's\n // snake_case still resolve, so adopting a card needs no rename pass.\n if (!(key in out)) out[key] = value\n }\n return out\n}\n\nfunction reservedKeys(card: AnalyticsCardDef): Set<string> {\n return new Set([\n ...(card.query.dimensions ?? []).map((d) => d.key),\n ...(card.query.measures ?? []).map((m) => m.key),\n ])\n}\n\n/** Text columns free-text search scans, taken from the card's own columns. */\nfunction searchColumns(card: AnalyticsCardDef): string[] | undefined {\n const cols = (card.columns ?? [])\n // 'person' is a text column with a richer cell — searching a customer list\n // by name has to keep working after the name became a link.\n .filter((c) => c.type === 'text' || c.type === 'email' || c.type === 'person')\n .map((c) => c.key)\n return cols.length ? cols : undefined\n}\n\nfunction camelToSnake(s: string): string {\n return s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`)\n}\n\n/**\n * Direct read of a view — the path every pre-existing ReportDef takes.\n *\n * Ports the semantics of the original report provider verbatim (tenant scope,\n * inclusive date window, equality/IN filters, ILIKE search over text columns,\n * sort, page) so adopting the analytics engine changed no existing report's\n * answer.\n */\nasync function selectFromView(\n card: AnalyticsCardDef,\n state: AnalyticsQueryState,\n db: any,\n tenantId: string | undefined,\n reserved: Set<string>,\n): Promise<AnalyticsResult> {\n const { source } = card.query\n const size = state.pageSize || 50\n let q = db.from(source.name!).select('*', { count: 'exact' })\n\n if (tenantId) q = q.eq(source.tenantColumn ?? 'tenant_id', tenantId)\n\n const snapshot = card.query.dateColumn === null\n const dateCol = card.query.dateColumn ?? 'created_at'\n if (!snapshot && state.dateRange?.from) q = q.gte(dateCol, state.dateRange.from)\n if (!snapshot && state.dateRange?.to) {\n // A timestamp column needs the whole final day; a plain date column does\n // not — appending a time to a `date` would compare against a cast and drop\n // the last day of every range.\n q = q.lte(dateCol, dateCol.endsWith('_at') ? `${state.dateRange.to}T23:59:59.999` : state.dateRange.to)\n }\n\n for (const [key, value] of Object.entries(state.filters ?? {})) {\n if (value == null || value === '') continue\n const col = camelToSnake(key)\n q = Array.isArray(value) ? q.in(col, value) : q.eq(col, value)\n }\n\n const searchable = searchColumns(card)\n if (state.search?.trim() && searchable?.length) {\n const term = `%${state.search.trim()}%`\n q = q.or(searchable.map((c) => `${camelToSnake(c)}.ilike.${term}`).join(','))\n }\n\n const sortBy = state.sortBy ?? card.query.defaultSort\n if (sortBy) {\n q = q.order(camelToSnake(sortBy), {\n ascending: (state.sortDir ?? card.query.defaultSortDir ?? 'desc') === 'asc',\n })\n }\n\n const from = ((state.page || 1) - 1) * size\n const { data, error, count } = await q.range(from, from + size - 1)\n if (error) throw error\n\n return {\n rows: (data ?? []).map((r: AnalyticsRow) => mapRow(r, reserved, source.columnMap)),\n total: count ?? 0,\n }\n}\n\n/**\n * A rejection the card can actually print.\n *\n * PostgREST rejects with a PLAIN OBJECT ({ message, details, hint, code }), not\n * an Error — so `new Error(String(err))` turned every failed card into the words\n * \"[object Object]\" and threw away the one sentence that says what broke.\n */\nfunction toError(err: unknown): Error {\n if (err instanceof Error) return err\n if (err && typeof err === 'object') {\n const e = err as Record<string, unknown>\n const message = [...new Set(\n [e.message, e.details, e.hint].filter(\n (part): part is string => typeof part === 'string' && part.trim().length > 0,\n ),\n )].join(' — ')\n if (message) return Object.assign(new Error(message), e.code ? { code: e.code } : {})\n }\n return new Error(String(err))\n}\n\n/**\n * True when the card is answered by the generic aggregate engine — the only\n * shape that can travel in a batch, because the batch function IS analytics_run\n * called in a loop. A detail listing is a plain PostgREST select and an 'fn'\n * card never touches the database at all.\n */\nfunction isAggregateCard(card: AnalyticsCardDef): boolean {\n const { source } = card.query\n if (source.kind !== 'view' || !source.name) return false\n return (card.query.dimensions?.length ?? 0) > 0 || (card.query.measures?.length ?? 0) > 0\n}\n\n/**\n * The arguments analytics_run wants, as a plain object. Named once so a single\n * call and a batched element cannot drift into asking different questions —\n * the bug that would show up as a KPI disagreeing with itself depending on how\n * many other cards happened to be on screen.\n */\nfunction runArgs(card: AnalyticsCardDef, state: AnalyticsQueryState, tenantId: string | undefined) {\n const size = state.pageSize || 50\n // A snapshot card (dateColumn: null) sends no window at all, so \"stock on\n // hand\" stays stock on hand no matter what the range picker says.\n const snapshot = card.query.dateColumn === null\n return {\n source: card.query.source.name!,\n tenant_id: tenantId ?? null,\n from: !snapshot && state.dateRange.from ? `${state.dateRange.from}T00:00:00` : null,\n // Inclusive end-of-day: the range picker speaks in days, the column is a\n // timestamp, and closing at midnight loses everything sold that day.\n to: !snapshot && state.dateRange.to ? `${state.dateRange.to}T23:59:59.999` : null,\n dimensions: (card.query.dimensions ?? []).map((d) => ({\n key: d.key,\n ...(d.grain && d.grain !== 'auto' ? { grain: d.grain } : {}),\n })),\n measures: (card.query.measures ?? [])\n .filter((m) => m.agg !== 'ratio')\n .map((m) => ({ key: m.key, agg: m.agg, ...(m.column ? { column: m.column } : {}) })),\n filters: state.filters ?? {},\n search: state.search ?? null,\n search_columns: searchColumns(card) ?? null,\n sort: state.sortBy ?? card.query.defaultSort ?? null,\n dir: state.sortDir ?? card.query.defaultSortDir ?? 'desc',\n limit: card.query.limit ?? size,\n offset: card.query.limit ? 0 : ((state.page || 1) - 1) * size,\n }\n}\n\n/** Shape analytics_run's envelope into a result, mapping row keys. */\nfunction toResult(data: any, card: AnalyticsCardDef, reserved: Set<string>): AnalyticsResult {\n const rows: AnalyticsRow[] = data?.rows ?? []\n return {\n rows: rows.map((r) => mapRow(r, reserved, card.query.source.columnMap)),\n total: data?.total ?? rows.length,\n summary: data?.summary ?? undefined,\n }\n}\n\n/** The batch function is missing on this project — 025 was never applied. */\nfunction batchUnavailable(err: any): boolean {\n const code = typeof err?.code === 'string' ? err.code : ''\n if (['42883', 'PGRST202'].includes(code)) return true\n return typeof err?.message === 'string' && err.message.includes('analytics_run_batch')\n}\n\nexport interface SupabaseAnalyticsProviderConfig {\n tenantId: string | (() => string | undefined)\n schema?: string\n}\n\nexport function createSupabaseAnalyticsProvider(config: SupabaseAnalyticsProviderConfig): AnalyticsProvider {\n const resolveTenantId = () =>\n (typeof config.tenantId === 'function' ? config.tenantId() : config.tenantId) || undefined\n\n function client() {\n const supabase = getSupabaseClientOptional() as any\n if (!supabase) throw new Error('Supabase client not available')\n return config.schema && config.schema !== 'public' ? supabase.schema(config.schema) : supabase\n }\n\n // Flipped off for good on the first \"function does not exist\", so an older\n // pool degrades to one-request-per-card instead of failing every card.\n let batchSupported = true\n\n return {\n async run(card: AnalyticsCardDef, state: AnalyticsQueryState): Promise<AnalyticsResult> {\n const { source } = card.query\n const reserved = reservedKeys(card)\n\n if (source.kind === 'fn') {\n if (!source.run) throw new Error(`analytics: card ${card.id} declares kind 'fn' with no run()`)\n const rows = await source.run({\n tenantId: resolveTenantId(),\n dateRange: state.dateRange,\n filters: state.filters,\n })\n return aggregateRows(rows, card, state)\n }\n\n if (!source.name) throw new Error(`analytics: card ${card.id} has no source name`)\n\n // A card with neither dimensions nor measures is a flat listing, and a\n // flat listing has nothing to aggregate. It reads the view DIRECTLY.\n //\n // This is not an optimisation — it is what keeps the five apps that\n // already ship ReportDef catalogues working. Their views (rep_appointments\n // _by_period, plg_courses_rep_revenue, …) predate analytics_run and are\n // not in its allowlist, so sending a plain SELECT through the aggregate\n // engine turned every existing report into PGRST202. Registration is the\n // price of GROUP BY, not the price of reading rows.\n const isDetail = (card.query.dimensions?.length ?? 0) === 0\n && (card.query.measures?.length ?? 0) === 0\n if (source.kind === 'view' && isDetail) {\n return selectFromView(card, state, client(), resolveTenantId(), reserved)\n }\n\n if (source.kind === 'rpc') {\n const { data, error } = await client().rpc(source.name, {\n p_tenant_id: resolveTenantId(),\n p_from: state.dateRange.from,\n p_to: state.dateRange.to,\n ...Object.fromEntries(Object.entries(state.filters ?? {}).map(([k, v]) => [`p_${k}`, v])),\n })\n if (error) throw error\n const rows: AnalyticsRow[] = Array.isArray(data) ? data : (data?.rows ?? [])\n return {\n rows: rows.map((r) => mapRow(r, reserved, source.columnMap)),\n total: Array.isArray(data) ? rows.length : (data?.total ?? rows.length),\n summary: Array.isArray(data) ? undefined : data?.summary,\n }\n }\n\n // The standard path: the generic aggregate engine.\n const args = runArgs(card, state, resolveTenantId())\n const { data, error } = await client().rpc('analytics_run', {\n p_source: args.source,\n p_tenant_id: args.tenant_id,\n p_from: args.from,\n p_to: args.to,\n p_dimensions: args.dimensions,\n p_measures: args.measures,\n p_filters: args.filters,\n p_search: args.search,\n p_search_columns: args.search_columns,\n p_sort: args.sort,\n p_dir: args.dir,\n p_limit: args.limit,\n p_offset: args.offset,\n })\n if (error) throw error\n return toResult(data, card, reserved)\n },\n\n // -----------------------------------------------------------------------\n // The batched path.\n //\n // Every aggregate card in the batch becomes ONE analytics_run_batch call;\n // detail listings and 'fn' cards, which the batch function cannot express,\n // still go one by one — but a dashboard is all aggregates, so opening\n // /analytics went from forty-one requests to one.\n //\n // Results keep their INDEX. The caller matched a promise to a position, and\n // returning a compacted array would silently hand card 7 card 9's numbers.\n // -----------------------------------------------------------------------\n async runMany(requests: AnalyticsBatchRequest[]): Promise<Array<AnalyticsResult | Error>> {\n const out: Array<AnalyticsResult | Error> = new Array(requests.length)\n const batchable: number[] = []\n\n for (let i = 0; i < requests.length; i++) {\n if (batchSupported && isAggregateCard(requests[i]!.card)) batchable.push(i)\n }\n\n // Anything the batch cannot carry runs on its own, concurrently.\n const singles = requests\n .map((req, i) => ({ req, i }))\n .filter(({ i }) => !batchable.includes(i))\n .map(({ req, i }) =>\n this.run(req.card, req.state)\n .then((r) => { out[i] = r })\n .catch((e: unknown) => { out[i] = toError(e) }))\n\n if (batchable.length > 0) {\n const tenantId = resolveTenantId()\n const payload = batchable.map((i) => runArgs(requests[i]!.card, requests[i]!.state, tenantId))\n const { data, error } = await client().rpc('analytics_run_batch', { p_requests: payload })\n\n if (error && batchUnavailable(error)) {\n // A pool that has analytics_run but not 034 must keep working rather\n // than reporting \"engine not installed\" on every card. Latched, so\n // the fallback costs one failed call per session, not per fetch.\n batchSupported = false\n await Promise.all([\n ...singles,\n ...batchable.map((i) =>\n this.run(requests[i]!.card, requests[i]!.state)\n .then((r) => { out[i] = r })\n .catch((e: unknown) => { out[i] = toError(e) })),\n ])\n return out\n }\n if (error) throw error\n\n const results: any[] = Array.isArray(data) ? data : []\n batchable.forEach((cardIndex, slot) => {\n const entry = results[slot]\n const { card } = requests[cardIndex]!\n out[cardIndex] = entry?.error\n ? Object.assign(toError(entry.error), { code: entry.code })\n : toResult(entry, card, reservedKeys(card))\n })\n }\n\n await Promise.all(singles)\n return out\n },\n }\n}\n","import type {\n AnalyticsCardDef, AnalyticsProvider, AnalyticsQueryState, AnalyticsRow,\n} from '@fayz-ai/core'\nimport { aggregateRows } from './aggregate'\n\n// ---------------------------------------------------------------------------\n// Mock analytics provider — synthesises rows shaped by whatever the card asks\n// for, then runs them through the SAME aggregator the 'fn' source uses. The\n// numbers are invented; the grouping, bucketing and rollup behaviour is real,\n// so a card that looks right against the mock is not lying about its shape.\n//\n// Deterministic on purpose: a seeded generator means the dev dashboard does not\n// reshuffle on every keystroke, and a screenshot stays reproducible.\n// ---------------------------------------------------------------------------\n\nfunction seeded(seed: string): () => number {\n let h = 2166136261\n for (let i = 0; i < seed.length; i++) {\n h ^= seed.charCodeAt(i)\n h = Math.imul(h, 16777619)\n }\n return () => {\n h += 0x6d2b79f5\n let t = h\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\nconst SAMPLE_LABELS: Record<string, string[]> = {\n product_name: ['Camiseta Preta', 'Caneca Fayz', 'Moletom', 'Boné', 'Adesivos'],\n category_name: ['Vestuário', 'Acessórios', 'Casa'],\n customer_name: ['Ana Souza', 'Bruno Lima', 'Carla Dias', 'Diego Alves'],\n status: ['open', 'archived', 'cancelled'],\n financial_status: ['paid', 'pending', 'refunded'],\n fulfillment_status: ['fulfilled', 'unfulfilled', 'partially_fulfilled'],\n}\n\nfunction labelsFor(key: string, rand: () => number): string[] {\n const known = SAMPLE_LABELS[key]\n if (known) return known\n const n = 3 + Math.floor(rand() * 3)\n return Array.from({ length: n }, (_, i) => `${key.replace(/_/g, ' ')} ${i + 1}`)\n}\n\nexport function createMockAnalyticsProvider(): AnalyticsProvider {\n return {\n async run(card: AnalyticsCardDef, state: AnalyticsQueryState) {\n const rand = seeded(card.id)\n const dateColumn = card.query.dateColumn ?? 'created_at'\n const dimensions = card.query.dimensions ?? []\n const measures = card.query.measures ?? []\n\n const from = new Date(`${state.dateRange.from}T12:00:00`).getTime()\n const to = new Date(`${state.dateRange.to}T12:00:00`).getTime()\n const span = Math.max(to - from, 86_400_000)\n\n // Enough rows that every bucket and every category is represented, capped\n // so a 90-day range does not synthesise thousands of throwaway objects.\n const rowCount = Math.min(400, Math.max(60, Math.round(span / 86_400_000) * 4))\n const categoricalDims = dimensions.filter((d) => !d.grain && d.key !== dateColumn)\n const labelPools = new Map(categoricalDims.map((d) => [d.key, labelsFor(d.key, rand)]))\n\n const rows: AnalyticsRow[] = Array.from({ length: rowCount }, () => {\n const row: AnalyticsRow = {\n [dateColumn]: new Date(from + rand() * span).toISOString(),\n }\n for (const [key, pool] of labelPools) {\n row[key] = pool[Math.floor(rand() * pool.length)]\n }\n for (const m of measures) {\n if (m.agg === 'count' || m.agg === 'ratio') continue\n const column = m.column ?? m.key\n row[column] = m.format === 'currency'\n ? Math.round(rand() * 40000) / 100\n : m.format === 'percent'\n ? Math.round(rand() * 10000) / 100\n : Math.round(rand() * 50)\n }\n for (const c of card.columns ?? []) {\n if (c.key in row) continue\n row[c.key] = c.type === 'currency' || c.type === 'number'\n ? Math.round(rand() * 10000) / 100\n : c.type === 'date'\n ? new Date(from + rand() * span).toISOString()\n : `${c.label} ${Math.ceil(rand() * 20)}`\n }\n return row\n })\n\n return aggregateRows(rows, card, state)\n },\n\n // There is no transport to save a round trip on, so this is just the loop.\n // It exists because the mock is reached through createSafeDataProvider,\n // whose Proxy answers EVERY property with a function — `provider.runMany`\n // is truthy even for a provider that never declared it, and the caller's\n // feature check therefore cannot detect its absence. Implementing it is how\n // the mock stops being a landmine behind that Proxy.\n async runMany(requests) {\n return Promise.all(requests.map((r) =>\n this.run(r.card, r.state).catch((e: unknown) => (e instanceof Error ? e : new Error(String(e))))))\n },\n }\n}\n","import { useOrganizationStore } from '@fayz-ai/admin'\n\n// ---------------------------------------------------------------------------\n// Which tenant the analytics surface is reporting on.\n//\n// Defaults to the organization the shell is currently switched to. Leaving it\n// undefined is NOT equivalent: with no tenant the engine sends no predicate and\n// falls back to RLS alone, and RLS on the shop tables admits every tenant the\n// user is a member of (`tenant_id IN user_tenant_ids()`). In a multi-org app\n// that is one page reporting the sum of every store the operator can see, while\n// every other screen beside it shows only the active one.\n// ---------------------------------------------------------------------------\n\nlet override: string | undefined\n\n/** Pin the surface to a tenant, overriding the active organization. */\nexport function setReportsTenantId(id: string | undefined): void {\n override = id\n}\n\nexport function getReportsTenantId(): string | undefined {\n if (override) return override\n try {\n return useOrganizationStore.getState().currentOrg?.id\n } catch {\n // No org store mounted (a bespoke host, a test): fall back to RLS rather\n // than throwing inside a data provider.\n return undefined\n }\n}\n","export const en: Record<string, string> = {\n 'reports.pageTitle': 'Reports',\n 'reports.pageSubtitle': 'Access complete reports for analysis and decision making',\n 'reports.overview': 'Overview',\n 'reports.allReports': 'All reports',\n 'reports.dateRange': 'Date Range',\n 'reports.from': 'From',\n 'reports.to': 'To',\n 'reports.export': 'Export',\n 'reports.exportCsv': 'Export CSV',\n 'reports.exportExcel': 'Export Excel',\n 'reports.exportPdf': 'Export PDF',\n 'reports.noResults': 'No results found.',\n 'reports.backToReports': 'Back',\n 'reports.reports': 'reports',\n 'reports.search': 'Search reports...',\n 'reports.today': 'Today',\n 'reports.yesterday': 'Yesterday',\n 'reports.last7Days': 'Last 7 days',\n 'reports.thisMonth': 'This month',\n 'reports.lastMonth': 'Last month',\n 'reports.thisQuarter': 'This quarter',\n 'reports.custom': 'Custom',\n 'reports.generate': 'Generate',\n 'reports.emptyStateTitle': 'Ready to generate',\n 'reports.emptyStateDescription': 'Select a date range and filters, then click Generate to view the report.',\n // The assistant's invitation on /analytics. It opens on a question, not on a\n // grid: the numbers are already downstairs, and what the owner actually wants\n // is to know what they mean.\n 'reports.assistant.persona': 'Growth Analyst',\n 'reports.assistant.headline': 'Hi {{name}}, what would you like to learn today?',\n 'reports.assistant.pitch': \"Let's find the opportunities hiding in your business\",\n 'reports.assistant.description':\n \"Tell me your goals and I'll help build a plan to hit them. I read the same data these reports do, and I'll point at what changed and what to do about it.\",\n 'reports.assistant.placeholder': 'Build a custom report...',\n 'reports.assistant.suggestion.0': 'How is my business doing this month?',\n 'reports.assistant.suggestion.1': \"What's growing and what's falling?\",\n 'reports.assistant.suggestion.2': 'Where am I losing money?',\n 'reports.unavailableTitle': 'Coming soon',\n 'reports.unavailableDescription': 'This report is not available yet. It will be enabled in a future update.',\n}\n","export const ptBR: Record<string, string> = {\n 'reports.pageTitle': 'Relatórios',\n 'reports.pageSubtitle': 'Acesse relatórios completos para análise e tomada de decisão',\n 'reports.overview': 'Visão geral',\n 'reports.allReports': 'Todos os relatórios',\n 'reports.dateRange': 'Período',\n 'reports.from': 'De',\n 'reports.to': 'Até',\n 'reports.export': 'Exportar',\n 'reports.exportCsv': 'Exportar CSV',\n 'reports.exportExcel': 'Exportar Excel',\n 'reports.exportPdf': 'Exportar PDF',\n 'reports.noResults': 'Nenhum resultado encontrado.',\n 'reports.backToReports': 'Voltar',\n 'reports.reports': 'relatórios',\n 'reports.search': 'Buscar relatórios...',\n 'reports.today': 'Hoje',\n 'reports.yesterday': 'Ontem',\n 'reports.last7Days': 'Últimos 7 dias',\n 'reports.thisMonth': 'Este mês',\n 'reports.lastMonth': 'Mês passado',\n 'reports.thisQuarter': 'Este trimestre',\n 'reports.custom': 'Personalizado',\n 'reports.generate': 'Gerar',\n 'reports.emptyStateTitle': 'Pronto para gerar',\n 'reports.emptyStateDescription': 'Selecione o período e os filtros desejados, depois clique em Gerar para visualizar o relatório.',\n 'reports.assistant.persona': 'Analista de Crescimento',\n 'reports.assistant.headline': 'Oi {{name}}, o que você quer entender hoje?',\n 'reports.assistant.pitch': 'Vamos achar as oportunidades escondidas no seu negócio',\n 'reports.assistant.description':\n 'Me conte sua meta e eu ajudo a montar o plano para bater. Leio os mesmos dados destes relatórios e aponto o que mudou e o que fazer a respeito.',\n 'reports.assistant.placeholder': 'Peça um relatório do seu jeito...',\n 'reports.assistant.suggestion.0': 'Como está meu negócio neste mês?',\n 'reports.assistant.suggestion.1': 'O que está crescendo e o que está caindo?',\n 'reports.assistant.suggestion.2': 'Onde estou perdendo dinheiro?',\n 'reports.unavailableTitle': 'Em breve',\n 'reports.unavailableDescription': 'Este relatório ainda não está disponível. Será habilitado em uma atualização futura.',\n}\n","import { en } from './en'\nimport { ptBR } from './pt-BR'\n\nexport const reportsLocales: Record<string, Record<string, string>> = {\n en,\n 'pt-BR': ptBR,\n}\n","import type { AnalyticsCardDef, AnalyticsColumnDef, AnalyticsFilterDef } from '@fayz-ai/core'\nimport type { ReportDef } from '../types'\n\n// ---------------------------------------------------------------------------\n// ReportDef → AnalyticsCardDef.\n//\n// Consuming apps declare hundreds of lines of ReportDef today. Rewriting them\n// all in one commit is how a refactor stalls, so the old shape keeps working: a\n// legacy report becomes a card with a table viz and no dashboard placement — it\n// appears in the report list, opens in the viewer, and simply never claims a\n// tile on the overview.\n//\n// Nothing here is lossy. When an app is ready, it upgrades a report in place by\n// adding dimensions/measures and a `dashboard` block, and the same definition\n// starts also being a chart on the overview.\n// ---------------------------------------------------------------------------\n\nexport function reportDefToCard(report: ReportDef, createdBy?: string): AnalyticsCardDef {\n return {\n id: report.id,\n name: report.name,\n description: report.description,\n icon: report.icon,\n category: report.category,\n createdBy,\n available: report.available,\n grain: report.grain,\n canonicalOwner: report.canonicalOwner,\n permission: report.permission,\n query: {\n source: {\n kind: report.dataSource.kind,\n name: report.dataSource.name,\n columnMap: report.dataSource.columnMap,\n },\n dateColumn: report.dataSource.dateColumn,\n defaultSort: report.dataSource.defaultSort,\n defaultSortDir: report.dataSource.defaultSortDir,\n filters: (report.filters ?? []).map((f): AnalyticsFilterDef => ({\n key: f.key,\n label: f.label,\n type: f.type,\n options: f.options,\n defaultValue: f.defaultValue,\n placeholder: f.placeholder,\n // Legacy filters declared no category. Grouping them under the report's\n // own category keeps the picker organised instead of dumping every\n // filter from every report into one flat list.\n group: report.category,\n })),\n },\n // No dimensions/measures: a legacy report is a detail listing, and inventing\n // aggregations for it would change what the numbers mean.\n viz: { type: 'table' },\n columns: report.columns.map((c): AnalyticsColumnDef => ({\n key: c.key,\n label: c.label,\n type: c.type as AnalyticsColumnDef['type'],\n sortable: c.sortable,\n currency: c.currency,\n idKey: c.idKey,\n personKind: c.personKind,\n renderCell: c.renderCell,\n visible: c.visible,\n align: c.align,\n aggregate: c.aggregate,\n })),\n }\n}\n\nexport function reportDefsToCards(reports: ReportDef[], createdBy?: string): AnalyticsCardDef[] {\n return reports.map((r) => reportDefToCard(r, createdBy))\n}\n","import * as React from 'react'\n\n// ---------------------------------------------------------------------------\n// \"Last viewed\" for the report list.\n//\n// A catalogue of eighty reports sorted alphabetically is a filing cabinet; the\n// three a merchant actually opens each Monday are what they came for. This is\n// per-browser rather than per-tenant on purpose — it is a convenience ordering,\n// not a business fact, and it should not cost a write to the database on every\n// report a user glances at.\n// ---------------------------------------------------------------------------\n\nconst KEY = 'fayz.analytics.lastViewed'\n\ntype LastViewedMap = Record<string, string>\n\nfunction read(): LastViewedMap {\n if (typeof window === 'undefined') return {}\n try {\n const raw = window.localStorage.getItem(KEY)\n return raw ? (JSON.parse(raw) as LastViewedMap) : {}\n } catch {\n return {}\n }\n}\n\nfunction write(map: LastViewedMap): void {\n if (typeof window === 'undefined') return\n try {\n window.localStorage.setItem(KEY, JSON.stringify(map))\n } catch {\n /* quota or private mode — losing this costs an ordering, not data */\n }\n}\n\nconst listeners = new Set<(map: LastViewedMap) => void>()\n\nexport function markViewed(cardId: string): void {\n const next = { ...read(), [cardId]: new Date().toISOString() }\n write(next)\n for (const listener of listeners) listener(next)\n}\n\nexport function useLastViewed(): LastViewedMap {\n const [map, setMap] = React.useState<LastViewedMap>(() => read())\n React.useEffect(() => {\n listeners.add(setMap)\n return () => { listeners.delete(setMap) }\n }, [])\n return map\n}\n","import React from 'react'\nimport {\n usePluginRuntime, getAnalyticsCards, hashRouterAdapter,\n type AnalyticsCardDef, type AnalyticsProvider as AnalyticsProviderType, type AnalyticsColumnDef,\n type AnalyticsCompare,\n} from '@fayz-ai/core'\nimport { AnalyticsContextProvider, type AnalyticsRangePreset } from '@fayz-ai/ui'\nimport { markViewed } from '../lib/lastViewed'\n\n// ---------------------------------------------------------------------------\n// The surface every analytics page mounts inside.\n//\n// Cards arrive from two places and are merged here: the plugins that own the\n// data contribute them through the runtime registry (`analyticsCards` on the\n// manifest), and the host app adds or overrides via options. Registry first,\n// app last — an app curating its own pack must be able to win.\n// ---------------------------------------------------------------------------\n\nexport const ANALYTICS_BASE = '/analytics'\nexport const REPORTS_BASE = `${ANALYTICS_BASE}/reports`\n\nexport interface AnalyticsLabels {\n analytics: string\n reports: string\n liveView: string\n /** Rail entry for the card grid. Falls back to the `reports.overview` key. */\n overview?: string\n overviewSubtitle: string\n reportsSubtitle: string\n searchReports: string\n category: string\n createdBy: string\n /** Cleared state of each facet chip: \"All categories\" / \"All authors\". */\n allCategories: string\n allCreatedBy: string\n lastViewed: string\n name: string\n noResults: string\n never: string\n back: string\n export: string\n print: string\n unavailableTitle: string\n unavailableDescription: string\n emptyOverviewTitle: string\n emptyOverviewDescription: string\n liveViewSoon: string\n results: string\n}\n\n/** How the assistant introduces itself on the analytics screens. Every field is\n * optional: what is not set falls back to the plugin's own locale strings. */\nexport interface AnalyticsAssistantConfig {\n /** Names the assistant here — \"Growth Analyst\". */\n persona?: string\n /** Hero headline. `{{name}}` resolves to the signed-in user's first name. */\n headline?: string\n pitch?: string\n description?: string\n placeholder?: string\n suggestions?: { label: string; prompt?: string }[]\n /** `true` opens on the hero takeover. Default FALSE here, unlike the shell's:\n * the analytics home is a page of numbers, and a full-column invitation over\n * them hides the very thing the user navigated to. The composer docks at the\n * bottom instead — the assistant is offered, the metrics stay readable. */\n auto?: boolean\n}\n\nexport interface ResolvedAnalyticsConfig {\n /** Cards declared by the host app (merged with the plugin registry at render). */\n cards: AnalyticsCardDef[]\n labels: AnalyticsLabels\n currency: { code: string; locale: string; symbol: string }\n /** Attribution for pre-built cards — the product name, e.g. \"FayzShop\". */\n createdBy: string\n defaultPageSize: number\n showHeader: boolean\n /** Range the surface opens on. A salon reads 30 days; a school reads a term. */\n defaultRange: AnalyticsRangePreset\n defaultCompare: AnalyticsCompare\n /** Whether the Live View entry appears in the module rail. */\n showLiveView: boolean\n /** `null` mounts no invite — the screen opens on its numbers, not on a\n * conversation. Otherwise: the overrides, over the locale defaults. */\n assistant: AnalyticsAssistantConfig | null\n}\n\nconst ConfigContext = React.createContext<ResolvedAnalyticsConfig | null>(null)\n\nexport function useAnalyticsConfig(): ResolvedAnalyticsConfig {\n const ctx = React.useContext(ConfigContext)\n if (!ctx) throw new Error('useAnalyticsConfig must be used inside <AnalyticsSurface>')\n return ctx\n}\n\n/**\n * Every card visible on this surface, registry + app, de-duplicated by id.\n *\n * The app's own definition wins a collision so a host can retune a card the\n * plugin shipped (relabel it, move it off the overview) without forking the\n * plugin — the alternative is apps carrying patched copies of plugin cards.\n */\nexport function useAnalyticsCards(): AnalyticsCardDef[] {\n const runtime = usePluginRuntime()\n const { cards, createdBy } = useAnalyticsConfig()\n return React.useMemo(() => {\n const byId = new Map<string, AnalyticsCardDef>()\n for (const card of getAnalyticsCards(runtime)) byId.set(card.id, card)\n for (const card of cards) byId.set(card.id, card)\n return [...byId.values()].map((c) => (c.createdBy ? c : { ...c, createdBy }))\n }, [runtime, cards, createdBy])\n}\n\n/** Cards a pack placed on the overview grid, in their declared order. */\nexport function useOverviewCards(): AnalyticsCardDef[] {\n const all = useAnalyticsCards()\n return React.useMemo(\n () => all\n .filter((c) => c.dashboard && c.dashboard.defaultVisible !== false)\n .sort((a, b) => (a.dashboard?.order ?? 0) - (b.dashboard?.order ?? 0)),\n [all],\n )\n}\n\n/**\n * Columns for a card's tabular view.\n *\n * An aggregate card has no `columns` of its own — its table IS its dimensions\n * and measures, so deriving them keeps one definition instead of asking every\n * card author to restate the same fields twice and let the two drift.\n */\nexport function cardColumns(card: AnalyticsCardDef): AnalyticsColumnDef[] {\n if (card.columns?.length) return card.columns\n return [\n // A hidden dimension is group-by only — the id a person column reads from,\n // never a column of UUIDs next to the name it belongs to.\n ...(card.query.dimensions ?? []).filter((d) => !d.hidden).map((d): AnalyticsColumnDef => ({\n key: d.key,\n label: d.label,\n type: d.person ? 'person' : (d.format ?? (d.grain ? 'date' : 'text')),\n idKey: d.person?.idKey,\n personKind: d.person?.kind,\n align: 'left',\n })),\n ...(card.query.measures ?? []).map((m): AnalyticsColumnDef => ({\n key: m.key,\n label: m.label,\n type: m.format ?? 'number',\n align: 'right',\n sortable: true,\n })),\n ]\n}\n\nexport function navigateAnalytics(path: string): void {\n hashRouterAdapter().navigate(path)\n}\n\nexport interface AnalyticsSurfaceProps {\n config: ResolvedAnalyticsConfig\n provider: AnalyticsProviderType\n children?: React.ReactNode\n}\n\nexport function AnalyticsSurface({ config, provider, children }: AnalyticsSurfaceProps) {\n const openCard = React.useCallback((card: AnalyticsCardDef) => {\n markViewed(card.id)\n navigateAnalytics(`${REPORTS_BASE}/${encodeURIComponent(card.id)}`)\n }, [])\n\n return (\n <ConfigContext.Provider value={config}>\n <AnalyticsContextProvider\n provider={provider}\n currency={config.currency}\n defaultPreset={config.defaultRange}\n defaultCompare={config.defaultCompare}\n defaultPageSize={config.defaultPageSize}\n onOpenCard={openCard}\n createdBy={config.createdBy}\n >\n {children}\n </AnalyticsContextProvider>\n </ConfigContext.Provider>\n )\n}\n","import React from 'react'\nimport { useTranslation } from '@fayz-ai/core'\nimport { AssistantInvite } from '@fayz-ai/admin'\nimport { useAnalyticsConfig } from './AnalyticsSurface'\n\n// ---------------------------------------------------------------------------\n// The assistant's offer on Analytics.\n//\n// It belongs to the MODULE, not to the overview: a question about a report is\n// asked while reading that report, and a composer that only exists on the home\n// screen makes the user navigate away from the number to ask about it.\n// ---------------------------------------------------------------------------\n\nexport function AnalyticsAssistant() {\n const { assistant } = useAnalyticsConfig()\n const t = useTranslation()\n\n // Prompts the screen offers. App overrides win whole; otherwise the plugin's\n // own three, which are business questions and not report names on purpose.\n const suggestions = React.useMemo(\n () => assistant?.suggestions ?? [0, 1, 2].map((i) => ({ label: t(`reports.assistant.suggestion.${i}`) })),\n [assistant?.suggestions, t],\n )\n\n if (!assistant) return null\n\n return (\n <AssistantInvite\n // One id across the module: the same invitation followed from the grid to\n // a report, which is what lets the bar stay put instead of folding back\n // into the FAB and unrolling again on every internal navigation.\n id=\"analytics\"\n auto={assistant.auto ?? false}\n persona={assistant.persona ?? t('reports.assistant.persona')}\n headline={assistant.headline ?? t('reports.assistant.headline')}\n pitch={assistant.pitch ?? t('reports.assistant.pitch')}\n description={assistant.description ?? t('reports.assistant.description')}\n placeholder={assistant.placeholder ?? t('reports.assistant.placeholder')}\n suggestions={suggestions}\n />\n )\n}\n","import React from 'react'\nimport { ModulePage, useModuleLayout, type ModuleNavItem, type NavigationItem } from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\nimport type { AnalyticsCardDef } from '@fayz-ai/core'\nimport { useContextualNav, useShellRailAvailable } from '@fayz-ai/admin'\nimport {\n useAnalyticsConfig, useAnalyticsCards, navigateAnalytics, ANALYTICS_BASE, REPORTS_BASE,\n} from './AnalyticsSurface'\nimport { AnalyticsAssistant } from './AnalyticsAssistant'\n\n// ---------------------------------------------------------------------------\n// Analytics is ONE entry in the app nav, not two.\n//\n// \"Analytics\" and \"Reports\" were two top-level links to the same engine, which\n// made the user pick a door before knowing what was behind it. There is one\n// door now; inside it, the report groups (a card's `category`) and the reports\n// themselves ARE the navigation.\n//\n// Where that navigation is drawn depends on the product's shell, and the module\n// declares the tree once either way:\n//\n// sidebar layout — it takes over the app rail, exactly as /settings does\n// (useContextualNav). A second left column beside the app\n// rail is a menu inside a menu.\n// topbar layout — there is no rail to take over, so ModulePage draws its own\n// in-page one, like every other module.\n//\n// Charts are not re-implemented here: AnalyticsCard renders through the same\n// ChartWidget the dashboard uses.\n// ---------------------------------------------------------------------------\n\nexport type AnalyticsView = 'overview' | 'reports' | 'report' | 'live'\n\nexport interface AnalyticsModuleProps {\n view: AnalyticsView\n /** Route param when `view === 'report'` — marks the active entry. */\n cardId?: string\n children?: React.ReactNode\n}\n\nconst reportRoute = (cardId: string) => `${REPORTS_BASE}/${encodeURIComponent(cardId)}`\n\n/** Cards by category, categories A→Z, reports A→Z inside each. */\nfunction groupCards(cards: AnalyticsCardDef[]): [string, AnalyticsCardDef[]][] {\n const groups = new Map<string, AnalyticsCardDef[]>()\n for (const card of cards) {\n const list = groups.get(card.category)\n if (list) list.push(card)\n else groups.set(card.category, [card])\n }\n return [...groups.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([category, list]) => [category, [...list].sort((a, b) => a.name.localeCompare(b.name))])\n}\n\n/** The module's whole tree, in the order both renderers walk it. */\nfunction useAnalyticsTree() {\n const t = useTranslation()\n const { labels, showLiveView } = useAnalyticsConfig()\n const cards = useAnalyticsCards()\n\n return React.useMemo(() => ({\n title: labels.analytics,\n // Only the overview. The searchable catalogue (/analytics/reports) is still\n // routed — bookmarks and the legacy /reports link resolve — but it is not\n // listed: the tree below already IS the catalogue, and a link named \"all\n // reports\" sitting above the reports reads as a different, fuller list.\n fixed: [\n { id: 'overview', label: labels.overview ?? t('reports.overview'), icon: 'BarChart3', route: ANALYTICS_BASE, view: 'overview' as const },\n ],\n groups: groupCards(cards),\n live: showLiveView\n ? { id: 'live', label: labels.liveView, icon: 'Radio', route: `${ANALYTICS_BASE}/live`, view: 'live' as const }\n : null,\n }), [labels, showLiveView, cards, t])\n}\n\nexport function AnalyticsModule({ view, cardId, children }: AnalyticsModuleProps) {\n const variant = useModuleLayout()\n const tree = useAnalyticsTree()\n const activeId = cardId ? decodeURIComponent(cardId) : undefined\n // Does a shell rail exist to take over? The SHELL answers — it is the only\n // thing that knows. Asking the module-nav context instead meant reading its\n // default ('rail' = \"draw your own\") whenever the provider was out of the\n // tree, and the app rail plus this module's own column made exactly the two\n // menus the takeover exists to remove. The context is the fallback, for a\n // module mounted outside an AdminShell at all.\n const shellRail = useShellRailAvailable()\n const claimsRail = shellRail ?? (variant !== 'rail')\n\n // --- the shell rail (sidebar layout) -------------------------------------\n const entries = React.useMemo<NavigationItem[]>(() => [\n ...tree.fixed.map((f) => ({\n id: `analytics:${f.id}`, label: f.label, icon: f.icon, route: f.route, section: 'main' as const,\n })),\n ...tree.groups.flatMap(([category, list]) => list.map((card) => ({\n id: `analytics:${card.id}`,\n label: card.name,\n icon: card.icon ?? 'FileText',\n route: reportRoute(card.id),\n section: 'main' as const,\n // Consecutive items sharing a group render under one heading — the same\n // mechanism that heads the settings rail's plugin runs.\n group: category,\n }))),\n ...(tree.live ? [{\n id: 'analytics:live', label: tree.live.label, icon: tree.live.icon, route: tree.live.route, section: 'main' as const,\n }] : []),\n ], [tree])\n\n useContextualNav(claimsRail ? { base: ANALYTICS_BASE, entries, label: tree.title } : null)\n\n // --- the in-page rail (topbar layout) ------------------------------------\n const nav = React.useMemo<ModuleNavItem[]>(() => {\n if (claimsRail) return []\n return [\n ...tree.fixed.map((f) => ({\n id: f.id, label: f.label, icon: f.icon, active: view === f.view, onClick: () => navigateAnalytics(f.route),\n })),\n ...tree.groups.map(([category, list]): ModuleNavItem => ({\n id: `group:${category}`,\n label: category,\n children: list.map((card) => ({\n id: card.id,\n label: card.name,\n active: view === 'report' && card.id === activeId,\n onClick: () => navigateAnalytics(reportRoute(card.id)),\n })),\n })),\n ...(tree.live ? [{\n id: tree.live.id, label: tree.live.label, icon: tree.live.icon,\n active: view === 'live', onClick: () => navigateAnalytics(tree.live!.route),\n }] : []),\n ]\n }, [tree, view, activeId, claimsRail])\n\n return (\n <ModulePage\n title={tree.title}\n nav={nav}\n // 'sidebar' renders no sub-nav in the page: the shell rail is carrying it.\n navVariant={claimsRail ? 'sidebar' : 'rail'}\n showHeader={false}\n viewKey={view === 'report' ? `report:${activeId}` : view}\n >\n {/* Above the page body and outside its flow: the invite occupies no\n layout, it only measures where the content column is. */}\n <AnalyticsAssistant />\n {/* Tail room for the docked composer, which floats over the column —\n without it the last row of every analytics page ends underneath it. */}\n <div className=\"md:pb-16\">{children}</div>\n </ModulePage>\n )\n}\n","import React from 'react'\nimport { BarChart3 } from 'lucide-react'\nimport { AnalyticsControls, AnalyticsGrid, collectFilters } from '@fayz-ai/ui'\nimport { useAnalyticsConfig, useOverviewCards } from './AnalyticsSurface'\n\n// ---------------------------------------------------------------------------\n// The one general dashboard.\n//\n// It is not a separate feature from the report list — it is the subset of cards\n// a pack chose to place, rendered at tile size. Every tile's ↗ opens the very\n// same definition as a full report, which is why there is no \"dashboard metric\"\n// that has no report behind it.\n// ---------------------------------------------------------------------------\n\nexport function AnalyticsOverview() {\n const { labels, showHeader } = useAnalyticsConfig()\n const cards = useOverviewCards()\n const filters = React.useMemo(() => collectFilters(cards), [cards])\n\n // The assistant's invite is mounted by the module, not here: it follows the\n // user from this grid into a report instead of belonging to one screen.\n return (\n <>\n <div className=\"space-y-4\">\n {showHeader ? (\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">{labels.analytics}</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">{labels.overviewSubtitle}</p>\n </div>\n ) : null}\n\n {/* Sticky so the range you are reading stays on screen while you scroll\n twenty cards. The surface itself (rounded, bordered, shadowed) comes\n from AnalyticsControls, so the report viewer gets the same bar.\n `top-3` and not `top-0`: a floating bar needs air above it or it welds\n itself to the page title the moment you scroll, and the shadow that\n says \"this is on top of the grid\" has nothing to fall on. */}\n <AnalyticsControls filters={filters} className=\"sticky top-3 z-20\" />\n\n {cards.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed py-16 text-center\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <BarChart3 className=\"h-5 w-5 text-muted-foreground\" />\n </div>\n <p className=\"font-medium\">{labels.emptyOverviewTitle}</p>\n <p className=\"mt-1 max-w-sm text-sm text-muted-foreground\">{labels.emptyOverviewDescription}</p>\n </div>\n ) : (\n <AnalyticsGrid cards={cards} />\n )}\n </div>\n </>\n )\n}\n","import React from 'react'\nimport { Search, User } from 'lucide-react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport {\n Card, DataTable, FilterChip, type FilterChipOption,\n} from '@fayz-ai/ui'\nimport type { AnalyticsCardDef } from '@fayz-ai/core'\nimport { useAnalyticsConfig, useAnalyticsCards, navigateAnalytics, REPORTS_BASE } from './AnalyticsSurface'\nimport { useLastViewed, markViewed } from '../lib/lastViewed'\n\n// ---------------------------------------------------------------------------\n// The one list where a user finds what they want.\n//\n// This replaces the old category-card hub. Cards-in-a-grid look richer but stop\n// working past about twenty reports: you cannot sort them, cannot see when you\n// last opened one, and finding \"sales by vendor\" means reading every tile. A\n// table sorts, scans and filters — which is what a catalogue is for.\n//\n// It renders through the shared DataTable rather than a hand-rolled <table>.\n// The first version copied DataTable's classes by hand and drifted from it\n// immediately — wrong header tint, wrong corner radius — because a copy has to\n// be re-copied every time the original moves. `variant=\"bare\"` exists for this\n// exact shape: a table under a search toolbar, inside a card that already owns\n// the border and radius.\n// ---------------------------------------------------------------------------\n\nfunction formatViewed(iso: string | undefined, locale: string, never: string): string {\n if (!iso) return never\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return never\n return d.toLocaleDateString(locale, { day: 'numeric', month: 'short', year: 'numeric' })\n}\n\nexport function ReportsListPage() {\n const { labels, currency, showHeader } = useAnalyticsConfig()\n const cards = useAnalyticsCards()\n const lastViewed = useLastViewed()\n\n const [search, setSearch] = React.useState('')\n // Single-select, like every other facet in the product (see FilterChip):\n // the chip states what is filtering right now, and picking \"all\" clears it.\n const [category, setCategory] = React.useState<string | undefined>()\n const [author, setAuthor] = React.useState<string | undefined>()\n\n const categoryOptions = React.useMemo<FilterChipOption[]>(\n () => [...new Set(cards.map((c) => c.category))]\n .sort((a, b) => a.localeCompare(b))\n .map((c) => ({ value: c, label: c })),\n [cards],\n )\n const authorOptions = React.useMemo<FilterChipOption[]>(\n () => [...new Set(cards.map((c) => c.createdBy ?? '—'))]\n .sort((a, b) => a.localeCompare(b))\n .map((a) => ({ value: a, label: a })),\n [cards],\n )\n\n const rows = React.useMemo(() => {\n const q = search.trim().toLowerCase()\n return cards.filter((card) => {\n if (category && card.category !== category) return false\n if (author && (card.createdBy ?? '—') !== author) return false\n if (!q) return true\n // Description is searched too: users look for \"no-show\" long before they\n // remember a report is filed under \"Cancellations\".\n return card.name.toLowerCase().includes(q)\n || card.description?.toLowerCase().includes(q)\n || card.category.toLowerCase().includes(q)\n })\n }, [cards, search, category, author])\n\n const columns = React.useMemo<ColumnDef<AnalyticsCardDef, unknown>[]>(() => [\n {\n id: 'name',\n accessorFn: (card) => card.name,\n header: labels.name,\n cell: ({ row }) => (\n <div className=\"min-w-0\">\n <span className=\"font-medium\">{row.original.name}</span>\n {row.original.available === false ? (\n <span className=\"ml-2 rounded-full border px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n {labels.unavailableTitle}\n </span>\n ) : null}\n {row.original.description ? (\n <p className=\"mt-0.5 line-clamp-1 text-muted-foreground sm:hidden\">{row.original.description}</p>\n ) : null}\n </div>\n ),\n },\n {\n id: 'category',\n accessorFn: (card) => card.category,\n header: labels.category,\n cell: ({ getValue }) => (\n <span className=\"rounded-md bg-muted px-2 py-0.5\">{String(getValue() ?? '')}</span>\n ),\n },\n {\n id: 'lastViewed',\n // Sorts on the timestamp, renders the date. Never-opened reports carry\n // undefined so they sink to the bottom in BOTH directions rather than\n // topping \"most recent\" as an epoch-zero date.\n accessorFn: (card) => {\n const iso = lastViewed[card.id]\n return iso ? new Date(iso).getTime() : undefined\n },\n sortUndefined: 1,\n header: labels.lastViewed,\n cell: ({ row }) => (\n <span className=\"text-muted-foreground\">\n {formatViewed(lastViewed[row.original.id], currency.locale, labels.never)}\n </span>\n ),\n },\n {\n id: 'createdBy',\n accessorFn: (card) => card.createdBy ?? '—',\n header: labels.createdBy,\n cell: ({ getValue }) => (\n <span className=\"inline-flex items-center gap-1.5 text-muted-foreground\">\n <User className=\"h-3 w-3\" />\n {String(getValue() ?? '—')}\n </span>\n ),\n },\n ], [labels, currency.locale, lastViewed])\n\n const open = (card: AnalyticsCardDef) => {\n markViewed(card.id)\n navigateAnalytics(`${REPORTS_BASE}/${encodeURIComponent(card.id)}`)\n }\n\n return (\n <div className=\"space-y-4\">\n {showHeader ? (\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">{labels.reports}</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">{labels.reportsSubtitle}</p>\n </div>\n ) : null}\n\n {/* Same composition as CrudListView: search, tools and the table are ONE\n surface, because they act on the same rows. The Card owns the border\n and radius, so the table inside goes `bare`. */}\n <Card className=\"overflow-hidden\">\n <div className=\"flex flex-wrap items-center gap-2 border-b border-border px-3 py-2\">\n <div className=\"min-w-[10rem] flex-1\">\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground\" />\n {/* Borderless, exactly as CrudListView's search box: the card\n already draws the boundary, and a second box inside it would\n be a frame inside a frame. */}\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder={labels.searchReports}\n className=\"w-full bg-transparent py-1.5 pl-8 pr-3 text-sm placeholder:text-muted-foreground focus:outline-none\"\n />\n </div>\n </div>\n\n <div className=\"flex shrink-0 flex-wrap items-center gap-1.5\">\n <FilterChip\n label={labels.category}\n allLabel={labels.allCategories}\n options={categoryOptions}\n value={category}\n onChange={setCategory}\n />\n <FilterChip\n label={labels.createdBy}\n allLabel={labels.allCreatedBy}\n options={authorOptions}\n value={author}\n onChange={setAuthor}\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n data={rows}\n variant=\"bare\"\n compact\n onRowClick={open}\n emptyMessage={labels.noResults}\n />\n\n <div className=\"border-t border-border px-3 py-2 text-xs text-muted-foreground\">\n {rows.length} {labels.results}\n </div>\n </Card>\n </div>\n )\n}\n","import { exportCSV } from '@fayz-ai/core'\nimport type { CSVColumn } from '@fayz-ai/core'\nimport type { ReportColumnDef } from '../types'\nimport { formatValuePlain } from '../lib/columns'\n\nexport function exportToCsv(\n columns: ReportColumnDef[],\n data: Record<string, any>[],\n filename: string,\n currency?: string,\n): void {\n const visibleCols = columns.filter((c) => c.visible !== false)\n\n const csvColumns: CSVColumn[] = visibleCols.map((col) => ({\n key: col.key,\n label: col.label,\n format: (value: any) => formatValuePlain(value, col, currency),\n }))\n\n exportCSV(csvColumns, data, filename)\n}\n","import React, { useEffect, useState } from 'react'\nimport { Download } from 'lucide-react'\nimport { Button } from '@fayz-ai/ui'\nimport {\n Dropdown,\n DropdownTrigger,\n DropdownContent,\n DropdownItem,\n} from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\nimport type { ReportColumnDef } from '../types'\nimport { exportToCsv } from '../export/csv'\n\ninterface ExportDropdownProps {\n columns: ReportColumnDef[]\n data: Record<string, any>[]\n filename: string\n currency?: string\n title?: string\n}\n\nexport function ExportDropdown({ columns, data, filename, currency, title }: ExportDropdownProps) {\n const t = useTranslation()\n const [excelAvailable, setExcelAvailable] = useState(false)\n const [pdfAvailable, setPdfAvailable] = useState(false)\n\n useEffect(() => {\n import('../export/excel').then((m) => m.isExcelAvailable()).then(setExcelAvailable).catch(() => {})\n import('../export/pdf').then((m) => m.isPdfAvailable()).then(setPdfAvailable).catch(() => {})\n }, [])\n\n const handleCsv = () => exportToCsv(columns, data, filename, currency)\n\n const handleExcel = async () => {\n const { exportToExcel } = await import('../export/excel')\n await exportToExcel(columns, data, filename, currency)\n }\n\n const handlePdf = async () => {\n const { exportToPdf } = await import('../export/pdf')\n await exportToPdf(columns, data, filename, { title, currency })\n }\n\n return (\n <Dropdown>\n <DropdownTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"h-4 w-4 mr-1.5\" />\n {t('reports.export')}\n </Button>\n </DropdownTrigger>\n <DropdownContent align=\"end\">\n <DropdownItem onClick={handleCsv}>{t('reports.exportCsv')}</DropdownItem>\n {excelAvailable && (\n <DropdownItem onClick={handleExcel}>{t('reports.exportExcel')}</DropdownItem>\n )}\n {pdfAvailable && (\n <DropdownItem onClick={handlePdf}>{t('reports.exportPdf')}</DropdownItem>\n )}\n </DropdownContent>\n </Dropdown>\n )\n}\n","import React from 'react'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\nimport { Button } from '@fayz-ai/ui'\n\ninterface ReportPaginationProps {\n page: number\n pageSize: number\n total: number\n onPageChange: (page: number) => void\n onPageSizeChange: (size: number) => void\n}\n\nexport function ReportPagination({ page, pageSize, total, onPageChange, onPageSizeChange }: ReportPaginationProps) {\n const totalPages = Math.max(1, Math.ceil(total / pageSize))\n const from = (page - 1) * pageSize + 1\n const to = Math.min(page * pageSize, total)\n\n return (\n <div className=\"flex items-center justify-between border-t px-4 py-3\">\n <div className=\"text-sm text-muted-foreground\">\n {total > 0 ? `${from}–${to} of ${total}` : 'No results'}\n </div>\n\n <div className=\"flex items-center gap-3\">\n <select\n value={pageSize}\n onChange={(e) => onPageSizeChange(Number(e.target.value))}\n className=\"h-8 rounded-input border border-input bg-card shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] px-2 text-sm\"\n >\n {[25, 50, 100].map((size) => (\n <option key={size} value={size}>{size} / page</option>\n ))}\n </select>\n\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={page <= 1}\n onClick={() => onPageChange(page - 1)}\n >\n <ChevronLeft className=\"h-4 w-4\" />\n </Button>\n <span className=\"text-sm px-2\">\n {page} / {totalPages}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={page >= totalPages}\n onClick={() => onPageChange(page + 1)}\n >\n <ChevronRight className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </div>\n )\n}\n","import React from 'react'\nimport { ArrowLeft, Construction, Printer } from 'lucide-react'\nimport {\n Button, SubpageHeader, AnalyticsCard, AnalyticsControls, useAnalyticsContext, useAnalyticsCard,\n} from '@fayz-ai/ui'\nimport type { AnalyticsCardDef } from '@fayz-ai/core'\nimport { DataTable } from '@fayz-ai/ui'\nimport { reportColumnsToTanstack } from '../lib/columns'\nimport { ExportDropdown } from '../components/ExportDropdown'\nimport { ReportPagination } from '../components/ReportPagination'\nimport type { ReportColumnDef } from '../types'\nimport {\n useAnalyticsConfig, useAnalyticsCards, cardColumns, navigateAnalytics,\n ANALYTICS_BASE, REPORTS_BASE,\n} from './AnalyticsSurface'\nimport { markViewed } from '../lib/lastViewed'\n\n// ---------------------------------------------------------------------------\n// A report, full size.\n//\n// The chart is not decoration bolted onto a table: it is the SAME card that\n// renders as a tile on the overview, given the whole width. Underneath sits the\n// data it was computed from — so \"show me the number\" and \"show me the rows\n// behind the number\" stop being two different features in two different places.\n// ---------------------------------------------------------------------------\n\nfunction ViewerBody({ card }: { card: AnalyticsCardDef }) {\n const { labels, currency } = useAnalyticsConfig()\n const { state, setPage, setPageSize } = useAnalyticsContext()\n // Same query as the chart above and the export below — the provider\n // de-duplicates them into one round trip.\n const { result, loading, error, engineMissing } = useAnalyticsCard(card)\n\n const columns = React.useMemo(() => cardColumns(card), [card])\n const tanstackColumns = React.useMemo(\n () => reportColumnsToTanstack(columns as unknown as ReportColumnDef[], currency.code),\n [columns, currency.code],\n )\n const rows = result?.rows ?? []\n\n if (card.available === false) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed py-16 text-center\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <Construction className=\"h-5 w-5 text-muted-foreground\" />\n </div>\n <p className=\"font-medium\">{labels.unavailableTitle}</p>\n <p className=\"mt-1 max-w-sm text-sm text-muted-foreground\">{labels.unavailableDescription}</p>\n </div>\n )\n }\n\n // A pure detail listing has nothing to chart — rendering an empty card frame\n // above the table would be chrome pretending to be information.\n const hasViz = card.viz.type !== 'table' || (card.query.measures?.length ?? 0) > 0\n\n return (\n <>\n {hasViz ? (\n <AnalyticsCard\n card={{ ...card, viz: { ...card.viz, height: card.viz.height ?? 280, limit: undefined } }}\n hideOpen\n />\n ) : null}\n\n {engineMissing ? (\n <div className=\"rounded-lg border bg-muted/40 p-3 text-sm\">\n <p className=\"font-medium\">Analytics engine not installed</p>\n <p className=\"mt-0.5 text-muted-foreground\">\n This report aggregates server-side and needs migration 0039\n (<code className=\"text-xs\">analytics_run</code> + the read models) applied to this project.\n </p>\n </div>\n ) : error ? (\n <div className=\"rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive\">\n {error}\n </div>\n ) : null}\n\n <DataTable\n columns={tanstackColumns}\n data={rows}\n loading={loading}\n skeletonRows={5}\n emptyMessage={labels.noResults}\n variant=\"card\"\n compact\n />\n\n {!loading ? (\n <div className=\"no-print\">\n <ReportPagination\n page={state.page}\n pageSize={state.pageSize}\n total={result?.total ?? 0}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </div>\n ) : null}\n </>\n )\n}\n\nexport function AnalyticsReportViewer({ cardId }: { cardId?: string }) {\n const { labels } = useAnalyticsConfig()\n const cards = useAnalyticsCards()\n const card = cards.find((c) => c.id === decodeURIComponent(cardId ?? ''))\n\n React.useEffect(() => { if (card) markViewed(card.id) }, [card?.id])\n\n if (!card) {\n return (\n <div className=\"space-y-4\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateAnalytics(REPORTS_BASE)}>\n <ArrowLeft className=\"mr-1.5 h-3.5 w-3.5\" />\n {labels.reports}\n </Button>\n <p className=\"py-12 text-center text-sm text-muted-foreground\">{labels.noResults}</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n {/* O título vive na barra da shell, não no corpo. Escrever \"← Relatórios /\n Nome\" aqui E deixar a rota declarar `parentRoute` produzia três\n cabeçalhos empilhados dizendo a mesma coisa. SubpageHeader reivindica a\n barra com o nome do card — que depende de dado e por isso não cabe em\n `route.title`. */}\n <SubpageHeader\n title={card.name}\n parentLabel={labels.analytics}\n onBack={() => navigateAnalytics(ANALYTICS_BASE)}\n />\n\n {card.description ? (\n <p className=\"text-sm text-muted-foreground\">{card.description}</p>\n ) : null}\n\n <AnalyticsControls\n filters={card.query.filters ?? []}\n showCompare={card.compare !== false}\n className=\"no-print\"\n actions={<ViewerActions card={card} />}\n />\n\n <ViewerBody card={card} />\n </div>\n )\n}\n\nfunction ViewerActions({ card }: { card: AnalyticsCardDef }) {\n const { currency } = useAnalyticsConfig()\n const { result } = useAnalyticsCard(card)\n const columns = React.useMemo(() => cardColumns(card), [card])\n if (!result?.rows?.length) return null\n return (\n <>\n <ExportDropdown\n columns={columns as unknown as ReportColumnDef[]}\n data={result.rows as Record<string, unknown>[]}\n filename={card.id}\n currency={currency.code}\n title={card.name}\n />\n <Button variant=\"outline\" size=\"sm\" className=\"h-8\" onClick={() => window.print()}>\n <Printer className=\"mr-1.5 h-3.5 w-3.5\" />\n Print\n </Button>\n </>\n )\n}\n","import React from 'react'\nimport { Radio } from 'lucide-react'\nimport { useAnalyticsConfig } from './AnalyticsSurface'\n\n// ---------------------------------------------------------------------------\n// Live View — the real-time surface.\n//\n// A deliberate stub. It needs a storefront event stream (sessions, carts,\n// checkouts) that does not exist yet, and the honest thing on a page with no\n// data source is to say so rather than render zeroes that look like a quiet\n// afternoon. It holds its nav slot so the shape of the section is visible.\n// ---------------------------------------------------------------------------\n\nexport function LiveViewPage() {\n const { labels } = useAnalyticsConfig()\n return (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed py-20 text-center\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <Radio className=\"h-5 w-5 text-muted-foreground\" />\n </div>\n <p className=\"font-medium\">{labels.liveView}</p>\n <p className=\"mt-1 max-w-sm text-sm text-muted-foreground\">{labels.liveViewSoon}</p>\n </div>\n )\n}\n","import { getSupabaseClientOptional } from '@fayz-ai/core'\nimport type { ReportDef, ReportQueryState } from '../types'\nimport type { ReportDataProvider, ReportResult } from './types'\n\n// ---------------------------------------------------------------------------\n// Case conversion\n// ---------------------------------------------------------------------------\n\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (c) => '_' + c.toLowerCase())\n}\n\nfunction snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase())\n}\n\nfunction mapRow(row: Record<string, unknown>, columnMap?: Record<string, string>): Record<string, any> {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(row)) {\n const camelKey = columnMap?.[key] ?? snakeToCamel(key)\n result[camelKey] = value\n }\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Provider factory\n// ---------------------------------------------------------------------------\n\nexport interface SupabaseReportProviderConfig {\n tenantId: string | (() => string | undefined)\n tenantIdColumn?: string\n schema?: string\n}\n\nexport function createSupabaseReportProvider(config: SupabaseReportProviderConfig): ReportDataProvider {\n const schema = config.schema ?? 'public'\n const tenantIdCol = config.tenantIdColumn ?? 'tenant_id'\n\n function resolveTenantId(): string | undefined {\n return typeof config.tenantId === 'function' ? config.tenantId() : config.tenantId\n }\n\n function getClient() {\n const supabase = getSupabaseClientOptional() as any\n if (!supabase) throw new Error('Supabase client not available')\n return schema === 'public' ? supabase : supabase.schema(schema)\n }\n\n return {\n async fetch(reportDef: ReportDef, query: ReportQueryState): Promise<ReportResult> {\n const { dataSource } = reportDef\n const columnMap = dataSource.columnMap\n\n if (dataSource.kind === 'rpc') {\n return fetchViaRpc(reportDef, query, getClient, resolveTenantId, columnMap)\n }\n\n return fetchViaView(reportDef, query, getClient, resolveTenantId, tenantIdCol, columnMap)\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// View-based fetch\n// ---------------------------------------------------------------------------\n\nasync function fetchViaView(\n reportDef: ReportDef,\n query: ReportQueryState,\n getClient: () => any,\n resolveTenantId: () => string | undefined,\n tenantIdCol: string,\n columnMap?: Record<string, string>,\n): Promise<ReportResult> {\n const { dataSource } = reportDef\n let q = getClient().from(dataSource.name).select('*', { count: 'exact' })\n\n // Tenant scoping\n const tenantId = resolveTenantId()\n if (tenantId) {\n q = q.eq(tenantIdCol, tenantId)\n }\n\n // Date range\n const dateCol = dataSource.dateColumn ?? 'created_at'\n if (query.dateRange.from) {\n q = q.gte(dateCol, query.dateRange.from)\n }\n if (query.dateRange.to) {\n // For date-type columns, plain date string is sufficient.\n // For timestamptz columns, extend to end of day.\n const toValue = dateCol === 'created_at' || dateCol.endsWith('_at')\n ? query.dateRange.to + 'T23:59:59'\n : query.dateRange.to\n q = q.lte(dateCol, toValue)\n }\n\n // Custom filters\n for (const [key, value] of Object.entries(query.filters)) {\n if (value == null || value === '') continue\n const col = camelToSnake(key)\n if (Array.isArray(value)) {\n q = q.in(col, value)\n } else {\n q = q.eq(col, value)\n }\n }\n\n // Search\n if (query.search) {\n const searchableCols = reportDef.columns\n .filter((c) => c.type === 'text' || c.type === 'email' || c.type === 'person')\n .map((c: any) => camelToSnake(c.key))\n if (searchableCols.length > 0) {\n const term = `%${query.search}%`\n const orClause = searchableCols.map((col) => `${col}.ilike.${term}`).join(',')\n q = q.or(orClause)\n }\n }\n\n // Sort\n const sortCol = query.sortBy\n ? camelToSnake(query.sortBy)\n : dataSource.defaultSort\n ? camelToSnake(dataSource.defaultSort)\n : dateCol\n const ascending = query.sortDir\n ? query.sortDir === 'asc'\n : dataSource.defaultSortDir\n ? dataSource.defaultSortDir === 'asc'\n : false\n q = q.order(sortCol, { ascending })\n\n // Pagination\n const from = (query.page - 1) * query.pageSize\n const to = from + query.pageSize - 1\n q = q.range(from, to)\n\n const { data, error, count } = await q\n\n if (error) throw error\n\n return {\n data: (data ?? []).map((row: any) => mapRow(row, columnMap)),\n total: count ?? 0,\n }\n}\n\n// ---------------------------------------------------------------------------\n// RPC-based fetch\n// ---------------------------------------------------------------------------\n\nasync function fetchViaRpc(\n reportDef: ReportDef,\n query: ReportQueryState,\n getClient: () => any,\n resolveTenantId: () => string | undefined,\n columnMap?: Record<string, string>,\n): Promise<ReportResult> {\n const { dataSource } = reportDef\n const tenantId = resolveTenantId()\n\n const params: Record<string, any> = {\n p_tenant_id: tenantId,\n p_from: query.dateRange.from,\n p_to: query.dateRange.to,\n p_page: query.page,\n p_page_size: query.pageSize,\n }\n\n // Custom filters\n for (const [key, value] of Object.entries(query.filters)) {\n if (value == null || value === '') continue\n params[`p_${camelToSnake(key)}`] = value\n }\n\n if (query.sortBy) {\n params.p_sort_by = camelToSnake(query.sortBy)\n params.p_sort_dir = query.sortDir ?? 'desc'\n }\n\n const { data, error } = await getClient().rpc(dataSource.name, params)\n if (error) throw error\n\n // RPC expected to return { data: [...], total: number }\n if (data && typeof data === 'object' && 'data' in data) {\n return {\n data: (data.data ?? []).map((row: any) => mapRow(row, columnMap)),\n total: data.total ?? 0,\n }\n }\n\n // Fallback: RPC returns a plain array\n const rows = Array.isArray(data) ? data : []\n return {\n data: rows.map((row: any) => mapRow(row, columnMap)),\n total: rows.length,\n }\n}\n","import type { ReportDataProvider } from './types'\n\nexport function createMockReportProvider(): ReportDataProvider {\n return {\n async fetch() {\n return { data: [], total: 0 }\n },\n }\n}\n","import React from 'react'\nimport type {\n PluginManifest, PluginScope, VerticalId, AnalyticsCardDef, AnalyticsProvider, AnalyticsCompare,\n} from '@fayz-ai/core'\nimport type { AnalyticsRangePreset } from '@fayz-ai/ui'\nimport { createSafeDataProvider, registerTranslations } from '@fayz-ai/core'\nimport { createSupabaseAnalyticsProvider } from './data/analytics-supabase'\nimport { createMockAnalyticsProvider } from './data/analytics-mock'\nimport { getReportsTenantId } from './lib/tenant'\nimport { reportsLocales } from './locales'\nimport { reportDefsToCards } from './lib/legacy'\nimport {\n AnalyticsSurface, ANALYTICS_BASE, REPORTS_BASE,\n type AnalyticsLabels, type ResolvedAnalyticsConfig, type AnalyticsAssistantConfig,\n} from './views/AnalyticsSurface'\nimport { AnalyticsModule, type AnalyticsView } from './views/AnalyticsModule'\nimport { AnalyticsOverview } from './views/AnalyticsOverview'\nimport { ReportsListPage } from './views/ReportsListPage'\nimport { AnalyticsReportViewer } from './views/AnalyticsReportViewer'\nimport { LiveViewPage } from './views/LiveViewPage'\nimport type { ReportsPluginOptions } from './types'\n\n// ---------------------------------------------------------------------------\n// Analytics — one engine, one door, several rooms.\n//\n// /analytics the general dashboard: the cards a pack placed\n// /analytics/reports the one list where a user finds what they want\n// /analytics/reports/:id a report, full size (chart AND rows)\n// /analytics/live real-time (stub, awaiting a storefront event stream)\n//\n// ONE nav entry. Analytics and Reports used to be two top-level links to the\n// same engine — the app menu asked the user to choose a door before showing\n// what was behind either. Everything below /analytics now hangs off the module\n// rail (AnalyticsModule), where the report groups and the reports themselves\n// are the navigation.\n//\n// The package is still called plugin-reports so the six consuming apps keep\n// their imports; the CONCEPT it exposes is Analytics, with Reports as the\n// catalogue inside it.\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_LABELS: AnalyticsLabels = {\n analytics: 'Analytics',\n reports: 'Reports',\n liveView: 'Live View',\n overviewSubtitle: 'Key metrics for your business',\n reportsSubtitle: 'Every report available to you',\n searchReports: 'Search reports',\n category: 'Category',\n createdBy: 'Created by',\n allCategories: 'All categories',\n allCreatedBy: 'All authors',\n lastViewed: 'Last viewed',\n name: 'Name',\n noResults: 'No results found.',\n never: '—',\n back: 'Back',\n export: 'Export',\n print: 'Print',\n unavailableTitle: 'Coming soon',\n unavailableDescription: 'This report is not connected to data yet. It will be enabled in a future update.',\n emptyOverviewTitle: 'No metrics yet',\n emptyOverviewDescription: 'Enable a plugin that contributes analytics cards, or add them to this app’s pack.',\n liveViewSoon: 'Real-time visitor and checkout activity will appear here once storefront events are being collected.',\n results: 'reports',\n}\n\nconst DEFAULT_CURRENCY = { code: 'BRL', locale: 'pt-BR', symbol: 'R$' }\n\nexport interface AnalyticsPluginOptions {\n /**\n * Cards the host app contributes or overrides. Cards owned by a plugin come\n * through the runtime registry automatically — this is for app-specific ones\n * and for retuning a plugin card by re-declaring its id.\n */\n cards?: AnalyticsCardDef[]\n /**\n * Legacy ReportDef catalogue. Still fully supported: each becomes a table\n * card in the report list. See lib/legacy.ts.\n */\n reports?: import('./types').ReportDef[]\n /** Attribution for pre-built cards — the product name, e.g. 'FayzShop'. */\n createdBy?: string\n labels?: Partial<AnalyticsLabels>\n currency?: { code?: string; locale?: string; symbol?: string }\n dataProvider?: AnalyticsProvider\n navPosition?: number\n navSection?: 'main' | 'secondary'\n scope?: PluginScope\n verticalId?: VerticalId\n defaultPageSize?: number\n /**\n * Render an in-content title above the page. Default: FALSE, matching\n * DashboardCanvas — the admin shell's top bar already names the page from the\n * active nav entry, so a title here prints the same word twice. Pass true\n * only where the surface is embedded with no chrome of its own.\n */\n showHeader?: boolean\n /** Register the Live View nav entry. Default: false while it is a stub. */\n showLiveView?: boolean\n /**\n * Range the surface opens on. Default 'last_30_days' — the common business\n * month. Set it where the domain's natural period differs (a school term, a\n * quarter), not to compensate for how much data a demo tenant happens to have.\n */\n defaultRange?: AnalyticsRangePreset\n defaultCompare?: AnalyticsCompare\n /**\n * The assistant's invitation on /analytics: a persona, a headline and the\n * questions worth asking here. Defaults come from the plugin's locales — pass\n * an object to retune the voice for a vertical, or `false` for an app whose\n * analytics screen should open on the numbers alone.\n */\n assistant?: false | AnalyticsAssistantConfig\n}\n\nfunction resolveConfig(options: AnalyticsPluginOptions): ResolvedAnalyticsConfig {\n const labels = { ...DEFAULT_LABELS, ...options.labels }\n const createdBy = options.createdBy ?? 'Fayz'\n return {\n labels,\n currency: { ...DEFAULT_CURRENCY, ...options.currency },\n createdBy,\n cards: [\n ...(options.cards ?? []),\n ...reportDefsToCards(options.reports ?? [], createdBy),\n ],\n defaultPageSize: options.defaultPageSize ?? 50,\n showHeader: options.showHeader === true,\n defaultRange: options.defaultRange ?? 'last_30_days',\n defaultCompare: options.defaultCompare ?? 'previous_period',\n showLiveView: options.showLiveView === true,\n assistant: options.assistant === false ? null : (options.assistant ?? {}),\n }\n}\n\nexport function createAnalyticsPlugin(options: AnalyticsPluginOptions = {}): PluginManifest {\n const config = resolveConfig(options)\n registerTranslations(reportsLocales)\n\n const provider: AnalyticsProvider = options.dataProvider ?? createSafeDataProvider(\n () => createSupabaseAnalyticsProvider({ tenantId: () => getReportsTenantId() }),\n () => createMockAnalyticsProvider(),\n )\n\n /**\n * Every page mounts inside the same surface AND the same module rail, so the\n * report tree is on screen wherever you are inside Analytics — and the app\n * nav never has to list a second Analytics entry to get you there.\n */\n const page = (Body: React.ComponentType<any>, view: AnalyticsView): React.FC<any> =>\n (props) => React.createElement(\n AnalyticsSurface,\n { config, provider },\n React.createElement(\n AnalyticsModule,\n { view, cardId: props?.cardId },\n React.createElement(Body, props),\n ),\n )\n\n const READ = { feature: 'reports', action: 'read' as const }\n const position = options.navPosition ?? 9\n const section = options.navSection ?? 'main'\n\n // One entry. Sub-paths of /analytics would be nested as children by the shell\n // (findModuleParent) and drawn as a dropdown — which is the split this module\n // exists to remove.\n const nav = [\n {\n section, position,\n label: config.labels.analytics,\n route: ANALYTICS_BASE,\n icon: 'BarChart3',\n permission: READ,\n },\n ]\n\n return {\n id: 'reports',\n name: config.labels.analytics,\n icon: 'BarChart3',\n version: '2.0.0',\n scope: options.scope ?? 'universal',\n verticalId: options.verticalId,\n defaultEnabled: true,\n dependencies: [],\n declaredFeatures: [\n { id: 'reports', label: config.labels.analytics, group: config.labels.analytics },\n ],\n navigation: nav,\n routes: [\n { path: ANALYTICS_BASE, component: page(AnalyticsOverview, 'overview'), permission: READ },\n { path: REPORTS_BASE, component: page(ReportsListPage, 'reports'), permission: READ },\n // Registered before the list would ever shadow it: matchRoute scores\n // static segments above params, so /analytics/reports still wins its own\n // exact path and only /analytics/reports/<id> lands here.\n // No `parentRoute` here on purpose: the viewer's title depends on DATA\n // (the card's name), so it claims the shell bar itself via PageHeader.\n // Declaring both gave the page two stacked back-crumbs saying the same\n // thing, one of them generic.\n { path: `${REPORTS_BASE}/:cardId`, component: page(AnalyticsReportViewer, 'report'), permission: READ },\n { path: `${ANALYTICS_BASE}/live`, component: page(LiveViewPage, 'live'), permission: READ },\n // The old top-level route kept as a redirect target: bookmarks, saved\n // links and the five apps still pointing at /reports must not 404.\n { path: '/reports', component: page(ReportsListPage, 'reports'), permission: READ },\n ],\n widgets: [],\n registries: [],\n // Measurement, not acquisition — what the Fayz plugin page lists for\n // Analytics.\n integrations: ['google-analytics', 'hotjar'],\n locales: reportsLocales,\n }\n}\n\n/**\n * @deprecated Prefer `createAnalyticsPlugin`. Kept so the apps that call\n * `createReportsPlugin({ reports: [...] })` keep working unchanged — the legacy\n * `reports` option is still first-class and their catalogues need no rewrite.\n */\nexport function createReportsPlugin(options: ReportsPluginOptions): PluginManifest {\n return createAnalyticsPlugin({\n reports: options.reports,\n labels: {\n ...(options.labels?.pageTitle ? { analytics: options.labels.pageTitle } : {}),\n ...(options.labels?.pageSubtitle ? { overviewSubtitle: options.labels.pageSubtitle } : {}),\n },\n currency: options.currency,\n navPosition: options.navPosition,\n navSection: options.navSection,\n scope: options.scope,\n verticalId: options.verticalId,\n defaultPageSize: options.defaultPageSize,\n showHeader: options.showHeader,\n })\n}\n\n// ---------------------------------------------------------------------------\n// Re-exports\n// ---------------------------------------------------------------------------\n\nexport {\n AnalyticsSurface, ANALYTICS_BASE, REPORTS_BASE, cardColumns,\n useAnalyticsConfig, useAnalyticsCards, useOverviewCards,\n} from './views/AnalyticsSurface'\nexport type {\n AnalyticsLabels, ResolvedAnalyticsConfig, AnalyticsAssistantConfig,\n} from './views/AnalyticsSurface'\nexport { AnalyticsModule } from './views/AnalyticsModule'\nexport type { AnalyticsView, AnalyticsModuleProps } from './views/AnalyticsModule'\nexport { AnalyticsOverview } from './views/AnalyticsOverview'\nexport { ReportsListPage } from './views/ReportsListPage'\nexport { AnalyticsReportViewer } from './views/AnalyticsReportViewer'\nexport { reportDefToCard, reportDefsToCards } from './lib/legacy'\nexport { aggregateRows } from './data/aggregate'\nexport { createSupabaseAnalyticsProvider } from './data/analytics-supabase'\nexport type { SupabaseAnalyticsProviderConfig } from './data/analytics-supabase'\nexport { createMockAnalyticsProvider } from './data/analytics-mock'\nexport { markViewed, useLastViewed } from './lib/lastViewed'\nexport { setReportsTenantId, getReportsTenantId } from './lib/tenant'\n\nexport type {\n ReportDef,\n ReportColumnDef,\n ReportFilterDef,\n ReportDateRange,\n ReportQueryState,\n ReportBadge,\n ReportDataSource,\n ReportGrain,\n ReportAllowedAction,\n ReportFilterOption,\n ReportsPluginOptions,\n ReportsPluginLabels,\n ResolvedReportsConfig,\n} from './types'\n\nexport type { ReportDataProvider, ReportResult } from './data/types'\nexport { createSupabaseReportProvider } from './data/supabase'\nexport type { SupabaseReportProviderConfig } from './data/supabase'\nexport { createMockReportProvider } from './data/mock'\n"]}
1
+ {"version":3,"sources":["../src/data/aggregate.ts","../src/data/analytics-supabase.ts","../src/data/analytics-mock.ts","../src/lib/tenant.ts","../src/locales/en.ts","../src/locales/pt-BR.ts","../src/locales/index.ts","../src/lib/legacy.ts","../src/lib/lastViewed.ts","../src/views/AnalyticsSurface.tsx","../src/views/AnalyticsAssistant.tsx","../src/views/AnalyticsModule.tsx","../src/views/AnalyticsOverview.tsx","../src/views/ReportsListPage.tsx","../src/export/csv.ts","../src/components/ExportDropdown.tsx","../src/components/ReportPagination.tsx","../src/views/AnalyticsReportViewer.tsx","../src/views/LiveViewPage.tsx","../src/data/supabase.ts","../src/data/mock.ts","../src/index.ts"],"names":["data","error","React","jsx","useTranslation","jsxs","useState","useEffect","page","Button","Fragment","DataTable","AnalyticsControls","camelToSnake","snakeToCamel","mapRow","getSupabaseClientOptional"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n AnalyticsCardDef, AnalyticsGrain, AnalyticsQueryState, AnalyticsResult, AnalyticsRow,\n} from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Client-side aggregation.\n//\n// The SQL engine (analytics_run) is the real one; this exists for the two cases\n// that cannot reach it — the mock provider, and cards whose source is an app\n// function rather than a read model. It deliberately mirrors the SQL semantics\n// step for step, because a card must not change meaning depending on which\n// provider answered it.\n// ---------------------------------------------------------------------------\n\nfunction num(value: unknown): number {\n if (value == null) return 0\n const n = typeof value === 'number' ? value : Number(value)\n return Number.isFinite(n) ? n : 0\n}\n\n/** Truncate a timestamp to the start of its bucket — the JS date_trunc. */\nexport function truncate(value: unknown, grain: AnalyticsGrain): string | null {\n const d = new Date(String(value))\n if (Number.isNaN(d.getTime())) return null\n const out = new Date(d)\n switch (grain) {\n case 'hour': out.setMinutes(0, 0, 0); break\n case 'week': {\n // ISO weeks start Monday; getDay() calls Sunday 0, hence the shift.\n const day = (out.getDay() + 6) % 7\n out.setDate(out.getDate() - day)\n out.setHours(0, 0, 0, 0)\n break\n }\n case 'month': out.setDate(1); out.setHours(0, 0, 0, 0); break\n case 'quarter': out.setMonth(Math.floor(out.getMonth() / 3) * 3, 1); out.setHours(0, 0, 0, 0); break\n case 'year': out.setMonth(0, 1); out.setHours(0, 0, 0, 0); break\n default: out.setHours(0, 0, 0, 0); break\n }\n return out.toISOString()\n}\n\nfunction matchesFilters(row: AnalyticsRow, filters: Record<string, unknown>): boolean {\n for (const [key, value] of Object.entries(filters)) {\n if (value == null || value === '') continue\n const actual = row[key]\n if (Array.isArray(value)) {\n if (value.length > 0 && !value.map(String).includes(String(actual))) return false\n } else if (String(actual) !== String(value)) {\n return false\n }\n }\n return true\n}\n\nfunction inRange(row: AnalyticsRow, dateColumn: string, from?: string, to?: string): boolean {\n const raw = row[dateColumn]\n if (raw == null) return true\n const t = new Date(String(raw)).getTime()\n if (Number.isNaN(t)) return true\n // `to` is an inclusive DAY, so the window closes at its final millisecond —\n // comparing against midnight would silently drop everything ordered that day.\n if (from && t < new Date(`${from}T00:00:00`).getTime()) return false\n if (to && t > new Date(`${to}T23:59:59.999`).getTime()) return false\n return true\n}\n\n/** Apply one measure over a bucket of rows. 'ratio' is resolved by the UI layer. */\nfunction applyMeasure(rows: AnalyticsRow[], agg: string, column: string): number | null {\n if (agg === 'count') return rows.length\n const values = rows.map((r) => r[column]).filter((v) => v != null)\n if (agg === 'count_distinct') return new Set(values.map(String)).size\n const numbers = values.map(num)\n if (numbers.length === 0) return agg === 'sum' ? 0 : null\n switch (agg) {\n case 'sum': return numbers.reduce((a, b) => a + b, 0)\n case 'avg': return numbers.reduce((a, b) => a + b, 0) / numbers.length\n case 'min': return Math.min(...numbers)\n case 'max': return Math.max(...numbers)\n default: return null\n }\n}\n\nexport interface AggregateOptions {\n /** Skip pagination and return every group (the export path). */\n all?: boolean\n}\n\n/**\n * Group, aggregate, sort and page a row set exactly as analytics_run does.\n * Returns the same {rows, total, summary} envelope so callers cannot tell which\n * engine answered.\n */\nexport function aggregateRows(\n source: AnalyticsRow[],\n card: AnalyticsCardDef,\n state: AnalyticsQueryState,\n options?: AggregateOptions,\n): AnalyticsResult {\n // dateColumn null ⇒ a snapshot: the range must not apply (see AnalyticsQuery).\n const snapshot = card.query.dateColumn === null\n const dateColumn = card.query.dateColumn ?? 'created_at'\n const dimensions = card.query.dimensions ?? []\n const measures = (card.query.measures ?? []).filter((m) => m.agg !== 'ratio')\n\n const filtered = source\n .filter((row) => snapshot || inRange(row, dateColumn, state.dateRange?.from, state.dateRange?.to))\n .filter((row) => matchesFilters(row, state.filters ?? {}))\n\n // The rollup: same rows, same filters, no grouping. Identical to SQL 8.11.\n const summary: Record<string, number> = {}\n for (const m of measures) {\n const value = applyMeasure(filtered, m.agg, m.column ?? m.key)\n summary[m.key] = value ?? 0\n }\n\n // No measures ⇒ a detail listing; the rows pass through untouched.\n if (measures.length === 0 && dimensions.length === 0) {\n const sorted = sortRows(filtered, state.sortBy ?? card.query.defaultSort, state.sortDir ?? card.query.defaultSortDir)\n return { rows: page(sorted, state, options), total: sorted.length, summary }\n }\n\n const buckets = new Map<string, { key: AnalyticsRow; rows: AnalyticsRow[] }>()\n for (const row of filtered) {\n const keyParts: AnalyticsRow = {}\n for (const d of dimensions) {\n const raw = row[d.key]\n keyParts[d.key] = d.grain && d.grain !== 'auto' ? truncate(raw, d.grain) : (raw ?? null)\n }\n const id = JSON.stringify(dimensions.map((d) => keyParts[d.key]))\n const existing = buckets.get(id)\n if (existing) existing.rows.push(row)\n else buckets.set(id, { key: keyParts, rows: [row] })\n }\n\n let grouped: AnalyticsRow[] = [...buckets.values()].map(({ key, rows }) => {\n const out: AnalyticsRow = { ...key }\n for (const m of measures) out[m.key] = applyMeasure(rows, m.agg, m.column ?? m.key)\n return out\n })\n\n grouped = sortRows(grouped, state.sortBy ?? card.query.defaultSort, state.sortDir ?? card.query.defaultSortDir)\n if (card.query.limit) grouped = grouped.slice(0, card.query.limit)\n\n return { rows: page(grouped, state, options), total: grouped.length, summary }\n}\n\nfunction sortRows(rows: AnalyticsRow[], sortBy?: string, dir?: 'asc' | 'desc'): AnalyticsRow[] {\n if (!sortBy) return rows\n const sign = dir === 'asc' ? 1 : -1\n return [...rows].sort((a, b) => {\n const av = a[sortBy]\n const bv = b[sortBy]\n // Nulls sort last in both directions — matching SQL's NULLS LAST, so a\n // never-shipped order does not top a \"fastest fulfillment\" report.\n if (av == null && bv == null) return 0\n if (av == null) return 1\n if (bv == null) return -1\n if (typeof av === 'number' || typeof bv === 'number') return (num(av) - num(bv)) * sign\n return String(av).localeCompare(String(bv)) * sign\n })\n}\n\nfunction page(rows: AnalyticsRow[], state: AnalyticsQueryState, options?: AggregateOptions): AnalyticsRow[] {\n if (options?.all) return rows\n const size = state.pageSize || 50\n const start = ((state.page || 1) - 1) * size\n return rows.slice(start, start + size)\n}\n","import { getSupabaseClientOptional } from '@fayz-ai/core'\nimport type {\n AnalyticsBatchRequest, AnalyticsCardDef, AnalyticsProvider, AnalyticsQueryState,\n AnalyticsResult, AnalyticsRow,\n} from '@fayz-ai/core'\nimport { aggregateRows } from './aggregate'\n\n// ---------------------------------------------------------------------------\n// The Supabase analytics provider.\n//\n// Everything a card asks for goes through ONE server function, analytics_run:\n// \"orders over time\" and \"sales by product\" are the same call with different\n// dimensions. That is what removes the per-report SQL that made adding a report\n// a database migration.\n//\n// kind 'view' → analytics_run over a registered read model (the normal path)\n// kind 'rpc' → a bespoke function, for the rare card the generic engine\n// cannot express (escape hatch, not the default)\n// kind 'fn' → an app-supplied async function, aggregated client-side\n// ---------------------------------------------------------------------------\n\nfunction snakeToCamel(s: string): string {\n return s.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())\n}\n\n/**\n * Map DB keys to JS keys. Measure and dimension keys are passed through\n * UNTOUCHED — the card named them, the SQL aliased them to exactly that, and\n * silently camelCasing `net_sales` into `netSales` would make every card whose\n * viz references `net_sales` render blank.\n */\nfunction mapRow(row: AnalyticsRow, reserved: Set<string>, columnMap?: Record<string, string>): AnalyticsRow {\n const out: AnalyticsRow = {}\n for (const [key, value] of Object.entries(row)) {\n if (reserved.has(key)) { out[key] = value; continue }\n out[columnMap?.[key] ?? snakeToCamel(key)] = value\n // Keep the raw key too: column definitions written against the read model's\n // snake_case still resolve, so adopting a card needs no rename pass.\n if (!(key in out)) out[key] = value\n }\n return out\n}\n\nfunction reservedKeys(card: AnalyticsCardDef): Set<string> {\n return new Set([\n ...(card.query.dimensions ?? []).map((d) => d.key),\n ...(card.query.measures ?? []).map((m) => m.key),\n ])\n}\n\n/** Text columns free-text search scans, taken from the card's own columns. */\nfunction searchColumns(card: AnalyticsCardDef): string[] | undefined {\n const cols = (card.columns ?? [])\n // 'person' is a text column with a richer cell — searching a customer list\n // by name has to keep working after the name became a link.\n .filter((c) => c.type === 'text' || c.type === 'email' || c.type === 'person')\n .map((c) => c.key)\n return cols.length ? cols : undefined\n}\n\nfunction camelToSnake(s: string): string {\n return s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`)\n}\n\n/**\n * Direct read of a view — the path every pre-existing ReportDef takes.\n *\n * Ports the semantics of the original report provider verbatim (tenant scope,\n * inclusive date window, equality/IN filters, ILIKE search over text columns,\n * sort, page) so adopting the analytics engine changed no existing report's\n * answer.\n */\nasync function selectFromView(\n card: AnalyticsCardDef,\n state: AnalyticsQueryState,\n db: any,\n tenantId: string | undefined,\n reserved: Set<string>,\n): Promise<AnalyticsResult> {\n const { source } = card.query\n const size = state.pageSize || 50\n let q = db.from(source.name!).select('*', { count: 'exact' })\n\n if (tenantId) q = q.eq(source.tenantColumn ?? 'tenant_id', tenantId)\n\n const snapshot = card.query.dateColumn === null\n const dateCol = card.query.dateColumn ?? 'created_at'\n if (!snapshot && state.dateRange?.from) q = q.gte(dateCol, state.dateRange.from)\n if (!snapshot && state.dateRange?.to) {\n // A timestamp column needs the whole final day; a plain date column does\n // not — appending a time to a `date` would compare against a cast and drop\n // the last day of every range.\n q = q.lte(dateCol, dateCol.endsWith('_at') ? `${state.dateRange.to}T23:59:59.999` : state.dateRange.to)\n }\n\n for (const [key, value] of Object.entries(state.filters ?? {})) {\n if (value == null || value === '') continue\n const col = camelToSnake(key)\n q = Array.isArray(value) ? q.in(col, value) : q.eq(col, value)\n }\n\n const searchable = searchColumns(card)\n if (state.search?.trim() && searchable?.length) {\n const term = `%${state.search.trim()}%`\n q = q.or(searchable.map((c) => `${camelToSnake(c)}.ilike.${term}`).join(','))\n }\n\n const sortBy = state.sortBy ?? card.query.defaultSort\n if (sortBy) {\n q = q.order(camelToSnake(sortBy), {\n ascending: (state.sortDir ?? card.query.defaultSortDir ?? 'desc') === 'asc',\n })\n }\n\n const from = ((state.page || 1) - 1) * size\n const { data, error, count } = await q.range(from, from + size - 1)\n if (error) throw error\n\n return {\n rows: (data ?? []).map((r: AnalyticsRow) => mapRow(r, reserved, source.columnMap)),\n total: count ?? 0,\n }\n}\n\n/**\n * A rejection the card can actually print.\n *\n * PostgREST rejects with a PLAIN OBJECT ({ message, details, hint, code }), not\n * an Error — so `new Error(String(err))` turned every failed card into the words\n * \"[object Object]\" and threw away the one sentence that says what broke.\n */\nfunction toError(err: unknown): Error {\n if (err instanceof Error) return err\n if (err && typeof err === 'object') {\n const e = err as Record<string, unknown>\n const message = [...new Set(\n [e.message, e.details, e.hint].filter(\n (part): part is string => typeof part === 'string' && part.trim().length > 0,\n ),\n )].join(' — ')\n if (message) return Object.assign(new Error(message), e.code ? { code: e.code } : {})\n }\n return new Error(String(err))\n}\n\n/**\n * True when the card is answered by the generic aggregate engine — the only\n * shape that can travel in a batch, because the batch function IS analytics_run\n * called in a loop. A detail listing is a plain PostgREST select and an 'fn'\n * card never touches the database at all.\n */\nfunction isAggregateCard(card: AnalyticsCardDef): boolean {\n const { source } = card.query\n if (source.kind !== 'view' || !source.name) return false\n return (card.query.dimensions?.length ?? 0) > 0 || (card.query.measures?.length ?? 0) > 0\n}\n\n/**\n * The arguments analytics_run wants, as a plain object. Named once so a single\n * call and a batched element cannot drift into asking different questions —\n * the bug that would show up as a KPI disagreeing with itself depending on how\n * many other cards happened to be on screen.\n */\nfunction runArgs(card: AnalyticsCardDef, state: AnalyticsQueryState, tenantId: string | undefined) {\n const size = state.pageSize || 50\n // A snapshot card (dateColumn: null) sends no window at all, so \"stock on\n // hand\" stays stock on hand no matter what the range picker says.\n const snapshot = card.query.dateColumn === null\n return {\n source: card.query.source.name!,\n tenant_id: tenantId ?? null,\n from: !snapshot && state.dateRange.from ? `${state.dateRange.from}T00:00:00` : null,\n // Inclusive end-of-day: the range picker speaks in days, the column is a\n // timestamp, and closing at midnight loses everything sold that day.\n to: !snapshot && state.dateRange.to ? `${state.dateRange.to}T23:59:59.999` : null,\n dimensions: (card.query.dimensions ?? []).map((d) => ({\n key: d.key,\n ...(d.grain && d.grain !== 'auto' ? { grain: d.grain } : {}),\n })),\n measures: (card.query.measures ?? [])\n .filter((m) => m.agg !== 'ratio')\n .map((m) => ({ key: m.key, agg: m.agg, ...(m.column ? { column: m.column } : {}) })),\n filters: state.filters ?? {},\n search: state.search ?? null,\n search_columns: searchColumns(card) ?? null,\n sort: state.sortBy ?? card.query.defaultSort ?? null,\n dir: state.sortDir ?? card.query.defaultSortDir ?? 'desc',\n limit: card.query.limit ?? size,\n offset: card.query.limit ? 0 : ((state.page || 1) - 1) * size,\n }\n}\n\n/** Shape analytics_run's envelope into a result, mapping row keys. */\nfunction toResult(data: any, card: AnalyticsCardDef, reserved: Set<string>): AnalyticsResult {\n const rows: AnalyticsRow[] = data?.rows ?? []\n return {\n rows: rows.map((r) => mapRow(r, reserved, card.query.source.columnMap)),\n total: data?.total ?? rows.length,\n summary: data?.summary ?? undefined,\n }\n}\n\n/** The batch function is missing on this project — 025 was never applied. */\nfunction batchUnavailable(err: any): boolean {\n const code = typeof err?.code === 'string' ? err.code : ''\n if (['42883', 'PGRST202'].includes(code)) return true\n return typeof err?.message === 'string' && err.message.includes('analytics_run_batch')\n}\n\nexport interface SupabaseAnalyticsProviderConfig {\n tenantId: string | (() => string | undefined)\n schema?: string\n}\n\nexport function createSupabaseAnalyticsProvider(config: SupabaseAnalyticsProviderConfig): AnalyticsProvider {\n const resolveTenantId = () =>\n (typeof config.tenantId === 'function' ? config.tenantId() : config.tenantId) || undefined\n\n function client() {\n const supabase = getSupabaseClientOptional() as any\n if (!supabase) throw new Error('Supabase client not available')\n return config.schema && config.schema !== 'public' ? supabase.schema(config.schema) : supabase\n }\n\n // Flipped off for good on the first \"function does not exist\", so an older\n // pool degrades to one-request-per-card instead of failing every card.\n let batchSupported = true\n\n return {\n async run(card: AnalyticsCardDef, state: AnalyticsQueryState): Promise<AnalyticsResult> {\n const { source } = card.query\n const reserved = reservedKeys(card)\n\n if (source.kind === 'fn') {\n if (!source.run) throw new Error(`analytics: card ${card.id} declares kind 'fn' with no run()`)\n const rows = await source.run({\n tenantId: resolveTenantId(),\n dateRange: state.dateRange,\n filters: state.filters,\n })\n return aggregateRows(rows, card, state)\n }\n\n if (!source.name) throw new Error(`analytics: card ${card.id} has no source name`)\n\n // A card with neither dimensions nor measures is a flat listing, and a\n // flat listing has nothing to aggregate. It reads the view DIRECTLY.\n //\n // This is not an optimisation — it is what keeps the five apps that\n // already ship ReportDef catalogues working. Their views (rep_appointments\n // _by_period, plg_courses_rep_revenue, …) predate analytics_run and are\n // not in its allowlist, so sending a plain SELECT through the aggregate\n // engine turned every existing report into PGRST202. Registration is the\n // price of GROUP BY, not the price of reading rows.\n const isDetail = (card.query.dimensions?.length ?? 0) === 0\n && (card.query.measures?.length ?? 0) === 0\n if (source.kind === 'view' && isDetail) {\n return selectFromView(card, state, client(), resolveTenantId(), reserved)\n }\n\n if (source.kind === 'rpc') {\n const { data, error } = await client().rpc(source.name, {\n p_tenant_id: resolveTenantId(),\n p_from: state.dateRange.from,\n p_to: state.dateRange.to,\n ...Object.fromEntries(Object.entries(state.filters ?? {}).map(([k, v]) => [`p_${k}`, v])),\n })\n if (error) throw error\n const rows: AnalyticsRow[] = Array.isArray(data) ? data : (data?.rows ?? [])\n return {\n rows: rows.map((r) => mapRow(r, reserved, source.columnMap)),\n total: Array.isArray(data) ? rows.length : (data?.total ?? rows.length),\n summary: Array.isArray(data) ? undefined : data?.summary,\n }\n }\n\n // The standard path: the generic aggregate engine.\n const args = runArgs(card, state, resolveTenantId())\n const { data, error } = await client().rpc('analytics_run', {\n p_source: args.source,\n p_tenant_id: args.tenant_id,\n p_from: args.from,\n p_to: args.to,\n p_dimensions: args.dimensions,\n p_measures: args.measures,\n p_filters: args.filters,\n p_search: args.search,\n p_search_columns: args.search_columns,\n p_sort: args.sort,\n p_dir: args.dir,\n p_limit: args.limit,\n p_offset: args.offset,\n })\n if (error) throw error\n return toResult(data, card, reserved)\n },\n\n // -----------------------------------------------------------------------\n // The batched path.\n //\n // Every aggregate card in the batch becomes ONE analytics_run_batch call;\n // detail listings and 'fn' cards, which the batch function cannot express,\n // still go one by one — but a dashboard is all aggregates, so opening\n // /analytics went from forty-one requests to one.\n //\n // Results keep their INDEX. The caller matched a promise to a position, and\n // returning a compacted array would silently hand card 7 card 9's numbers.\n // -----------------------------------------------------------------------\n async runMany(requests: AnalyticsBatchRequest[]): Promise<Array<AnalyticsResult | Error>> {\n const out: Array<AnalyticsResult | Error> = new Array(requests.length)\n const batchable: number[] = []\n\n for (let i = 0; i < requests.length; i++) {\n if (batchSupported && isAggregateCard(requests[i]!.card)) batchable.push(i)\n }\n\n // Anything the batch cannot carry runs on its own, concurrently.\n const singles = requests\n .map((req, i) => ({ req, i }))\n .filter(({ i }) => !batchable.includes(i))\n .map(({ req, i }) =>\n this.run(req.card, req.state)\n .then((r) => { out[i] = r })\n .catch((e: unknown) => { out[i] = toError(e) }))\n\n if (batchable.length > 0) {\n const tenantId = resolveTenantId()\n const payload = batchable.map((i) => runArgs(requests[i]!.card, requests[i]!.state, tenantId))\n const { data, error } = await client().rpc('analytics_run_batch', { p_requests: payload })\n\n if (error && batchUnavailable(error)) {\n // A pool that has analytics_run but not 034 must keep working rather\n // than reporting \"engine not installed\" on every card. Latched, so\n // the fallback costs one failed call per session, not per fetch.\n batchSupported = false\n await Promise.all([\n ...singles,\n ...batchable.map((i) =>\n this.run(requests[i]!.card, requests[i]!.state)\n .then((r) => { out[i] = r })\n .catch((e: unknown) => { out[i] = toError(e) })),\n ])\n return out\n }\n if (error) throw error\n\n const results: any[] = Array.isArray(data) ? data : []\n batchable.forEach((cardIndex, slot) => {\n const entry = results[slot]\n const { card } = requests[cardIndex]!\n out[cardIndex] = entry?.error\n ? Object.assign(toError(entry.error), { code: entry.code })\n : toResult(entry, card, reservedKeys(card))\n })\n }\n\n await Promise.all(singles)\n return out\n },\n }\n}\n","import type {\n AnalyticsCardDef, AnalyticsProvider, AnalyticsQueryState, AnalyticsRow,\n} from '@fayz-ai/core'\nimport { aggregateRows } from './aggregate'\n\n// ---------------------------------------------------------------------------\n// Mock analytics provider — synthesises rows shaped by whatever the card asks\n// for, then runs them through the SAME aggregator the 'fn' source uses. The\n// numbers are invented; the grouping, bucketing and rollup behaviour is real,\n// so a card that looks right against the mock is not lying about its shape.\n//\n// Deterministic on purpose: a seeded generator means the dev dashboard does not\n// reshuffle on every keystroke, and a screenshot stays reproducible.\n// ---------------------------------------------------------------------------\n\nfunction seeded(seed: string): () => number {\n let h = 2166136261\n for (let i = 0; i < seed.length; i++) {\n h ^= seed.charCodeAt(i)\n h = Math.imul(h, 16777619)\n }\n return () => {\n h += 0x6d2b79f5\n let t = h\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\nconst SAMPLE_LABELS: Record<string, string[]> = {\n product_name: ['Camiseta Preta', 'Caneca Fayz', 'Moletom', 'Boné', 'Adesivos'],\n category_name: ['Vestuário', 'Acessórios', 'Casa'],\n customer_name: ['Ana Souza', 'Bruno Lima', 'Carla Dias', 'Diego Alves'],\n status: ['open', 'archived', 'cancelled'],\n financial_status: ['paid', 'pending', 'refunded'],\n fulfillment_status: ['fulfilled', 'unfulfilled', 'partially_fulfilled'],\n}\n\nfunction labelsFor(key: string, rand: () => number): string[] {\n const known = SAMPLE_LABELS[key]\n if (known) return known\n const n = 3 + Math.floor(rand() * 3)\n return Array.from({ length: n }, (_, i) => `${key.replace(/_/g, ' ')} ${i + 1}`)\n}\n\nexport function createMockAnalyticsProvider(): AnalyticsProvider {\n return {\n async run(card: AnalyticsCardDef, state: AnalyticsQueryState) {\n const rand = seeded(card.id)\n const dateColumn = card.query.dateColumn ?? 'created_at'\n const dimensions = card.query.dimensions ?? []\n const measures = card.query.measures ?? []\n\n const from = new Date(`${state.dateRange.from}T12:00:00`).getTime()\n const to = new Date(`${state.dateRange.to}T12:00:00`).getTime()\n const span = Math.max(to - from, 86_400_000)\n\n // Enough rows that every bucket and every category is represented, capped\n // so a 90-day range does not synthesise thousands of throwaway objects.\n const rowCount = Math.min(400, Math.max(60, Math.round(span / 86_400_000) * 4))\n const categoricalDims = dimensions.filter((d) => !d.grain && d.key !== dateColumn)\n const labelPools = new Map(categoricalDims.map((d) => [d.key, labelsFor(d.key, rand)]))\n\n const rows: AnalyticsRow[] = Array.from({ length: rowCount }, () => {\n const row: AnalyticsRow = {\n [dateColumn]: new Date(from + rand() * span).toISOString(),\n }\n for (const [key, pool] of labelPools) {\n row[key] = pool[Math.floor(rand() * pool.length)]\n }\n for (const m of measures) {\n if (m.agg === 'count' || m.agg === 'ratio') continue\n const column = m.column ?? m.key\n row[column] = m.format === 'currency'\n ? Math.round(rand() * 40000) / 100\n : m.format === 'percent'\n ? Math.round(rand() * 10000) / 100\n : Math.round(rand() * 50)\n }\n for (const c of card.columns ?? []) {\n if (c.key in row) continue\n row[c.key] = c.type === 'currency' || c.type === 'number'\n ? Math.round(rand() * 10000) / 100\n : c.type === 'date'\n ? new Date(from + rand() * span).toISOString()\n : `${c.label} ${Math.ceil(rand() * 20)}`\n }\n return row\n })\n\n return aggregateRows(rows, card, state)\n },\n\n // There is no transport to save a round trip on, so this is just the loop.\n // It exists because the mock is reached through createSafeDataProvider,\n // whose Proxy answers EVERY property with a function — `provider.runMany`\n // is truthy even for a provider that never declared it, and the caller's\n // feature check therefore cannot detect its absence. Implementing it is how\n // the mock stops being a landmine behind that Proxy.\n async runMany(requests) {\n return Promise.all(requests.map((r) =>\n this.run(r.card, r.state).catch((e: unknown) => (e instanceof Error ? e : new Error(String(e))))))\n },\n }\n}\n","import { useOrganizationStore } from '@fayz-ai/admin'\n\n// ---------------------------------------------------------------------------\n// Which tenant the analytics surface is reporting on.\n//\n// Defaults to the organization the shell is currently switched to. Leaving it\n// undefined is NOT equivalent: with no tenant the engine sends no predicate and\n// falls back to RLS alone, and RLS on the shop tables admits every tenant the\n// user is a member of (`tenant_id IN user_tenant_ids()`). In a multi-org app\n// that is one page reporting the sum of every store the operator can see, while\n// every other screen beside it shows only the active one.\n// ---------------------------------------------------------------------------\n\nlet override: string | undefined\n\n/** Pin the surface to a tenant, overriding the active organization. */\nexport function setReportsTenantId(id: string | undefined): void {\n override = id\n}\n\nexport function getReportsTenantId(): string | undefined {\n if (override) return override\n try {\n return useOrganizationStore.getState().currentOrg?.id\n } catch {\n // No org store mounted (a bespoke host, a test): fall back to RLS rather\n // than throwing inside a data provider.\n return undefined\n }\n}\n","export const en: Record<string, string> = {\n 'reports.pageTitle': 'Reports',\n 'reports.pageSubtitle': 'Access complete reports for analysis and decision making',\n 'reports.overview': 'Overview',\n 'reports.allReports': 'All reports',\n 'reports.dateRange': 'Date Range',\n 'reports.from': 'From',\n 'reports.to': 'To',\n 'reports.export': 'Export',\n 'reports.exportCsv': 'Export CSV',\n 'reports.exportExcel': 'Export Excel',\n 'reports.exportPdf': 'Export PDF',\n 'reports.noResults': 'No results found.',\n 'reports.backToReports': 'Back',\n 'reports.reports': 'reports',\n 'reports.search': 'Search reports...',\n 'reports.today': 'Today',\n 'reports.yesterday': 'Yesterday',\n 'reports.last7Days': 'Last 7 days',\n 'reports.thisMonth': 'This month',\n 'reports.lastMonth': 'Last month',\n 'reports.thisQuarter': 'This quarter',\n 'reports.custom': 'Custom',\n 'reports.generate': 'Generate',\n 'reports.emptyStateTitle': 'Ready to generate',\n 'reports.emptyStateDescription': 'Select a date range and filters, then click Generate to view the report.',\n // The assistant's invitation on /analytics. It opens on a question, not on a\n // grid: the numbers are already downstairs, and what the owner actually wants\n // is to know what they mean.\n 'reports.assistant.persona': 'Growth Analyst',\n 'reports.assistant.headline': 'Hi {{name}}, what would you like to learn today?',\n 'reports.assistant.pitch': \"Let's find the opportunities hiding in your business\",\n 'reports.assistant.description':\n \"Tell me your goals and I'll help build a plan to hit them. I read the same data these reports do, and I'll point at what changed and what to do about it.\",\n 'reports.assistant.placeholder': 'Build a custom report...',\n 'reports.assistant.suggestion.0': 'How is my business doing this month?',\n 'reports.assistant.suggestion.1': \"What's growing and what's falling?\",\n 'reports.assistant.suggestion.2': 'Where am I losing money?',\n 'reports.unavailableTitle': 'Coming soon',\n 'reports.unavailableDescription': 'This report is not available yet. It will be enabled in a future update.',\n}\n","export const ptBR: Record<string, string> = {\n 'reports.pageTitle': 'Relatórios',\n 'reports.pageSubtitle': 'Acesse relatórios completos para análise e tomada de decisão',\n 'reports.overview': 'Visão geral',\n 'reports.allReports': 'Todos os relatórios',\n 'reports.dateRange': 'Período',\n 'reports.from': 'De',\n 'reports.to': 'Até',\n 'reports.export': 'Exportar',\n 'reports.exportCsv': 'Exportar CSV',\n 'reports.exportExcel': 'Exportar Excel',\n 'reports.exportPdf': 'Exportar PDF',\n 'reports.noResults': 'Nenhum resultado encontrado.',\n 'reports.backToReports': 'Voltar',\n 'reports.reports': 'relatórios',\n 'reports.search': 'Buscar relatórios...',\n 'reports.today': 'Hoje',\n 'reports.yesterday': 'Ontem',\n 'reports.last7Days': 'Últimos 7 dias',\n 'reports.thisMonth': 'Este mês',\n 'reports.lastMonth': 'Mês passado',\n 'reports.thisQuarter': 'Este trimestre',\n 'reports.custom': 'Personalizado',\n 'reports.generate': 'Gerar',\n 'reports.emptyStateTitle': 'Pronto para gerar',\n 'reports.emptyStateDescription': 'Selecione o período e os filtros desejados, depois clique em Gerar para visualizar o relatório.',\n 'reports.assistant.persona': 'Analista de Crescimento',\n 'reports.assistant.headline': 'Oi {{name}}, o que você quer entender hoje?',\n 'reports.assistant.pitch': 'Vamos achar as oportunidades escondidas no seu negócio',\n 'reports.assistant.description':\n 'Me conte sua meta e eu ajudo a montar o plano para bater. Leio os mesmos dados destes relatórios e aponto o que mudou e o que fazer a respeito.',\n 'reports.assistant.placeholder': 'Peça um relatório do seu jeito...',\n 'reports.assistant.suggestion.0': 'Como está meu negócio neste mês?',\n 'reports.assistant.suggestion.1': 'O que está crescendo e o que está caindo?',\n 'reports.assistant.suggestion.2': 'Onde estou perdendo dinheiro?',\n 'reports.unavailableTitle': 'Em breve',\n 'reports.unavailableDescription': 'Este relatório ainda não está disponível. Será habilitado em uma atualização futura.',\n}\n","import { en } from './en'\nimport { ptBR } from './pt-BR'\n\nexport const reportsLocales: Record<string, Record<string, string>> = {\n en,\n 'pt-BR': ptBR,\n}\n","import type { AnalyticsCardDef, AnalyticsColumnDef, AnalyticsFilterDef } from '@fayz-ai/core'\nimport type { ReportDef } from '../types'\n\n// ---------------------------------------------------------------------------\n// ReportDef → AnalyticsCardDef.\n//\n// Consuming apps declare hundreds of lines of ReportDef today. Rewriting them\n// all in one commit is how a refactor stalls, so the old shape keeps working: a\n// legacy report becomes a card with a table viz and no dashboard placement — it\n// appears in the report list, opens in the viewer, and simply never claims a\n// tile on the overview.\n//\n// Nothing here is lossy. When an app is ready, it upgrades a report in place by\n// adding dimensions/measures and a `dashboard` block, and the same definition\n// starts also being a chart on the overview.\n// ---------------------------------------------------------------------------\n\nexport function reportDefToCard(report: ReportDef, createdBy?: string): AnalyticsCardDef {\n return {\n id: report.id,\n name: report.name,\n description: report.description,\n icon: report.icon,\n category: report.category,\n createdBy,\n available: report.available,\n grain: report.grain,\n canonicalOwner: report.canonicalOwner,\n permission: report.permission,\n query: {\n source: {\n kind: report.dataSource.kind,\n name: report.dataSource.name,\n columnMap: report.dataSource.columnMap,\n },\n dateColumn: report.dataSource.dateColumn,\n defaultSort: report.dataSource.defaultSort,\n defaultSortDir: report.dataSource.defaultSortDir,\n filters: (report.filters ?? []).map((f): AnalyticsFilterDef => ({\n key: f.key,\n label: f.label,\n type: f.type,\n options: f.options,\n defaultValue: f.defaultValue,\n placeholder: f.placeholder,\n // Legacy filters declared no category. Grouping them under the report's\n // own category keeps the picker organised instead of dumping every\n // filter from every report into one flat list.\n group: report.category,\n })),\n },\n // No dimensions/measures: a legacy report is a detail listing, and inventing\n // aggregations for it would change what the numbers mean.\n viz: { type: 'table' },\n columns: report.columns.map((c): AnalyticsColumnDef => ({\n key: c.key,\n label: c.label,\n type: c.type as AnalyticsColumnDef['type'],\n sortable: c.sortable,\n currency: c.currency,\n idKey: c.idKey,\n personKind: c.personKind,\n renderCell: c.renderCell,\n visible: c.visible,\n align: c.align,\n aggregate: c.aggregate,\n })),\n }\n}\n\nexport function reportDefsToCards(reports: ReportDef[], createdBy?: string): AnalyticsCardDef[] {\n return reports.map((r) => reportDefToCard(r, createdBy))\n}\n","import * as React from 'react'\n\n// ---------------------------------------------------------------------------\n// \"Last viewed\" for the report list.\n//\n// A catalogue of eighty reports sorted alphabetically is a filing cabinet; the\n// three a merchant actually opens each Monday are what they came for. This is\n// per-browser rather than per-tenant on purpose — it is a convenience ordering,\n// not a business fact, and it should not cost a write to the database on every\n// report a user glances at.\n// ---------------------------------------------------------------------------\n\nconst KEY = 'fayz.analytics.lastViewed'\n\ntype LastViewedMap = Record<string, string>\n\nfunction read(): LastViewedMap {\n if (typeof window === 'undefined') return {}\n try {\n const raw = window.localStorage.getItem(KEY)\n return raw ? (JSON.parse(raw) as LastViewedMap) : {}\n } catch {\n return {}\n }\n}\n\nfunction write(map: LastViewedMap): void {\n if (typeof window === 'undefined') return\n try {\n window.localStorage.setItem(KEY, JSON.stringify(map))\n } catch {\n /* quota or private mode — losing this costs an ordering, not data */\n }\n}\n\nconst listeners = new Set<(map: LastViewedMap) => void>()\n\nexport function markViewed(cardId: string): void {\n const next = { ...read(), [cardId]: new Date().toISOString() }\n write(next)\n for (const listener of listeners) listener(next)\n}\n\nexport function useLastViewed(): LastViewedMap {\n const [map, setMap] = React.useState<LastViewedMap>(() => read())\n React.useEffect(() => {\n listeners.add(setMap)\n return () => { listeners.delete(setMap) }\n }, [])\n return map\n}\n","import React from 'react'\nimport {\n usePluginRuntime, getAnalyticsCards, hashRouterAdapter,\n type AnalyticsCardDef, type AnalyticsProvider as AnalyticsProviderType, type AnalyticsColumnDef,\n type AnalyticsCompare,\n} from '@fayz-ai/core'\nimport { AnalyticsContextProvider, type AnalyticsRangePreset } from '@fayz-ai/ui'\nimport { markViewed } from '../lib/lastViewed'\n\n// ---------------------------------------------------------------------------\n// The surface every analytics page mounts inside.\n//\n// Cards arrive from two places and are merged here: the plugins that own the\n// data contribute them through the runtime registry (`analyticsCards` on the\n// manifest), and the host app adds or overrides via options. Registry first,\n// app last — an app curating its own pack must be able to win.\n// ---------------------------------------------------------------------------\n\nexport const ANALYTICS_BASE = '/analytics'\nexport const REPORTS_BASE = `${ANALYTICS_BASE}/reports`\n\nexport interface AnalyticsLabels {\n analytics: string\n reports: string\n liveView: string\n /** Rail entry for the card grid. Falls back to the `reports.overview` key. */\n overview?: string\n overviewSubtitle: string\n reportsSubtitle: string\n searchReports: string\n category: string\n createdBy: string\n /** Cleared state of each facet chip: \"All categories\" / \"All authors\". */\n allCategories: string\n allCreatedBy: string\n lastViewed: string\n name: string\n noResults: string\n never: string\n back: string\n export: string\n print: string\n unavailableTitle: string\n unavailableDescription: string\n emptyOverviewTitle: string\n emptyOverviewDescription: string\n liveViewSoon: string\n results: string\n}\n\n/** How the assistant introduces itself on the analytics screens. Every field is\n * optional: what is not set falls back to the plugin's own locale strings. */\nexport interface AnalyticsAssistantConfig {\n /** Names the assistant here — \"Growth Analyst\". */\n persona?: string\n /** Hero headline. `{{name}}` resolves to the signed-in user's first name. */\n headline?: string\n pitch?: string\n description?: string\n placeholder?: string\n suggestions?: { label: string; prompt?: string }[]\n /** `true` opens on the hero takeover. Default FALSE here, unlike the shell's:\n * the analytics home is a page of numbers, and a full-column invitation over\n * them hides the very thing the user navigated to. The composer docks at the\n * bottom instead — the assistant is offered, the metrics stay readable. */\n auto?: boolean\n}\n\nexport interface ResolvedAnalyticsConfig {\n /** Cards declared by the host app (merged with the plugin registry at render). */\n cards: AnalyticsCardDef[]\n labels: AnalyticsLabels\n currency: { code: string; locale: string; symbol: string }\n /** Attribution for pre-built cards — the product name, e.g. \"FayzShop\". */\n createdBy: string\n defaultPageSize: number\n showHeader: boolean\n /** Range the surface opens on. A salon reads 30 days; a school reads a term. */\n defaultRange: AnalyticsRangePreset\n defaultCompare: AnalyticsCompare\n /** Whether the Live View entry appears in the module rail. */\n showLiveView: boolean\n /** `null` mounts no invite — the screen opens on its numbers, not on a\n * conversation. Otherwise: the overrides, over the locale defaults. */\n assistant: AnalyticsAssistantConfig | null\n}\n\nconst ConfigContext = React.createContext<ResolvedAnalyticsConfig | null>(null)\n\nexport function useAnalyticsConfig(): ResolvedAnalyticsConfig {\n const ctx = React.useContext(ConfigContext)\n if (!ctx) throw new Error('useAnalyticsConfig must be used inside <AnalyticsSurface>')\n return ctx\n}\n\n/**\n * Every card visible on this surface, registry + app, de-duplicated by id.\n *\n * The app's own definition wins a collision so a host can retune a card the\n * plugin shipped (relabel it, move it off the overview) without forking the\n * plugin — the alternative is apps carrying patched copies of plugin cards.\n */\nexport function useAnalyticsCards(): AnalyticsCardDef[] {\n const runtime = usePluginRuntime()\n const { cards, createdBy } = useAnalyticsConfig()\n return React.useMemo(() => {\n const byId = new Map<string, AnalyticsCardDef>()\n for (const card of getAnalyticsCards(runtime)) byId.set(card.id, card)\n for (const card of cards) byId.set(card.id, card)\n return [...byId.values()].map((c) => (c.createdBy ? c : { ...c, createdBy }))\n }, [runtime, cards, createdBy])\n}\n\n/** Cards a pack placed on the overview grid, in their declared order. */\nexport function useOverviewCards(): AnalyticsCardDef[] {\n const all = useAnalyticsCards()\n return React.useMemo(\n () => all\n .filter((c) => c.dashboard && c.dashboard.defaultVisible !== false)\n .sort((a, b) => (a.dashboard?.order ?? 0) - (b.dashboard?.order ?? 0)),\n [all],\n )\n}\n\n/**\n * Columns for a card's tabular view.\n *\n * An aggregate card has no `columns` of its own — its table IS its dimensions\n * and measures, so deriving them keeps one definition instead of asking every\n * card author to restate the same fields twice and let the two drift.\n */\nexport function cardColumns(card: AnalyticsCardDef): AnalyticsColumnDef[] {\n if (card.columns?.length) return card.columns\n return [\n // A hidden dimension is group-by only — the id a person column reads from,\n // never a column of UUIDs next to the name it belongs to.\n ...(card.query.dimensions ?? []).filter((d) => !d.hidden).map((d): AnalyticsColumnDef => ({\n key: d.key,\n label: d.label,\n type: d.person ? 'person' : (d.format ?? (d.grain ? 'date' : 'text')),\n idKey: d.person?.idKey,\n personKind: d.person?.kind,\n align: 'left',\n })),\n ...(card.query.measures ?? []).map((m): AnalyticsColumnDef => ({\n key: m.key,\n label: m.label,\n type: m.format ?? 'number',\n align: 'right',\n sortable: true,\n })),\n ]\n}\n\nexport function navigateAnalytics(path: string): void {\n hashRouterAdapter().navigate(path)\n}\n\nexport interface AnalyticsSurfaceProps {\n config: ResolvedAnalyticsConfig\n provider: AnalyticsProviderType\n children?: React.ReactNode\n}\n\nexport function AnalyticsSurface({ config, provider, children }: AnalyticsSurfaceProps) {\n const openCard = React.useCallback((card: AnalyticsCardDef) => {\n markViewed(card.id)\n navigateAnalytics(`${REPORTS_BASE}/${encodeURIComponent(card.id)}`)\n }, [])\n\n return (\n <ConfigContext.Provider value={config}>\n <AnalyticsContextProvider\n provider={provider}\n currency={config.currency}\n defaultPreset={config.defaultRange}\n defaultCompare={config.defaultCompare}\n defaultPageSize={config.defaultPageSize}\n onOpenCard={openCard}\n createdBy={config.createdBy}\n >\n {children}\n </AnalyticsContextProvider>\n </ConfigContext.Provider>\n )\n}\n","import React from 'react'\nimport { useTranslation } from '@fayz-ai/core'\nimport { AssistantInvite } from '@fayz-ai/admin'\nimport { useAnalyticsConfig } from './AnalyticsSurface'\n\n// ---------------------------------------------------------------------------\n// The assistant's offer on Analytics.\n//\n// It belongs to the MODULE, not to the overview: a question about a report is\n// asked while reading that report, and a composer that only exists on the home\n// screen makes the user navigate away from the number to ask about it.\n// ---------------------------------------------------------------------------\n\nexport function AnalyticsAssistant() {\n const { assistant } = useAnalyticsConfig()\n const t = useTranslation()\n\n // Prompts the screen offers. App overrides win whole; otherwise the plugin's\n // own three, which are business questions and not report names on purpose.\n const suggestions = React.useMemo(\n () => assistant?.suggestions ?? [0, 1, 2].map((i) => ({ label: t(`reports.assistant.suggestion.${i}`) })),\n [assistant?.suggestions, t],\n )\n\n if (!assistant) return null\n\n return (\n <AssistantInvite\n // One id across the module: the same invitation followed from the grid to\n // a report, which is what lets the bar stay put instead of folding back\n // into the FAB and unrolling again on every internal navigation.\n id=\"analytics\"\n auto={assistant.auto ?? false}\n persona={assistant.persona ?? t('reports.assistant.persona')}\n headline={assistant.headline ?? t('reports.assistant.headline')}\n pitch={assistant.pitch ?? t('reports.assistant.pitch')}\n description={assistant.description ?? t('reports.assistant.description')}\n placeholder={assistant.placeholder ?? t('reports.assistant.placeholder')}\n suggestions={suggestions}\n />\n )\n}\n","import React from 'react'\nimport { ModulePage, useModuleLayout, type ModuleNavItem, type NavigationItem } from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\nimport type { AnalyticsCardDef } from '@fayz-ai/core'\nimport { useContextualNav, useShellRailAvailable } from '@fayz-ai/admin'\nimport {\n useAnalyticsConfig, useAnalyticsCards, navigateAnalytics, ANALYTICS_BASE, REPORTS_BASE,\n} from './AnalyticsSurface'\nimport { AnalyticsAssistant } from './AnalyticsAssistant'\n\n// ---------------------------------------------------------------------------\n// Analytics is ONE entry in the app nav, not two.\n//\n// \"Analytics\" and \"Reports\" were two top-level links to the same engine, which\n// made the user pick a door before knowing what was behind it. There is one\n// door now; inside it, the report groups (a card's `category`) and the reports\n// themselves ARE the navigation.\n//\n// Where that navigation is drawn depends on the product's shell, and the module\n// declares the tree once either way:\n//\n// sidebar layout — it takes over the app rail, exactly as /settings does\n// (useContextualNav). A second left column beside the app\n// rail is a menu inside a menu.\n// topbar layout — there is no rail to take over, so ModulePage draws its own\n// in-page one, like every other module.\n//\n// Charts are not re-implemented here: AnalyticsCard renders through the same\n// ChartWidget the dashboard uses.\n// ---------------------------------------------------------------------------\n\nexport type AnalyticsView = 'overview' | 'reports' | 'report' | 'live'\n\nexport interface AnalyticsModuleProps {\n view: AnalyticsView\n /** Route param when `view === 'report'` — marks the active entry. */\n cardId?: string\n children?: React.ReactNode\n}\n\nconst reportRoute = (cardId: string) => `${REPORTS_BASE}/${encodeURIComponent(cardId)}`\n\n/** Cards by category, categories A→Z, reports A→Z inside each. */\nfunction groupCards(cards: AnalyticsCardDef[]): [string, AnalyticsCardDef[]][] {\n const groups = new Map<string, AnalyticsCardDef[]>()\n for (const card of cards) {\n const list = groups.get(card.category)\n if (list) list.push(card)\n else groups.set(card.category, [card])\n }\n return [...groups.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([category, list]) => [category, [...list].sort((a, b) => a.name.localeCompare(b.name))])\n}\n\n/** The module's whole tree, in the order both renderers walk it. */\nfunction useAnalyticsTree() {\n const t = useTranslation()\n const { labels, showLiveView } = useAnalyticsConfig()\n const cards = useAnalyticsCards()\n\n return React.useMemo(() => ({\n title: labels.analytics,\n // Only the overview. The searchable catalogue (/analytics/reports) is still\n // routed — bookmarks and the legacy /reports link resolve — but it is not\n // listed: the tree below already IS the catalogue, and a link named \"all\n // reports\" sitting above the reports reads as a different, fuller list.\n fixed: [\n { id: 'overview', label: labels.overview ?? t('reports.overview'), icon: 'BarChart3', route: ANALYTICS_BASE, view: 'overview' as const },\n ],\n groups: groupCards(cards),\n live: showLiveView\n ? { id: 'live', label: labels.liveView, icon: 'Radio', route: `${ANALYTICS_BASE}/live`, view: 'live' as const }\n : null,\n }), [labels, showLiveView, cards, t])\n}\n\nexport function AnalyticsModule({ view, cardId, children }: AnalyticsModuleProps) {\n const variant = useModuleLayout()\n const tree = useAnalyticsTree()\n const activeId = cardId ? decodeURIComponent(cardId) : undefined\n // Does a shell rail exist to take over? The SHELL answers — it is the only\n // thing that knows. Asking the module-nav context instead meant reading its\n // default ('rail' = \"draw your own\") whenever the provider was out of the\n // tree, and the app rail plus this module's own column made exactly the two\n // menus the takeover exists to remove. The context is the fallback, for a\n // module mounted outside an AdminShell at all.\n const shellRail = useShellRailAvailable()\n const claimsRail = shellRail ?? (variant !== 'rail')\n\n // --- the shell rail (sidebar layout) -------------------------------------\n const entries = React.useMemo<NavigationItem[]>(() => [\n ...tree.fixed.map((f) => ({\n id: `analytics:${f.id}`, label: f.label, icon: f.icon, route: f.route, section: 'main' as const,\n })),\n ...tree.groups.flatMap(([category, list]) => list.map((card) => ({\n id: `analytics:${card.id}`,\n label: card.name,\n icon: card.icon ?? 'FileText',\n route: reportRoute(card.id),\n section: 'main' as const,\n // Consecutive items sharing a group render under one heading — the same\n // mechanism that heads the settings rail's plugin runs.\n group: category,\n }))),\n ...(tree.live ? [{\n id: 'analytics:live', label: tree.live.label, icon: tree.live.icon, route: tree.live.route, section: 'main' as const,\n }] : []),\n ], [tree])\n\n useContextualNav(claimsRail ? { base: ANALYTICS_BASE, entries, label: tree.title } : null)\n\n // --- the in-page rail (topbar layout) ------------------------------------\n const nav = React.useMemo<ModuleNavItem[]>(() => {\n if (claimsRail) return []\n return [\n ...tree.fixed.map((f) => ({\n id: f.id, label: f.label, icon: f.icon, active: view === f.view, onClick: () => navigateAnalytics(f.route),\n })),\n ...tree.groups.map(([category, list]): ModuleNavItem => ({\n id: `group:${category}`,\n label: category,\n children: list.map((card) => ({\n id: card.id,\n label: card.name,\n active: view === 'report' && card.id === activeId,\n onClick: () => navigateAnalytics(reportRoute(card.id)),\n })),\n })),\n ...(tree.live ? [{\n id: tree.live.id, label: tree.live.label, icon: tree.live.icon,\n active: view === 'live', onClick: () => navigateAnalytics(tree.live!.route),\n }] : []),\n ]\n }, [tree, view, activeId, claimsRail])\n\n return (\n <ModulePage\n title={tree.title}\n nav={nav}\n // 'sidebar' renders no sub-nav in the page: the shell rail is carrying it.\n navVariant={claimsRail ? 'sidebar' : 'rail'}\n showHeader={false}\n viewKey={view === 'report' ? `report:${activeId}` : view}\n >\n {/* Above the page body and outside its flow: the invite occupies no\n layout, it only measures where the content column is. */}\n <AnalyticsAssistant />\n {/* Tail room for the docked composer, which floats over the column —\n without it the last row of every analytics page ends underneath it. */}\n <div className=\"md:pb-16\">{children}</div>\n </ModulePage>\n )\n}\n","import React from 'react'\nimport { BarChart3 } from 'lucide-react'\nimport { AnalyticsControls, AnalyticsGrid, collectFilters } from '@fayz-ai/ui'\nimport { useAnalyticsConfig, useOverviewCards } from './AnalyticsSurface'\n\n// ---------------------------------------------------------------------------\n// The one general dashboard.\n//\n// It is not a separate feature from the report list — it is the subset of cards\n// a pack chose to place, rendered at tile size. Every tile's ↗ opens the very\n// same definition as a full report, which is why there is no \"dashboard metric\"\n// that has no report behind it.\n// ---------------------------------------------------------------------------\n\nexport function AnalyticsOverview() {\n const { labels } = useAnalyticsConfig()\n const cards = useOverviewCards()\n const filters = React.useMemo(() => collectFilters(cards), [cards])\n\n // The assistant's invite is mounted by the module, not here: it follows the\n // user from this grid into a report instead of belonging to one screen.\n return (\n <>\n <div className=\"space-y-4\">\n {/* Sem título nem descrição: a barra da shell já escreve \"Análises\", e a\n frase abaixo custava uma linha antes do primeiro número. */}\n {/* A superfície, o encosto à direita e o grudar no topo são de\n PageToolbar agora — a mesma barra que o dashboard usa. */}\n <AnalyticsControls filters={filters} />\n\n {cards.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed py-16 text-center\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <BarChart3 className=\"h-5 w-5 text-muted-foreground\" />\n </div>\n <p className=\"font-medium\">{labels.emptyOverviewTitle}</p>\n <p className=\"mt-1 max-w-sm text-sm text-muted-foreground\">{labels.emptyOverviewDescription}</p>\n </div>\n ) : (\n <AnalyticsGrid cards={cards} />\n )}\n </div>\n </>\n )\n}\n","import React from 'react'\nimport { Search, User } from 'lucide-react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport {\n Card, DataTable, FilterChip, type FilterChipOption,\n} from '@fayz-ai/ui'\nimport type { AnalyticsCardDef } from '@fayz-ai/core'\nimport { useAnalyticsConfig, useAnalyticsCards, navigateAnalytics, REPORTS_BASE } from './AnalyticsSurface'\nimport { useLastViewed, markViewed } from '../lib/lastViewed'\n\n// ---------------------------------------------------------------------------\n// The one list where a user finds what they want.\n//\n// This replaces the old category-card hub. Cards-in-a-grid look richer but stop\n// working past about twenty reports: you cannot sort them, cannot see when you\n// last opened one, and finding \"sales by vendor\" means reading every tile. A\n// table sorts, scans and filters — which is what a catalogue is for.\n//\n// It renders through the shared DataTable rather than a hand-rolled <table>.\n// The first version copied DataTable's classes by hand and drifted from it\n// immediately — wrong header tint, wrong corner radius — because a copy has to\n// be re-copied every time the original moves. `variant=\"bare\"` exists for this\n// exact shape: a table under a search toolbar, inside a card that already owns\n// the border and radius.\n// ---------------------------------------------------------------------------\n\nfunction formatViewed(iso: string | undefined, locale: string, never: string): string {\n if (!iso) return never\n const d = new Date(iso)\n if (Number.isNaN(d.getTime())) return never\n return d.toLocaleDateString(locale, { day: 'numeric', month: 'short', year: 'numeric' })\n}\n\nexport function ReportsListPage() {\n const { labels, currency, showHeader } = useAnalyticsConfig()\n const cards = useAnalyticsCards()\n const lastViewed = useLastViewed()\n\n const [search, setSearch] = React.useState('')\n // Single-select, like every other facet in the product (see FilterChip):\n // the chip states what is filtering right now, and picking \"all\" clears it.\n const [category, setCategory] = React.useState<string | undefined>()\n const [author, setAuthor] = React.useState<string | undefined>()\n\n const categoryOptions = React.useMemo<FilterChipOption[]>(\n () => [...new Set(cards.map((c) => c.category))]\n .sort((a, b) => a.localeCompare(b))\n .map((c) => ({ value: c, label: c })),\n [cards],\n )\n const authorOptions = React.useMemo<FilterChipOption[]>(\n () => [...new Set(cards.map((c) => c.createdBy ?? '—'))]\n .sort((a, b) => a.localeCompare(b))\n .map((a) => ({ value: a, label: a })),\n [cards],\n )\n\n const rows = React.useMemo(() => {\n const q = search.trim().toLowerCase()\n return cards.filter((card) => {\n if (category && card.category !== category) return false\n if (author && (card.createdBy ?? '—') !== author) return false\n if (!q) return true\n // Description is searched too: users look for \"no-show\" long before they\n // remember a report is filed under \"Cancellations\".\n return card.name.toLowerCase().includes(q)\n || card.description?.toLowerCase().includes(q)\n || card.category.toLowerCase().includes(q)\n })\n }, [cards, search, category, author])\n\n const columns = React.useMemo<ColumnDef<AnalyticsCardDef, unknown>[]>(() => [\n {\n id: 'name',\n accessorFn: (card) => card.name,\n header: labels.name,\n cell: ({ row }) => (\n <div className=\"min-w-0\">\n <span className=\"font-medium\">{row.original.name}</span>\n {row.original.available === false ? (\n <span className=\"ml-2 rounded-full border px-1.5 py-0.5 text-[10px] text-muted-foreground\">\n {labels.unavailableTitle}\n </span>\n ) : null}\n {row.original.description ? (\n <p className=\"mt-0.5 line-clamp-1 text-muted-foreground sm:hidden\">{row.original.description}</p>\n ) : null}\n </div>\n ),\n },\n {\n id: 'category',\n accessorFn: (card) => card.category,\n header: labels.category,\n cell: ({ getValue }) => (\n <span className=\"rounded-md bg-muted px-2 py-0.5\">{String(getValue() ?? '')}</span>\n ),\n },\n {\n id: 'lastViewed',\n // Sorts on the timestamp, renders the date. Never-opened reports carry\n // undefined so they sink to the bottom in BOTH directions rather than\n // topping \"most recent\" as an epoch-zero date.\n accessorFn: (card) => {\n const iso = lastViewed[card.id]\n return iso ? new Date(iso).getTime() : undefined\n },\n sortUndefined: 1,\n header: labels.lastViewed,\n cell: ({ row }) => (\n <span className=\"text-muted-foreground\">\n {formatViewed(lastViewed[row.original.id], currency.locale, labels.never)}\n </span>\n ),\n },\n {\n id: 'createdBy',\n accessorFn: (card) => card.createdBy ?? '—',\n header: labels.createdBy,\n cell: ({ getValue }) => (\n <span className=\"inline-flex items-center gap-1.5 text-muted-foreground\">\n <User className=\"h-3 w-3\" />\n {String(getValue() ?? '—')}\n </span>\n ),\n },\n ], [labels, currency.locale, lastViewed])\n\n const open = (card: AnalyticsCardDef) => {\n markViewed(card.id)\n navigateAnalytics(`${REPORTS_BASE}/${encodeURIComponent(card.id)}`)\n }\n\n return (\n <div className=\"space-y-4\">\n {showHeader ? (\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">{labels.reports}</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">{labels.reportsSubtitle}</p>\n </div>\n ) : null}\n\n {/* Same composition as CrudListView: search, tools and the table are ONE\n surface, because they act on the same rows. The Card owns the border\n and radius, so the table inside goes `bare`. */}\n <Card className=\"overflow-hidden\">\n <div className=\"flex flex-wrap items-center gap-2 border-b border-border px-3 py-2\">\n <div className=\"min-w-[10rem] flex-1\">\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground\" />\n {/* Borderless, exactly as CrudListView's search box: the card\n already draws the boundary, and a second box inside it would\n be a frame inside a frame. */}\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder={labels.searchReports}\n className=\"w-full bg-transparent py-1.5 pl-8 pr-3 text-sm placeholder:text-muted-foreground focus:outline-none\"\n />\n </div>\n </div>\n\n <div className=\"flex shrink-0 flex-wrap items-center gap-1.5\">\n <FilterChip\n label={labels.category}\n allLabel={labels.allCategories}\n options={categoryOptions}\n value={category}\n onChange={setCategory}\n />\n <FilterChip\n label={labels.createdBy}\n allLabel={labels.allCreatedBy}\n options={authorOptions}\n value={author}\n onChange={setAuthor}\n />\n </div>\n </div>\n\n <DataTable\n columns={columns}\n data={rows}\n variant=\"bare\"\n compact\n onRowClick={open}\n emptyMessage={labels.noResults}\n />\n\n <div className=\"border-t border-border px-3 py-2 text-xs text-muted-foreground\">\n {rows.length} {labels.results}\n </div>\n </Card>\n </div>\n )\n}\n","import { exportCSV } from '@fayz-ai/core'\nimport type { CSVColumn } from '@fayz-ai/core'\nimport type { ReportColumnDef } from '../types'\nimport { formatValuePlain } from '../lib/columns'\n\nexport function exportToCsv(\n columns: ReportColumnDef[],\n data: Record<string, any>[],\n filename: string,\n currency?: string,\n): void {\n const visibleCols = columns.filter((c) => c.visible !== false)\n\n const csvColumns: CSVColumn[] = visibleCols.map((col) => ({\n key: col.key,\n label: col.label,\n format: (value: any) => formatValuePlain(value, col, currency),\n }))\n\n exportCSV(csvColumns, data, filename)\n}\n","import React, { useEffect, useState } from 'react'\nimport { Download } from 'lucide-react'\nimport { Button } from '@fayz-ai/ui'\nimport {\n Dropdown,\n DropdownTrigger,\n DropdownContent,\n DropdownItem,\n} from '@fayz-ai/ui'\nimport { useTranslation } from '@fayz-ai/core'\nimport type { ReportColumnDef } from '../types'\nimport { exportToCsv } from '../export/csv'\n\ninterface ExportDropdownProps {\n columns: ReportColumnDef[]\n data: Record<string, any>[]\n filename: string\n currency?: string\n title?: string\n}\n\nexport function ExportDropdown({ columns, data, filename, currency, title }: ExportDropdownProps) {\n const t = useTranslation()\n const [excelAvailable, setExcelAvailable] = useState(false)\n const [pdfAvailable, setPdfAvailable] = useState(false)\n\n useEffect(() => {\n import('../export/excel').then((m) => m.isExcelAvailable()).then(setExcelAvailable).catch(() => {})\n import('../export/pdf').then((m) => m.isPdfAvailable()).then(setPdfAvailable).catch(() => {})\n }, [])\n\n const handleCsv = () => exportToCsv(columns, data, filename, currency)\n\n const handleExcel = async () => {\n const { exportToExcel } = await import('../export/excel')\n await exportToExcel(columns, data, filename, currency)\n }\n\n const handlePdf = async () => {\n const { exportToPdf } = await import('../export/pdf')\n await exportToPdf(columns, data, filename, { title, currency })\n }\n\n return (\n <Dropdown>\n <DropdownTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"h-4 w-4 mr-1.5\" />\n {t('reports.export')}\n </Button>\n </DropdownTrigger>\n <DropdownContent align=\"end\">\n <DropdownItem onClick={handleCsv}>{t('reports.exportCsv')}</DropdownItem>\n {excelAvailable && (\n <DropdownItem onClick={handleExcel}>{t('reports.exportExcel')}</DropdownItem>\n )}\n {pdfAvailable && (\n <DropdownItem onClick={handlePdf}>{t('reports.exportPdf')}</DropdownItem>\n )}\n </DropdownContent>\n </Dropdown>\n )\n}\n","import React from 'react'\nimport { ChevronLeft, ChevronRight } from 'lucide-react'\nimport { Button } from '@fayz-ai/ui'\n\ninterface ReportPaginationProps {\n page: number\n pageSize: number\n total: number\n onPageChange: (page: number) => void\n onPageSizeChange: (size: number) => void\n}\n\nexport function ReportPagination({ page, pageSize, total, onPageChange, onPageSizeChange }: ReportPaginationProps) {\n const totalPages = Math.max(1, Math.ceil(total / pageSize))\n const from = (page - 1) * pageSize + 1\n const to = Math.min(page * pageSize, total)\n\n return (\n <div className=\"flex items-center justify-between border-t px-4 py-3\">\n <div className=\"text-sm text-muted-foreground\">\n {total > 0 ? `${from}–${to} of ${total}` : 'No results'}\n </div>\n\n <div className=\"flex items-center gap-3\">\n <select\n value={pageSize}\n onChange={(e) => onPageSizeChange(Number(e.target.value))}\n className=\"h-8 rounded-input border border-input bg-card shadow-[inset_0_1px_0_rgb(0_0_0_/0.06)] px-2 text-sm\"\n >\n {[25, 50, 100].map((size) => (\n <option key={size} value={size}>{size} / page</option>\n ))}\n </select>\n\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={page <= 1}\n onClick={() => onPageChange(page - 1)}\n >\n <ChevronLeft className=\"h-4 w-4\" />\n </Button>\n <span className=\"text-sm px-2\">\n {page} / {totalPages}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n disabled={page >= totalPages}\n onClick={() => onPageChange(page + 1)}\n >\n <ChevronRight className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n </div>\n )\n}\n","import React from 'react'\nimport { ArrowLeft, Construction, Printer } from 'lucide-react'\nimport {\n Button, SubpageHeader, AnalyticsCard, AnalyticsControls, useAnalyticsContext, useAnalyticsCard,\n} from '@fayz-ai/ui'\nimport type { AnalyticsCardDef } from '@fayz-ai/core'\nimport { DataTable } from '@fayz-ai/ui'\nimport { reportColumnsToTanstack } from '../lib/columns'\nimport { ExportDropdown } from '../components/ExportDropdown'\nimport { ReportPagination } from '../components/ReportPagination'\nimport type { ReportColumnDef } from '../types'\nimport {\n useAnalyticsConfig, useAnalyticsCards, cardColumns, navigateAnalytics,\n ANALYTICS_BASE, REPORTS_BASE,\n} from './AnalyticsSurface'\nimport { markViewed } from '../lib/lastViewed'\n\n// ---------------------------------------------------------------------------\n// A report, full size.\n//\n// The chart is not decoration bolted onto a table: it is the SAME card that\n// renders as a tile on the overview, given the whole width. Underneath sits the\n// data it was computed from — so \"show me the number\" and \"show me the rows\n// behind the number\" stop being two different features in two different places.\n// ---------------------------------------------------------------------------\n\nfunction ViewerBody({ card }: { card: AnalyticsCardDef }) {\n const { labels, currency } = useAnalyticsConfig()\n const { state, setPage, setPageSize } = useAnalyticsContext()\n // Same query as the chart above and the export below — the provider\n // de-duplicates them into one round trip.\n const { result, loading, error, engineMissing } = useAnalyticsCard(card)\n\n const columns = React.useMemo(() => cardColumns(card), [card])\n const tanstackColumns = React.useMemo(\n () => reportColumnsToTanstack(columns as unknown as ReportColumnDef[], currency.code),\n [columns, currency.code],\n )\n const rows = result?.rows ?? []\n\n if (card.available === false) {\n return (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed py-16 text-center\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <Construction className=\"h-5 w-5 text-muted-foreground\" />\n </div>\n <p className=\"font-medium\">{labels.unavailableTitle}</p>\n <p className=\"mt-1 max-w-sm text-sm text-muted-foreground\">{labels.unavailableDescription}</p>\n </div>\n )\n }\n\n // A pure detail listing has nothing to chart — rendering an empty card frame\n // above the table would be chrome pretending to be information.\n const hasViz = card.viz.type !== 'table' || (card.query.measures?.length ?? 0) > 0\n\n return (\n <>\n {hasViz ? (\n <AnalyticsCard\n card={{ ...card, viz: { ...card.viz, height: card.viz.height ?? 280, limit: undefined } }}\n hideOpen\n />\n ) : null}\n\n {engineMissing ? (\n <div className=\"rounded-lg border bg-muted/40 p-3 text-sm\">\n <p className=\"font-medium\">Analytics engine not installed</p>\n <p className=\"mt-0.5 text-muted-foreground\">\n This report aggregates server-side and needs migration 0039\n (<code className=\"text-xs\">analytics_run</code> + the read models) applied to this project.\n </p>\n </div>\n ) : error ? (\n <div className=\"rounded-lg border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive\">\n {error}\n </div>\n ) : null}\n\n <DataTable\n columns={tanstackColumns}\n data={rows}\n loading={loading}\n skeletonRows={5}\n emptyMessage={labels.noResults}\n variant=\"card\"\n compact\n />\n\n {!loading ? (\n <div className=\"no-print\">\n <ReportPagination\n page={state.page}\n pageSize={state.pageSize}\n total={result?.total ?? 0}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </div>\n ) : null}\n </>\n )\n}\n\nexport function AnalyticsReportViewer({ cardId }: { cardId?: string }) {\n const { labels } = useAnalyticsConfig()\n const cards = useAnalyticsCards()\n const card = cards.find((c) => c.id === decodeURIComponent(cardId ?? ''))\n\n React.useEffect(() => { if (card) markViewed(card.id) }, [card?.id])\n\n if (!card) {\n return (\n <div className=\"space-y-4\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => navigateAnalytics(REPORTS_BASE)}>\n <ArrowLeft className=\"mr-1.5 h-3.5 w-3.5\" />\n {labels.reports}\n </Button>\n <p className=\"py-12 text-center text-sm text-muted-foreground\">{labels.noResults}</p>\n </div>\n )\n }\n\n return (\n <div className=\"space-y-4\">\n {/* O título vive na barra da shell, não no corpo. Escrever \"← Relatórios /\n Nome\" aqui E deixar a rota declarar `parentRoute` produzia três\n cabeçalhos empilhados dizendo a mesma coisa. SubpageHeader reivindica a\n barra com o nome do card — que depende de dado e por isso não cabe em\n `route.title`. */}\n <SubpageHeader\n title={card.name}\n parentLabel={labels.analytics}\n onBack={() => navigateAnalytics(ANALYTICS_BASE)}\n />\n\n {card.description ? (\n <p className=\"text-sm text-muted-foreground\">{card.description}</p>\n ) : null}\n\n <AnalyticsControls\n filters={card.query.filters ?? []}\n showCompare={card.compare !== false}\n className=\"no-print\"\n actions={<ViewerActions card={card} />}\n />\n\n <ViewerBody card={card} />\n </div>\n )\n}\n\nfunction ViewerActions({ card }: { card: AnalyticsCardDef }) {\n const { currency } = useAnalyticsConfig()\n const { result } = useAnalyticsCard(card)\n const columns = React.useMemo(() => cardColumns(card), [card])\n if (!result?.rows?.length) return null\n return (\n <>\n <ExportDropdown\n columns={columns as unknown as ReportColumnDef[]}\n data={result.rows as Record<string, unknown>[]}\n filename={card.id}\n currency={currency.code}\n title={card.name}\n />\n <Button variant=\"outline\" size=\"sm\" className=\"h-8\" onClick={() => window.print()}>\n <Printer className=\"mr-1.5 h-3.5 w-3.5\" />\n Print\n </Button>\n </>\n )\n}\n","import React from 'react'\nimport { Radio } from 'lucide-react'\nimport { useAnalyticsConfig } from './AnalyticsSurface'\n\n// ---------------------------------------------------------------------------\n// Live View — the real-time surface.\n//\n// A deliberate stub. It needs a storefront event stream (sessions, carts,\n// checkouts) that does not exist yet, and the honest thing on a page with no\n// data source is to say so rather than render zeroes that look like a quiet\n// afternoon. It holds its nav slot so the shape of the section is visible.\n// ---------------------------------------------------------------------------\n\nexport function LiveViewPage() {\n const { labels } = useAnalyticsConfig()\n return (\n <div className=\"flex flex-col items-center justify-center rounded-xl border border-dashed py-20 text-center\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <Radio className=\"h-5 w-5 text-muted-foreground\" />\n </div>\n <p className=\"font-medium\">{labels.liveView}</p>\n <p className=\"mt-1 max-w-sm text-sm text-muted-foreground\">{labels.liveViewSoon}</p>\n </div>\n )\n}\n","import { getSupabaseClientOptional } from '@fayz-ai/core'\nimport type { ReportDef, ReportQueryState } from '../types'\nimport type { ReportDataProvider, ReportResult } from './types'\n\n// ---------------------------------------------------------------------------\n// Case conversion\n// ---------------------------------------------------------------------------\n\nfunction camelToSnake(str: string): string {\n return str.replace(/[A-Z]/g, (c) => '_' + c.toLowerCase())\n}\n\nfunction snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase())\n}\n\nfunction mapRow(row: Record<string, unknown>, columnMap?: Record<string, string>): Record<string, any> {\n const result: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(row)) {\n const camelKey = columnMap?.[key] ?? snakeToCamel(key)\n result[camelKey] = value\n }\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Provider factory\n// ---------------------------------------------------------------------------\n\nexport interface SupabaseReportProviderConfig {\n tenantId: string | (() => string | undefined)\n tenantIdColumn?: string\n schema?: string\n}\n\nexport function createSupabaseReportProvider(config: SupabaseReportProviderConfig): ReportDataProvider {\n const schema = config.schema ?? 'public'\n const tenantIdCol = config.tenantIdColumn ?? 'tenant_id'\n\n function resolveTenantId(): string | undefined {\n return typeof config.tenantId === 'function' ? config.tenantId() : config.tenantId\n }\n\n function getClient() {\n const supabase = getSupabaseClientOptional() as any\n if (!supabase) throw new Error('Supabase client not available')\n return schema === 'public' ? supabase : supabase.schema(schema)\n }\n\n return {\n async fetch(reportDef: ReportDef, query: ReportQueryState): Promise<ReportResult> {\n const { dataSource } = reportDef\n const columnMap = dataSource.columnMap\n\n if (dataSource.kind === 'rpc') {\n return fetchViaRpc(reportDef, query, getClient, resolveTenantId, columnMap)\n }\n\n return fetchViaView(reportDef, query, getClient, resolveTenantId, tenantIdCol, columnMap)\n },\n }\n}\n\n// ---------------------------------------------------------------------------\n// View-based fetch\n// ---------------------------------------------------------------------------\n\nasync function fetchViaView(\n reportDef: ReportDef,\n query: ReportQueryState,\n getClient: () => any,\n resolveTenantId: () => string | undefined,\n tenantIdCol: string,\n columnMap?: Record<string, string>,\n): Promise<ReportResult> {\n const { dataSource } = reportDef\n let q = getClient().from(dataSource.name).select('*', { count: 'exact' })\n\n // Tenant scoping\n const tenantId = resolveTenantId()\n if (tenantId) {\n q = q.eq(tenantIdCol, tenantId)\n }\n\n // Date range\n const dateCol = dataSource.dateColumn ?? 'created_at'\n if (query.dateRange.from) {\n q = q.gte(dateCol, query.dateRange.from)\n }\n if (query.dateRange.to) {\n // For date-type columns, plain date string is sufficient.\n // For timestamptz columns, extend to end of day.\n const toValue = dateCol === 'created_at' || dateCol.endsWith('_at')\n ? query.dateRange.to + 'T23:59:59'\n : query.dateRange.to\n q = q.lte(dateCol, toValue)\n }\n\n // Custom filters\n for (const [key, value] of Object.entries(query.filters)) {\n if (value == null || value === '') continue\n const col = camelToSnake(key)\n if (Array.isArray(value)) {\n q = q.in(col, value)\n } else {\n q = q.eq(col, value)\n }\n }\n\n // Search\n if (query.search) {\n const searchableCols = reportDef.columns\n .filter((c) => c.type === 'text' || c.type === 'email' || c.type === 'person')\n .map((c: any) => camelToSnake(c.key))\n if (searchableCols.length > 0) {\n const term = `%${query.search}%`\n const orClause = searchableCols.map((col) => `${col}.ilike.${term}`).join(',')\n q = q.or(orClause)\n }\n }\n\n // Sort\n const sortCol = query.sortBy\n ? camelToSnake(query.sortBy)\n : dataSource.defaultSort\n ? camelToSnake(dataSource.defaultSort)\n : dateCol\n const ascending = query.sortDir\n ? query.sortDir === 'asc'\n : dataSource.defaultSortDir\n ? dataSource.defaultSortDir === 'asc'\n : false\n q = q.order(sortCol, { ascending })\n\n // Pagination\n const from = (query.page - 1) * query.pageSize\n const to = from + query.pageSize - 1\n q = q.range(from, to)\n\n const { data, error, count } = await q\n\n if (error) throw error\n\n return {\n data: (data ?? []).map((row: any) => mapRow(row, columnMap)),\n total: count ?? 0,\n }\n}\n\n// ---------------------------------------------------------------------------\n// RPC-based fetch\n// ---------------------------------------------------------------------------\n\nasync function fetchViaRpc(\n reportDef: ReportDef,\n query: ReportQueryState,\n getClient: () => any,\n resolveTenantId: () => string | undefined,\n columnMap?: Record<string, string>,\n): Promise<ReportResult> {\n const { dataSource } = reportDef\n const tenantId = resolveTenantId()\n\n const params: Record<string, any> = {\n p_tenant_id: tenantId,\n p_from: query.dateRange.from,\n p_to: query.dateRange.to,\n p_page: query.page,\n p_page_size: query.pageSize,\n }\n\n // Custom filters\n for (const [key, value] of Object.entries(query.filters)) {\n if (value == null || value === '') continue\n params[`p_${camelToSnake(key)}`] = value\n }\n\n if (query.sortBy) {\n params.p_sort_by = camelToSnake(query.sortBy)\n params.p_sort_dir = query.sortDir ?? 'desc'\n }\n\n const { data, error } = await getClient().rpc(dataSource.name, params)\n if (error) throw error\n\n // RPC expected to return { data: [...], total: number }\n if (data && typeof data === 'object' && 'data' in data) {\n return {\n data: (data.data ?? []).map((row: any) => mapRow(row, columnMap)),\n total: data.total ?? 0,\n }\n }\n\n // Fallback: RPC returns a plain array\n const rows = Array.isArray(data) ? data : []\n return {\n data: rows.map((row: any) => mapRow(row, columnMap)),\n total: rows.length,\n }\n}\n","import type { ReportDataProvider } from './types'\n\nexport function createMockReportProvider(): ReportDataProvider {\n return {\n async fetch() {\n return { data: [], total: 0 }\n },\n }\n}\n","import React from 'react'\nimport type {\n PluginManifest, PluginScope, VerticalId, AnalyticsCardDef, AnalyticsProvider, AnalyticsCompare,\n} from '@fayz-ai/core'\nimport type { AnalyticsRangePreset } from '@fayz-ai/ui'\nimport { createSafeDataProvider, registerTranslations } from '@fayz-ai/core'\nimport { createSupabaseAnalyticsProvider } from './data/analytics-supabase'\nimport { createMockAnalyticsProvider } from './data/analytics-mock'\nimport { getReportsTenantId } from './lib/tenant'\nimport { reportsLocales } from './locales'\nimport { reportDefsToCards } from './lib/legacy'\nimport {\n AnalyticsSurface, ANALYTICS_BASE, REPORTS_BASE,\n type AnalyticsLabels, type ResolvedAnalyticsConfig, type AnalyticsAssistantConfig,\n} from './views/AnalyticsSurface'\nimport { AnalyticsModule, type AnalyticsView } from './views/AnalyticsModule'\nimport { AnalyticsOverview } from './views/AnalyticsOverview'\nimport { ReportsListPage } from './views/ReportsListPage'\nimport { AnalyticsReportViewer } from './views/AnalyticsReportViewer'\nimport { LiveViewPage } from './views/LiveViewPage'\nimport type { ReportsPluginOptions } from './types'\n\n// ---------------------------------------------------------------------------\n// Analytics — one engine, one door, several rooms.\n//\n// /analytics the general dashboard: the cards a pack placed\n// /analytics/reports the one list where a user finds what they want\n// /analytics/reports/:id a report, full size (chart AND rows)\n// /analytics/live real-time (stub, awaiting a storefront event stream)\n//\n// ONE nav entry. Analytics and Reports used to be two top-level links to the\n// same engine — the app menu asked the user to choose a door before showing\n// what was behind either. Everything below /analytics now hangs off the module\n// rail (AnalyticsModule), where the report groups and the reports themselves\n// are the navigation.\n//\n// The package is still called plugin-reports so the six consuming apps keep\n// their imports; the CONCEPT it exposes is Analytics, with Reports as the\n// catalogue inside it.\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_LABELS: AnalyticsLabels = {\n analytics: 'Analytics',\n reports: 'Reports',\n liveView: 'Live View',\n overviewSubtitle: 'Key metrics for your business',\n reportsSubtitle: 'Every report available to you',\n searchReports: 'Search reports',\n category: 'Category',\n createdBy: 'Created by',\n allCategories: 'All categories',\n allCreatedBy: 'All authors',\n lastViewed: 'Last viewed',\n name: 'Name',\n noResults: 'No results found.',\n never: '—',\n back: 'Back',\n export: 'Export',\n print: 'Print',\n unavailableTitle: 'Coming soon',\n unavailableDescription: 'This report is not connected to data yet. It will be enabled in a future update.',\n emptyOverviewTitle: 'No metrics yet',\n emptyOverviewDescription: 'Enable a plugin that contributes analytics cards, or add them to this app’s pack.',\n liveViewSoon: 'Real-time visitor and checkout activity will appear here once storefront events are being collected.',\n results: 'reports',\n}\n\nconst DEFAULT_CURRENCY = { code: 'BRL', locale: 'pt-BR', symbol: 'R$' }\n\nexport interface AnalyticsPluginOptions {\n /**\n * Cards the host app contributes or overrides. Cards owned by a plugin come\n * through the runtime registry automatically — this is for app-specific ones\n * and for retuning a plugin card by re-declaring its id.\n */\n cards?: AnalyticsCardDef[]\n /**\n * Legacy ReportDef catalogue. Still fully supported: each becomes a table\n * card in the report list. See lib/legacy.ts.\n */\n reports?: import('./types').ReportDef[]\n /** Attribution for pre-built cards — the product name, e.g. 'FayzShop'. */\n createdBy?: string\n labels?: Partial<AnalyticsLabels>\n currency?: { code?: string; locale?: string; symbol?: string }\n dataProvider?: AnalyticsProvider\n navPosition?: number\n navSection?: 'main' | 'secondary'\n scope?: PluginScope\n verticalId?: VerticalId\n defaultPageSize?: number\n /**\n * Render an in-content title above the page. Default: FALSE, matching\n * DashboardCanvas — the admin shell's top bar already names the page from the\n * active nav entry, so a title here prints the same word twice. Pass true\n * only where the surface is embedded with no chrome of its own.\n */\n showHeader?: boolean\n /** Register the Live View nav entry. Default: false while it is a stub. */\n showLiveView?: boolean\n /**\n * Range the surface opens on. Default 'last_30_days' — the common business\n * month. Set it where the domain's natural period differs (a school term, a\n * quarter), not to compensate for how much data a demo tenant happens to have.\n */\n defaultRange?: AnalyticsRangePreset\n defaultCompare?: AnalyticsCompare\n /**\n * The assistant's invitation on /analytics: a persona, a headline and the\n * questions worth asking here. Defaults come from the plugin's locales — pass\n * an object to retune the voice for a vertical, or `false` for an app whose\n * analytics screen should open on the numbers alone.\n */\n assistant?: false | AnalyticsAssistantConfig\n}\n\nfunction resolveConfig(options: AnalyticsPluginOptions): ResolvedAnalyticsConfig {\n const labels = { ...DEFAULT_LABELS, ...options.labels }\n const createdBy = options.createdBy ?? 'Fayz'\n return {\n labels,\n currency: { ...DEFAULT_CURRENCY, ...options.currency },\n createdBy,\n cards: [\n ...(options.cards ?? []),\n ...reportDefsToCards(options.reports ?? [], createdBy),\n ],\n defaultPageSize: options.defaultPageSize ?? 50,\n showHeader: options.showHeader === true,\n defaultRange: options.defaultRange ?? 'last_30_days',\n defaultCompare: options.defaultCompare ?? 'previous_period',\n showLiveView: options.showLiveView === true,\n assistant: options.assistant === false ? null : (options.assistant ?? {}),\n }\n}\n\nexport function createAnalyticsPlugin(options: AnalyticsPluginOptions = {}): PluginManifest {\n const config = resolveConfig(options)\n registerTranslations(reportsLocales)\n\n const provider: AnalyticsProvider = options.dataProvider ?? createSafeDataProvider(\n () => createSupabaseAnalyticsProvider({ tenantId: () => getReportsTenantId() }),\n () => createMockAnalyticsProvider(),\n )\n\n /**\n * Every page mounts inside the same surface AND the same module rail, so the\n * report tree is on screen wherever you are inside Analytics — and the app\n * nav never has to list a second Analytics entry to get you there.\n */\n const page = (Body: React.ComponentType<any>, view: AnalyticsView): React.FC<any> =>\n (props) => React.createElement(\n AnalyticsSurface,\n { config, provider },\n React.createElement(\n AnalyticsModule,\n { view, cardId: props?.cardId },\n React.createElement(Body, props),\n ),\n )\n\n const READ = { feature: 'reports', action: 'read' as const }\n const position = options.navPosition ?? 9\n const section = options.navSection ?? 'main'\n\n // One entry. Sub-paths of /analytics would be nested as children by the shell\n // (findModuleParent) and drawn as a dropdown — which is the split this module\n // exists to remove.\n const nav = [\n {\n section, position,\n label: config.labels.analytics,\n route: ANALYTICS_BASE,\n icon: 'BarChart3',\n permission: READ,\n },\n ]\n\n return {\n id: 'reports',\n name: config.labels.analytics,\n icon: 'BarChart3',\n version: '2.0.0',\n scope: options.scope ?? 'universal',\n verticalId: options.verticalId,\n defaultEnabled: true,\n dependencies: [],\n declaredFeatures: [\n { id: 'reports', label: config.labels.analytics, group: config.labels.analytics },\n ],\n navigation: nav,\n routes: [\n { path: ANALYTICS_BASE, component: page(AnalyticsOverview, 'overview'), permission: READ },\n { path: REPORTS_BASE, component: page(ReportsListPage, 'reports'), permission: READ },\n // Registered before the list would ever shadow it: matchRoute scores\n // static segments above params, so /analytics/reports still wins its own\n // exact path and only /analytics/reports/<id> lands here.\n // No `parentRoute` here on purpose: the viewer's title depends on DATA\n // (the card's name), so it claims the shell bar itself via PageHeader.\n // Declaring both gave the page two stacked back-crumbs saying the same\n // thing, one of them generic.\n { path: `${REPORTS_BASE}/:cardId`, component: page(AnalyticsReportViewer, 'report'), permission: READ },\n { path: `${ANALYTICS_BASE}/live`, component: page(LiveViewPage, 'live'), permission: READ },\n // The old top-level route kept as a redirect target: bookmarks, saved\n // links and the five apps still pointing at /reports must not 404.\n { path: '/reports', component: page(ReportsListPage, 'reports'), permission: READ },\n ],\n widgets: [],\n registries: [],\n // Measurement, not acquisition — what the Fayz plugin page lists for\n // Analytics.\n integrations: ['google-analytics', 'hotjar'],\n locales: reportsLocales,\n }\n}\n\n/**\n * @deprecated Prefer `createAnalyticsPlugin`. Kept so the apps that call\n * `createReportsPlugin({ reports: [...] })` keep working unchanged — the legacy\n * `reports` option is still first-class and their catalogues need no rewrite.\n */\nexport function createReportsPlugin(options: ReportsPluginOptions): PluginManifest {\n return createAnalyticsPlugin({\n reports: options.reports,\n labels: {\n ...(options.labels?.pageTitle ? { analytics: options.labels.pageTitle } : {}),\n ...(options.labels?.pageSubtitle ? { overviewSubtitle: options.labels.pageSubtitle } : {}),\n },\n currency: options.currency,\n navPosition: options.navPosition,\n navSection: options.navSection,\n scope: options.scope,\n verticalId: options.verticalId,\n defaultPageSize: options.defaultPageSize,\n showHeader: options.showHeader,\n })\n}\n\n// ---------------------------------------------------------------------------\n// Re-exports\n// ---------------------------------------------------------------------------\n\nexport {\n AnalyticsSurface, ANALYTICS_BASE, REPORTS_BASE, cardColumns,\n useAnalyticsConfig, useAnalyticsCards, useOverviewCards,\n} from './views/AnalyticsSurface'\nexport type {\n AnalyticsLabels, ResolvedAnalyticsConfig, AnalyticsAssistantConfig,\n} from './views/AnalyticsSurface'\nexport { AnalyticsModule } from './views/AnalyticsModule'\nexport type { AnalyticsView, AnalyticsModuleProps } from './views/AnalyticsModule'\nexport { AnalyticsOverview } from './views/AnalyticsOverview'\nexport { ReportsListPage } from './views/ReportsListPage'\nexport { AnalyticsReportViewer } from './views/AnalyticsReportViewer'\nexport { reportDefToCard, reportDefsToCards } from './lib/legacy'\nexport { aggregateRows } from './data/aggregate'\nexport { createSupabaseAnalyticsProvider } from './data/analytics-supabase'\nexport type { SupabaseAnalyticsProviderConfig } from './data/analytics-supabase'\nexport { createMockAnalyticsProvider } from './data/analytics-mock'\nexport { markViewed, useLastViewed } from './lib/lastViewed'\nexport { setReportsTenantId, getReportsTenantId } from './lib/tenant'\n\nexport type {\n ReportDef,\n ReportColumnDef,\n ReportFilterDef,\n ReportDateRange,\n ReportQueryState,\n ReportBadge,\n ReportDataSource,\n ReportGrain,\n ReportAllowedAction,\n ReportFilterOption,\n ReportsPluginOptions,\n ReportsPluginLabels,\n ResolvedReportsConfig,\n} from './types'\n\nexport type { ReportDataProvider, ReportResult } from './data/types'\nexport { createSupabaseReportProvider } from './data/supabase'\nexport type { SupabaseReportProviderConfig } from './data/supabase'\nexport { createMockReportProvider } from './data/mock'\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsOverview.d.ts","sourceRoot":"","sources":["../../src/views/AnalyticsOverview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAczB,wBAAgB,iBAAiB,sBAuChC"}
1
+ {"version":3,"file":"AnalyticsOverview.d.ts","sourceRoot":"","sources":["../../src/views/AnalyticsOverview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAczB,wBAAgB,iBAAiB,sBA8BhC"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "fayz": {
4
4
  "status": "preview"
5
5
  },
6
- "version": "0.11.0",
6
+ "version": "0.11.1",
7
7
  "description": "[experimental] Fayz SDK — plugin-reports plugin",
8
8
  "type": "module",
9
9
  "sideEffects": false,
@@ -27,9 +27,9 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@tanstack/react-table": "^8.20.0",
30
- "@fayz-ai/core": "^0.12.0",
31
- "@fayz-ai/ui": "^0.12.0",
32
- "@fayz-ai/admin": "^0.12.0"
30
+ "@fayz-ai/core": "^0.14.0",
31
+ "@fayz-ai/ui": "^0.14.0",
32
+ "@fayz-ai/admin": "^0.14.0"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/react": "^18.3.0",
@@ -50,9 +50,9 @@
50
50
  "access": "public"
51
51
  },
52
52
  "scripts": {
53
- "build": "tsup && tsc --emitDeclarationOnly --declaration --declarationMap --noEmit false",
53
+ "build": "tsup && tsc -b --force",
54
54
  "dev": "tsup --watch",
55
- "typecheck": "tsc --noEmit",
56
- "clean": "rm -rf dist"
55
+ "typecheck": "tsc -b",
56
+ "clean": "rm -rf dist .tsbuildinfo"
57
57
  }
58
58
  }