adaria-ai 0.1.0

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 (337) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/apps.example.yaml +65 -0
  4. package/dist/agent/audit.d.ts +16 -0
  5. package/dist/agent/audit.d.ts.map +1 -0
  6. package/dist/agent/audit.js +42 -0
  7. package/dist/agent/audit.js.map +1 -0
  8. package/dist/agent/claude.d.ts +62 -0
  9. package/dist/agent/claude.d.ts.map +1 -0
  10. package/dist/agent/claude.js +297 -0
  11. package/dist/agent/claude.js.map +1 -0
  12. package/dist/agent/conversation-summary.d.ts +29 -0
  13. package/dist/agent/conversation-summary.d.ts.map +1 -0
  14. package/dist/agent/conversation-summary.js +221 -0
  15. package/dist/agent/conversation-summary.js.map +1 -0
  16. package/dist/agent/core.d.ts +81 -0
  17. package/dist/agent/core.d.ts.map +1 -0
  18. package/dist/agent/core.js +527 -0
  19. package/dist/agent/core.js.map +1 -0
  20. package/dist/agent/mcp-launcher.d.ts +42 -0
  21. package/dist/agent/mcp-launcher.d.ts.map +1 -0
  22. package/dist/agent/mcp-launcher.js +38 -0
  23. package/dist/agent/mcp-launcher.js.map +1 -0
  24. package/dist/agent/mcp-manager.d.ts +81 -0
  25. package/dist/agent/mcp-manager.d.ts.map +1 -0
  26. package/dist/agent/mcp-manager.js +136 -0
  27. package/dist/agent/mcp-manager.js.map +1 -0
  28. package/dist/agent/memory.d.ts +10 -0
  29. package/dist/agent/memory.d.ts.map +1 -0
  30. package/dist/agent/memory.js +95 -0
  31. package/dist/agent/memory.js.map +1 -0
  32. package/dist/agent/safety.d.ts +45 -0
  33. package/dist/agent/safety.d.ts.map +1 -0
  34. package/dist/agent/safety.js +71 -0
  35. package/dist/agent/safety.js.map +1 -0
  36. package/dist/agent/session.d.ts +27 -0
  37. package/dist/agent/session.d.ts.map +1 -0
  38. package/dist/agent/session.js +124 -0
  39. package/dist/agent/session.js.map +1 -0
  40. package/dist/agent/tool-descriptions.d.ts +8 -0
  41. package/dist/agent/tool-descriptions.d.ts.map +1 -0
  42. package/dist/agent/tool-descriptions.js +26 -0
  43. package/dist/agent/tool-descriptions.js.map +1 -0
  44. package/dist/cli/analyze.d.ts +8 -0
  45. package/dist/cli/analyze.d.ts.map +1 -0
  46. package/dist/cli/analyze.js +114 -0
  47. package/dist/cli/analyze.js.map +1 -0
  48. package/dist/cli/daemon.d.ts +2 -0
  49. package/dist/cli/daemon.d.ts.map +1 -0
  50. package/dist/cli/daemon.js +91 -0
  51. package/dist/cli/daemon.js.map +1 -0
  52. package/dist/cli/doctor.d.ts +2 -0
  53. package/dist/cli/doctor.d.ts.map +1 -0
  54. package/dist/cli/doctor.js +198 -0
  55. package/dist/cli/doctor.js.map +1 -0
  56. package/dist/cli/init.d.ts +3 -0
  57. package/dist/cli/init.d.ts.map +1 -0
  58. package/dist/cli/init.js +459 -0
  59. package/dist/cli/init.js.map +1 -0
  60. package/dist/cli/logs.d.ts +4 -0
  61. package/dist/cli/logs.d.ts.map +1 -0
  62. package/dist/cli/logs.js +50 -0
  63. package/dist/cli/logs.js.map +1 -0
  64. package/dist/cli/monitor-cmd.d.ts +11 -0
  65. package/dist/cli/monitor-cmd.d.ts.map +1 -0
  66. package/dist/cli/monitor-cmd.js +59 -0
  67. package/dist/cli/monitor-cmd.js.map +1 -0
  68. package/dist/cli/start.d.ts +11 -0
  69. package/dist/cli/start.d.ts.map +1 -0
  70. package/dist/cli/start.js +103 -0
  71. package/dist/cli/start.js.map +1 -0
  72. package/dist/cli/status.d.ts +9 -0
  73. package/dist/cli/status.d.ts.map +1 -0
  74. package/dist/cli/status.js +49 -0
  75. package/dist/cli/status.js.map +1 -0
  76. package/dist/cli/stop.d.ts +2 -0
  77. package/dist/cli/stop.d.ts.map +1 -0
  78. package/dist/cli/stop.js +34 -0
  79. package/dist/cli/stop.js.map +1 -0
  80. package/dist/collectors/appstore.d.ts +51 -0
  81. package/dist/collectors/appstore.d.ts.map +1 -0
  82. package/dist/collectors/appstore.js +166 -0
  83. package/dist/collectors/appstore.js.map +1 -0
  84. package/dist/collectors/arden-tts.d.ts +60 -0
  85. package/dist/collectors/arden-tts.d.ts.map +1 -0
  86. package/dist/collectors/arden-tts.js +83 -0
  87. package/dist/collectors/arden-tts.js.map +1 -0
  88. package/dist/collectors/asomobile.d.ts +37 -0
  89. package/dist/collectors/asomobile.d.ts.map +1 -0
  90. package/dist/collectors/asomobile.js +88 -0
  91. package/dist/collectors/asomobile.js.map +1 -0
  92. package/dist/collectors/eodin-blog.d.ts +90 -0
  93. package/dist/collectors/eodin-blog.d.ts.map +1 -0
  94. package/dist/collectors/eodin-blog.js +238 -0
  95. package/dist/collectors/eodin-blog.js.map +1 -0
  96. package/dist/collectors/eodin-sdk.d.ts +60 -0
  97. package/dist/collectors/eodin-sdk.d.ts.map +1 -0
  98. package/dist/collectors/eodin-sdk.js +112 -0
  99. package/dist/collectors/eodin-sdk.js.map +1 -0
  100. package/dist/collectors/fridgify-recipes.d.ts +65 -0
  101. package/dist/collectors/fridgify-recipes.d.ts.map +1 -0
  102. package/dist/collectors/fridgify-recipes.js +111 -0
  103. package/dist/collectors/fridgify-recipes.js.map +1 -0
  104. package/dist/collectors/playstore.d.ts +46 -0
  105. package/dist/collectors/playstore.d.ts.map +1 -0
  106. package/dist/collectors/playstore.js +140 -0
  107. package/dist/collectors/playstore.js.map +1 -0
  108. package/dist/collectors/youtube.d.ts +44 -0
  109. package/dist/collectors/youtube.d.ts.map +1 -0
  110. package/dist/collectors/youtube.js +107 -0
  111. package/dist/collectors/youtube.js.map +1 -0
  112. package/dist/config/apps-schema.d.ts +94 -0
  113. package/dist/config/apps-schema.d.ts.map +1 -0
  114. package/dist/config/apps-schema.js +66 -0
  115. package/dist/config/apps-schema.js.map +1 -0
  116. package/dist/config/keychain.d.ts +14 -0
  117. package/dist/config/keychain.d.ts.map +1 -0
  118. package/dist/config/keychain.js +89 -0
  119. package/dist/config/keychain.js.map +1 -0
  120. package/dist/config/load-apps.d.ts +16 -0
  121. package/dist/config/load-apps.d.ts.map +1 -0
  122. package/dist/config/load-apps.js +38 -0
  123. package/dist/config/load-apps.js.map +1 -0
  124. package/dist/config/schema.d.ts +306 -0
  125. package/dist/config/schema.d.ts.map +1 -0
  126. package/dist/config/schema.js +220 -0
  127. package/dist/config/schema.js.map +1 -0
  128. package/dist/config/store.d.ts +38 -0
  129. package/dist/config/store.d.ts.map +1 -0
  130. package/dist/config/store.js +180 -0
  131. package/dist/config/store.js.map +1 -0
  132. package/dist/db/queries.d.ts +304 -0
  133. package/dist/db/queries.d.ts.map +1 -0
  134. package/dist/db/queries.js +327 -0
  135. package/dist/db/queries.js.map +1 -0
  136. package/dist/db/schema.d.ts +15 -0
  137. package/dist/db/schema.d.ts.map +1 -0
  138. package/dist/db/schema.js +252 -0
  139. package/dist/db/schema.js.map +1 -0
  140. package/dist/index.d.ts +3 -0
  141. package/dist/index.d.ts.map +1 -0
  142. package/dist/index.js +86 -0
  143. package/dist/index.js.map +1 -0
  144. package/dist/messenger/adapter.d.ts +63 -0
  145. package/dist/messenger/adapter.d.ts.map +1 -0
  146. package/dist/messenger/adapter.js +7 -0
  147. package/dist/messenger/adapter.js.map +1 -0
  148. package/dist/messenger/factory.d.ts +12 -0
  149. package/dist/messenger/factory.d.ts.map +1 -0
  150. package/dist/messenger/factory.js +9 -0
  151. package/dist/messenger/factory.js.map +1 -0
  152. package/dist/messenger/slack.d.ts +30 -0
  153. package/dist/messenger/slack.d.ts.map +1 -0
  154. package/dist/messenger/slack.js +309 -0
  155. package/dist/messenger/slack.js.map +1 -0
  156. package/dist/messenger/split.d.ts +17 -0
  157. package/dist/messenger/split.d.ts.map +1 -0
  158. package/dist/messenger/split.js +56 -0
  159. package/dist/messenger/split.js.map +1 -0
  160. package/dist/orchestrator/dashboard.d.ts +67 -0
  161. package/dist/orchestrator/dashboard.d.ts.map +1 -0
  162. package/dist/orchestrator/dashboard.js +113 -0
  163. package/dist/orchestrator/dashboard.js.map +1 -0
  164. package/dist/orchestrator/monitor.d.ts +37 -0
  165. package/dist/orchestrator/monitor.d.ts.map +1 -0
  166. package/dist/orchestrator/monitor.js +236 -0
  167. package/dist/orchestrator/monitor.js.map +1 -0
  168. package/dist/orchestrator/types.d.ts +82 -0
  169. package/dist/orchestrator/types.d.ts.map +1 -0
  170. package/dist/orchestrator/types.js +12 -0
  171. package/dist/orchestrator/types.js.map +1 -0
  172. package/dist/orchestrator/weekly.d.ts +66 -0
  173. package/dist/orchestrator/weekly.d.ts.map +1 -0
  174. package/dist/orchestrator/weekly.js +376 -0
  175. package/dist/orchestrator/weekly.js.map +1 -0
  176. package/dist/prompts/loader.d.ts +18 -0
  177. package/dist/prompts/loader.d.ts.map +1 -0
  178. package/dist/prompts/loader.js +28 -0
  179. package/dist/prompts/loader.js.map +1 -0
  180. package/dist/security/auth.d.ts +14 -0
  181. package/dist/security/auth.d.ts.map +1 -0
  182. package/dist/security/auth.js +14 -0
  183. package/dist/security/auth.js.map +1 -0
  184. package/dist/security/prompt-guard.d.ts +21 -0
  185. package/dist/security/prompt-guard.d.ts.map +1 -0
  186. package/dist/security/prompt-guard.js +54 -0
  187. package/dist/security/prompt-guard.js.map +1 -0
  188. package/dist/skills/aso.d.ts +60 -0
  189. package/dist/skills/aso.d.ts.map +1 -0
  190. package/dist/skills/aso.js +322 -0
  191. package/dist/skills/aso.js.map +1 -0
  192. package/dist/skills/content.d.ts +25 -0
  193. package/dist/skills/content.d.ts.map +1 -0
  194. package/dist/skills/content.js +90 -0
  195. package/dist/skills/content.js.map +1 -0
  196. package/dist/skills/index.d.ts +65 -0
  197. package/dist/skills/index.d.ts.map +1 -0
  198. package/dist/skills/index.js +90 -0
  199. package/dist/skills/index.js.map +1 -0
  200. package/dist/skills/onboarding.d.ts +58 -0
  201. package/dist/skills/onboarding.d.ts.map +1 -0
  202. package/dist/skills/onboarding.js +274 -0
  203. package/dist/skills/onboarding.js.map +1 -0
  204. package/dist/skills/registry.d.ts +24 -0
  205. package/dist/skills/registry.d.ts.map +1 -0
  206. package/dist/skills/registry.js +66 -0
  207. package/dist/skills/registry.js.map +1 -0
  208. package/dist/skills/review.d.ts +33 -0
  209. package/dist/skills/review.d.ts.map +1 -0
  210. package/dist/skills/review.js +236 -0
  211. package/dist/skills/review.js.map +1 -0
  212. package/dist/skills/sdk-request.d.ts +30 -0
  213. package/dist/skills/sdk-request.d.ts.map +1 -0
  214. package/dist/skills/sdk-request.js +72 -0
  215. package/dist/skills/sdk-request.js.map +1 -0
  216. package/dist/skills/seo-blog.d.ts +64 -0
  217. package/dist/skills/seo-blog.d.ts.map +1 -0
  218. package/dist/skills/seo-blog.js +268 -0
  219. package/dist/skills/seo-blog.js.map +1 -0
  220. package/dist/skills/short-form.d.ts +28 -0
  221. package/dist/skills/short-form.d.ts.map +1 -0
  222. package/dist/skills/short-form.js +121 -0
  223. package/dist/skills/short-form.js.map +1 -0
  224. package/dist/skills/social-publish.d.ts +32 -0
  225. package/dist/skills/social-publish.d.ts.map +1 -0
  226. package/dist/skills/social-publish.js +133 -0
  227. package/dist/skills/social-publish.js.map +1 -0
  228. package/dist/social/base.d.ts +47 -0
  229. package/dist/social/base.d.ts.map +1 -0
  230. package/dist/social/base.js +26 -0
  231. package/dist/social/base.js.map +1 -0
  232. package/dist/social/facebook.d.ts +27 -0
  233. package/dist/social/facebook.d.ts.map +1 -0
  234. package/dist/social/facebook.js +166 -0
  235. package/dist/social/facebook.js.map +1 -0
  236. package/dist/social/factory.d.ts +26 -0
  237. package/dist/social/factory.d.ts.map +1 -0
  238. package/dist/social/factory.js +32 -0
  239. package/dist/social/factory.js.map +1 -0
  240. package/dist/social/linkedin.d.ts +26 -0
  241. package/dist/social/linkedin.d.ts.map +1 -0
  242. package/dist/social/linkedin.js +190 -0
  243. package/dist/social/linkedin.js.map +1 -0
  244. package/dist/social/threads.d.ts +21 -0
  245. package/dist/social/threads.d.ts.map +1 -0
  246. package/dist/social/threads.js +122 -0
  247. package/dist/social/threads.js.map +1 -0
  248. package/dist/social/tiktok.d.ts +23 -0
  249. package/dist/social/tiktok.d.ts.map +1 -0
  250. package/dist/social/tiktok.js +110 -0
  251. package/dist/social/tiktok.js.map +1 -0
  252. package/dist/social/twitter.d.ts +30 -0
  253. package/dist/social/twitter.d.ts.map +1 -0
  254. package/dist/social/twitter.js +189 -0
  255. package/dist/social/twitter.js.map +1 -0
  256. package/dist/social/youtube.d.ts +21 -0
  257. package/dist/social/youtube.d.ts.map +1 -0
  258. package/dist/social/youtube.js +108 -0
  259. package/dist/social/youtube.js.map +1 -0
  260. package/dist/tools/app-info.d.ts +7 -0
  261. package/dist/tools/app-info.d.ts.map +1 -0
  262. package/dist/tools/app-info.js +53 -0
  263. package/dist/tools/app-info.js.map +1 -0
  264. package/dist/tools/collector-fetch.d.ts +11 -0
  265. package/dist/tools/collector-fetch.d.ts.map +1 -0
  266. package/dist/tools/collector-fetch.js +101 -0
  267. package/dist/tools/collector-fetch.js.map +1 -0
  268. package/dist/tools/db-query.d.ts +29 -0
  269. package/dist/tools/db-query.d.ts.map +1 -0
  270. package/dist/tools/db-query.js +159 -0
  271. package/dist/tools/db-query.js.map +1 -0
  272. package/dist/tools/skill-result.d.ts +8 -0
  273. package/dist/tools/skill-result.d.ts.map +1 -0
  274. package/dist/tools/skill-result.js +63 -0
  275. package/dist/tools/skill-result.js.map +1 -0
  276. package/dist/tools/tool-host.d.ts +12 -0
  277. package/dist/tools/tool-host.d.ts.map +1 -0
  278. package/dist/tools/tool-host.js +124 -0
  279. package/dist/tools/tool-host.js.map +1 -0
  280. package/dist/types/collectors.d.ts +198 -0
  281. package/dist/types/collectors.d.ts.map +1 -0
  282. package/dist/types/collectors.js +28 -0
  283. package/dist/types/collectors.js.map +1 -0
  284. package/dist/types/skill.d.ts +60 -0
  285. package/dist/types/skill.d.ts.map +1 -0
  286. package/dist/types/skill.js +9 -0
  287. package/dist/types/skill.js.map +1 -0
  288. package/dist/utils/circuit-breaker.d.ts +26 -0
  289. package/dist/utils/circuit-breaker.d.ts.map +1 -0
  290. package/dist/utils/circuit-breaker.js +67 -0
  291. package/dist/utils/circuit-breaker.js.map +1 -0
  292. package/dist/utils/errors.d.ts +44 -0
  293. package/dist/utils/errors.d.ts.map +1 -0
  294. package/dist/utils/errors.js +75 -0
  295. package/dist/utils/errors.js.map +1 -0
  296. package/dist/utils/escape.d.ts +11 -0
  297. package/dist/utils/escape.d.ts.map +1 -0
  298. package/dist/utils/escape.js +19 -0
  299. package/dist/utils/escape.js.map +1 -0
  300. package/dist/utils/logger.d.ts +19 -0
  301. package/dist/utils/logger.d.ts.map +1 -0
  302. package/dist/utils/logger.js +93 -0
  303. package/dist/utils/logger.js.map +1 -0
  304. package/dist/utils/parse-json.d.ts +13 -0
  305. package/dist/utils/parse-json.d.ts.map +1 -0
  306. package/dist/utils/parse-json.js +61 -0
  307. package/dist/utils/parse-json.js.map +1 -0
  308. package/dist/utils/paths.d.ts +14 -0
  309. package/dist/utils/paths.d.ts.map +1 -0
  310. package/dist/utils/paths.js +19 -0
  311. package/dist/utils/paths.js.map +1 -0
  312. package/dist/utils/rate-limiter.d.ts +20 -0
  313. package/dist/utils/rate-limiter.d.ts.map +1 -0
  314. package/dist/utils/rate-limiter.js +47 -0
  315. package/dist/utils/rate-limiter.js.map +1 -0
  316. package/dist/utils/retry.d.ts +26 -0
  317. package/dist/utils/retry.d.ts.map +1 -0
  318. package/dist/utils/retry.js +61 -0
  319. package/dist/utils/retry.js.map +1 -0
  320. package/launchd/.gitkeep +0 -0
  321. package/launchd/com.adaria-ai.daemon.plist.template +62 -0
  322. package/launchd/com.adaria-ai.monitor.plist.template +41 -0
  323. package/launchd/com.adaria-ai.weekly.plist.template +43 -0
  324. package/package.json +72 -0
  325. package/prompts/aso-description.md +44 -0
  326. package/prompts/aso-inapp-events.md +20 -0
  327. package/prompts/aso-metadata.md +34 -0
  328. package/prompts/aso-screenshots.md +20 -0
  329. package/prompts/onboarding-hypotheses.md +38 -0
  330. package/prompts/onboarding-review-timing.md +24 -0
  331. package/prompts/review-clustering.md +19 -0
  332. package/prompts/review-replies.md +18 -0
  333. package/prompts/review-sentiment.md +16 -0
  334. package/prompts/seo-blog-fridgify-recipe.md +116 -0
  335. package/prompts/seo-blog.md +69 -0
  336. package/prompts/short-form-ideas.md +50 -0
  337. package/prompts/social-publish.md +46 -0
@@ -0,0 +1,327 @@
1
+ /**
2
+ * DB query helpers — typed prepared statements with WeakMap caching.
3
+ *
4
+ * Ported from growth-agent `src/db/queries.js`. All functions take a
5
+ * better-sqlite3 Database instance as the first argument so callers
6
+ * control the connection lifecycle.
7
+ *
8
+ * Convention: insert/upsert params use snake_case field names matching
9
+ * the DDL column names. Return types are typed where consumers exist.
10
+ */
11
+ // ---------------------------------------------------------------------------
12
+ // Statement cache
13
+ // ---------------------------------------------------------------------------
14
+ const stmtCache = new WeakMap();
15
+ function getStmt(db, sql) {
16
+ let cache = stmtCache.get(db);
17
+ if (!cache) {
18
+ cache = new Map();
19
+ stmtCache.set(db, cache);
20
+ }
21
+ if (!cache.has(sql)) {
22
+ cache.set(sql, db.prepare(sql));
23
+ }
24
+ return cache.get(sql);
25
+ }
26
+ // ---------------------------------------------------------------------------
27
+ // Keyword Rankings
28
+ // ---------------------------------------------------------------------------
29
+ const SQL_INSERT_KEYWORD = `INSERT INTO keyword_rankings (app_id, keyword, platform, rank, search_volume)
30
+ VALUES (?, ?, ?, ?, ?)`;
31
+ const SQL_RECENT_KEYWORDS = `SELECT * FROM keyword_rankings
32
+ WHERE app_id = ? AND recorded_at >= datetime('now', ?)
33
+ ORDER BY recorded_at DESC`;
34
+ const SQL_RANK_CHANGE = `SELECT
35
+ (SELECT rank FROM keyword_rankings
36
+ WHERE app_id = ? AND keyword = ? AND platform = ?
37
+ ORDER BY recorded_at DESC LIMIT 1) as current_rank,
38
+ (SELECT rank FROM keyword_rankings
39
+ WHERE app_id = ? AND keyword = ? AND platform = ?
40
+ AND recorded_at < datetime('now', '-7 days')
41
+ ORDER BY recorded_at DESC LIMIT 1) as previous_rank`;
42
+ export function insertKeywordRanking(db, params) {
43
+ return getStmt(db, SQL_INSERT_KEYWORD).run(params.app_id, params.keyword, params.platform, params.rank, params.search_volume);
44
+ }
45
+ export function getRecentKeywordRankings(db, appId, days = 7) {
46
+ return getStmt(db, SQL_RECENT_KEYWORDS).all(appId, `-${days} days`);
47
+ }
48
+ export function getKeywordRankChange(db, appId, keyword, platform) {
49
+ return getStmt(db, SQL_RANK_CHANGE).get(appId, keyword, platform, appId, keyword, platform);
50
+ }
51
+ // ---------------------------------------------------------------------------
52
+ // SDK Events
53
+ // ---------------------------------------------------------------------------
54
+ const SQL_UPSERT_EVENT = `INSERT INTO sdk_events (app_id, event_name, count, date)
55
+ VALUES (?, ?, ?, ?)
56
+ ON CONFLICT(app_id, event_name, date) DO UPDATE SET count = excluded.count`;
57
+ const SQL_EVENTS_BY_RANGE = `SELECT * FROM sdk_events
58
+ WHERE app_id = ? AND date BETWEEN ? AND ?
59
+ ORDER BY date ASC, event_name ASC`;
60
+ const SQL_FUNNEL = `SELECT event_name, SUM(count) as total
61
+ FROM sdk_events
62
+ WHERE app_id = ? AND date BETWEEN ? AND ?
63
+ GROUP BY event_name`;
64
+ export function upsertSdkEvent(db, params) {
65
+ return getStmt(db, SQL_UPSERT_EVENT).run(params.app_id, params.event_name, params.count, params.date);
66
+ }
67
+ export function getSdkEventsByRange(db, appId, startDate, endDate) {
68
+ return getStmt(db, SQL_EVENTS_BY_RANGE).all(appId, startDate, endDate);
69
+ }
70
+ export function getFunnelConversion(db, appId, startDate, endDate) {
71
+ return getStmt(db, SQL_FUNNEL).all(appId, startDate, endDate);
72
+ }
73
+ // ---------------------------------------------------------------------------
74
+ // Reviews
75
+ // ---------------------------------------------------------------------------
76
+ const SQL_INSERT_REVIEW = `INSERT OR IGNORE INTO reviews (app_id, platform, review_id, rating, body)
77
+ VALUES (?, ?, ?, ?, ?)`;
78
+ const SQL_RECENT_REVIEWS = `SELECT * FROM reviews
79
+ WHERE app_id = ? AND recorded_at >= datetime('now', ?)
80
+ ORDER BY recorded_at DESC`;
81
+ const SQL_UPDATE_SENTIMENT = "UPDATE reviews SET sentiment = ? WHERE review_id = ?";
82
+ const SQL_UPDATE_REPLY = "UPDATE reviews SET reply_draft = ? WHERE review_id = ?";
83
+ const SQL_MARK_REPLIED = "UPDATE reviews SET replied_at = datetime('now') WHERE review_id = ?";
84
+ const SQL_SENTIMENT_SUMMARY = `SELECT sentiment, COUNT(*) as count
85
+ FROM reviews
86
+ WHERE app_id = ? AND recorded_at >= datetime('now', ?)
87
+ GROUP BY sentiment`;
88
+ const SQL_ONE_STAR_COUNT = `SELECT COUNT(*) as count FROM reviews
89
+ WHERE app_id = ? AND rating = 1 AND recorded_at >= datetime('now', ?)`;
90
+ export function insertReview(db, params) {
91
+ return getStmt(db, SQL_INSERT_REVIEW).run(params.app_id, params.platform, params.review_id, params.rating, params.body);
92
+ }
93
+ export function getRecentReviews(db, appId, days = 7) {
94
+ return getStmt(db, SQL_RECENT_REVIEWS).all(appId, `-${days} days`);
95
+ }
96
+ export function updateReviewSentiment(db, reviewId, sentiment) {
97
+ return getStmt(db, SQL_UPDATE_SENTIMENT).run(sentiment, reviewId);
98
+ }
99
+ export function updateReplyDraft(db, reviewId, replyDraft) {
100
+ return getStmt(db, SQL_UPDATE_REPLY).run(replyDraft, reviewId);
101
+ }
102
+ export function markReviewReplied(db, reviewId) {
103
+ return getStmt(db, SQL_MARK_REPLIED).run(reviewId);
104
+ }
105
+ export function getSentimentSummary(db, appId, days = 7) {
106
+ return getStmt(db, SQL_SENTIMENT_SUMMARY).all(appId, `-${days} days`);
107
+ }
108
+ export function getRecentOneStarCount(db, appId, days = 1) {
109
+ const row = getStmt(db, SQL_ONE_STAR_COUNT).get(appId, `-${days} days`);
110
+ return row?.count ?? 0;
111
+ }
112
+ // ---------------------------------------------------------------------------
113
+ // Competitor Metadata
114
+ // ---------------------------------------------------------------------------
115
+ const SQL_INSERT_COMPETITOR = `INSERT INTO competitor_metadata (app_id, competitor_id, platform, title, subtitle, description, keywords)
116
+ VALUES (?, ?, ?, ?, ?, ?, ?)`;
117
+ const SQL_PREV_COMPETITOR = `SELECT * FROM competitor_metadata
118
+ WHERE app_id = ? AND competitor_id = ? AND platform = ?
119
+ AND recorded_at < datetime('now', '-7 days')
120
+ ORDER BY recorded_at DESC LIMIT 1`;
121
+ export function insertCompetitorMetadata(db, params) {
122
+ const kw = Array.isArray(params.keywords)
123
+ ? params.keywords.join(",")
124
+ : params.keywords;
125
+ return getStmt(db, SQL_INSERT_COMPETITOR).run(params.app_id, params.competitor_id, params.platform, params.title, params.subtitle, params.description, kw);
126
+ }
127
+ export function getPreviousCompetitorMetadata(db, appId, competitorId, platform) {
128
+ return getStmt(db, SQL_PREV_COMPETITOR).get(appId, competitorId, platform);
129
+ }
130
+ // ---------------------------------------------------------------------------
131
+ // Agent Metrics
132
+ // ---------------------------------------------------------------------------
133
+ const SQL_INSERT_METRIC = `INSERT INTO agent_metrics (app_id, agent, run_date, duration_ms, status, alerts_count, actions_count, approval_rate, metadata)
134
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
135
+ ON CONFLICT(app_id, agent, run_date) DO UPDATE SET
136
+ duration_ms = excluded.duration_ms,
137
+ status = excluded.status,
138
+ alerts_count = excluded.alerts_count,
139
+ actions_count = excluded.actions_count,
140
+ approval_rate = excluded.approval_rate,
141
+ metadata = excluded.metadata,
142
+ recorded_at = CURRENT_TIMESTAMP`;
143
+ const SQL_RECENT_METRICS = `SELECT * FROM agent_metrics
144
+ WHERE app_id = ? AND agent = ? AND run_date >= date('now', ?)
145
+ ORDER BY run_date DESC`;
146
+ const SQL_AGENT_TREND = `SELECT agent, run_date, duration_ms, status, alerts_count, actions_count, approval_rate
147
+ FROM agent_metrics
148
+ WHERE app_id = ? AND run_date >= date('now', ?)
149
+ ORDER BY agent, run_date ASC`;
150
+ export function insertAgentMetric(db, params) {
151
+ return getStmt(db, SQL_INSERT_METRIC).run(params.app_id, params.agent, params.run_date, params.duration_ms, params.status, params.alerts_count ?? 0, params.actions_count ?? 0, params.approval_rate ?? null, params.metadata ? JSON.stringify(params.metadata) : null);
152
+ }
153
+ export function getAgentMetrics(db, appId, agent, days = 30) {
154
+ return getStmt(db, SQL_RECENT_METRICS).all(appId, agent, `-${days} days`);
155
+ }
156
+ export function getAgentTrend(db, appId, days = 30) {
157
+ return getStmt(db, SQL_AGENT_TREND).all(appId, `-${days} days`);
158
+ }
159
+ // ---------------------------------------------------------------------------
160
+ // Approvals
161
+ // ---------------------------------------------------------------------------
162
+ const SQL_INSERT_APPROVAL = `INSERT INTO approvals (app_id, agent, action, status, payload)
163
+ VALUES (?, ?, ?, ?, ?)`;
164
+ const SQL_RECENT_APPROVALS = `SELECT * FROM approvals
165
+ WHERE app_id = ? AND decided_at >= datetime('now', ?)
166
+ ORDER BY decided_at DESC`;
167
+ export function insertApproval(db, params) {
168
+ return getStmt(db, SQL_INSERT_APPROVAL).run(params.app_id, params.agent, params.action, params.status, JSON.stringify(params.payload));
169
+ }
170
+ export function getRecentApprovals(db, appId, days = 30) {
171
+ return getStmt(db, SQL_RECENT_APPROVALS).all(appId, `-${days} days`);
172
+ }
173
+ // ---------------------------------------------------------------------------
174
+ // Blog Posts
175
+ // ---------------------------------------------------------------------------
176
+ const SQL_INSERT_BLOG = `INSERT INTO blog_posts (app_id, title, slug, keywords, seo_score, published_at)
177
+ VALUES (?, ?, ?, ?, ?, ?)`;
178
+ const SQL_GET_BLOG_SLUGS = "SELECT slug FROM blog_posts ORDER BY recorded_at DESC";
179
+ const SQL_RECENT_BLOGS = `SELECT * FROM blog_posts
180
+ WHERE app_id = ? AND recorded_at >= datetime('now', ?)
181
+ ORDER BY recorded_at DESC`;
182
+ export function insertBlogPost(db, params) {
183
+ return getStmt(db, SQL_INSERT_BLOG).run(params.app_id, params.title, params.slug, params.keywords, params.seo_score ?? null, params.published_at ?? null);
184
+ }
185
+ export function getBlogSlugs(db) {
186
+ return getStmt(db, SQL_GET_BLOG_SLUGS).all().map((r) => r.slug);
187
+ }
188
+ export function getRecentBlogPosts(db, appId, days = 30) {
189
+ return getStmt(db, SQL_RECENT_BLOGS).all(appId, `-${days} days`);
190
+ }
191
+ // ---------------------------------------------------------------------------
192
+ // Short-form Performance
193
+ // ---------------------------------------------------------------------------
194
+ const SQL_UPSERT_SHORT_FORM = `INSERT INTO short_form_performance (app_id, platform, video_id, title, views, likes, comments, avg_watch_time, published_at)
195
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
196
+ ON CONFLICT(video_id) DO UPDATE SET
197
+ views = excluded.views,
198
+ likes = excluded.likes,
199
+ comments = excluded.comments,
200
+ avg_watch_time = excluded.avg_watch_time,
201
+ recorded_at = CURRENT_TIMESTAMP`;
202
+ const SQL_RECENT_SHORT_FORM = `SELECT * FROM short_form_performance
203
+ WHERE app_id = ? AND recorded_at >= datetime('now', ?)
204
+ ORDER BY views DESC`;
205
+ export function upsertShortFormPerformance(db, params) {
206
+ return getStmt(db, SQL_UPSERT_SHORT_FORM).run(params.app_id, params.platform, params.video_id, params.title, params.views ?? 0, params.likes ?? 0, params.comments ?? 0, params.avg_watch_time ?? null, params.published_at ?? null);
207
+ }
208
+ export function getRecentShortFormPerformance(db, appId, days = 30) {
209
+ return getStmt(db, SQL_RECENT_SHORT_FORM).all(appId, `-${days} days`);
210
+ }
211
+ // ---------------------------------------------------------------------------
212
+ // SEO Metrics
213
+ // ---------------------------------------------------------------------------
214
+ const SQL_UPSERT_SEO = `INSERT INTO seo_metrics (date, clicks, impressions, ctr, avg_position)
215
+ VALUES (?, ?, ?, ?, ?)
216
+ ON CONFLICT(date) DO UPDATE SET
217
+ clicks = excluded.clicks,
218
+ impressions = excluded.impressions,
219
+ ctr = excluded.ctr,
220
+ avg_position = excluded.avg_position,
221
+ recorded_at = CURRENT_TIMESTAMP`;
222
+ const SQL_SEO_BY_RANGE = `SELECT * FROM seo_metrics
223
+ WHERE date BETWEEN ? AND ?
224
+ ORDER BY date ASC`;
225
+ const SQL_SEO_TOTALS = `SELECT
226
+ SUM(clicks) as total_clicks,
227
+ SUM(impressions) as total_impressions,
228
+ AVG(ctr) as avg_ctr,
229
+ AVG(avg_position) as avg_position
230
+ FROM seo_metrics WHERE date BETWEEN ? AND ?`;
231
+ export function upsertSeoMetric(db, params) {
232
+ return getStmt(db, SQL_UPSERT_SEO).run(params.date, params.clicks ?? 0, params.impressions ?? 0, params.ctr ?? 0, params.avg_position ?? 0);
233
+ }
234
+ export function getSeoMetricsByRange(db, startDate, endDate) {
235
+ return getStmt(db, SQL_SEO_BY_RANGE).all(startDate, endDate);
236
+ }
237
+ export function getSeoTotals(db, startDate, endDate) {
238
+ return getStmt(db, SQL_SEO_TOTALS).get(startDate, endDate);
239
+ }
240
+ // ---------------------------------------------------------------------------
241
+ // Web Traffic
242
+ // ---------------------------------------------------------------------------
243
+ const SQL_UPSERT_TRAFFIC = `INSERT INTO web_traffic (date, page_views, users, sessions, bounce_rate)
244
+ VALUES (?, ?, ?, ?, ?)
245
+ ON CONFLICT(date) DO UPDATE SET
246
+ page_views = excluded.page_views,
247
+ users = excluded.users,
248
+ sessions = excluded.sessions,
249
+ bounce_rate = excluded.bounce_rate,
250
+ recorded_at = CURRENT_TIMESTAMP`;
251
+ const SQL_TRAFFIC_BY_RANGE = `SELECT * FROM web_traffic
252
+ WHERE date BETWEEN ? AND ?
253
+ ORDER BY date ASC`;
254
+ const SQL_TRAFFIC_TOTALS = `SELECT
255
+ SUM(page_views) as total_pv,
256
+ SUM(users) as total_users,
257
+ SUM(sessions) as total_sessions,
258
+ AVG(bounce_rate) as avg_bounce_rate
259
+ FROM web_traffic WHERE date BETWEEN ? AND ?`;
260
+ export function upsertWebTraffic(db, params) {
261
+ return getStmt(db, SQL_UPSERT_TRAFFIC).run(params.date, params.page_views ?? 0, params.users ?? 0, params.sessions ?? 0, params.bounce_rate ?? 0);
262
+ }
263
+ export function getWebTrafficByRange(db, startDate, endDate) {
264
+ return getStmt(db, SQL_TRAFFIC_BY_RANGE).all(startDate, endDate);
265
+ }
266
+ export function getWebTrafficTotals(db, startDate, endDate) {
267
+ return getStmt(db, SQL_TRAFFIC_TOTALS).get(startDate, endDate);
268
+ }
269
+ // ---------------------------------------------------------------------------
270
+ // Blog Performance
271
+ // ---------------------------------------------------------------------------
272
+ const SQL_UPSERT_BLOG_PERF = `INSERT INTO blog_performance
273
+ (slug, date, page_views, avg_session_duration, bounce_rate, seo_clicks, seo_impressions, seo_ctr, seo_position)
274
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
275
+ ON CONFLICT(slug, date) DO UPDATE SET
276
+ page_views = excluded.page_views,
277
+ avg_session_duration = excluded.avg_session_duration,
278
+ bounce_rate = excluded.bounce_rate,
279
+ seo_clicks = excluded.seo_clicks,
280
+ seo_impressions = excluded.seo_impressions,
281
+ seo_ctr = excluded.seo_ctr,
282
+ seo_position = excluded.seo_position,
283
+ recorded_at = CURRENT_TIMESTAMP`;
284
+ const SQL_BLOG_PERF_BY_SLUG = `SELECT * FROM blog_performance
285
+ WHERE slug = ? AND date BETWEEN ? AND ?
286
+ ORDER BY date ASC`;
287
+ const SQL_BLOG_PERF_TOP = `SELECT slug,
288
+ SUM(page_views) as total_pv,
289
+ SUM(seo_clicks) as total_clicks,
290
+ AVG(avg_session_duration) as avg_duration,
291
+ AVG(bounce_rate) as avg_bounce
292
+ FROM blog_performance
293
+ WHERE date BETWEEN ? AND ?
294
+ GROUP BY slug
295
+ ORDER BY total_pv DESC
296
+ LIMIT ?`;
297
+ export function upsertBlogPerformance(db, params) {
298
+ return getStmt(db, SQL_UPSERT_BLOG_PERF).run(params.slug, params.date, params.page_views ?? 0, params.avg_session_duration ?? 0, params.bounce_rate ?? 0, params.seo_clicks ?? 0, params.seo_impressions ?? 0, params.seo_ctr ?? 0, params.seo_position ?? 0);
299
+ }
300
+ export function getBlogPerformanceBySlug(db, slug, startDate, endDate) {
301
+ return getStmt(db, SQL_BLOG_PERF_BY_SLUG).all(slug, startDate, endDate);
302
+ }
303
+ export function getTopBlogPerformance(db, startDate, endDate, limit = 5) {
304
+ return getStmt(db, SQL_BLOG_PERF_TOP).all(startDate, endDate, limit);
305
+ }
306
+ const SQL_INSERT_SOCIAL_POST = `INSERT INTO social_posts (app_id, platform, post_id, post_url, content, image_url, status)
307
+ VALUES (?, ?, ?, ?, ?, ?, ?)`;
308
+ const SQL_SOCIAL_POSTS_BY_APP = `SELECT * FROM social_posts
309
+ WHERE app_id = ? AND posted_at >= datetime('now', ?)
310
+ ORDER BY posted_at DESC`;
311
+ const SQL_SOCIAL_POSTS_BY_PLATFORM = `SELECT * FROM social_posts
312
+ WHERE app_id = ? AND platform = ? AND posted_at >= datetime('now', ?)
313
+ ORDER BY posted_at DESC`;
314
+ const SQL_UPDATE_SOCIAL_POST_STATUS = "UPDATE social_posts SET status = ? WHERE id = ?";
315
+ export function insertSocialPost(db, params) {
316
+ return getStmt(db, SQL_INSERT_SOCIAL_POST).run(params.app_id, params.platform, params.post_id, params.post_url, params.content, params.image_url, params.status ?? "posted");
317
+ }
318
+ export function getSocialPostsByApp(db, appId, days = 30) {
319
+ return getStmt(db, SQL_SOCIAL_POSTS_BY_APP).all(appId, `-${String(days)} days`);
320
+ }
321
+ export function getSocialPostsByPlatform(db, appId, platform, days = 30) {
322
+ return getStmt(db, SQL_SOCIAL_POSTS_BY_PLATFORM).all(appId, platform, `-${String(days)} days`);
323
+ }
324
+ export function updateSocialPostStatus(db, id, status) {
325
+ return getStmt(db, SQL_UPDATE_SOCIAL_POST_STATUS).run(status, id);
326
+ }
327
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/db/queries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,MAAM,SAAS,GAAG,IAAI,OAAO,EAAsD,CAAC;AAEpF,SAAS,OAAO,CAAC,EAAqB,EAAE,GAAW;IACjD,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;QAClB,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;AACzB,CAAC;AAmLD,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,kBAAkB,GAAG;8BACG,CAAC;AAE/B,MAAM,mBAAmB,GAAG;;iCAEK,CAAC;AAElC,MAAM,eAAe,GAAG;;;;;;;8DAOsC,CAAC;AAE/D,MAAM,UAAU,oBAAoB,CAClC,EAAqB,EACrB,MAAgH;IAEhH,OAAO,OAAO,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,GAAG,CACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,aAAa,CAClF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,EAAqB,EACrB,KAAa,EACb,IAAI,GAAG,CAAC;IAER,OAAO,OAAO,CAAC,EAAE,EAAE,mBAAmB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,CAAwB,CAAC;AAC7F,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,EAAqB,EACrB,KAAa,EACb,OAAe,EACf,QAAgB;IAEhB,OAAO,OAAO,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC,GAAG,CACrC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAClC,CAAC;AACrB,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,MAAM,gBAAgB,GAAG;;kFAEyD,CAAC;AAEnF,MAAM,mBAAmB,GAAG;;yCAEa,CAAC;AAE1C,MAAM,UAAU,GAAG;;;2BAGQ,CAAC;AAE5B,MAAM,UAAU,cAAc,CAC5B,EAAqB,EACrB,MAA2E;IAE3E,OAAO,OAAO,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC,GAAG,CACtC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAC5D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,EAAqB,EACrB,KAAa,EACb,SAAiB,EACjB,OAAe;IAEf,OAAO,OAAO,CAAC,EAAE,EAAE,mBAAmB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAkB,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,EAAqB,EACrB,KAAa,EACb,SAAiB,EACjB,OAAe;IAEf,OAAO,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAgB,CAAC;AAC/E,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,MAAM,iBAAiB,GAAG;8BACI,CAAC;AAE/B,MAAM,kBAAkB,GAAG;;iCAEM,CAAC;AAElC,MAAM,oBAAoB,GAAG,sDAAsD,CAAC;AACpF,MAAM,gBAAgB,GAAG,wDAAwD,CAAC;AAClF,MAAM,gBAAgB,GAAG,qEAAqE,CAAC;AAE/F,MAAM,qBAAqB,GAAG;;;0BAGJ,CAAC;AAE3B,MAAM,kBAAkB,GAAG;6EACkD,CAAC;AAE9E,MAAM,UAAU,YAAY,CAC1B,EAAqB,EACrB,MAAoG;IAEpG,OAAO,OAAO,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC,GAAG,CACvC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAC7E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,EAAqB,EACrB,KAAa,EACb,IAAI,GAAG,CAAC;IAER,OAAO,OAAO,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,CAAgB,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,EAAqB,EACrB,QAAgB,EAChB,SAAiB;IAEjB,OAAO,OAAO,CAAC,EAAE,EAAE,oBAAoB,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,EAAqB,EACrB,QAAgB,EAChB,UAAkB;IAElB,OAAO,OAAO,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,EAAqB,EACrB,QAAgB;IAEhB,OAAO,OAAO,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,EAAqB,EACrB,KAAa,EACb,IAAI,GAAG,CAAC;IAER,OAAO,OAAO,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,CAAmB,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,EAAqB,EACrB,KAAa,EACb,IAAI,GAAG,CAAC;IAER,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,CAAkC,CAAC;IACzG,OAAO,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,MAAM,qBAAqB,GAAG;oCACM,CAAC;AAErC,MAAM,mBAAmB,GAAG;;;yCAGa,CAAC;AAE1C,MAAM,UAAU,wBAAwB,CACtC,EAAqB,EACrB,MAQC;IAED,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;QACvC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;QAC3B,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;IACpB,OAAO,OAAO,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC,GAAG,CAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,QAAQ,EACpD,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,EAAE,CACtD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,EAAqB,EACrB,KAAa,EACb,YAAoB,EACpB,QAAgB;IAEhB,OAAO,OAAO,CAAC,EAAE,EAAE,mBAAmB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,CAAsC,CAAC;AAClH,CAAC;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E,MAAM,iBAAiB,GAAG;;;;;;;;;yCASe,CAAC;AAE1C,MAAM,kBAAkB,GAAG;;8BAEG,CAAC;AAE/B,MAAM,eAAe,GAAG;;;oCAGY,CAAC;AAErC,MAAM,UAAU,iBAAiB,CAC/B,EAAqB,EACrB,MAUC;IAED,OAAO,OAAO,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC,GAAG,CACvC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAC/E,MAAM,CAAC,YAAY,IAAI,CAAC,EAAE,MAAM,CAAC,aAAa,IAAI,CAAC,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI,EACjF,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CACzD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,EAAqB,EACrB,KAAa,EACb,KAAa,EACb,IAAI,GAAG,EAAE;IAET,OAAO,OAAO,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,IAAI,OAAO,CAAqB,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,EAAqB,EACrB,KAAa,EACb,IAAI,GAAG,EAAE;IAET,OAAO,OAAO,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,CAAoB,CAAC;AACrF,CAAC;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,mBAAmB,GAAG;8BACE,CAAC;AAE/B,MAAM,oBAAoB,GAAG;;gCAEG,CAAC;AAEjC,MAAM,UAAU,cAAc,CAC5B,EAAqB,EACrB,MAMC;IAED,OAAO,OAAO,CAAC,EAAE,EAAE,mBAAmB,CAAC,CAAC,GAAG,CACzC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAC1F,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,EAAqB,EACrB,KAAa,EACb,IAAI,GAAG,EAAE;IAET,OAAO,OAAO,CAAC,EAAE,EAAE,oBAAoB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,CAAkB,CAAC;AACxF,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,MAAM,eAAe,GAAG;iCACS,CAAC;AAElC,MAAM,kBAAkB,GAAG,uDAAuD,CAAC;AAEnF,MAAM,gBAAgB,GAAG;;iCAEQ,CAAC;AAElC,MAAM,UAAU,cAAc,CAC5B,EAAqB,EACrB,MAOC;IAED,OAAO,OAAO,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC,GAAG,CACrC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,EACzD,MAAM,CAAC,SAAS,IAAI,IAAI,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI,CACtD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAqB;IAChD,OAAQ,OAAO,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,GAAG,EAA8B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC/F,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,EAAqB,EACrB,KAAa,EACb,IAAI,GAAG,EAAE;IAET,OAAO,OAAO,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,CAAkB,CAAC;AACpF,CAAC;AAED,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E,MAAM,qBAAqB,GAAG;;;;;;;yCAOW,CAAC;AAE1C,MAAM,qBAAqB,GAAG;;2BAEH,CAAC;AAE5B,MAAM,UAAU,0BAA0B,CACxC,EAAqB,EACrB,MAUC;IAED,OAAO,OAAO,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC,GAAG,CAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,EAC7D,MAAM,CAAC,KAAK,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,IAAI,CAAC,EAC1D,MAAM,CAAC,cAAc,IAAI,IAAI,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI,CAC3D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,EAAqB,EACrB,KAAa,EACb,IAAI,GAAG,EAAE;IAET,OAAO,OAAO,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,IAAI,OAAO,CAAmB,CAAC;AAC1F,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,MAAM,cAAc,GAAG;;;;;;;yCAOkB,CAAC;AAE1C,MAAM,gBAAgB,GAAG;;yBAEA,CAAC;AAE1B,MAAM,cAAc,GAAG;;;;;mDAK4B,CAAC;AAEpD,MAAM,UAAU,eAAe,CAC7B,EAAqB,EACrB,MAAoG;IAEpG,OAAO,OAAO,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,GAAG,CACpC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,MAAM,CAAC,WAAW,IAAI,CAAC,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,CACpG,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,EAAqB,EACrB,SAAiB,EACjB,OAAe;IAEf,OAAO,OAAO,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAmB,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,EAAqB,EACrB,SAAiB,EACjB,OAAe;IAEf,OAAO,OAAO,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAiB,CAAC;AAC7E,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,MAAM,kBAAkB,GAAG;;;;;;;yCAOc,CAAC;AAE1C,MAAM,oBAAoB,GAAG;;yBAEJ,CAAC;AAE1B,MAAM,kBAAkB,GAAG;;;;;mDAKwB,CAAC;AAEpD,MAAM,UAAU,gBAAgB,CAC9B,EAAqB,EACrB,MAAsG;IAEtG,OAAO,OAAO,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,GAAG,CACxC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,IAAI,CAAC,EAAE,MAAM,CAAC,WAAW,IAAI,CAAC,CACtG,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,EAAqB,EACrB,SAAiB,EACjB,OAAe;IAEf,OAAO,OAAO,CAAC,EAAE,EAAE,oBAAoB,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAoB,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,EAAqB,EACrB,SAAiB,EACjB,OAAe;IAEf,OAAO,OAAO,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAwB,CAAC;AACxF,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,oBAAoB,GAAG;;;;;;;;;;;yCAWY,CAAC;AAE1C,MAAM,qBAAqB,GAAG;;yBAEL,CAAC;AAE1B,MAAM,iBAAiB,GAAG;;;;;;;;;eASX,CAAC;AAEhB,MAAM,UAAU,qBAAqB,CACnC,EAAqB,EACrB,MAUC;IAED,OAAO,OAAO,CAAC,EAAE,EAAE,oBAAoB,CAAC,CAAC,GAAG,CAC1C,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,IAAI,CAAC,EAChD,MAAM,CAAC,oBAAoB,IAAI,CAAC,EAAE,MAAM,CAAC,WAAW,IAAI,CAAC,EACzD,MAAM,CAAC,UAAU,IAAI,CAAC,EAAE,MAAM,CAAC,eAAe,IAAI,CAAC,EACnD,MAAM,CAAC,OAAO,IAAI,CAAC,EAAE,MAAM,CAAC,YAAY,IAAI,CAAC,CAC9C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,EAAqB,EACrB,IAAY,EACZ,SAAiB,EACjB,OAAe;IAEf,OAAO,OAAO,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAyB,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,EAAqB,EACrB,SAAiB,EACjB,OAAe,EACf,KAAK,GAAG,CAAC;IAET,OAAO,OAAO,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAA4B,CAAC;AAClG,CAAC;AAkBD,MAAM,sBAAsB,GAAG;oCACK,CAAC;AAErC,MAAM,uBAAuB,GAAG;;+BAED,CAAC;AAEhC,MAAM,4BAA4B,GAAG;;+BAEN,CAAC;AAEhC,MAAM,6BAA6B,GAAG,iDAAiD,CAAC;AAExF,MAAM,UAAU,gBAAgB,CAC9B,EAAqB,EACrB,MAQC;IAED,OAAO,OAAO,CAAC,EAAE,EAAE,sBAAsB,CAAC,CAAC,GAAG,CAC5C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,EAC/D,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,IAAI,QAAQ,CAC5D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,EAAqB,EACrB,KAAa,EACb,IAAI,GAAG,EAAE;IAET,OAAO,OAAO,CAAC,EAAE,EAAE,uBAAuB,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAoB,CAAC;AACrG,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,EAAqB,EACrB,KAAa,EACb,QAAgB,EAChB,IAAI,GAAG,EAAE;IAET,OAAO,OAAO,CAAC,EAAE,EAAE,4BAA4B,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAoB,CAAC;AACpH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,EAAqB,EACrB,EAAU,EACV,MAAuC;IAEvC,OAAO,OAAO,CAAC,EAAE,EAAE,6BAA6B,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,15 @@
1
+ import Database from "better-sqlite3";
2
+ export interface Migration {
3
+ version: number;
4
+ up: string;
5
+ }
6
+ /**
7
+ * Initialize SQLite database with WAL mode and run pending migrations.
8
+ *
9
+ * DB path defaults to `$ADARIA_HOME/data/adaria.db` (resolved via paths.ts).
10
+ * Callers are responsible for calling `db.close()` on shutdown.
11
+ */
12
+ export declare function initDatabase(dbPath?: string): Database.Database;
13
+ /** Exported for testing — not part of the public API. */
14
+ export declare const _testMigrations: Migration[];
15
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAKtC,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAyND;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CA+B/D;AAED,yDAAyD;AACzD,eAAO,MAAM,eAAe,aAAa,CAAC"}
@@ -0,0 +1,252 @@
1
+ import Database from "better-sqlite3";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { DB_PATH } from "../utils/paths.js";
5
+ const MIGRATIONS = [
6
+ {
7
+ version: 1,
8
+ up: `
9
+ CREATE TABLE IF NOT EXISTS keyword_rankings (
10
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
11
+ app_id TEXT NOT NULL,
12
+ keyword TEXT NOT NULL,
13
+ platform TEXT NOT NULL CHECK(platform IN ('ios', 'android')),
14
+ rank INTEGER,
15
+ search_volume INTEGER,
16
+ recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP
17
+ );
18
+
19
+ CREATE INDEX IF NOT EXISTS idx_kr_app_keyword
20
+ ON keyword_rankings(app_id, keyword, platform);
21
+
22
+ CREATE INDEX IF NOT EXISTS idx_kr_recorded_at
23
+ ON keyword_rankings(recorded_at);
24
+
25
+ CREATE TABLE IF NOT EXISTS sdk_events (
26
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
27
+ app_id TEXT NOT NULL,
28
+ event_name TEXT NOT NULL CHECK(event_name IN ('install', 'signup', 'subscription')),
29
+ count INTEGER NOT NULL DEFAULT 0,
30
+ date DATE NOT NULL,
31
+ UNIQUE(app_id, event_name, date)
32
+ );
33
+
34
+ CREATE TABLE IF NOT EXISTS reviews (
35
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
36
+ app_id TEXT NOT NULL,
37
+ platform TEXT NOT NULL CHECK(platform IN ('ios', 'android')),
38
+ review_id TEXT UNIQUE NOT NULL,
39
+ rating INTEGER NOT NULL CHECK(rating BETWEEN 1 AND 5),
40
+ body TEXT,
41
+ sentiment TEXT CHECK(sentiment IN ('positive', 'negative', 'neutral')),
42
+ reply_draft TEXT,
43
+ replied_at DATETIME,
44
+ recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP
45
+ );
46
+
47
+ CREATE INDEX IF NOT EXISTS idx_reviews_app_platform
48
+ ON reviews(app_id, platform);
49
+
50
+ CREATE INDEX IF NOT EXISTS idx_reviews_recorded_at
51
+ ON reviews(recorded_at);
52
+
53
+ CREATE TABLE IF NOT EXISTS approvals (
54
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
55
+ app_id TEXT NOT NULL,
56
+ agent TEXT NOT NULL CHECK(agent IN ('aso', 'onboarding', 'review', 'content', 'sdk-request', 'seo-blog', 'short-form')),
57
+ action TEXT NOT NULL,
58
+ status TEXT NOT NULL CHECK(status IN ('pending', 'approved', 'rejected', 'modified')),
59
+ payload TEXT,
60
+ decided_at DATETIME DEFAULT CURRENT_TIMESTAMP
61
+ );
62
+
63
+ CREATE INDEX IF NOT EXISTS idx_approvals_app_agent
64
+ ON approvals(app_id, agent);
65
+ `,
66
+ },
67
+ {
68
+ version: 2,
69
+ up: `
70
+ CREATE TABLE IF NOT EXISTS competitor_metadata (
71
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
72
+ app_id TEXT NOT NULL,
73
+ competitor_id TEXT NOT NULL,
74
+ platform TEXT NOT NULL CHECK(platform IN ('ios', 'android')),
75
+ title TEXT,
76
+ subtitle TEXT,
77
+ description TEXT,
78
+ keywords TEXT,
79
+ recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP
80
+ );
81
+
82
+ CREATE INDEX IF NOT EXISTS idx_cm_app_comp
83
+ ON competitor_metadata(app_id, competitor_id, platform);
84
+
85
+ CREATE INDEX IF NOT EXISTS idx_cm_recorded_at
86
+ ON competitor_metadata(recorded_at);
87
+ `,
88
+ },
89
+ {
90
+ version: 3,
91
+ up: `
92
+ CREATE TABLE IF NOT EXISTS agent_metrics (
93
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
94
+ app_id TEXT NOT NULL,
95
+ agent TEXT NOT NULL,
96
+ run_date DATE NOT NULL,
97
+ duration_ms INTEGER,
98
+ status TEXT NOT NULL CHECK(status IN ('success', 'partial', 'failure')),
99
+ alerts_count INTEGER DEFAULT 0,
100
+ actions_count INTEGER DEFAULT 0,
101
+ approval_rate REAL,
102
+ metadata TEXT,
103
+ recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP,
104
+ UNIQUE(app_id, agent, run_date)
105
+ );
106
+
107
+ CREATE INDEX IF NOT EXISTS idx_am_app_agent
108
+ ON agent_metrics(app_id, agent, run_date);
109
+ `,
110
+ },
111
+ {
112
+ version: 4,
113
+ up: `
114
+ CREATE TABLE IF NOT EXISTS blog_posts (
115
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
116
+ app_id TEXT NOT NULL,
117
+ title TEXT NOT NULL,
118
+ slug TEXT UNIQUE NOT NULL,
119
+ keywords TEXT,
120
+ seo_score INTEGER,
121
+ published_at DATETIME,
122
+ recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP
123
+ );
124
+
125
+ CREATE INDEX IF NOT EXISTS idx_bp_app_id
126
+ ON blog_posts(app_id);
127
+
128
+ CREATE INDEX IF NOT EXISTS idx_bp_slug
129
+ ON blog_posts(slug);
130
+
131
+ CREATE TABLE IF NOT EXISTS short_form_performance (
132
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
133
+ app_id TEXT NOT NULL,
134
+ platform TEXT NOT NULL CHECK(platform IN ('youtube', 'tiktok')),
135
+ video_id TEXT UNIQUE NOT NULL,
136
+ title TEXT,
137
+ views INTEGER DEFAULT 0,
138
+ likes INTEGER DEFAULT 0,
139
+ comments INTEGER DEFAULT 0,
140
+ avg_watch_time REAL,
141
+ published_at DATETIME,
142
+ recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP
143
+ );
144
+
145
+ CREATE INDEX IF NOT EXISTS idx_sfp_app_platform
146
+ ON short_form_performance(app_id, platform);
147
+ `,
148
+ },
149
+ {
150
+ version: 5,
151
+ up: `
152
+ CREATE TABLE IF NOT EXISTS seo_metrics (
153
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
154
+ date DATE NOT NULL,
155
+ clicks INTEGER DEFAULT 0,
156
+ impressions INTEGER DEFAULT 0,
157
+ ctr REAL DEFAULT 0,
158
+ avg_position REAL DEFAULT 0,
159
+ recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP,
160
+ UNIQUE(date)
161
+ );
162
+
163
+ CREATE TABLE IF NOT EXISTS web_traffic (
164
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
165
+ date DATE NOT NULL,
166
+ page_views INTEGER DEFAULT 0,
167
+ users INTEGER DEFAULT 0,
168
+ sessions INTEGER DEFAULT 0,
169
+ bounce_rate REAL DEFAULT 0,
170
+ recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP,
171
+ UNIQUE(date)
172
+ );
173
+
174
+ CREATE TABLE IF NOT EXISTS blog_performance (
175
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
176
+ slug TEXT NOT NULL,
177
+ date DATE NOT NULL,
178
+ page_views INTEGER DEFAULT 0,
179
+ avg_session_duration REAL DEFAULT 0,
180
+ bounce_rate REAL DEFAULT 0,
181
+ seo_clicks INTEGER DEFAULT 0,
182
+ seo_impressions INTEGER DEFAULT 0,
183
+ seo_ctr REAL DEFAULT 0,
184
+ seo_position REAL DEFAULT 0,
185
+ recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP,
186
+ UNIQUE(slug, date)
187
+ );
188
+
189
+ CREATE INDEX IF NOT EXISTS idx_bp_perf_slug
190
+ ON blog_performance(slug);
191
+
192
+ CREATE INDEX IF NOT EXISTS idx_bp_perf_date
193
+ ON blog_performance(date);
194
+ `,
195
+ },
196
+ {
197
+ version: 6,
198
+ up: `
199
+ CREATE TABLE IF NOT EXISTS social_posts (
200
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
201
+ app_id TEXT NOT NULL,
202
+ platform TEXT NOT NULL CHECK(platform IN ('twitter', 'facebook', 'threads', 'tiktok', 'youtube', 'linkedin')),
203
+ post_id TEXT,
204
+ post_url TEXT,
205
+ content TEXT NOT NULL,
206
+ image_url TEXT,
207
+ status TEXT NOT NULL DEFAULT 'posted' CHECK(status IN ('posted', 'deleted', 'failed')),
208
+ posted_at DATETIME DEFAULT CURRENT_TIMESTAMP
209
+ );
210
+
211
+ CREATE INDEX IF NOT EXISTS idx_sp_app_platform
212
+ ON social_posts(app_id, platform);
213
+
214
+ CREATE INDEX IF NOT EXISTS idx_sp_posted_at
215
+ ON social_posts(posted_at);
216
+ `,
217
+ },
218
+ ];
219
+ /**
220
+ * Initialize SQLite database with WAL mode and run pending migrations.
221
+ *
222
+ * DB path defaults to `$ADARIA_HOME/data/adaria.db` (resolved via paths.ts).
223
+ * Callers are responsible for calling `db.close()` on shutdown.
224
+ */
225
+ export function initDatabase(dbPath) {
226
+ const resolvedPath = dbPath ?? DB_PATH;
227
+ fs.mkdirSync(path.dirname(resolvedPath), { recursive: true });
228
+ const db = new Database(resolvedPath);
229
+ db.pragma("journal_mode = WAL");
230
+ db.pragma("foreign_keys = ON");
231
+ db.exec(`
232
+ CREATE TABLE IF NOT EXISTS schema_version (
233
+ version INTEGER PRIMARY KEY
234
+ );
235
+ `);
236
+ const row = db
237
+ .prepare("SELECT MAX(version) as v FROM schema_version")
238
+ .get();
239
+ const currentVersion = row?.v ?? 0;
240
+ for (const migration of MIGRATIONS) {
241
+ if (migration.version > currentVersion) {
242
+ db.transaction(() => {
243
+ db.exec(migration.up);
244
+ db.prepare("INSERT INTO schema_version (version) VALUES (?)").run(migration.version);
245
+ })();
246
+ }
247
+ }
248
+ return db;
249
+ }
250
+ /** Exported for testing — not part of the public API. */
251
+ export const _testMigrations = MIGRATIONS;
252
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/db/schema.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAO5C,MAAM,UAAU,GAAgB;IAC9B;QACE,OAAO,EAAE,CAAC;QACV,EAAE,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAyDH;KACF;IACD;QACE,OAAO,EAAE,CAAC;QACV,EAAE,EAAE;;;;;;;;;;;;;;;;;;KAkBH;KACF;IACD;QACE,OAAO,EAAE,CAAC;QACV,EAAE,EAAE;;;;;;;;;;;;;;;;;;KAkBH;KACF;IACD;QACE,OAAO,EAAE,CAAC;QACV,EAAE,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAkCH;KACF;IACD;QACE,OAAO,EAAE,CAAC;QACV,EAAE,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2CH;KACF;IACD;QACE,OAAO,EAAE,CAAC;QACV,EAAE,EAAE;;;;;;;;;;;;;;;;;;KAkBH;KACF;CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAe;IAC1C,MAAM,YAAY,GAAG,MAAM,IAAI,OAAO,CAAC;IACvC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEtC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAE/B,EAAE,CAAC,IAAI,CAAC;;;;GAIP,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,EAAE;SACX,OAAO,CAAC,8CAA8C,CAAC;SACvD,GAAG,EAAsC,CAAC;IAC7C,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAEnC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,SAAS,CAAC,OAAO,GAAG,cAAc,EAAE,CAAC;YACvC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;gBAClB,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBACtB,EAAE,CAAC,OAAO,CAAC,iDAAiD,CAAC,CAAC,GAAG,CAC/D,SAAS,CAAC,OAAO,CAClB,CAAC;YACJ,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;IACH,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,yDAAyD;AACzD,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}