@growth-labs/cms 0.5.8 → 0.5.10

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.
Files changed (48) hide show
  1. package/README.md +26 -0
  2. package/dist/engine/content-insights.d.ts +11 -4
  3. package/dist/engine/content-insights.d.ts.map +1 -1
  4. package/dist/engine/content-insights.js +22 -7
  5. package/dist/engine/content-insights.js.map +1 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/routes/content-insights.d.ts +1 -1
  11. package/dist/routes/content-insights.d.ts.map +1 -1
  12. package/dist/routes/content-insights.js +20 -5
  13. package/dist/routes/content-insights.js.map +1 -1
  14. package/dist/schema/index.d.ts +1 -0
  15. package/dist/schema/index.d.ts.map +1 -1
  16. package/dist/schema/index.js +1 -0
  17. package/dist/schema/index.js.map +1 -1
  18. package/dist/schema/insights-ingest.d.ts +2386 -0
  19. package/dist/schema/insights-ingest.d.ts.map +1 -1
  20. package/dist/schema/insights-ingest.js +78 -0
  21. package/dist/schema/insights-ingest.js.map +1 -1
  22. package/dist/schema/migrations.d.ts.map +1 -1
  23. package/dist/schema/migrations.js +9 -0
  24. package/dist/schema/migrations.js.map +1 -1
  25. package/dist/schema/types.d.ts +67 -0
  26. package/dist/schema/types.d.ts.map +1 -1
  27. package/dist/schema/types.js +10 -0
  28. package/dist/schema/types.js.map +1 -1
  29. package/dist/surveys/schema.d.ts +48 -48
  30. package/dist/ui/screens/ContentInsightsScreen.d.ts +28 -0
  31. package/dist/ui/screens/ContentInsightsScreen.d.ts.map +1 -1
  32. package/dist/ui/screens/ContentInsightsScreen.js +111 -36
  33. package/dist/ui/screens/ContentInsightsScreen.js.map +1 -1
  34. package/dist/ui/screens/content-insights-data.d.ts +13 -1
  35. package/dist/ui/screens/content-insights-data.d.ts.map +1 -1
  36. package/dist/ui/screens/content-insights-data.js +29 -1
  37. package/dist/ui/screens/content-insights-data.js.map +1 -1
  38. package/migrations/0022_content_insight_dismissal_reasons.sql +8 -0
  39. package/package.json +1 -1
  40. package/src/engine/content-insights.ts +32 -7
  41. package/src/index.ts +2 -0
  42. package/src/routes/content-insights.ts +31 -5
  43. package/src/schema/index.ts +1 -0
  44. package/src/schema/insights-ingest.ts +94 -0
  45. package/src/schema/migrations.ts +9 -0
  46. package/src/schema/types.ts +92 -0
  47. package/src/ui/screens/ContentInsightsScreen.tsx +416 -195
  48. package/src/ui/screens/content-insights-data.ts +40 -2
@@ -1,4 +1,4 @@
1
- import type { ContentInsightRow, InsightEvidence } from '../../schema/types.js'
1
+ import type { ContentInsightRow, InsightEvidence, InsightLane } from '../../schema/types.js'
2
2
 
3
3
  /** InsightCard is ContentInsightRow — alias to prevent drift. */
4
4
  export type InsightCard = ContentInsightRow
@@ -8,6 +8,20 @@ export interface DeskGroup {
8
8
  cards: InsightCard[]
9
9
  }
10
10
 
11
+ export interface InsightLaneGroup {
12
+ lane: InsightLane | null
13
+ label: string
14
+ cards: InsightCard[]
15
+ }
16
+
17
+ const CANONICAL_LANES: ReadonlyArray<{ lane: InsightLane; label: string }> = [
18
+ { lane: 'commission', label: 'Commission' },
19
+ { lane: 'refresh', label: 'Refresh' },
20
+ { lane: 'optimize-ctr', label: 'Optimize CTR' },
21
+ { lane: 'consolidate', label: 'Consolidate' },
22
+ { lane: 'monitor', label: 'Monitor' },
23
+ ]
24
+
11
25
  export interface InsightsState {
12
26
  loading: boolean
13
27
  error: string | null
@@ -49,7 +63,7 @@ export function insightsReducer(state: InsightsState, action: InsightsAction): I
49
63
  loaded: true,
50
64
  }
51
65
  case 'fetch-error':
52
- return { ...state, loading: false, error: action.error, loaded: true }
66
+ return { ...state, loading: false, error: action.error, loaded: state.loaded }
53
67
  case 'schema-not-ready':
54
68
  return { ...state, loading: false, error: null, schemaNotReady: true, loaded: true }
55
69
  case 'dismiss-ok':
@@ -59,6 +73,30 @@ export function insightsReducer(state: InsightsState, action: InsightsAction): I
59
73
  }
60
74
  }
61
75
 
76
+ /** Show lane panels only after a successful board load, retaining the last good board on errors. */
77
+ export function shouldRenderInsightLanes(state: InsightsState): boolean {
78
+ return state.loaded && !state.schemaNotReady
79
+ }
80
+
81
+ /**
82
+ * Project a board into the five Insight Engine action lanes. Legacy cards stay
83
+ * readable in one conditional appendix instead of being dropped or duplicated.
84
+ */
85
+ export function laneGroups(cards: InsightCard[]): InsightLaneGroup[] {
86
+ const sorted = (items: InsightCard[]) =>
87
+ items.sort((a, b) => a.desk_rank - b.desk_rank || a.headline.localeCompare(b.headline))
88
+ const groups: InsightLaneGroup[] = CANONICAL_LANES.map(({ lane, label }) => ({
89
+ lane,
90
+ label,
91
+ cards: sorted(cards.filter((card) => card.evidence.lane === lane)),
92
+ }))
93
+ const legacy = sorted(cards.filter((card) => card.evidence.lane == null))
94
+ if (legacy.length > 0) {
95
+ groups.push({ lane: null, label: 'Legacy / unclassified', cards: legacy })
96
+ }
97
+ return groups
98
+ }
99
+
62
100
  /** Group cards by desk (desks alphabetical), each desk's cards sorted by desk_rank then headline. */
63
101
  export function deskGroups(cards: InsightCard[]): DeskGroup[] {
64
102
  const byDesk = new Map<string, InsightCard[]>()