install.sql 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. SET @sName = 'bx_analytics';
  2. -- TABLES
  3. -- One row per visit: the visitor, the client it came from and how it arrived
  4. CREATE TABLE IF NOT EXISTS `bx_analytics_sessions` (
  5. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  6. `visitor` binary(16) NOT NULL,
  7. `profile_id` int(11) unsigned NOT NULL DEFAULT '0',
  8. `platform` varchar(16) NOT NULL DEFAULT '',
  9. `app` varchar(64) NOT NULL DEFAULT '',
  10. `app_version` varchar(32) NOT NULL DEFAULT '',
  11. `started` int(11) unsigned NOT NULL DEFAULT '0',
  12. `last_seen` int(11) unsigned NOT NULL DEFAULT '0',
  13. `duration` int(11) unsigned NOT NULL DEFAULT '0',
  14. `pageviews` smallint(5) unsigned NOT NULL DEFAULT '0',
  15. `events` smallint(5) unsigned NOT NULL DEFAULT '0',
  16. `errors` smallint(5) unsigned NOT NULL DEFAULT '0',
  17. `bounce` tinyint(4) unsigned NOT NULL DEFAULT '1',
  18. `hostname` varchar(128) NOT NULL DEFAULT '',
  19. `entry_path` varchar(255) NOT NULL DEFAULT '',
  20. `exit_path` varchar(255) NOT NULL DEFAULT '',
  21. `referrer` varchar(255) NOT NULL DEFAULT '',
  22. `referrer_host` varchar(128) NOT NULL DEFAULT '',
  23. `channel` varchar(16) NOT NULL DEFAULT '',
  24. `utm_source` varchar(128) NOT NULL DEFAULT '',
  25. `utm_medium` varchar(128) NOT NULL DEFAULT '',
  26. `utm_campaign` varchar(128) NOT NULL DEFAULT '',
  27. `utm_term` varchar(128) NOT NULL DEFAULT '',
  28. `utm_content` varchar(128) NOT NULL DEFAULT '',
  29. `country` char(2) NOT NULL DEFAULT '',
  30. `region` varchar(64) NOT NULL DEFAULT '',
  31. `city` varchar(64) NOT NULL DEFAULT '',
  32. `lat` decimal(4,1) DEFAULT NULL,
  33. `lng` decimal(4,1) DEFAULT NULL,
  34. `language` varchar(16) NOT NULL DEFAULT '',
  35. `browser` varchar(32) NOT NULL DEFAULT '',
  36. `browser_version` varchar(16) NOT NULL DEFAULT '',
  37. `os` varchar(32) NOT NULL DEFAULT '',
  38. `os_version` varchar(16) NOT NULL DEFAULT '',
  39. `device` varchar(16) NOT NULL DEFAULT '',
  40. `screen` varchar(16) NOT NULL DEFAULT '',
  41. PRIMARY KEY (`id`),
  42. -- the visitor's open visit; read in this order, retention cohorts need no sort
  43. KEY `visitor` (`visitor`, `last_seen`, `started`, `platform`, `profile_id`),
  44. -- covers the key figures and their chart (no row is read for them)
  45. KEY `started` (`started`, `platform`, `visitor`, `profile_id`, `pageviews`, `bounce`, `duration`),
  46. KEY `last_seen` (`last_seen`),
  47. KEY `platform_seen` (`platform`, `last_seen`),
  48. -- a member's visits; with the last hit and the platform it pages the members list alone
  49. KEY `profile_id` (`profile_id`, `started`, `last_seen`, `platform`)
  50. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  51. -- One row per pageview or event; visitor, profile and platform are copied from the session
  52. CREATE TABLE IF NOT EXISTS `bx_analytics_events` (
  53. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  54. `session_id` bigint(20) unsigned NOT NULL,
  55. `visitor` binary(16) NOT NULL,
  56. `profile_id` int(11) unsigned NOT NULL DEFAULT '0',
  57. `platform` varchar(16) NOT NULL DEFAULT '',
  58. `ts` int(11) unsigned NOT NULL DEFAULT '0',
  59. `type` varchar(16) NOT NULL DEFAULT 'pageview',
  60. `name` varchar(64) NOT NULL DEFAULT '',
  61. `hostname` varchar(128) NOT NULL DEFAULT '',
  62. `path` varchar(255) NOT NULL DEFAULT '',
  63. `title` varchar(255) NOT NULL DEFAULT '',
  64. `module` varchar(32) NOT NULL DEFAULT '',
  65. `object_id` int(11) unsigned NOT NULL DEFAULT '0',
  66. `context_id` int(11) unsigned NOT NULL DEFAULT '0',
  67. `value` double NOT NULL DEFAULT '0',
  68. `engaged` int(11) unsigned NOT NULL DEFAULT '0',
  69. `props` text NOT NULL,
  70. PRIMARY KEY (`id`),
  71. KEY `ts` (`ts`, `type`, `platform`),
  72. -- covers pages and the events list by type and period
  73. KEY `type_ts` (`type`, `ts`, `platform`, `path`, `name`, `module`, `visitor`, `session_id`, `engaged`),
  74. KEY `platform` (`platform`, `ts`),
  75. KEY `session_id` (`session_id`, `ts`),
  76. -- covers one page (a filter, a goal, a funnel step, the Query chart) over a period, on a platform too
  77. KEY `path` (`type`, `path`, `ts`, `platform`, `session_id`, `visitor`, `engaged`),
  78. -- the same for page titles: the titles tab, a title filter
  79. KEY `title` (`type`, `title`, `ts`, `platform`, `session_id`, `visitor`, `engaged`),
  80. KEY `name` (`type`, `name`, `ts`),
  81. -- a site action about something: forgetting a deleted profile finds its creation by it
  82. KEY `object` (`type`, `name`, `object_id`),
  83. -- a member's events: forgetting a deleted profile, the member's actions in a period
  84. KEY `profile_id` (`profile_id`, `ts`)
  85. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  86. -- A random salt per day for cookieless visitor ids; cron deletes old ones
  87. CREATE TABLE IF NOT EXISTS `bx_analytics_salts` (
  88. `day` date NOT NULL,
  89. `salt` binary(32) NOT NULL,
  90. PRIMARY KEY (`day`)
  91. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  92. -- Rate limits of the public collector: hits per address and minute, new visits per address
  93. -- and hour. The key is a keyed hash of the kind and the address with the day's salt, never
  94. -- the address; `bucket` is the minute's or hour's start. Cron deletes buckets over 2 hours old
  95. CREATE TABLE IF NOT EXISTS `bx_analytics_limits` (
  96. `key` binary(8) NOT NULL,
  97. `bucket` int(11) unsigned NOT NULL,
  98. `hits` int(11) unsigned NOT NULL DEFAULT '0',
  99. PRIMARY KEY (`key`, `bucket`),
  100. KEY `bucket` (`bucket`)
  101. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  102. -- Bots and agents per day: crawlers, AI fetchers, link previews and scripts don't run the
  103. -- tracker, so they are counted on the server and kept as daily totals, not as visits
  104. CREATE TABLE IF NOT EXISTS `bx_analytics_bots` (
  105. `day` date NOT NULL,
  106. `bot` varchar(64) NOT NULL,
  107. `category` varchar(16) NOT NULL DEFAULT '',
  108. `platform` varchar(16) NOT NULL DEFAULT '',
  109. `hits` int(11) unsigned NOT NULL DEFAULT '0',
  110. `last_seen` int(11) unsigned NOT NULL DEFAULT '0',
  111. PRIMARY KEY (`day`, `bot`, `platform`),
  112. KEY `category` (`category`, `day`)
  113. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  114. -- Pages bots asked for, per day and bot category
  115. CREATE TABLE IF NOT EXISTS `bx_analytics_bot_pages` (
  116. `day` date NOT NULL,
  117. `category` varchar(16) NOT NULL DEFAULT '',
  118. `path_hash` binary(8) NOT NULL,
  119. `path` varchar(255) NOT NULL DEFAULT '',
  120. `hits` int(11) unsigned NOT NULL DEFAULT '0',
  121. PRIMARY KEY (`day`, `category`, `path_hash`)
  122. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  123. -- Goals: a page (path, * for any characters) or an event (name, or name@module) that
  124. -- counts as a conversion
  125. CREATE TABLE IF NOT EXISTS `bx_analytics_goals` (
  126. `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  127. `name` varchar(128) NOT NULL DEFAULT '',
  128. `type` varchar(16) NOT NULL DEFAULT 'page',
  129. `pattern` varchar(255) NOT NULL DEFAULT '',
  130. `added` int(11) unsigned NOT NULL DEFAULT '0',
  131. `order` int(11) NOT NULL DEFAULT '0',
  132. PRIMARY KEY (`id`)
  133. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  134. -- Funnels: steps as a JSON list of {type, pattern}, matched in order within a visit
  135. CREATE TABLE IF NOT EXISTS `bx_analytics_funnels` (
  136. `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  137. `name` varchar(128) NOT NULL DEFAULT '',
  138. `steps` text NOT NULL,
  139. `added` int(11) unsigned NOT NULL DEFAULT '0',
  140. `order` int(11) NOT NULL DEFAULT '0',
  141. PRIMARY KEY (`id`)
  142. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  143. -- Revenue ledger: one row per money movement the payment module reports (a sale, a renewal,
  144. -- a refund or a reversal of a processed order), with the amount in the site's default
  145. -- currency and the platform and traffic source of the buyer. Pruning never touches it.
  146. -- A subscription's trial is registered at the full price although nothing was charged: those
  147. -- rows have the kind `trial` and no revenue report reads them. A transaction has one charge
  148. -- row (sale, renewal or trial) and at most one negation (refund or reversal), hence the
  149. -- unique key on the payment module, transaction and kind.
  150. CREATE TABLE IF NOT EXISTS `bx_analytics_revenue` (
  151. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  152. `ts` int(11) unsigned NOT NULL DEFAULT '0',
  153. `kind` varchar(16) NOT NULL DEFAULT '',
  154. `cash` tinyint(4) unsigned NOT NULL DEFAULT '1',
  155. `payment` varchar(32) NOT NULL DEFAULT '',
  156. `pending_id` int(11) unsigned NOT NULL DEFAULT '0',
  157. `transaction_id` int(11) unsigned NOT NULL DEFAULT '0',
  158. `order` varchar(32) NOT NULL DEFAULT '',
  159. `module_id` int(11) unsigned NOT NULL DEFAULT '0',
  160. `module` varchar(32) NOT NULL DEFAULT '',
  161. `item_id` int(11) unsigned NOT NULL DEFAULT '0',
  162. `item_count` int(11) unsigned NOT NULL DEFAULT '0',
  163. `seller_id` int(11) unsigned NOT NULL DEFAULT '0',
  164. `author_id` int(11) unsigned NOT NULL DEFAULT '0',
  165. `client_id` int(11) unsigned NOT NULL DEFAULT '0',
  166. `provider` varchar(32) NOT NULL DEFAULT '',
  167. `type` varchar(16) NOT NULL DEFAULT '',
  168. `amount` decimal(14,4) NOT NULL DEFAULT '0',
  169. `currency` varchar(4) NOT NULL DEFAULT '',
  170. `rate` double NOT NULL DEFAULT '1',
  171. `amount_default` decimal(14,4) DEFAULT NULL,
  172. `platform` varchar(16) NOT NULL DEFAULT '',
  173. `session_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  174. `first_channel` varchar(16) NOT NULL DEFAULT '',
  175. `first_referrer_host` varchar(128) NOT NULL DEFAULT '',
  176. `first_utm_campaign` varchar(128) NOT NULL DEFAULT '',
  177. `last_channel` varchar(16) NOT NULL DEFAULT '',
  178. `last_referrer_host` varchar(128) NOT NULL DEFAULT '',
  179. `last_utm_campaign` varchar(128) NOT NULL DEFAULT '',
  180. PRIMARY KEY (`id`),
  181. UNIQUE KEY `movement` (`payment`, `transaction_id`, `kind`),
  182. KEY `ts` (`cash`, `ts`, `platform`),
  183. KEY `pending` (`payment`, `pending_id`),
  184. KEY `module` (`module_id`, `ts`),
  185. KEY `seller` (`seller_id`, `ts`),
  186. KEY `client` (`client_id`, `ts`)
  187. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  188. -- Subscriptions as the ledger sees them: plan, price per period and per month (MRR) in the
  189. -- default currency, when they started, were first and last paid, and were cancelled
  190. CREATE TABLE IF NOT EXISTS `bx_analytics_subscriptions` (
  191. `payment` varchar(32) NOT NULL DEFAULT '',
  192. `pending_id` int(11) unsigned NOT NULL DEFAULT '0',
  193. `subscription_id` varchar(32) NOT NULL DEFAULT '',
  194. `client_id` int(11) unsigned NOT NULL DEFAULT '0',
  195. `seller_id` int(11) unsigned NOT NULL DEFAULT '0',
  196. `module_id` int(11) unsigned NOT NULL DEFAULT '0',
  197. `module` varchar(32) NOT NULL DEFAULT '',
  198. `item_id` int(11) unsigned NOT NULL DEFAULT '0',
  199. `provider` varchar(32) NOT NULL DEFAULT '',
  200. `period` int(11) unsigned NOT NULL DEFAULT '1',
  201. `period_unit` varchar(16) NOT NULL DEFAULT '',
  202. `trial` int(11) unsigned NOT NULL DEFAULT '0',
  203. `amount_default` decimal(14,4) DEFAULT NULL,
  204. `mrr_default` decimal(14,4) DEFAULT NULL,
  205. `status` varchar(16) NOT NULL DEFAULT '',
  206. `started` int(11) unsigned NOT NULL DEFAULT '0',
  207. `first_paid` int(11) unsigned NOT NULL DEFAULT '0',
  208. `last_paid` int(11) unsigned NOT NULL DEFAULT '0',
  209. `paid_count` int(11) unsigned NOT NULL DEFAULT '0',
  210. `canceled` int(11) unsigned NOT NULL DEFAULT '0',
  211. `reason` varchar(255) NOT NULL DEFAULT '',
  212. `platform` varchar(16) NOT NULL DEFAULT '',
  213. PRIMARY KEY (`payment`, `pending_id`),
  214. KEY `paid` (`first_paid`, `canceled`),
  215. KEY `started` (`started`),
  216. KEY `canceled` (`canceled`)
  217. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  218. -- Client errors grouped by fingerprint (kind, normalized message, top frame, HTTP status),
  219. -- with a sample stack. `created` is server time, for the limit of new groups an hour;
  220. -- `first_seen` and `last_seen` are when the errors happened.
  221. CREATE TABLE IF NOT EXISTS `bx_analytics_errors` (
  222. `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  223. `fingerprint` binary(16) NOT NULL,
  224. `kind` varchar(16) NOT NULL DEFAULT 'js',
  225. `message` varchar(255) NOT NULL DEFAULT '',
  226. `source` varchar(255) NOT NULL DEFAULT '',
  227. `line` int(11) unsigned NOT NULL DEFAULT '0',
  228. `col` int(11) unsigned NOT NULL DEFAULT '0',
  229. `status_code` smallint(5) unsigned NOT NULL DEFAULT '0',
  230. `stack` text NOT NULL,
  231. `stack_ts` int(11) unsigned NOT NULL DEFAULT '0',
  232. `first_seen` int(11) unsigned NOT NULL DEFAULT '0',
  233. `last_seen` int(11) unsigned NOT NULL DEFAULT '0',
  234. `occurrences` int(11) unsigned NOT NULL DEFAULT '0',
  235. `fatal` tinyint(4) unsigned NOT NULL DEFAULT '0',
  236. `status` varchar(16) NOT NULL DEFAULT 'open',
  237. `status_changed` int(11) unsigned NOT NULL DEFAULT '0',
  238. `created` int(11) unsigned NOT NULL DEFAULT '0',
  239. PRIMARY KEY (`id`),
  240. UNIQUE KEY `fingerprint` (`fingerprint`),
  241. KEY `created` (`created`),
  242. KEY `last_seen` (`last_seen`)
  243. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  244. -- One row per error report from a client (repeats on one page counted in `repeats`). The
  245. -- client's columns are copied, so an error outside a visit (`session_id` 0) still has them.
  246. CREATE TABLE IF NOT EXISTS `bx_analytics_error_hits` (
  247. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  248. `error_id` int(11) unsigned NOT NULL,
  249. `ts` int(11) unsigned NOT NULL DEFAULT '0',
  250. `session_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  251. `visitor` binary(16) NOT NULL,
  252. `profile_id` int(11) unsigned NOT NULL DEFAULT '0',
  253. `platform` varchar(16) NOT NULL DEFAULT '',
  254. `app_version` varchar(32) NOT NULL DEFAULT '',
  255. `browser` varchar(32) NOT NULL DEFAULT '',
  256. `os` varchar(32) NOT NULL DEFAULT '',
  257. `device` varchar(16) NOT NULL DEFAULT '',
  258. `country` char(2) NOT NULL DEFAULT '',
  259. `path` varchar(255) NOT NULL DEFAULT '',
  260. `route` varchar(128) NOT NULL DEFAULT '',
  261. `repeats` smallint(5) unsigned NOT NULL DEFAULT '1',
  262. `fatal` tinyint(4) unsigned NOT NULL DEFAULT '0',
  263. PRIMARY KEY (`id`),
  264. KEY `ts` (`ts`, `platform`),
  265. KEY `error_id` (`error_id`, `ts`),
  266. KEY `profile_id` (`profile_id`)
  267. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  268. -- Web vitals and app timings: one row per sampled page view or screen, NULL for what wasn't
  269. -- measured; milliseconds, CLS in thousandths. No visitor or member is stored.
  270. CREATE TABLE IF NOT EXISTS `bx_analytics_vitals` (
  271. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  272. `ts` int(11) unsigned NOT NULL DEFAULT '0',
  273. `session_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  274. `platform` varchar(16) NOT NULL DEFAULT '',
  275. `device` varchar(16) NOT NULL DEFAULT '',
  276. `path` varchar(255) NOT NULL DEFAULT '',
  277. `route` varchar(128) NOT NULL DEFAULT '',
  278. `nav` varchar(16) NOT NULL DEFAULT '',
  279. `ttfb` mediumint(8) unsigned DEFAULT NULL,
  280. `fcp` mediumint(8) unsigned DEFAULT NULL,
  281. `lcp` mediumint(8) unsigned DEFAULT NULL,
  282. `inp` mediumint(8) unsigned DEFAULT NULL,
  283. `cls` smallint(5) unsigned DEFAULT NULL,
  284. `screen_load` mediumint(8) unsigned DEFAULT NULL,
  285. `app_start` mediumint(8) unsigned DEFAULT NULL,
  286. PRIMARY KEY (`id`),
  287. KEY `ts` (`ts`, `platform`),
  288. KEY `route` (`route`, `ts`)
  289. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  290. -- STUDIO: page & widget
  291. INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
  292. (3, @sName, '_bx_analytics', '_bx_analytics', 'bx_analytics@modules/boonex/analytics/|std-icon.svg');
  293. SET @iPageId = LAST_INSERT_ID();
  294. INSERT INTO `sys_std_widgets` (`page_id`, `module`, `type`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`, `featured`)
  295. VALUES(@iPageId, @sName, 'extensions', '{url_studio}module.php?name=bx_analytics', '', 'bx_analytics@modules/boonex/analytics/|std-icon.svg', '_bx_analytics', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}', 0);
  296. SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
  297. SET @iParentPageOrder = (SELECT IFNULL(MAX(`order`), 0) + 1 FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
  298. INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
  299. (@iParentPageId, LAST_INSERT_ID(), @iParentPageOrder);