@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,259 @@
1
+ # Architecture Documentation
2
+
3
+ **Project:** Echo
4
+ **Type:** Web Application (Next.js + React + TypeScript)
5
+ **Generated:** 2025-12-31
6
+
7
+ ## Executive Summary
8
+
9
+ Echo 是一个基于 Next.js 16 和 React 19 的现代 Web 应用,使用 App Router 架构和 React Server Components。项目采用 TypeScript 严格模式,使用 Shadcn/ui 作为组件库,Tailwind CSS v4 进行样式管理。
10
+
11
+ ## Technology Stack
12
+
13
+ ### Core Framework
14
+
15
+ | 技术 | 版本 | 用途 |
16
+ |------|------|------|
17
+ | **Next.js** | 16.1.1 | React 框架(App Router)|
18
+ | **React** | 19.2.3 | UI 库(RSC enabled)|
19
+ | **TypeScript** | 5.x | 类型系统(strict mode)|
20
+
21
+ ### Styling
22
+
23
+ | 技术 | 版本 | 用途 |
24
+ |------|------|------|
25
+ | **Tailwind CSS** | 4.x | 实用优先的 CSS 框架 |
26
+ | **tw-animate-css** | 1.4.0 | 动画支持 |
27
+
28
+ ### Component Library
29
+
30
+ | 技术 | 版本 | 用途 |
31
+ |------|------|------|
32
+ | **Shadcn/ui** | 3.6.2 | 组件系统 |
33
+ | **Radix UI** | 1.4.3 | 无障碍基础组件 |
34
+ | **Base UI** | 1.0.0 | React 基础组件 |
35
+ | **Lucide React** | 0.562.0 | 图标库 |
36
+
37
+ ### Utilities
38
+
39
+ | 技术 | 用途 |
40
+ |------|------|
41
+ | **clsx** | 条件类名 |
42
+ | **tailwind-merge** | 合并 Tailwind 类名 |
43
+ | **class-variance-authority** | 组件变体管理 |
44
+
45
+ ## Architecture Pattern
46
+
47
+ ### Next.js App Router
48
+
49
+ 项目使用 Next.js 13+ 引入的 App Router 架构:
50
+
51
+ ```
52
+ app/
53
+ ├── layout.tsx # 根布局(持久 UI)
54
+ ├── page.tsx # 首页路由
55
+ └── globals.css # 全局样式
56
+ ```
57
+
58
+ **特点:**
59
+ - 基于文件系统的路由
60
+ - 支持嵌套布局
61
+ - React Server Components (RSC)
62
+ - 流式渲染
63
+ - 并行路由
64
+
65
+ ### React Server Components
66
+
67
+ | 特性 | 说明 |
68
+ |------|------|
69
+ | **默认服务器组件** | 减少客户端 JavaScript |
70
+ | **选择性客户端组件** | 使用 'use client' 指令 |
71
+ | **数据获取** | 在服务器组件中直接获取 |
72
+
73
+ ### Component Architecture
74
+
75
+ ```
76
+ components/
77
+ ├── ui/ # Shadcn/ui 基础组件(14 个)
78
+ │ ├── alert-dialog.tsx
79
+ │ ├── badge.tsx
80
+ │ ├── button.tsx
81
+ │ ├── card.tsx
82
+ │ ├── combobox.tsx
83
+ │ ├── dropdown-menu.tsx
84
+ │ ├── field.tsx
85
+ │ ├── input-group.tsx
86
+ │ ├── input.tsx
87
+ │ ├── label.tsx
88
+ │ ├── select.tsx
89
+ │ ├── separator.tsx
90
+ │ └── textarea.tsx
91
+ ├── component-example.tsx # 自定义组件
92
+ └── example.tsx
93
+ ```
94
+
95
+ ## Data Architecture
96
+
97
+ ### 当前状态
98
+
99
+ **无数据层实现** - 项目目前是纯前端应用,没有:
100
+
101
+ - ❌ 数据库连接
102
+ - ❌ ORM/数据模型
103
+ - ❌ API 集成
104
+ - ❌ 状态管理
105
+
106
+ ### 扩展点
107
+
108
+ 当需要添加数据功能时:
109
+
110
+ 1. **API 路由** - 在 `app/api/` 创建 RESTful 端点
111
+ 2. **数据获取** - 在 Server Components 中获取
112
+ 3. **状态管理** - 添加 React Context 或 Zustand
113
+ 4. **数据库** - 集成 Prisma + PostgreSQL
114
+
115
+ ## API Design
116
+
117
+ ### 当前状态
118
+
119
+ **无 API 实现** - 项目未定义 API 端点。
120
+
121
+ ### 推荐扩展
122
+
123
+ 在 `app/api/` 目录添加路由:
124
+
125
+ ```
126
+ app/api/
127
+ ├── auth/
128
+ │ └── route.ts # POST /api/auth
129
+ ├── feedback/
130
+ │ └── route.ts # POST /api/feedback
131
+ └── users/
132
+ └── route.ts # GET/POST /api/users
133
+ ```
134
+
135
+ ## Component Overview
136
+
137
+ ### Shadcn/ui Components
138
+
139
+ | 组件 | 用途 | 状态 |
140
+ |------|------|------|
141
+ | alert-dialog | 警告/确认对话框 | ✅ 已安装 |
142
+ | badge | 徽章/标签 | ✅ 已安装 |
143
+ | button | 按钮 | ✅ 已安装 |
144
+ | card | 卡片容器 | ✅ 已安装 |
145
+ | combobox | 组合输入框 | ✅ 已安装 |
146
+ | dropdown-menu | 下拉菜单 | ✅ 已安装 |
147
+ | field | 表单字段包装器 | ✅ 已安装 |
148
+ | input-group | 输入组 | ✅ 已安装 |
149
+ | input | 文本输入 | ✅ 已安装 |
150
+ | label | 表单标签 | ✅ 已安装 |
151
+ | select | 选择器 | ✅ 已安装 |
152
+ | separator | 分隔线 | ✅ 已安装 |
153
+ | textarea | 多行文本输入 | ✅ 已安装 |
154
+
155
+ ### Custom Components
156
+
157
+ | 组件 | 位置 | 状态 |
158
+ |------|------|------|
159
+ | ComponentExample | components/component-example.tsx | ✅ 示例 |
160
+ | Example | components/example.tsx | ✅ 示例 |
161
+
162
+ ## Source Tree
163
+
164
+ 完整源代码树请参阅:[Source Tree Analysis](./source-tree-analysis.md)
165
+
166
+ ## Development Workflow
167
+
168
+ 开发流程请参阅:[Development Guide](./development-guide.md)
169
+
170
+ ## Deployment Architecture
171
+
172
+ ### 当前配置
173
+
174
+ | 项目 | 状态 |
175
+ |------|------|
176
+ | **构建输出** | `.next/` 目录 |
177
+ | **启动命令** | `bun start` |
178
+ | **环境变量** | `.env.local` |
179
+ | **Docker** | ❌ 未配置 |
180
+ | **CI/CD** | ❌ 未配置 |
181
+
182
+ ### 推荐部署
183
+
184
+ - **Vercel** - Next.js 官方平台(零配置)
185
+ - **Netlify** - 支持 Next.js
186
+ - **自托管** - 使用 Docker 容器化
187
+
188
+ ## Security Considerations
189
+
190
+ ### 当前状态
191
+
192
+ | 安全措施 | 状态 |
193
+ |----------|------|
194
+ | **环境变量** | `NEXT_PUBLIC_*` 前缀 |
195
+ | **TypeScript** | Strict mode(类型安全)|
196
+ | **ESLint** | 已配置 |
197
+ | **认证/授权** | ❌ 未实现 |
198
+ | **HTTPS** | 部署平台处理 |
199
+
200
+ ### 推荐添加
201
+
202
+ 1. **认证** - NextAuth.js 或 Clerk
203
+ 2. **API 安全** - CSRF 保护、速率限制
204
+ 3. **输入验证** - Zod schema 验证
205
+ 4. **CORS** - API 路由配置
206
+
207
+ ## Performance Considerations
208
+
209
+ ### 优化措施
210
+
211
+ | 优化 | 说明 |
212
+ |------|------|
213
+ | **Server Components** | 减少客户端 JavaScript |
214
+ | **字体优化** | next/font (Geist, Inter) |
215
+ | **图片优化** | next/image(未使用)|
216
+ | **代码分割** | App Router 自动处理 |
217
+
218
+ ### 推荐添加
219
+
220
+ 1. **图片优化** - 使用 `next/image`
221
+ 2. **动态导入** - `next/dynamic`
222
+ 3. **缓存策略** - Next.js 缓存配置
223
+ 4. **性能监控** - Vercel Analytics
224
+
225
+ ## Testing Strategy
226
+
227
+ ### 当前状态
228
+
229
+ ❌ **无测试配置**
230
+
231
+ ### 推荐添加
232
+
233
+ 1. **单元测试** - Vitest + Testing Library
234
+ 2. **组件测试** - Playwright 或 Cypress
235
+ 3. **E2E 测试** - Playwright
236
+ 4. **类型检查** - TypeScript + tsc
237
+
238
+ ## Future Enhancements
239
+
240
+ ### 短期(1-2 周)
241
+
242
+ 1. 添加测试套件
243
+ 2. 实现 API 路由
244
+ 3. 添加状态管理
245
+ 4. 配置 CI/CD
246
+
247
+ ### 中期(1-2 月)
248
+
249
+ 1. 数据库集成
250
+ 2. 用户认证
251
+ 3. 错误处理
252
+ 4. 性能监控
253
+
254
+ ### 长期(3+ 月)
255
+
256
+ 1. 微服务架构(如需要)
257
+ 2. 国际化 (i18n)
258
+ 3. PWA 支持
259
+ 4. 离线功能
@@ -0,0 +1,261 @@
1
+ # Component Inventory
2
+
3
+ **Project:** Echo
4
+ **Generated:** 2025-12-31
5
+
6
+ ## Overview
7
+
8
+ 项目使用 **Shadcn/ui 3.6.2** 组件库,基于 Radix UI primitives 和 Base UI 构建。
9
+
10
+ ## Design System Configuration
11
+
12
+ | 配置 | 值 |
13
+ |------|-----|
14
+ | **样式变体** | radix-maia |
15
+ | **基础颜色** | neutral |
16
+ | **图标库** | lucide-react |
17
+ | **RSC** | enabled |
18
+ | **CSS 变量** | enabled |
19
+
20
+ ## Shadcn/ui Components (14 个)
21
+
22
+ ### Form Components
23
+
24
+ | 组件 | 文件 | 描述 |
25
+ |------|------|------|
26
+ | **Input** | `input.tsx` | 单行文本输入 |
27
+ | **Textarea** | `textarea.tsx` | 多行文本输入 |
28
+ | **Label** | `label.tsx` | 表单标签 |
29
+ | **Field** | `field.tsx` | 表单字段包装器 |
30
+ | **Input Group** | `input-group.tsx` | 输入组容器 |
31
+ | **Select** | `select.tsx` | 下拉选择器 |
32
+ | **Combobox** | `combobox.tsx` | 组合输入/搜索 |
33
+
34
+ ### Action Components
35
+
36
+ | 组件 | 文件 | 描述 |
37
+ |------|------|------|
38
+ | **Button** | `button.tsx` | 按钮(多种变体)|
39
+ | **Dropdown Menu** | `dropdown-menu.tsx` | 下拉菜单 |
40
+ | **Alert Dialog** | `alert-dialog.tsx` | 警告/确认对话框 |
41
+
42
+ ### Layout Components
43
+
44
+ | 组件 | 文件 | 描述 |
45
+ |------|------|------|
46
+ | **Card** | `card.tsx` | 卡片容器 |
47
+ | **Separator** | `separator.tsx` | 分隔线 |
48
+
49
+ ### Display Components
50
+
51
+ | 组件 | 文件 | 描述 |
52
+ |------|------|------|
53
+ | **Badge** | `badge.tsx` | 徽章/标签 |
54
+
55
+ ## Component Usage
56
+
57
+ ### Button
58
+
59
+ ```tsx
60
+ import { Button } from "@/components/ui/button";
61
+
62
+ <Button variant="default">Click me</Button>
63
+ <Button variant="outline">Outline</Button>
64
+ <Button variant="ghost">Ghost</Button>
65
+ ```
66
+
67
+ ### Card
68
+
69
+ ```tsx
70
+ import { Card } from "@/components/ui/card";
71
+
72
+ <Card>
73
+ <CardHeader>
74
+ <CardTitle>Title</CardTitle>
75
+ </CardHeader>
76
+ <CardContent>Content</CardContent>
77
+ </Card>
78
+ ```
79
+
80
+ ### Input
81
+
82
+ ```tsx
83
+ import { Input } from "@/components/ui/input";
84
+
85
+ <Input type="text" placeholder="Enter text..." />
86
+ ```
87
+
88
+ ## Custom Components
89
+
90
+ | 组件 | 文件 | 描述 | 状态 |
91
+ |------|------|------|------|
92
+ | **ComponentExample** | `component-example.tsx` | 示例组件 | ✅ |
93
+ | **Example** | `example.tsx` | 简单示例 | ✅ |
94
+
95
+ ## Reusable Patterns
96
+
97
+ ### cn() Utility
98
+
99
+ 合并 Tailwind 类名:
100
+
101
+ ```tsx
102
+ import { cn } from "@/lib/utils";
103
+
104
+ className={cn(
105
+ "base-class",
106
+ condition && "conditional-class",
107
+ "another-class"
108
+ )}
109
+ ```
110
+
111
+ ### Component Variants
112
+
113
+ 使用 `class-variance-authority` 管理变体:
114
+
115
+ ```tsx
116
+ const buttonVariants = cva(
117
+ "base-classes",
118
+ {
119
+ variants: {
120
+ variant: {
121
+ default: "default-classes",
122
+ outline: "outline-classes",
123
+ },
124
+ },
125
+ }
126
+ );
127
+ ```
128
+
129
+ ## Component Organization
130
+
131
+ ```
132
+ components/
133
+ ├── ui/ # Shadcn/ui 基础组件(不要直接修改)
134
+ │ ├── alert-dialog.tsx
135
+ │ ├── badge.tsx
136
+ │ ├── button.tsx
137
+ │ ├── card.tsx
138
+ │ ├── combobox.tsx
139
+ │ ├── dropdown-menu.tsx
140
+ │ ├── field.tsx
141
+ │ ├── input-group.tsx
142
+ │ ├── input.tsx
143
+ │ ├── label.tsx
144
+ │ ├── select.tsx
145
+ │ ├── separator.tsx
146
+ │ └── textarea.tsx
147
+ ├── component-example.tsx # 自定义组件
148
+ └── example.tsx
149
+ ```
150
+
151
+ ## Adding New Components
152
+
153
+ ### Option 1: Add Shadcn/ui Component
154
+
155
+ 使用 Shadcn CLI 添加新组件:
156
+
157
+ ```bash
158
+ npx shadcn@latest add [component-name]
159
+ ```
160
+
161
+ 例如:
162
+ ```bash
163
+ npx shadcn@latest add dialog
164
+ npx shadcn@latest add tooltip
165
+ npx shadcn@latest add switch
166
+ ```
167
+
168
+ ### Option 2: Create Custom Component
169
+
170
+ 1. 在 `components/` 创建新文件
171
+ 2. 使用 Shadcn/ui 组件作为基础
172
+ 3. 应用项目样式变体
173
+
174
+ ```tsx
175
+ // components/my-feature.tsx
176
+ import { Button } from "@/components/ui/button";
177
+ import { Card } from "@/components/ui/card";
178
+
179
+ export function MyFeature() {
180
+ return (
181
+ <Card>
182
+ <CardHeader>
183
+ <CardTitle>My Feature</CardTitle>
184
+ </CardHeader>
185
+ <CardContent>
186
+ <Button>Action</Button>
187
+ </CardContent>
188
+ </Card>
189
+ );
190
+ }
191
+ ```
192
+
193
+ ## Styling Conventions
194
+
195
+ ### Tailwind Integration
196
+
197
+ 所有组件使用 Tailwind CSS 实用类:
198
+
199
+ ```tsx
200
+ className="flex items-center justify-between p-4 rounded-lg"
201
+ ```
202
+
203
+ ### Theme Variables
204
+
205
+ 使用 CSS 自定义属性:
206
+
207
+ ```tsx
208
+ className="bg-primary text-primary-foreground"
209
+ ```
210
+
211
+ 可用变量:
212
+ - `background`, `foreground`
213
+ - `primary`, `primary-foreground`
214
+ - `secondary`, `secondary-foreground`
215
+ - `accent`, `accent-foreground`
216
+ - `muted`, `muted-foreground`
217
+ - `card`, `card-foreground`
218
+ - `popover`, `popover-foreground`
219
+ - `border`, `input`, `ring`
220
+
221
+ ## Icon Usage
222
+
223
+ 使用 Lucide React 图标:
224
+
225
+ ```tsx
226
+ import { ChevronLeft, Search, User } from "lucide-react";
227
+
228
+ <ChevronLeft className="h-4 w-4" />
229
+ <Search className="h-5 w-5" />
230
+ <User className="h-6 w-6" />
231
+ ```
232
+
233
+ ## Component Best Practices
234
+
235
+ 1. **优先使用 Shadcn/ui 组件** - 避免重复造轮
236
+ 2. **直接修改 ui/ 组件** - 项目采用直接修改方式,不是重新安装
237
+ 3. **使用 cn() 合并类名** - 保持类名可预测
238
+ 4. **遵循命名约定** - PascalCase 用于组件
239
+ 5. **保持组件小而专注** - 单一职责原则
240
+
241
+ ## Missing Components
242
+
243
+ 以下常用组件未安装,可以根据需要添加:
244
+
245
+ - dialog(对话框)
246
+ - tooltip(工具提示)
247
+ - toast(通知)
248
+ - switch(开关)
249
+ - checkbox(复选框)
250
+ - radio(单选框)
251
+ - tabs(选项卡)
252
+ - table(表格)
253
+ - avatar(头像)
254
+ - progress(进度条)
255
+ - slider(滑块)
256
+ - calendar(日历)
257
+
258
+ 要添加这些组件,运行:
259
+ ```bash
260
+ npx shadcn@latest add [component-name]
261
+ ```
@@ -0,0 +1,76 @@
1
+ # Database Migration Guide
2
+
3
+ ## Generating Migrations
4
+
5
+ After changing the schema in `lib/db/schema/`, run:
6
+
7
+ ```bash
8
+ bun run db:generate
9
+ ```
10
+
11
+ This creates a new migration in `lib/db/migrations/`.
12
+
13
+ ## Applying Migrations
14
+
15
+ **Development:**
16
+
17
+ ```bash
18
+ bun run db:push
19
+ ```
20
+
21
+ `db:push` applies schema changes directly and is useful for local iteration.
22
+
23
+ **Production:**
24
+
25
+ ```bash
26
+ bun run db:migrate
27
+ ```
28
+
29
+ `db:migrate` applies generated migration files in order.
30
+
31
+ ## Checking Schema
32
+
33
+ ```bash
34
+ bun run db:check
35
+ ```
36
+
37
+ Verifies the database schema matches your Drizzle schema.
38
+
39
+ ## Database Studio
40
+
41
+ ```bash
42
+ bun run db:studio
43
+ ```
44
+
45
+ Opens Drizzle Studio (default: http://localhost:4983).
46
+
47
+ ## Rollback
48
+
49
+ Drizzle does not generate down migrations automatically. To rollback:
50
+
51
+ 1. Create a rollback SQL file alongside the migration:
52
+ `lib/db/migrations/<migration-name>-rollback.sql`
53
+ 2. Run the rollback script:
54
+
55
+ ```bash
56
+ bun run scripts/rollback.ts 1
57
+ ```
58
+
59
+ ## Pre-deploy Migration
60
+
61
+ Use the pre-deploy script in CI/CD or release automation to verify connectivity,
62
+ optionally run backups, apply migrations, and validate the resulting schema:
63
+
64
+ ```bash
65
+ bun run scripts/pre-deploy.ts
66
+ ```
67
+
68
+ Set `DB_BACKUP_BEFORE_MIGRATE=true` to enable backup integration (Story 8.5).
69
+
70
+ ## Best Practices
71
+
72
+ 1. Test migrations on a production-like copy first
73
+ 2. Keep migrations small and reversible when possible
74
+ 3. Prefer additive changes (`ADD COLUMN` with defaults) to avoid data loss
75
+ 4. Avoid long-running migrations during peak traffic
76
+ 5. Document any manual steps in the PR description