@nexttylabs/echo 0.2.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 (579) hide show
  1. package/.changeset/README.md +21 -0
  2. package/.changeset/config.json +11 -0
  3. package/.changeset/cozy-ghosts-care.md +5 -0
  4. package/.changeset/sharp-lines-stand.md +5 -0
  5. package/.changeset/sour-doodles-eat.md +5 -0
  6. package/.changeset/tender-moose-shop.md +5 -0
  7. package/.github/pull_request_template.md +13 -0
  8. package/.github/workflows/ci.yml +41 -0
  9. package/.github/workflows/publish.yml +44 -0
  10. package/.github/workflows/release.yml +73 -0
  11. package/AGENTS.md +92 -0
  12. package/CHANGELOG.md +13 -0
  13. package/Dockerfile +57 -0
  14. package/LICENSE +661 -0
  15. package/Makefile +77 -0
  16. package/README.md +198 -0
  17. package/app/(auth)/login/page.tsx +53 -0
  18. package/app/(auth)/register/page.tsx +48 -0
  19. package/app/(auth)/sign-in/page.tsx +22 -0
  20. package/app/(dashboard)/admin/feedback/[id]/edit/page.tsx +103 -0
  21. package/app/(dashboard)/admin/feedback/[id]/page.tsx +154 -0
  22. package/app/(dashboard)/admin/feedback/new/page.tsx +91 -0
  23. package/app/(dashboard)/admin/feedback/page.tsx +81 -0
  24. package/app/(dashboard)/admin/layout.tsx +48 -0
  25. package/app/(dashboard)/analytics/portal/page.tsx +30 -0
  26. package/app/(dashboard)/dashboard/page.tsx +133 -0
  27. package/app/(dashboard)/layout.tsx +69 -0
  28. package/app/(dashboard)/no-access/page.tsx +45 -0
  29. package/app/(dashboard)/settings/access/page.tsx +56 -0
  30. package/app/(dashboard)/settings/api-keys/page.tsx +55 -0
  31. package/app/(dashboard)/settings/appearance/page.tsx +40 -0
  32. package/app/(dashboard)/settings/branding/page.tsx +62 -0
  33. package/app/(dashboard)/settings/changelog/page.tsx +51 -0
  34. package/app/(dashboard)/settings/danger-zone/page.tsx +92 -0
  35. package/app/(dashboard)/settings/feedback/page.tsx +63 -0
  36. package/app/(dashboard)/settings/integrations/page.tsx +94 -0
  37. package/app/(dashboard)/settings/layout.tsx +43 -0
  38. package/app/(dashboard)/settings/modules/page.tsx +54 -0
  39. package/app/(dashboard)/settings/notifications/page.tsx +48 -0
  40. package/app/(dashboard)/settings/organization/page.tsx +104 -0
  41. package/app/(dashboard)/settings/organization/portal/access/page.tsx +22 -0
  42. package/app/(dashboard)/settings/organization/portal/experience/page.tsx +22 -0
  43. package/app/(dashboard)/settings/organization/portal/growth/page.tsx +22 -0
  44. package/app/(dashboard)/settings/organization/portal/layout.tsx +24 -0
  45. package/app/(dashboard)/settings/organization/portal/page.tsx +22 -0
  46. package/app/(dashboard)/settings/organizations/[orgId]/members/page.tsx +69 -0
  47. package/app/(dashboard)/settings/organizations/new/page.tsx +36 -0
  48. package/app/(dashboard)/settings/page.tsx +22 -0
  49. package/app/(dashboard)/settings/portal-access/page.tsx +53 -0
  50. package/app/(dashboard)/settings/portal-branding/page.tsx +59 -0
  51. package/app/(dashboard)/settings/portal-growth/page.tsx +57 -0
  52. package/app/(dashboard)/settings/portal-modules/page.tsx +49 -0
  53. package/app/(dashboard)/settings/portal-resources/page.tsx +66 -0
  54. package/app/(dashboard)/settings/profile/page.tsx +48 -0
  55. package/app/(dashboard)/settings/widgets/page.tsx +63 -0
  56. package/app/(public)/[organizationSlug]/changelog/page.tsx +109 -0
  57. package/app/(public)/[organizationSlug]/feedback/[id]/page.tsx +146 -0
  58. package/app/(public)/[organizationSlug]/page.tsx +160 -0
  59. package/app/(public)/[organizationSlug]/roadmap/page.tsx +142 -0
  60. package/app/(public)/docs/page.tsx +48 -0
  61. package/app/(public)/feedback/[id]/not-found.tsx +33 -0
  62. package/app/(public)/feedback/[id]/page.tsx +102 -0
  63. package/app/(public)/invite/[token]/page.tsx +121 -0
  64. package/app/(public)/page.tsx +22 -0
  65. package/app/(public)/widget/[organizationId]/page.tsx +122 -0
  66. package/app/api/_utils.ts +29 -0
  67. package/app/api/admin/backup/route.ts +72 -0
  68. package/app/api/api-keys/[keyId]/route.ts +92 -0
  69. package/app/api/api-keys/route.ts +116 -0
  70. package/app/api/auth/[...all]/route.ts +21 -0
  71. package/app/api/auth/clear-session/route.ts +43 -0
  72. package/app/api/auth/register/handler.ts +176 -0
  73. package/app/api/auth/register/route.ts +26 -0
  74. package/app/api/docs/route.ts +28 -0
  75. package/app/api/feedback/[id]/comments/[commentId]/route.ts +105 -0
  76. package/app/api/feedback/[id]/comments/route.ts +421 -0
  77. package/app/api/feedback/[id]/duplicates/route.ts +285 -0
  78. package/app/api/feedback/[id]/handler.ts +91 -0
  79. package/app/api/feedback/[id]/processing-status/route.ts +199 -0
  80. package/app/api/feedback/[id]/reclassify/route.ts +145 -0
  81. package/app/api/feedback/[id]/route.ts +511 -0
  82. package/app/api/feedback/[id]/suggest-tags/route.ts +227 -0
  83. package/app/api/feedback/[id]/sync-github/route.ts +52 -0
  84. package/app/api/feedback/[id]/vote/route.ts +431 -0
  85. package/app/api/feedback/bulk/route.ts +212 -0
  86. package/app/api/feedback/handler.ts +138 -0
  87. package/app/api/feedback/route.ts +298 -0
  88. package/app/api/feedback/similar/route.ts +100 -0
  89. package/app/api/health/route.test.ts +64 -0
  90. package/app/api/health/route.ts +92 -0
  91. package/app/api/identify/jwt/route.ts +29 -0
  92. package/app/api/integrations/github/route.ts +196 -0
  93. package/app/api/internal/domain-lookup/route.ts +67 -0
  94. package/app/api/invitations/accept/handler.ts +101 -0
  95. package/app/api/invitations/accept/route.ts +29 -0
  96. package/app/api/notifications/preferences/route.ts +109 -0
  97. package/app/api/organizations/[orgId]/handler.ts +123 -0
  98. package/app/api/organizations/[orgId]/invitations/handler.ts +121 -0
  99. package/app/api/organizations/[orgId]/invitations/route.ts +29 -0
  100. package/app/api/organizations/[orgId]/members/[memberId]/handler.ts +208 -0
  101. package/app/api/organizations/[orgId]/members/[memberId]/route.ts +30 -0
  102. package/app/api/organizations/[orgId]/members/handler.ts +77 -0
  103. package/app/api/organizations/[orgId]/members/route.ts +29 -0
  104. package/app/api/organizations/[orgId]/route.ts +30 -0
  105. package/app/api/organizations/handler.ts +97 -0
  106. package/app/api/organizations/route.ts +29 -0
  107. package/app/api/tags/sync/route.ts +88 -0
  108. package/app/api/upload/handler.ts +79 -0
  109. package/app/api/upload/route.ts +37 -0
  110. package/app/api/v1/feedback/[id]/route.ts +276 -0
  111. package/app/api/v1/feedback/route.ts +250 -0
  112. package/app/api/v1/spec/route.ts +356 -0
  113. package/app/api/webhooks/[webhookId]/route.ts +213 -0
  114. package/app/api/webhooks/github/route.ts +158 -0
  115. package/app/api/webhooks/route.ts +143 -0
  116. package/app/favicon.ico +0 -0
  117. package/app/globals.css +139 -0
  118. package/app/health/route.ts +108 -0
  119. package/app/layout.tsx +60 -0
  120. package/bun.lock +2503 -0
  121. package/components/api/rate-limit-info.tsx +86 -0
  122. package/components/api-keys/api-key-manager.tsx +262 -0
  123. package/components/auth/login-form.tsx +207 -0
  124. package/components/auth/register-form.tsx +230 -0
  125. package/components/comment/comment-form.tsx +111 -0
  126. package/components/comment/internal-notes.tsx +219 -0
  127. package/components/comment/public-comments.tsx +387 -0
  128. package/components/component-example-client-only.tsx +29 -0
  129. package/components/component-example.tsx +519 -0
  130. package/components/dashboard/index.ts +22 -0
  131. package/components/dashboard/organization-switcher.tsx +96 -0
  132. package/components/dashboard/quick-actions.tsx +57 -0
  133. package/components/dashboard/recent-feedback-list.tsx +152 -0
  134. package/components/dashboard/stats-cards.tsx +88 -0
  135. package/components/dashboard/status-chart.tsx +106 -0
  136. package/components/example.tsx +70 -0
  137. package/components/feedback/attachment-list.tsx +103 -0
  138. package/components/feedback/auto-classification-badge.tsx +92 -0
  139. package/components/feedback/classification-override.tsx +64 -0
  140. package/components/feedback/duplicate-suggestions-inline.tsx +158 -0
  141. package/components/feedback/duplicate-suggestions.tsx +188 -0
  142. package/components/feedback/embedded-feedback-form.tsx +439 -0
  143. package/components/feedback/feedback-actions.tsx +160 -0
  144. package/components/feedback/feedback-bulk-actions.tsx +184 -0
  145. package/components/feedback/feedback-detail-view.tsx +321 -0
  146. package/components/feedback/feedback-detail.tsx +305 -0
  147. package/components/feedback/feedback-edit-form.tsx +131 -0
  148. package/components/feedback/feedback-filters.tsx +222 -0
  149. package/components/feedback/feedback-list-controls.tsx +433 -0
  150. package/components/feedback/feedback-list-item.tsx +298 -0
  151. package/components/feedback/feedback-list-skeleton.tsx +49 -0
  152. package/components/feedback/feedback-list.tsx +523 -0
  153. package/components/feedback/feedback-sorter.tsx +117 -0
  154. package/components/feedback/feedback-stats.tsx +124 -0
  155. package/components/feedback/file-upload.tsx +289 -0
  156. package/components/feedback/processing-status.tsx +161 -0
  157. package/components/feedback/status-history.tsx +134 -0
  158. package/components/feedback/status-selector.tsx +153 -0
  159. package/components/feedback/submit-on-behalf-form.tsx +403 -0
  160. package/components/feedback/tag-suggestions.tsx +212 -0
  161. package/components/feedback/vote-button.tsx +113 -0
  162. package/components/feedback/vote-list.tsx +108 -0
  163. package/components/integrations/github-config.tsx +200 -0
  164. package/components/landing/hero.tsx +150 -0
  165. package/components/layout/dashboard-layout.tsx +59 -0
  166. package/components/layout/index.ts +20 -0
  167. package/components/layout/language-switcher.tsx +129 -0
  168. package/components/layout/mobile-sidebar.tsx +66 -0
  169. package/components/layout/sidebar.tsx +279 -0
  170. package/components/portal/changelog-entry.tsx +132 -0
  171. package/components/portal/changelog-list.tsx +85 -0
  172. package/components/portal/contributor-badge.tsx +29 -0
  173. package/components/portal/contributors-sidebar.tsx +98 -0
  174. package/components/portal/create-post-dialog.tsx +247 -0
  175. package/components/portal/feedback-board.tsx +205 -0
  176. package/components/portal/feedback-post-card.tsx +198 -0
  177. package/components/portal/help-center.tsx +169 -0
  178. package/components/portal/leaderboard.tsx +29 -0
  179. package/components/portal/portal-header.tsx +153 -0
  180. package/components/portal/portal-layout.tsx +62 -0
  181. package/components/portal/portal-modules-panel.tsx +118 -0
  182. package/components/portal/portal-nav.tsx +59 -0
  183. package/components/portal/portal-overview.tsx +174 -0
  184. package/components/portal/portal-settings-nav.tsx +62 -0
  185. package/components/portal/portal-settings-shell.tsx +71 -0
  186. package/components/portal/portal-shell.tsx +62 -0
  187. package/components/portal/portal-tab-nav.tsx +77 -0
  188. package/components/portal/project-switcher.tsx +20 -0
  189. package/components/portal/roadmap-board.tsx +82 -0
  190. package/components/portal/roadmap-card.tsx +76 -0
  191. package/components/portal/roadmap-column.tsx +78 -0
  192. package/components/portal/settings-forms/access-form.tsx +194 -0
  193. package/components/portal/settings-forms/copy-form.tsx +95 -0
  194. package/components/portal/settings-forms/index.ts +23 -0
  195. package/components/portal/settings-forms/languages-form.tsx +223 -0
  196. package/components/portal/settings-forms/seo-form.tsx +156 -0
  197. package/components/portal/settings-forms/sharing-form.tsx +155 -0
  198. package/components/portal/settings-forms/theme-form.tsx +104 -0
  199. package/components/settings/api-keys-list.tsx +167 -0
  200. package/components/settings/appearance-form.tsx +71 -0
  201. package/components/settings/index.ts +25 -0
  202. package/components/settings/invite-member-form.tsx +119 -0
  203. package/components/settings/notification-preferences.tsx +174 -0
  204. package/components/settings/organization-form.tsx +165 -0
  205. package/components/settings/organization-members-list.tsx +197 -0
  206. package/components/settings/profile-form.tsx +124 -0
  207. package/components/settings/role-selector.tsx +57 -0
  208. package/components/settings/settings-sidebar.tsx +115 -0
  209. package/components/shared/pagination.tsx +215 -0
  210. package/components/ui/alert-dialog.tsx +201 -0
  211. package/components/ui/alert.tsx +75 -0
  212. package/components/ui/avatar.tsx +126 -0
  213. package/components/ui/badge.tsx +62 -0
  214. package/components/ui/button.tsx +77 -0
  215. package/components/ui/card.tsx +111 -0
  216. package/components/ui/combobox.tsx +311 -0
  217. package/components/ui/dialog.tsx +158 -0
  218. package/components/ui/dropdown-menu.tsx +272 -0
  219. package/components/ui/field.tsx +256 -0
  220. package/components/ui/input-group.tsx +164 -0
  221. package/components/ui/input.tsx +36 -0
  222. package/components/ui/label.tsx +41 -0
  223. package/components/ui/pagination.tsx +142 -0
  224. package/components/ui/select.tsx +202 -0
  225. package/components/ui/separator.tsx +45 -0
  226. package/components/ui/sheet.tsx +151 -0
  227. package/components/ui/skeleton.tsx +32 -0
  228. package/components/ui/switch.tsx +49 -0
  229. package/components/ui/table.tsx +118 -0
  230. package/components/ui/tabs.tsx +107 -0
  231. package/components/ui/textarea.tsx +35 -0
  232. package/components/ui/tooltip.tsx +78 -0
  233. package/components/widget/widget-form.tsx +439 -0
  234. package/components.json +24 -0
  235. package/db/init/01-init.sql +13 -0
  236. package/docker-compose.dev.yml +26 -0
  237. package/docker-compose.yml +98 -0
  238. package/docs/architecture.md +259 -0
  239. package/docs/component-inventory.md +261 -0
  240. package/docs/database-migrations.md +76 -0
  241. package/docs/development-guide.md +209 -0
  242. package/docs/e2e-user-flows.csv +31 -0
  243. package/docs/er-diagram-feedback.mmd +138 -0
  244. package/docs/er-diagram.mmd +281 -0
  245. package/docs/i18n-check-report.md +296 -0
  246. package/docs/index.md +214 -0
  247. package/docs/logic-chain.md +94 -0
  248. package/docs/plans/2026-01-02-database-migration-scripts.md +496 -0
  249. package/docs/plans/2026-01-02-user-login-design.md +37 -0
  250. package/docs/plans/2026-01-02-user-login.md +437 -0
  251. package/docs/plans/2026-01-02-user-registration-design.md +47 -0
  252. package/docs/plans/2026-01-02-user-registration.md +628 -0
  253. package/docs/plans/2026-01-03-roles-permissions-design.md +20 -0
  254. package/docs/plans/2026-01-03-roles-permissions.md +266 -0
  255. package/docs/plans/2026-01-05-authentication-middleware.md +207 -0
  256. package/docs/plans/2026-01-05-member-removal.md +186 -0
  257. package/docs/plans/2026-01-05-organization-creation.md +374 -0
  258. package/docs/plans/2026-01-05-rbac-middleware.md +112 -0
  259. package/docs/plans/2026-01-05-role-configuration.md +441 -0
  260. package/docs/plans/2026-01-06-file-upload-support.md +804 -0
  261. package/docs/plans/2026-01-06-permission-check-hook.md +155 -0
  262. package/docs/plans/2026-01-06-resource-ownership-check.md +231 -0
  263. package/docs/plans/2026-01-07-feedback-tracking-link.md +459 -0
  264. package/docs/plans/2026-01-09-logout-redirect-design.md +52 -0
  265. package/docs/plans/2026-01-09-phase2-3-plan.md +654 -0
  266. package/docs/plans/2026-01-09-portal-execution-plan.md +408 -0
  267. package/docs/plans/2026-01-09-project-delete-feature-design.md +163 -0
  268. package/docs/plans/2026-01-09-project-delete-implementation.md +451 -0
  269. package/docs/plans/2026-01-09-project-edit-delete-design.md +52 -0
  270. package/docs/plans/2026-01-09-settings-center-design.md +114 -0
  271. package/docs/plans/2026-01-09-settings-center.md +948 -0
  272. package/docs/plans/2026-01-10-organization-only-design.md +66 -0
  273. package/docs/plans/2026-01-10-organization-only-implementation.md +433 -0
  274. package/docs/plans/2026-01-10-portal-settings-restructure-plan.md +18 -0
  275. package/docs/plans/2026-01-10-project-settings-tabs-design-implementation.md +296 -0
  276. package/docs/plans/2026-01-14-e2e-playwright-feedback.md +173 -0
  277. package/docs/plans/2026-01-15-feedback-management-org-context-design.md +82 -0
  278. package/docs/plans/2026-01-15-feedback-management-org-context-implementation-plan.md +521 -0
  279. package/docs/plans/2026-01-16-admin-feedback-filters-design.md +75 -0
  280. package/docs/plans/2026-01-16-admin-feedback-filters-implementation.md +293 -0
  281. package/docs/plans/2026-01-16-admin-feedback-route-consolidation.md +180 -0
  282. package/docs/plans/2026-01-16-e2e-test-fixes.md +158 -0
  283. package/docs/plans/2026-01-17-admin-feedback-filters.md +214 -0
  284. package/docs/plans/2026-01-17-admin-feedback-improvements.md +453 -0
  285. package/docs/plans/2026-01-18-changesets-design.md +40 -0
  286. package/docs/product_changes.md +37 -0
  287. package/docs/project-overview.md +159 -0
  288. package/docs/project-scan-report.json +104 -0
  289. package/docs/route-role-visibility.md +51 -0
  290. package/docs/source-tree-analysis.md +150 -0
  291. package/docs/testing/delete-project-manual-tests.md +18 -0
  292. package/docs/user-story-tracking.md +191 -0
  293. package/drizzle.config.ts +32 -0
  294. package/eslint.config.mjs +19 -0
  295. package/hooks/use-permissions.ts +56 -0
  296. package/i18n/config.ts +45 -0
  297. package/i18n/request.ts +28 -0
  298. package/i18n/resolve-locale.ts +38 -0
  299. package/lib/api/errors.ts +62 -0
  300. package/lib/auth/cli-config.ts +35 -0
  301. package/lib/auth/client.ts +20 -0
  302. package/lib/auth/config.ts +55 -0
  303. package/lib/auth/jwt-identity.ts +21 -0
  304. package/lib/auth/org-context.ts +71 -0
  305. package/lib/auth/organization.ts +107 -0
  306. package/lib/auth/permissions.ts +87 -0
  307. package/lib/auth/session.ts +23 -0
  308. package/lib/config/rate-limits.ts +64 -0
  309. package/lib/dashboard/get-dashboard-stats.ts +136 -0
  310. package/lib/db/index.ts +41 -0
  311. package/lib/db/migrate.test.ts +49 -0
  312. package/lib/db/migrate.ts +62 -0
  313. package/lib/db/migrations/.gitkeep +0 -0
  314. package/lib/db/migrations/0000_cynical_gladiator.sql +53 -0
  315. package/lib/db/migrations/0001_wandering_sunfire.sql +27 -0
  316. package/lib/db/migrations/0002_shallow_speedball.sql +1 -0
  317. package/lib/db/migrations/0003_add_org_description.sql +1 -0
  318. package/lib/db/migrations/0003_boring_wild_pack.sql +13 -0
  319. package/lib/db/migrations/0004_windy_tyrannus.sql +27 -0
  320. package/lib/db/migrations/0005_perpetual_doorman.sql +5 -0
  321. package/lib/db/migrations/0006_aberrant_captain_midlands.sql +13 -0
  322. package/lib/db/migrations/0007_clever_captain_cross.sql +14 -0
  323. package/lib/db/migrations/0008_sparkling_pandemic.sql +2 -0
  324. package/lib/db/migrations/0009_happy_black_tom.sql +29 -0
  325. package/lib/db/migrations/0010_kind_junta.sql +8 -0
  326. package/lib/db/migrations/0011_mute_squadron_supreme.sql +25 -0
  327. package/lib/db/migrations/0012_giant_power_man.sql +24 -0
  328. package/lib/db/migrations/0013_damp_titanium_man.sql +17 -0
  329. package/lib/db/migrations/0014_blue_alice.sql +18 -0
  330. package/lib/db/migrations/0015_webhook_tables.sql +41 -0
  331. package/lib/db/migrations/0016_github_integration.sql +30 -0
  332. package/lib/db/migrations/0016_overjoyed_ghost_rider.sql +22 -0
  333. package/lib/db/migrations/0017_slimy_inhumans.sql +6 -0
  334. package/lib/db/migrations/0018_same_spitfire.sql +1 -0
  335. package/lib/db/migrations/0019_jittery_loners.sql +16 -0
  336. package/lib/db/migrations/0019_remove_projects_add_org_settings.sql +14 -0
  337. package/lib/db/migrations/meta/0000_snapshot.json +374 -0
  338. package/lib/db/migrations/meta/0001_snapshot.json +553 -0
  339. package/lib/db/migrations/meta/0002_snapshot.json +560 -0
  340. package/lib/db/migrations/meta/0003_snapshot.json +650 -0
  341. package/lib/db/migrations/meta/0004_snapshot.json +852 -0
  342. package/lib/db/migrations/meta/0005_snapshot.json +900 -0
  343. package/lib/db/migrations/meta/0006_snapshot.json +1011 -0
  344. package/lib/db/migrations/meta/0007_snapshot.json +1125 -0
  345. package/lib/db/migrations/meta/0008_snapshot.json +1146 -0
  346. package/lib/db/migrations/meta/0009_snapshot.json +1386 -0
  347. package/lib/db/migrations/meta/0010_snapshot.json +1419 -0
  348. package/lib/db/migrations/meta/0011_snapshot.json +1615 -0
  349. package/lib/db/migrations/meta/0012_snapshot.json +1805 -0
  350. package/lib/db/migrations/meta/0013_snapshot.json +1948 -0
  351. package/lib/db/migrations/meta/0014_snapshot.json +2082 -0
  352. package/lib/db/migrations/meta/0015_snapshot.json +2476 -0
  353. package/lib/db/migrations/meta/0016_snapshot.json +2633 -0
  354. package/lib/db/migrations/meta/0017_snapshot.json +2680 -0
  355. package/lib/db/migrations/meta/0018_snapshot.json +2686 -0
  356. package/lib/db/migrations/meta/0019_snapshot.json +2741 -0
  357. package/lib/db/migrations/meta/_journal.json +146 -0
  358. package/lib/db/schema/ai-processing.ts +90 -0
  359. package/lib/db/schema/api-keys.ts +61 -0
  360. package/lib/db/schema/attachments.ts +48 -0
  361. package/lib/db/schema/auth.ts +111 -0
  362. package/lib/db/schema/comments.ts +74 -0
  363. package/lib/db/schema/duplicates.ts +80 -0
  364. package/lib/db/schema/feedback.ts +88 -0
  365. package/lib/db/schema/github-integrations.ts +66 -0
  366. package/lib/db/schema/index.ts +35 -0
  367. package/lib/db/schema/invitations.ts +32 -0
  368. package/lib/db/schema/notifications.ts +85 -0
  369. package/lib/db/schema/organization-members.ts +37 -0
  370. package/lib/db/schema/organization-settings.ts +134 -0
  371. package/lib/db/schema/organizations.ts +30 -0
  372. package/lib/db/schema/projects.ts +145 -0
  373. package/lib/db/schema/status-history.ts +63 -0
  374. package/lib/db/schema/tags.ts +194 -0
  375. package/lib/db/schema/user-profiles.ts +31 -0
  376. package/lib/db/schema/votes.ts +60 -0
  377. package/lib/db/schema/webhooks.ts +106 -0
  378. package/lib/feedback/filters.ts +28 -0
  379. package/lib/feedback/find-similar.ts +49 -0
  380. package/lib/feedback/get-feedback-by-id.ts +159 -0
  381. package/lib/feedback/prefill.ts +51 -0
  382. package/lib/http/get-request-url.ts +28 -0
  383. package/lib/integrations/github.ts +159 -0
  384. package/lib/invitations.ts +22 -0
  385. package/lib/logger.test.ts +31 -0
  386. package/lib/logger.ts +58 -0
  387. package/lib/middleware/api-key.ts +126 -0
  388. package/lib/middleware/rate-limit-keys.ts +47 -0
  389. package/lib/middleware/rate-limit.ts +148 -0
  390. package/lib/middleware/rbac.ts +39 -0
  391. package/lib/middleware/request-id.test.ts +28 -0
  392. package/lib/middleware/request-id.ts +30 -0
  393. package/lib/middleware/request-logger.test.ts +36 -0
  394. package/lib/middleware/request-logger.ts +41 -0
  395. package/lib/middleware/with-rate-limit.ts +33 -0
  396. package/lib/portal/analytics.ts +20 -0
  397. package/lib/portal/contributors.ts +27 -0
  398. package/lib/portal/i18n.ts +20 -0
  399. package/lib/portal/leaderboard-settings.ts +20 -0
  400. package/lib/portal/modules.ts +20 -0
  401. package/lib/portal/portal-copy.ts +20 -0
  402. package/lib/portal/public-context.tsx +110 -0
  403. package/lib/portal/seo.ts +20 -0
  404. package/lib/portal/settings-context.ts +56 -0
  405. package/lib/portal/sharing.ts +20 -0
  406. package/lib/portal/sorting.ts +20 -0
  407. package/lib/portal/theme.ts +20 -0
  408. package/lib/services/ai/classifier.ts +296 -0
  409. package/lib/services/ai/duplicate-detector.ts +255 -0
  410. package/lib/services/ai/tag-suggester.ts +108 -0
  411. package/lib/services/api-keys.ts +164 -0
  412. package/lib/services/backup.ts +173 -0
  413. package/lib/services/email/templates.ts +158 -0
  414. package/lib/services/email.ts +68 -0
  415. package/lib/services/github-sync.ts +205 -0
  416. package/lib/services/notifications/index.ts +224 -0
  417. package/lib/services/portal-settings.ts +157 -0
  418. package/lib/swagger/config.ts +296 -0
  419. package/lib/swagger/generate.ts +400 -0
  420. package/lib/upload/file-validator.ts +52 -0
  421. package/lib/upload/storage.ts +59 -0
  422. package/lib/utils/format.ts +26 -0
  423. package/lib/utils/slug.ts +28 -0
  424. package/lib/utils.ts +23 -0
  425. package/lib/validations/auth.ts +56 -0
  426. package/lib/validations/comment.ts +44 -0
  427. package/lib/validations/feedback.ts +51 -0
  428. package/lib/validations/invitations.ts +23 -0
  429. package/lib/validations/organizations.ts +34 -0
  430. package/lib/validations/projects.ts +49 -0
  431. package/lib/validators/feedback.ts +57 -0
  432. package/lib/validators/index.ts +18 -0
  433. package/lib/webhooks/events.ts +73 -0
  434. package/lib/webhooks/index.ts +21 -0
  435. package/lib/webhooks/retry.ts +188 -0
  436. package/lib/webhooks/sender.ts +183 -0
  437. package/lib/webhooks/verify.ts +37 -0
  438. package/lib/workers/feedback-processor.ts +255 -0
  439. package/messages/en.json +965 -0
  440. package/messages/jp.json +862 -0
  441. package/messages/zh-CN.json +855 -0
  442. package/next-env.d.ts +6 -0
  443. package/next.config.ts +66 -0
  444. package/package.json +84 -0
  445. package/playwright.config.ts +44 -0
  446. package/postcss.config.mjs +7 -0
  447. package/proxy.test.ts +131 -0
  448. package/proxy.ts +190 -0
  449. package/public/file.svg +1 -0
  450. package/public/globe.svg +1 -0
  451. package/public/logo-64.svg +5 -0
  452. package/public/logo.svg +5 -0
  453. package/public/next.svg +1 -0
  454. package/public/openapi.json +673 -0
  455. package/public/uploads/.gitkeep +0 -0
  456. package/public/uploads/02695701-ded0-4c81-8a21-9326c1d65448.pdf +1 -0
  457. package/public/uploads/178843ea-2780-48ef-8988-f4cba442e4cb.pdf +1 -0
  458. package/public/uploads/24b0a9ef-da93-49da-934f-637f89c7871d.pdf +1 -0
  459. package/public/uploads/7a11626d-a8e4-4b91-a8eb-20b6213b0a5a.pdf +1 -0
  460. package/public/uploads/b0703f4d-6e7b-4aab-8191-1a7b15f1b8ee.pdf +1 -0
  461. package/public/uploads/c8de0aed-4d3a-44aa-83bb-6594b7a2ddb3.pdf +1 -0
  462. package/public/uploads/e4cce295-0d85-4525-a1b0-a61c45722e26.pdf +1 -0
  463. package/public/uploads/eb4df45e-563c-48b8-9c68-c18212312426.pdf +1 -0
  464. package/public/vercel.svg +1 -0
  465. package/public/widget/embed.js +249 -0
  466. package/public/window.svg +1 -0
  467. package/scripts/backup-db.sh +57 -0
  468. package/scripts/backup-db.ts +24 -0
  469. package/scripts/generate-openapi.ts +22 -0
  470. package/scripts/migration-helper.ts +39 -0
  471. package/scripts/pre-deploy.ts +75 -0
  472. package/scripts/restore-db.sh +60 -0
  473. package/scripts/rollback.ts +72 -0
  474. package/scripts/seed-tags.ts +48 -0
  475. package/tests/api/feedback-bulk.test.ts +47 -0
  476. package/tests/api/feedback-by-id.test.ts +67 -0
  477. package/tests/api/feedback-comments-route-import.test.ts +26 -0
  478. package/tests/api/feedback-create.test.ts +71 -0
  479. package/tests/api/feedback-delete.test.ts +160 -0
  480. package/tests/api/feedback-filter.test.ts +250 -0
  481. package/tests/api/feedback-list.test.ts +234 -0
  482. package/tests/api/feedback-route-assignee-condition.test.ts +32 -0
  483. package/tests/api/feedback-similar.test.ts +46 -0
  484. package/tests/api/feedback-sort.test.ts +261 -0
  485. package/tests/api/feedback-status-enum.test.ts +49 -0
  486. package/tests/api/feedback-status-filter.test.ts +117 -0
  487. package/tests/api/feedback-submit-on-behalf.test.ts +269 -0
  488. package/tests/api/feedback.test.ts +175 -0
  489. package/tests/api/identify-jwt.test.ts +25 -0
  490. package/tests/api/invitation-accept.test.ts +213 -0
  491. package/tests/api/organization-invitations.test.ts +186 -0
  492. package/tests/api/organization-members-list.test.ts +79 -0
  493. package/tests/api/organization-members.test.ts +340 -0
  494. package/tests/api/organizations.test.ts +149 -0
  495. package/tests/api/register.test.ts +112 -0
  496. package/tests/api/upload.test.ts +103 -0
  497. package/tests/api/vote.test.ts +82 -0
  498. package/tests/app/admin-feedback-detail-page.test.tsx +25 -0
  499. package/tests/app/admin-feedback-list-page.test.tsx +25 -0
  500. package/tests/app/admin-feedback-new-page.test.tsx +25 -0
  501. package/tests/app/health-route-helpers.test.ts +27 -0
  502. package/tests/app/login-page.test.ts +26 -0
  503. package/tests/app/portal-page.test.ts +29 -0
  504. package/tests/app/project-portal-overview.test.tsx +25 -0
  505. package/tests/app/widget-page-import.test.ts +25 -0
  506. package/tests/components/create-post-dialog-defaults.test.ts +43 -0
  507. package/tests/components/feedback/duplicate-suggestions-inline.test.tsx +27 -0
  508. package/tests/components/feedback/embedded-feedback-form.test.tsx +96 -0
  509. package/tests/components/feedback/feedback-detail.test.tsx +25 -0
  510. package/tests/components/feedback/feedback-stats.test.tsx +49 -0
  511. package/tests/components/feedback-bulk-actions.test.tsx +39 -0
  512. package/tests/components/feedback-i18n-keys.test.ts +70 -0
  513. package/tests/components/feedback-list-controls-compile.test.ts +25 -0
  514. package/tests/components/feedback-list-controls.test.tsx +204 -0
  515. package/tests/components/feedback-list-item.test.tsx +67 -0
  516. package/tests/components/landing/hero.test.tsx +46 -0
  517. package/tests/components/layout/language-switcher.test.tsx +25 -0
  518. package/tests/components/layout/sidebar.test.tsx +157 -0
  519. package/tests/components/login-form.test.ts +25 -0
  520. package/tests/components/organization-form.test.ts +32 -0
  521. package/tests/components/organization-switcher.test.ts +25 -0
  522. package/tests/components/pagination.test.tsx +43 -0
  523. package/tests/components/portal-overview.test.tsx +25 -0
  524. package/tests/components/profile-form.test.tsx +139 -0
  525. package/tests/components/role-selector.test.ts +31 -0
  526. package/tests/components/status-chart.test.tsx +90 -0
  527. package/tests/e2e/auth.e2e.ts +323 -0
  528. package/tests/e2e/feedback-actions.e2e.ts +471 -0
  529. package/tests/e2e/feedback-attachment.e2e.ts +168 -0
  530. package/tests/e2e/feedback-customer.e2e.ts +226 -0
  531. package/tests/e2e/feedback-management.e2e.ts +565 -0
  532. package/tests/e2e/feedback-submit.e2e.ts +133 -0
  533. package/tests/e2e/feedback-view.e2e.ts +297 -0
  534. package/tests/e2e/fixtures/test-data.ts +235 -0
  535. package/tests/e2e/health-check.e2e.ts +230 -0
  536. package/tests/e2e/helpers/test-utils-helpers.test.ts +43 -0
  537. package/tests/e2e/helpers/test-utils.ts +298 -0
  538. package/tests/e2e/integration-placeholders.e2e.ts +199 -0
  539. package/tests/e2e/organization.e2e.ts +292 -0
  540. package/tests/e2e/permissions.e2e.ts +424 -0
  541. package/tests/e2e/project-widget.e2e.ts +63 -0
  542. package/tests/feedback/filters.test.ts +29 -0
  543. package/tests/hooks/use-permissions.test.ts +52 -0
  544. package/tests/lib/ai/classifier.test.ts +104 -0
  545. package/tests/lib/ai/duplicate-detector.test.ts +234 -0
  546. package/tests/lib/attachments-schema.test.ts +30 -0
  547. package/tests/lib/auth/session.test.ts +49 -0
  548. package/tests/lib/auth-client.test.ts +37 -0
  549. package/tests/lib/auth-config.test.ts +26 -0
  550. package/tests/lib/feedback-prefill.test.ts +52 -0
  551. package/tests/lib/feedback-processor.test.ts +41 -0
  552. package/tests/lib/feedback-schema.test.ts +33 -0
  553. package/tests/lib/file-validator.test.ts +48 -0
  554. package/tests/lib/get-feedback-by-id.test.ts +37 -0
  555. package/tests/lib/invitations.test.ts +35 -0
  556. package/tests/lib/login-schema.test.ts +36 -0
  557. package/tests/lib/org-context.test.ts +95 -0
  558. package/tests/lib/organization-access.test.ts +44 -0
  559. package/tests/lib/organization-member-role-schema.test.ts +41 -0
  560. package/tests/lib/permissions.test.ts +88 -0
  561. package/tests/lib/portal-analytics.test.ts +25 -0
  562. package/tests/lib/portal-contributors.test.ts +25 -0
  563. package/tests/lib/portal-copy.test.ts +27 -0
  564. package/tests/lib/portal-i18n.test.ts +30 -0
  565. package/tests/lib/portal-leaderboard-settings.test.ts +25 -0
  566. package/tests/lib/portal-modules.test.ts +25 -0
  567. package/tests/lib/portal-seo.test.ts +25 -0
  568. package/tests/lib/portal-sharing.test.ts +25 -0
  569. package/tests/lib/portal-sorting.test.ts +25 -0
  570. package/tests/lib/portal-theme.test.ts +25 -0
  571. package/tests/lib/rate-limit.test.ts +142 -0
  572. package/tests/lib/resolve-locale.test.ts +34 -0
  573. package/tests/lib/services/backup.test.ts +145 -0
  574. package/tests/lib/user-organizations.test.ts +42 -0
  575. package/tests/lib/user-role-schema.test.ts +33 -0
  576. package/tests/lib/user-schema.test.ts +25 -0
  577. package/tests/setup.ts +74 -0
  578. package/tsconfig.json +34 -0
  579. package/types/bun-test.d.ts +31 -0
@@ -0,0 +1,209 @@
1
+ # Development Guide
2
+
3
+ **Project:** Echo
4
+ **Generated:** 2025-12-31
5
+
6
+ ## Prerequisites
7
+
8
+ | 依赖 | 版本 | 说明 |
9
+ |------|------|------|
10
+ | **Bun** | 最新版 | 包管理器(项目使用 Bun) |
11
+ | **Node.js** | 20.x | 运行时(通过 Bun 管理) |
12
+ | **TypeScript** | 5.x | 类型系统 |
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ # 安装依赖
18
+ bun install
19
+ ```
20
+
21
+ ## Development
22
+
23
+ ```bash
24
+ # 启动开发服务器
25
+ bun dev
26
+
27
+ # 访问 http://localhost:3000
28
+ ```
29
+
30
+ 开发服务器启动后,访问 [http://localhost:3000](http://localhost:3000) 查看应用。
31
+
32
+ ## Build
33
+
34
+ ```bash
35
+ # 生产构建
36
+ bun run build
37
+
38
+ # 启动生产服务器
39
+ bun start
40
+ ```
41
+
42
+ ## Linting
43
+
44
+ ```bash
45
+ # 运行 ESLint
46
+ bun run lint
47
+ ```
48
+
49
+ ## Project Structure
50
+
51
+ ```
52
+ echo/
53
+ ├── app/ # Next.js App Router
54
+ ├── components/ # React 组件
55
+ │ └── ui/ # Shadcn/ui 组件
56
+ ├── lib/ # 工具函数
57
+ ├── public/ # 静态资源
58
+ └── docs/ # 项目文档
59
+ ```
60
+
61
+ ## Available Scripts
62
+
63
+ | 命令 | 说明 |
64
+ |------|------|
65
+ | `bun dev` | 启动开发服务器 |
66
+ | `bun run build` | 生产构建 |
67
+ | `bun start` | 启动生产服务器 |
68
+ | `bun run lint` | 运行代码检查 |
69
+
70
+ ## Component Development
71
+
72
+ ### 添加 Shadcn/ui 组件
73
+
74
+ Shadcn/ui 组件已安装在 `components/ui/` 目录。
75
+
76
+ 当前组件库包括:
77
+ - alert-dialog, badge, button, card, combobox
78
+ - dropdown-menu, field, input-group, input
79
+ - label, select, separator, textarea
80
+
81
+ ### 创建新组件
82
+
83
+ ```tsx
84
+ // components/my-component.tsx
85
+ export function MyComponent() {
86
+ return <div>My Component</div>;
87
+ }
88
+ ```
89
+
90
+ ### 使用工具函数
91
+
92
+ ```tsx
93
+ import { cn } from "@/lib/utils";
94
+
95
+ // 合并 Tailwind 类名
96
+ className={cn("base-class", condition && "conditional-class")}
97
+ ```
98
+
99
+ ## Styling
100
+
101
+ ### Tailwind CSS v4
102
+
103
+ 项目使用 Tailwind CSS v4,配置在 `app/globals.css` 中:
104
+
105
+ ```css
106
+ @theme inline {
107
+ --color-primary: var(--primary);
108
+ /* ... 更多主题变量 */
109
+ }
110
+ ```
111
+
112
+ ### 暗黑模式
113
+
114
+ 使用 `.dark` 类选择器:
115
+
116
+ ```html
117
+ <html class="dark">
118
+ ```
119
+
120
+ ### 色彩空间
121
+
122
+ 项目使用 **OKLCH** 色彩空间,提供感知上均匀的颜色。
123
+
124
+ ## Import Aliases
125
+
126
+ ```typescript
127
+ @/components → components/
128
+ @/lib → lib/
129
+ @/components/ui → components/ui
130
+ ```
131
+
132
+ ## Code Quality
133
+
134
+ ### TypeScript 配置
135
+
136
+ - **Strict mode:** 已启用
137
+ - **Target:** ES2017
138
+ - **Module:** ESNext (bundler resolution)
139
+
140
+ ### ESLint
141
+
142
+ 配置文件:`eslint.config.mjs`
143
+ - 使用 Next.js ESLint 配置
144
+
145
+ ## Common Development Tasks
146
+
147
+ ### 添加新页面
148
+
149
+ 在 `app/` 目录创建新文件:
150
+
151
+ ```
152
+ app/
153
+ ├── about/
154
+ │ └── page.tsx # /about 路由
155
+ └── dashboard/
156
+ └── page.tsx # /dashboard 路由
157
+ ```
158
+
159
+ ### 添加 API 路由
160
+
161
+ 在 `app/api/` 目录创建路由处理器:
162
+
163
+ ```
164
+ app/
165
+ └── api/
166
+ └── users/
167
+ └── route.ts # /api/users 端点
168
+ ```
169
+
170
+ ### 环境变量
171
+
172
+ 创建 `.env.local` 文件:
173
+
174
+ ```bash
175
+ NEXT_PUBLIC_API_URL=your_api_url
176
+ ```
177
+
178
+ ## Deployment Notes
179
+
180
+ ### 推荐平台
181
+
182
+ - **Vercel** (Next.js 官方平台)
183
+ - 其他支持 Next.js 的托管平台
184
+
185
+ ### 部署步骤
186
+
187
+ ```bash
188
+ # 1. 构建项目
189
+ bun run build
190
+
191
+ # 2. 输出在 .next/ 目录
192
+ # 3. 使用 bun start 启动或部署到平台
193
+ ```
194
+
195
+ ## Troubleshooting
196
+
197
+ ### 常见问题
198
+
199
+ | 问题 | 解决方案 |
200
+ |------|----------|
201
+ | 依赖安装失败 | 清除缓存:`rm -rf node_modules bun.lockb && bun install` |
202
+ | 端口被占用 | 修改端口或关闭占用 3000 端口的进程 |
203
+ | 类型错误 | 运行 `bun run lint` 检查 |
204
+
205
+ ### 获取帮助
206
+
207
+ - 查看 [Next.js 文档](https://nextjs.org/docs)
208
+ - 查看 [Shadcn/ui 文档](https://ui.shadcn.com)
209
+ - 查看 [Tailwind CSS 文档](https://tailwindcss.com/docs)
@@ -0,0 +1,31 @@
1
+ flow_id,role,module,title,entry,preconditions,steps_summary,assertions,refs,phase,is_completed
2
+ E2E-UF-001,终端用户,反馈收集,提交反馈(基础字段+类型+优先级),Widget/Portal,项目已创建且嵌入入口可用,"打开表单->填标题/描述/类型/优先级->提交->获得跟踪链接","提交成功提示;生成可访问跟踪链接;新反馈可在列表/详情看到","FR1;FR2;FR3;FR5;FR30-FR32",Phase1(MVP),true
3
+ E2E-UF-002,终端用户,反馈收集,提交反馈(带附件上传),Widget/Portal,同E2E-UF-001,"提交时上传附件->提交成功","附件上传成功;详情页可看到/下载附件","FR1;FR4",Phase1(MVP),true
4
+ E2E-UF-003,终端用户,反馈查看,使用跟踪链接查看反馈详情,跟踪链接,已存在公开反馈,"访问跟踪链接->查看标题/描述/状态/附件","详情页可访问;状态展示与后台一致","FR5;FR14",Phase1(MVP),true
5
+ E2E-UF-004,终端用户,投票,对反馈投票,Portal反馈详情页,存在可投票公开反馈,"打开详情->点击投票","投票数变化或投票状态变化","FR15",Phase1(MVP),true
6
+ E2E-UF-005,客服,反馈收集,代客户提交反馈(代表客户提交),后台提交入口,客服账号已登录且有代提交权限,"登录->填写反馈->勾选代提交->提交->生成反馈链接","创建成功;带代提交标记/来源信息;可复制链接","FR6;FR23;FR29",Phase1(MVP),true
7
+ E2E-UF-006,产品团队,认证,登录系统(团队成员),登录页,存在有效用户,"打开登录页->输入凭据->登录->进入后台","进入受保护页面成功","FR23",Phase1(MVP),true
8
+ E2E-UF-007,产品经理/管理员,反馈管理,查看反馈列表(默认加载),后台反馈列表页,已登录且存在反馈数据,"进入列表页->加载列表","列表加载成功;关键字段可见","FR7",Phase1(MVP),true
9
+ E2E-UF-008,产品经理/管理员,反馈管理,列表筛选:按状态筛选,后台反馈列表页,存在多状态反馈,"选择状态筛选->列表刷新","列表项均符合筛选状态","FR8",Phase1(MVP),true
10
+ E2E-UF-009,产品经理/管理员,反馈管理,列表排序:按投票数/按时间排序,后台反馈列表页,存在投票数和时间差异数据,"选择按投票排序->切换按时间排序","排序结果符合预期","FR9;FR10",Phase1(MVP),true
11
+ E2E-UF-010,产品经理/管理员,反馈管理,查看反馈详情(后台),后台反馈列表/详情页,已登录且存在反馈,"从列表进入详情->查看完整信息","详情字段展示完整","FR11",Phase1(MVP),true
12
+ E2E-UF-011,产品经理/管理员,反馈管理,修改反馈状态,后台反馈详情页,已登录且对目标反馈有权限,"打开详情->修改状态->保存","状态更新后列表/详情同步","FR12",Phase1(MVP),true
13
+ E2E-UF-012,产品经理,反馈管理,编辑反馈标题与描述,后台反馈详情页,产品经理登录,"编辑标题/描述->保存->刷新","内容持久化","FR17",Phase1(MVP),true
14
+ E2E-UF-013,产品经理/管理员,反馈管理,删除反馈,后台反馈详情/列表页,有可删除反馈,"触发删除->二次确认","列表移除;详情不可访问/404","FR13",Phase1(MVP),true
15
+ E2E-UF-014,产品经理,协作与沟通,添加内部备注,后台反馈详情页,产品经理登录,"添加备注->保存","备注可见且持久化","FR16",Phase1(MVP),true
16
+ E2E-UF-015,管理员,协作与沟通,回复反馈并通知提交者(占位),后台反馈详情页,管理员登录,"回复->触发通知","回复成功;通知产生(需实现后通过Outbox/Mock SMTP断言)","FR18",Phase1(MVP/占位),true
17
+ E2E-UF-016,管理员,组织管理,创建组织,组织创建入口,允许创建组织,"创建组织->进入组织后台","组织创建成功;进入组织作用域","FR19",Phase1(MVP),true
18
+ E2E-UF-017,管理员,组织管理,邀请成员加入组织(邀请链接),组织成员管理页,管理员在组织内,"输入邮箱邀请->生成邀请链接->使用链接加入","成员出现在成员列表","FR20",Phase1(MVP),true
19
+ E2E-UF-018,管理员,组织管理,配置成员角色(RBAC),组织成员管理页,存在成员,"设置成员角色->刷新权限","不同角色权限生效","FR24;FR25",Phase1(MVP),true
20
+ E2E-UF-019,管理员,组织管理,移除组织成员,组织成员管理页,存在可移除成员,"移除成员->确认","成员被移除;无法访问组织资源","FR21",Phase1(MVP),true
21
+ E2E-UF-020,用户,认证,用户注册账户,注册页,允许自注册,"填写注册信息->提交->登录","注册成功且可登录","FR22;FR23",Phase1(MVP),true
22
+ E2E-UF-021,管理员,项目管理,创建项目,项目管理页,管理员登录,"创建项目->进入项目","项目创建成功","FR30",Phase1(MVP),true
23
+ E2E-UF-022,管理员/终端用户,项目管理,配置嵌入式Widget,项目设置/Widget配置页,已创建项目,"修改Widget配置->保存","配置持久化;预览/嵌入代码反映配置","FR31",Phase1(MVP),true
24
+ E2E-UF-023,管理员/终端用户,项目管理,获取嵌入代码并在外部页面使用(集成级占位),宿主页面+Widget,已创建项目且可复制嵌入代码,"复制嵌入代码->宿主页加载->打开Widget->提交反馈","Widget可加载;提交成功","FR32;FR1",Phase1(MVP/占位),true
25
+ E2E-UF-024,系统/产品团队,AI(基础),自动分类(关键词触发),提交反馈后/详情页,准备包含特定关键词的文本,"提交反馈->查看AI分类/建议","出现自动分类结果或建议提示","FR33;FR34",Phase1(MVP),true
26
+ E2E-UF-025,系统/产品团队,AI(基础),重复反馈检测建议(占位),创建/详情页,存在相似反馈A并创建相似反馈B,"创建B->查看重复建议","出现潜在重复建议UI","FR35",Phase1(MVP/占位),true
27
+ E2E-UF-026,匿名用户,权限控制,未登录访问后台受保护页面被拦截,直接访问后台URL,无,"访问受保护URL","重定向登录或401","FR25",Phase1(MVP),true
28
+ E2E-UF-027,开发者/客服,权限控制,无权编辑反馈状态(RBAC),后台反馈详情页,开发者/客服登录,"尝试修改状态","不显示入口或操作失败且提示无权限","FR25;RBAC",Phase1(MVP),true
29
+ E2E-UF-028,非管理员,权限控制,无权进行组织管理操作(RBAC),组织管理页/动作,非管理员登录,"访问组织管理页或执行邀请/移除/配置角色","被禁止访问","FR25;FR26;RBAC",Phase1(MVP),true
30
+ E2E-UF-029,运维,运维与部署,健康检查端点可用,/health,服务已运行,"请求/health","返回200且包含健康状态","FR39",Phase1(MVP),true
31
+ E2E-UF-030,运维/系统,可观测性,结构化日志产出(占位),日志系统,可读取日志输出,"执行一次关键操作->检查日志","至少出现结构化日志条目","FR40",Phase1(MVP/占位),true
@@ -0,0 +1,138 @@
1
+ erDiagram
2
+ feedback {
3
+ int feedbackId PK
4
+ text title
5
+ text description
6
+ text type
7
+ text priority
8
+ text status
9
+ text organizationId
10
+ boolean submittedOnBehalf
11
+ text submittedBy FK
12
+ jsonb customerInfo
13
+ timestamp createdAt
14
+ timestamp updatedAt
15
+ timestamp deletedAt
16
+ boolean autoClassified
17
+ text processingStatus
18
+ timestamp processedAt
19
+ int githubIssueId
20
+ int githubIssueNumber
21
+ text githubIssueUrl
22
+ timestamp githubSyncedAt
23
+ text githubStatus
24
+ }
25
+
26
+ attachments {
27
+ int attachmentId PK
28
+ int feedbackId FK
29
+ text fileName
30
+ text filePath
31
+ int fileSize
32
+ text mimeType
33
+ timestamp createdAt
34
+ }
35
+
36
+ votes {
37
+ int voteId PK
38
+ int feedbackId FK
39
+ text visitorId
40
+ text userId FK
41
+ timestamp createdAt
42
+ }
43
+
44
+ comments {
45
+ int commentId PK
46
+ int feedbackId FK
47
+ text userId FK
48
+ text authorName
49
+ text authorEmail
50
+ text guestToken
51
+ text content
52
+ boolean isInternal
53
+ timestamp createdAt
54
+ timestamp updatedAt
55
+ }
56
+
57
+ status_history {
58
+ int historyId PK
59
+ int feedbackId FK
60
+ text oldStatus
61
+ text newStatus
62
+ text changedBy FK
63
+ timestamp changedAt
64
+ text comment
65
+ }
66
+
67
+ tags {
68
+ int tagId PK
69
+ text name
70
+ text slug
71
+ text color
72
+ text description
73
+ timestamp createdAt
74
+ }
75
+
76
+ feedback_tags {
77
+ int id PK
78
+ int feedbackId FK
79
+ int tagId FK
80
+ timestamp createdAt
81
+ }
82
+
83
+ ai_processing_results {
84
+ int id PK
85
+ int feedbackId FK
86
+ jsonb classification
87
+ jsonb tagSuggestions
88
+ jsonb duplicateCandidates
89
+ int processingTime
90
+ text status
91
+ text errorMessage
92
+ timestamp createdAt
93
+ timestamp updatedAt
94
+ }
95
+
96
+ duplicate_feedback {
97
+ int id PK
98
+ int originalFeedbackId FK
99
+ int duplicateFeedbackId FK
100
+ int similarity
101
+ text status
102
+ text confirmedBy FK
103
+ timestamp confirmedAt
104
+ timestamp createdAt
105
+ }
106
+
107
+ notifications {
108
+ int notificationId PK
109
+ text userId FK
110
+ int feedbackId FK
111
+ text type
112
+ jsonb data
113
+ text status
114
+ timestamp sentAt
115
+ text error
116
+ timestamp createdAt
117
+ }
118
+
119
+ user {
120
+ text id PK
121
+ text name
122
+ text email
123
+ }
124
+
125
+ feedback ||--o{ attachments : has
126
+ feedback ||--o{ votes : has
127
+ feedback ||--o{ comments : has
128
+ feedback ||--o{ status_history : status
129
+ feedback ||--o{ feedback_tags : tags
130
+ feedback ||--o{ ai_processing_results : ai
131
+ feedback ||--o{ duplicate_feedback : duplicates
132
+ feedback ||--o{ notifications : notifies
133
+
134
+ tags ||--o{ feedback_tags : maps
135
+ user ||--o{ votes : votes
136
+ user ||--o{ comments : comments
137
+ user ||--o{ status_history : changes
138
+ user ||--o{ notifications : receives
@@ -0,0 +1,281 @@
1
+ erDiagram
2
+ organizations {
3
+ text id PK
4
+ text name
5
+ text slug
6
+ text description
7
+ timestamp created_at
8
+ timestamp updated_at
9
+ }
10
+
11
+ organization_members {
12
+ text organization_id FK
13
+ text user_id FK
14
+ text role
15
+ timestamp created_at
16
+ }
17
+
18
+ invitations {
19
+ text id PK
20
+ text organization_id FK
21
+ text email
22
+ text role
23
+ text token
24
+ timestamp expires_at
25
+ timestamp accepted_at
26
+ timestamp created_at
27
+ }
28
+
29
+ organization_settings {
30
+ text organizationId PK FK
31
+ jsonb widgetConfig
32
+ jsonb portalConfig
33
+ text customDomain
34
+ timestamp createdAt
35
+ timestamp updatedAt
36
+ }
37
+
38
+ user {
39
+ text id PK
40
+ text name
41
+ text email
42
+ text role
43
+ boolean email_verified
44
+ text image
45
+ timestamp created_at
46
+ timestamp updated_at
47
+ }
48
+
49
+ user_profiles {
50
+ text user_id PK FK
51
+ text name
52
+ timestamp created_at
53
+ timestamp updated_at
54
+ }
55
+
56
+ session {
57
+ text id PK
58
+ timestamp expires_at
59
+ text token
60
+ text user_id FK
61
+ }
62
+
63
+ account {
64
+ text id PK
65
+ text user_id FK
66
+ text provider_id
67
+ text account_id
68
+ }
69
+
70
+ verification {
71
+ text id PK
72
+ text identifier
73
+ text value
74
+ timestamp expires_at
75
+ }
76
+
77
+ feedback {
78
+ int feedbackId PK
79
+ text title
80
+ text description
81
+ text type
82
+ text priority
83
+ text status
84
+ text organizationId
85
+ boolean submittedOnBehalf
86
+ text submittedBy FK
87
+ jsonb customerInfo
88
+ timestamp createdAt
89
+ timestamp updatedAt
90
+ timestamp deletedAt
91
+ boolean autoClassified
92
+ text processingStatus
93
+ timestamp processedAt
94
+ int githubIssueId
95
+ int githubIssueNumber
96
+ text githubIssueUrl
97
+ timestamp githubSyncedAt
98
+ text githubStatus
99
+ }
100
+
101
+ attachments {
102
+ int attachmentId PK
103
+ int feedbackId FK
104
+ text fileName
105
+ text filePath
106
+ int fileSize
107
+ text mimeType
108
+ timestamp createdAt
109
+ }
110
+
111
+ votes {
112
+ int voteId PK
113
+ int feedbackId FK
114
+ text visitorId
115
+ text userId FK
116
+ timestamp createdAt
117
+ }
118
+
119
+ comments {
120
+ int commentId PK
121
+ int feedbackId FK
122
+ text userId FK
123
+ text authorName
124
+ text authorEmail
125
+ text guestToken
126
+ text content
127
+ boolean isInternal
128
+ timestamp createdAt
129
+ timestamp updatedAt
130
+ }
131
+
132
+ status_history {
133
+ int historyId PK
134
+ int feedbackId FK
135
+ text oldStatus
136
+ text newStatus
137
+ text changedBy FK
138
+ timestamp changedAt
139
+ text comment
140
+ }
141
+
142
+ tags {
143
+ int tagId PK
144
+ text name
145
+ text slug
146
+ text color
147
+ text description
148
+ timestamp createdAt
149
+ }
150
+
151
+ feedback_tags {
152
+ int id PK
153
+ int feedbackId FK
154
+ int tagId FK
155
+ timestamp createdAt
156
+ }
157
+
158
+ ai_processing_results {
159
+ int id PK
160
+ int feedbackId FK
161
+ jsonb classification
162
+ jsonb tagSuggestions
163
+ jsonb duplicateCandidates
164
+ int processingTime
165
+ text status
166
+ text errorMessage
167
+ timestamp createdAt
168
+ timestamp updatedAt
169
+ }
170
+
171
+ duplicate_feedback {
172
+ int id PK
173
+ int originalFeedbackId FK
174
+ int duplicateFeedbackId FK
175
+ int similarity
176
+ text status
177
+ text confirmedBy FK
178
+ timestamp confirmedAt
179
+ timestamp createdAt
180
+ }
181
+
182
+ notifications {
183
+ int notificationId PK
184
+ text userId FK
185
+ int feedbackId FK
186
+ text type
187
+ jsonb data
188
+ text status
189
+ timestamp sentAt
190
+ text error
191
+ timestamp createdAt
192
+ }
193
+
194
+ notification_preferences {
195
+ text userId PK FK
196
+ boolean statusChange
197
+ boolean newComment
198
+ timestamp updatedAt
199
+ }
200
+
201
+ api_keys {
202
+ int keyId PK
203
+ text name
204
+ text hashedKey
205
+ text prefix
206
+ text organizationId FK
207
+ boolean disabled
208
+ timestamp lastUsed
209
+ timestamp createdAt
210
+ timestamp updatedAt
211
+ }
212
+
213
+ webhooks {
214
+ int webhookId PK
215
+ text organizationId FK
216
+ text name
217
+ text url
218
+ text secret
219
+ jsonb events
220
+ boolean enabled
221
+ timestamp createdAt
222
+ timestamp updatedAt
223
+ }
224
+
225
+ webhook_events {
226
+ int eventId PK
227
+ int webhookId FK
228
+ text eventType
229
+ jsonb payload
230
+ text status
231
+ int responseStatus
232
+ text responseBody
233
+ int retryCount
234
+ int maxRetries
235
+ timestamp nextRetryAt
236
+ timestamp deliveredAt
237
+ timestamp createdAt
238
+ timestamp updatedAt
239
+ }
240
+
241
+ github_integrations {
242
+ int id PK
243
+ text organizationId FK
244
+ text accessToken
245
+ text owner
246
+ text repo
247
+ jsonb labelMapping
248
+ jsonb statusMapping
249
+ boolean autoSync
250
+ text webhookSecret
251
+ timestamp createdAt
252
+ timestamp updatedAt
253
+ }
254
+
255
+ organizations ||--o{ organization_members : has
256
+ organizations ||--o{ invitations : has
257
+ organizations ||--|| organization_settings : config
258
+ organizations ||--o{ feedback : owns
259
+ organizations ||--o{ api_keys : owns
260
+ organizations ||--o{ webhooks : owns
261
+ organizations ||--o{ github_integrations : owns
262
+
263
+ user ||--o{ organization_members : member
264
+ user ||--|| user_profiles : profile
265
+ user ||--o{ session : sessions
266
+ user ||--o{ account : accounts
267
+ user ||--o{ notifications : receives
268
+ user ||--|| notification_preferences : prefs
269
+
270
+ feedback ||--o{ attachments : has
271
+ feedback ||--o{ votes : has
272
+ feedback ||--o{ comments : has
273
+ feedback ||--o{ status_history : status
274
+ feedback ||--o{ feedback_tags : tags
275
+ feedback ||--o{ ai_processing_results : ai
276
+ feedback ||--o{ duplicate_feedback : duplicates
277
+ feedback ||--o{ notifications : notifies
278
+
279
+ tags ||--o{ feedback_tags : maps
280
+
281
+ webhooks ||--o{ webhook_events : events