@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.
- package/.changeset/README.md +21 -0
- package/.changeset/config.json +11 -0
- package/.changeset/cozy-ghosts-care.md +5 -0
- package/.changeset/sharp-lines-stand.md +5 -0
- package/.changeset/sour-doodles-eat.md +5 -0
- package/.changeset/tender-moose-shop.md +5 -0
- package/.github/pull_request_template.md +13 -0
- package/.github/workflows/ci.yml +41 -0
- package/.github/workflows/publish.yml +44 -0
- package/.github/workflows/release.yml +73 -0
- package/AGENTS.md +92 -0
- package/CHANGELOG.md +13 -0
- package/Dockerfile +57 -0
- package/LICENSE +661 -0
- package/Makefile +77 -0
- package/README.md +198 -0
- package/app/(auth)/login/page.tsx +53 -0
- package/app/(auth)/register/page.tsx +48 -0
- package/app/(auth)/sign-in/page.tsx +22 -0
- package/app/(dashboard)/admin/feedback/[id]/edit/page.tsx +103 -0
- package/app/(dashboard)/admin/feedback/[id]/page.tsx +154 -0
- package/app/(dashboard)/admin/feedback/new/page.tsx +91 -0
- package/app/(dashboard)/admin/feedback/page.tsx +81 -0
- package/app/(dashboard)/admin/layout.tsx +48 -0
- package/app/(dashboard)/analytics/portal/page.tsx +30 -0
- package/app/(dashboard)/dashboard/page.tsx +133 -0
- package/app/(dashboard)/layout.tsx +69 -0
- package/app/(dashboard)/no-access/page.tsx +45 -0
- package/app/(dashboard)/settings/access/page.tsx +56 -0
- package/app/(dashboard)/settings/api-keys/page.tsx +55 -0
- package/app/(dashboard)/settings/appearance/page.tsx +40 -0
- package/app/(dashboard)/settings/branding/page.tsx +62 -0
- package/app/(dashboard)/settings/changelog/page.tsx +51 -0
- package/app/(dashboard)/settings/danger-zone/page.tsx +92 -0
- package/app/(dashboard)/settings/feedback/page.tsx +63 -0
- package/app/(dashboard)/settings/integrations/page.tsx +94 -0
- package/app/(dashboard)/settings/layout.tsx +43 -0
- package/app/(dashboard)/settings/modules/page.tsx +54 -0
- package/app/(dashboard)/settings/notifications/page.tsx +48 -0
- package/app/(dashboard)/settings/organization/page.tsx +104 -0
- package/app/(dashboard)/settings/organization/portal/access/page.tsx +22 -0
- package/app/(dashboard)/settings/organization/portal/experience/page.tsx +22 -0
- package/app/(dashboard)/settings/organization/portal/growth/page.tsx +22 -0
- package/app/(dashboard)/settings/organization/portal/layout.tsx +24 -0
- package/app/(dashboard)/settings/organization/portal/page.tsx +22 -0
- package/app/(dashboard)/settings/organizations/[orgId]/members/page.tsx +69 -0
- package/app/(dashboard)/settings/organizations/new/page.tsx +36 -0
- package/app/(dashboard)/settings/page.tsx +22 -0
- package/app/(dashboard)/settings/portal-access/page.tsx +53 -0
- package/app/(dashboard)/settings/portal-branding/page.tsx +59 -0
- package/app/(dashboard)/settings/portal-growth/page.tsx +57 -0
- package/app/(dashboard)/settings/portal-modules/page.tsx +49 -0
- package/app/(dashboard)/settings/portal-resources/page.tsx +66 -0
- package/app/(dashboard)/settings/profile/page.tsx +48 -0
- package/app/(dashboard)/settings/widgets/page.tsx +63 -0
- package/app/(public)/[organizationSlug]/changelog/page.tsx +109 -0
- package/app/(public)/[organizationSlug]/feedback/[id]/page.tsx +146 -0
- package/app/(public)/[organizationSlug]/page.tsx +160 -0
- package/app/(public)/[organizationSlug]/roadmap/page.tsx +142 -0
- package/app/(public)/docs/page.tsx +48 -0
- package/app/(public)/feedback/[id]/not-found.tsx +33 -0
- package/app/(public)/feedback/[id]/page.tsx +102 -0
- package/app/(public)/invite/[token]/page.tsx +121 -0
- package/app/(public)/page.tsx +22 -0
- package/app/(public)/widget/[organizationId]/page.tsx +122 -0
- package/app/api/_utils.ts +29 -0
- package/app/api/admin/backup/route.ts +72 -0
- package/app/api/api-keys/[keyId]/route.ts +92 -0
- package/app/api/api-keys/route.ts +116 -0
- package/app/api/auth/[...all]/route.ts +21 -0
- package/app/api/auth/clear-session/route.ts +43 -0
- package/app/api/auth/register/handler.ts +176 -0
- package/app/api/auth/register/route.ts +26 -0
- package/app/api/docs/route.ts +28 -0
- package/app/api/feedback/[id]/comments/[commentId]/route.ts +105 -0
- package/app/api/feedback/[id]/comments/route.ts +421 -0
- package/app/api/feedback/[id]/duplicates/route.ts +285 -0
- package/app/api/feedback/[id]/handler.ts +91 -0
- package/app/api/feedback/[id]/processing-status/route.ts +199 -0
- package/app/api/feedback/[id]/reclassify/route.ts +145 -0
- package/app/api/feedback/[id]/route.ts +511 -0
- package/app/api/feedback/[id]/suggest-tags/route.ts +227 -0
- package/app/api/feedback/[id]/sync-github/route.ts +52 -0
- package/app/api/feedback/[id]/vote/route.ts +431 -0
- package/app/api/feedback/bulk/route.ts +212 -0
- package/app/api/feedback/handler.ts +138 -0
- package/app/api/feedback/route.ts +298 -0
- package/app/api/feedback/similar/route.ts +100 -0
- package/app/api/health/route.test.ts +64 -0
- package/app/api/health/route.ts +92 -0
- package/app/api/identify/jwt/route.ts +29 -0
- package/app/api/integrations/github/route.ts +196 -0
- package/app/api/internal/domain-lookup/route.ts +67 -0
- package/app/api/invitations/accept/handler.ts +101 -0
- package/app/api/invitations/accept/route.ts +29 -0
- package/app/api/notifications/preferences/route.ts +109 -0
- package/app/api/organizations/[orgId]/handler.ts +123 -0
- package/app/api/organizations/[orgId]/invitations/handler.ts +121 -0
- package/app/api/organizations/[orgId]/invitations/route.ts +29 -0
- package/app/api/organizations/[orgId]/members/[memberId]/handler.ts +208 -0
- package/app/api/organizations/[orgId]/members/[memberId]/route.ts +30 -0
- package/app/api/organizations/[orgId]/members/handler.ts +77 -0
- package/app/api/organizations/[orgId]/members/route.ts +29 -0
- package/app/api/organizations/[orgId]/route.ts +30 -0
- package/app/api/organizations/handler.ts +97 -0
- package/app/api/organizations/route.ts +29 -0
- package/app/api/tags/sync/route.ts +88 -0
- package/app/api/upload/handler.ts +79 -0
- package/app/api/upload/route.ts +37 -0
- package/app/api/v1/feedback/[id]/route.ts +276 -0
- package/app/api/v1/feedback/route.ts +250 -0
- package/app/api/v1/spec/route.ts +356 -0
- package/app/api/webhooks/[webhookId]/route.ts +213 -0
- package/app/api/webhooks/github/route.ts +158 -0
- package/app/api/webhooks/route.ts +143 -0
- package/app/favicon.ico +0 -0
- package/app/globals.css +139 -0
- package/app/health/route.ts +108 -0
- package/app/layout.tsx +60 -0
- package/bun.lock +2503 -0
- package/components/api/rate-limit-info.tsx +86 -0
- package/components/api-keys/api-key-manager.tsx +262 -0
- package/components/auth/login-form.tsx +207 -0
- package/components/auth/register-form.tsx +230 -0
- package/components/comment/comment-form.tsx +111 -0
- package/components/comment/internal-notes.tsx +219 -0
- package/components/comment/public-comments.tsx +387 -0
- package/components/component-example-client-only.tsx +29 -0
- package/components/component-example.tsx +519 -0
- package/components/dashboard/index.ts +22 -0
- package/components/dashboard/organization-switcher.tsx +96 -0
- package/components/dashboard/quick-actions.tsx +57 -0
- package/components/dashboard/recent-feedback-list.tsx +152 -0
- package/components/dashboard/stats-cards.tsx +88 -0
- package/components/dashboard/status-chart.tsx +106 -0
- package/components/example.tsx +70 -0
- package/components/feedback/attachment-list.tsx +103 -0
- package/components/feedback/auto-classification-badge.tsx +92 -0
- package/components/feedback/classification-override.tsx +64 -0
- package/components/feedback/duplicate-suggestions-inline.tsx +158 -0
- package/components/feedback/duplicate-suggestions.tsx +188 -0
- package/components/feedback/embedded-feedback-form.tsx +439 -0
- package/components/feedback/feedback-actions.tsx +160 -0
- package/components/feedback/feedback-bulk-actions.tsx +184 -0
- package/components/feedback/feedback-detail-view.tsx +321 -0
- package/components/feedback/feedback-detail.tsx +305 -0
- package/components/feedback/feedback-edit-form.tsx +131 -0
- package/components/feedback/feedback-filters.tsx +222 -0
- package/components/feedback/feedback-list-controls.tsx +433 -0
- package/components/feedback/feedback-list-item.tsx +298 -0
- package/components/feedback/feedback-list-skeleton.tsx +49 -0
- package/components/feedback/feedback-list.tsx +523 -0
- package/components/feedback/feedback-sorter.tsx +117 -0
- package/components/feedback/feedback-stats.tsx +124 -0
- package/components/feedback/file-upload.tsx +289 -0
- package/components/feedback/processing-status.tsx +161 -0
- package/components/feedback/status-history.tsx +134 -0
- package/components/feedback/status-selector.tsx +153 -0
- package/components/feedback/submit-on-behalf-form.tsx +403 -0
- package/components/feedback/tag-suggestions.tsx +212 -0
- package/components/feedback/vote-button.tsx +113 -0
- package/components/feedback/vote-list.tsx +108 -0
- package/components/integrations/github-config.tsx +200 -0
- package/components/landing/hero.tsx +150 -0
- package/components/layout/dashboard-layout.tsx +59 -0
- package/components/layout/index.ts +20 -0
- package/components/layout/language-switcher.tsx +129 -0
- package/components/layout/mobile-sidebar.tsx +66 -0
- package/components/layout/sidebar.tsx +279 -0
- package/components/portal/changelog-entry.tsx +132 -0
- package/components/portal/changelog-list.tsx +85 -0
- package/components/portal/contributor-badge.tsx +29 -0
- package/components/portal/contributors-sidebar.tsx +98 -0
- package/components/portal/create-post-dialog.tsx +247 -0
- package/components/portal/feedback-board.tsx +205 -0
- package/components/portal/feedback-post-card.tsx +198 -0
- package/components/portal/help-center.tsx +169 -0
- package/components/portal/leaderboard.tsx +29 -0
- package/components/portal/portal-header.tsx +153 -0
- package/components/portal/portal-layout.tsx +62 -0
- package/components/portal/portal-modules-panel.tsx +118 -0
- package/components/portal/portal-nav.tsx +59 -0
- package/components/portal/portal-overview.tsx +174 -0
- package/components/portal/portal-settings-nav.tsx +62 -0
- package/components/portal/portal-settings-shell.tsx +71 -0
- package/components/portal/portal-shell.tsx +62 -0
- package/components/portal/portal-tab-nav.tsx +77 -0
- package/components/portal/project-switcher.tsx +20 -0
- package/components/portal/roadmap-board.tsx +82 -0
- package/components/portal/roadmap-card.tsx +76 -0
- package/components/portal/roadmap-column.tsx +78 -0
- package/components/portal/settings-forms/access-form.tsx +194 -0
- package/components/portal/settings-forms/copy-form.tsx +95 -0
- package/components/portal/settings-forms/index.ts +23 -0
- package/components/portal/settings-forms/languages-form.tsx +223 -0
- package/components/portal/settings-forms/seo-form.tsx +156 -0
- package/components/portal/settings-forms/sharing-form.tsx +155 -0
- package/components/portal/settings-forms/theme-form.tsx +104 -0
- package/components/settings/api-keys-list.tsx +167 -0
- package/components/settings/appearance-form.tsx +71 -0
- package/components/settings/index.ts +25 -0
- package/components/settings/invite-member-form.tsx +119 -0
- package/components/settings/notification-preferences.tsx +174 -0
- package/components/settings/organization-form.tsx +165 -0
- package/components/settings/organization-members-list.tsx +197 -0
- package/components/settings/profile-form.tsx +124 -0
- package/components/settings/role-selector.tsx +57 -0
- package/components/settings/settings-sidebar.tsx +115 -0
- package/components/shared/pagination.tsx +215 -0
- package/components/ui/alert-dialog.tsx +201 -0
- package/components/ui/alert.tsx +75 -0
- package/components/ui/avatar.tsx +126 -0
- package/components/ui/badge.tsx +62 -0
- package/components/ui/button.tsx +77 -0
- package/components/ui/card.tsx +111 -0
- package/components/ui/combobox.tsx +311 -0
- package/components/ui/dialog.tsx +158 -0
- package/components/ui/dropdown-menu.tsx +272 -0
- package/components/ui/field.tsx +256 -0
- package/components/ui/input-group.tsx +164 -0
- package/components/ui/input.tsx +36 -0
- package/components/ui/label.tsx +41 -0
- package/components/ui/pagination.tsx +142 -0
- package/components/ui/select.tsx +202 -0
- package/components/ui/separator.tsx +45 -0
- package/components/ui/sheet.tsx +151 -0
- package/components/ui/skeleton.tsx +32 -0
- package/components/ui/switch.tsx +49 -0
- package/components/ui/table.tsx +118 -0
- package/components/ui/tabs.tsx +107 -0
- package/components/ui/textarea.tsx +35 -0
- package/components/ui/tooltip.tsx +78 -0
- package/components/widget/widget-form.tsx +439 -0
- package/components.json +24 -0
- package/db/init/01-init.sql +13 -0
- package/docker-compose.dev.yml +26 -0
- package/docker-compose.yml +98 -0
- package/docs/architecture.md +259 -0
- package/docs/component-inventory.md +261 -0
- package/docs/database-migrations.md +76 -0
- package/docs/development-guide.md +209 -0
- package/docs/e2e-user-flows.csv +31 -0
- package/docs/er-diagram-feedback.mmd +138 -0
- package/docs/er-diagram.mmd +281 -0
- package/docs/i18n-check-report.md +296 -0
- package/docs/index.md +214 -0
- package/docs/logic-chain.md +94 -0
- package/docs/plans/2026-01-02-database-migration-scripts.md +496 -0
- package/docs/plans/2026-01-02-user-login-design.md +37 -0
- package/docs/plans/2026-01-02-user-login.md +437 -0
- package/docs/plans/2026-01-02-user-registration-design.md +47 -0
- package/docs/plans/2026-01-02-user-registration.md +628 -0
- package/docs/plans/2026-01-03-roles-permissions-design.md +20 -0
- package/docs/plans/2026-01-03-roles-permissions.md +266 -0
- package/docs/plans/2026-01-05-authentication-middleware.md +207 -0
- package/docs/plans/2026-01-05-member-removal.md +186 -0
- package/docs/plans/2026-01-05-organization-creation.md +374 -0
- package/docs/plans/2026-01-05-rbac-middleware.md +112 -0
- package/docs/plans/2026-01-05-role-configuration.md +441 -0
- package/docs/plans/2026-01-06-file-upload-support.md +804 -0
- package/docs/plans/2026-01-06-permission-check-hook.md +155 -0
- package/docs/plans/2026-01-06-resource-ownership-check.md +231 -0
- package/docs/plans/2026-01-07-feedback-tracking-link.md +459 -0
- package/docs/plans/2026-01-09-logout-redirect-design.md +52 -0
- package/docs/plans/2026-01-09-phase2-3-plan.md +654 -0
- package/docs/plans/2026-01-09-portal-execution-plan.md +408 -0
- package/docs/plans/2026-01-09-project-delete-feature-design.md +163 -0
- package/docs/plans/2026-01-09-project-delete-implementation.md +451 -0
- package/docs/plans/2026-01-09-project-edit-delete-design.md +52 -0
- package/docs/plans/2026-01-09-settings-center-design.md +114 -0
- package/docs/plans/2026-01-09-settings-center.md +948 -0
- package/docs/plans/2026-01-10-organization-only-design.md +66 -0
- package/docs/plans/2026-01-10-organization-only-implementation.md +433 -0
- package/docs/plans/2026-01-10-portal-settings-restructure-plan.md +18 -0
- package/docs/plans/2026-01-10-project-settings-tabs-design-implementation.md +296 -0
- package/docs/plans/2026-01-14-e2e-playwright-feedback.md +173 -0
- package/docs/plans/2026-01-15-feedback-management-org-context-design.md +82 -0
- package/docs/plans/2026-01-15-feedback-management-org-context-implementation-plan.md +521 -0
- package/docs/plans/2026-01-16-admin-feedback-filters-design.md +75 -0
- package/docs/plans/2026-01-16-admin-feedback-filters-implementation.md +293 -0
- package/docs/plans/2026-01-16-admin-feedback-route-consolidation.md +180 -0
- package/docs/plans/2026-01-16-e2e-test-fixes.md +158 -0
- package/docs/plans/2026-01-17-admin-feedback-filters.md +214 -0
- package/docs/plans/2026-01-17-admin-feedback-improvements.md +453 -0
- package/docs/plans/2026-01-18-changesets-design.md +40 -0
- package/docs/product_changes.md +37 -0
- package/docs/project-overview.md +159 -0
- package/docs/project-scan-report.json +104 -0
- package/docs/route-role-visibility.md +51 -0
- package/docs/source-tree-analysis.md +150 -0
- package/docs/testing/delete-project-manual-tests.md +18 -0
- package/docs/user-story-tracking.md +191 -0
- package/drizzle.config.ts +32 -0
- package/eslint.config.mjs +19 -0
- package/hooks/use-permissions.ts +56 -0
- package/i18n/config.ts +45 -0
- package/i18n/request.ts +28 -0
- package/i18n/resolve-locale.ts +38 -0
- package/lib/api/errors.ts +62 -0
- package/lib/auth/cli-config.ts +35 -0
- package/lib/auth/client.ts +20 -0
- package/lib/auth/config.ts +55 -0
- package/lib/auth/jwt-identity.ts +21 -0
- package/lib/auth/org-context.ts +71 -0
- package/lib/auth/organization.ts +107 -0
- package/lib/auth/permissions.ts +87 -0
- package/lib/auth/session.ts +23 -0
- package/lib/config/rate-limits.ts +64 -0
- package/lib/dashboard/get-dashboard-stats.ts +136 -0
- package/lib/db/index.ts +41 -0
- package/lib/db/migrate.test.ts +49 -0
- package/lib/db/migrate.ts +62 -0
- package/lib/db/migrations/.gitkeep +0 -0
- package/lib/db/migrations/0000_cynical_gladiator.sql +53 -0
- package/lib/db/migrations/0001_wandering_sunfire.sql +27 -0
- package/lib/db/migrations/0002_shallow_speedball.sql +1 -0
- package/lib/db/migrations/0003_add_org_description.sql +1 -0
- package/lib/db/migrations/0003_boring_wild_pack.sql +13 -0
- package/lib/db/migrations/0004_windy_tyrannus.sql +27 -0
- package/lib/db/migrations/0005_perpetual_doorman.sql +5 -0
- package/lib/db/migrations/0006_aberrant_captain_midlands.sql +13 -0
- package/lib/db/migrations/0007_clever_captain_cross.sql +14 -0
- package/lib/db/migrations/0008_sparkling_pandemic.sql +2 -0
- package/lib/db/migrations/0009_happy_black_tom.sql +29 -0
- package/lib/db/migrations/0010_kind_junta.sql +8 -0
- package/lib/db/migrations/0011_mute_squadron_supreme.sql +25 -0
- package/lib/db/migrations/0012_giant_power_man.sql +24 -0
- package/lib/db/migrations/0013_damp_titanium_man.sql +17 -0
- package/lib/db/migrations/0014_blue_alice.sql +18 -0
- package/lib/db/migrations/0015_webhook_tables.sql +41 -0
- package/lib/db/migrations/0016_github_integration.sql +30 -0
- package/lib/db/migrations/0016_overjoyed_ghost_rider.sql +22 -0
- package/lib/db/migrations/0017_slimy_inhumans.sql +6 -0
- package/lib/db/migrations/0018_same_spitfire.sql +1 -0
- package/lib/db/migrations/0019_jittery_loners.sql +16 -0
- package/lib/db/migrations/0019_remove_projects_add_org_settings.sql +14 -0
- package/lib/db/migrations/meta/0000_snapshot.json +374 -0
- package/lib/db/migrations/meta/0001_snapshot.json +553 -0
- package/lib/db/migrations/meta/0002_snapshot.json +560 -0
- package/lib/db/migrations/meta/0003_snapshot.json +650 -0
- package/lib/db/migrations/meta/0004_snapshot.json +852 -0
- package/lib/db/migrations/meta/0005_snapshot.json +900 -0
- package/lib/db/migrations/meta/0006_snapshot.json +1011 -0
- package/lib/db/migrations/meta/0007_snapshot.json +1125 -0
- package/lib/db/migrations/meta/0008_snapshot.json +1146 -0
- package/lib/db/migrations/meta/0009_snapshot.json +1386 -0
- package/lib/db/migrations/meta/0010_snapshot.json +1419 -0
- package/lib/db/migrations/meta/0011_snapshot.json +1615 -0
- package/lib/db/migrations/meta/0012_snapshot.json +1805 -0
- package/lib/db/migrations/meta/0013_snapshot.json +1948 -0
- package/lib/db/migrations/meta/0014_snapshot.json +2082 -0
- package/lib/db/migrations/meta/0015_snapshot.json +2476 -0
- package/lib/db/migrations/meta/0016_snapshot.json +2633 -0
- package/lib/db/migrations/meta/0017_snapshot.json +2680 -0
- package/lib/db/migrations/meta/0018_snapshot.json +2686 -0
- package/lib/db/migrations/meta/0019_snapshot.json +2741 -0
- package/lib/db/migrations/meta/_journal.json +146 -0
- package/lib/db/schema/ai-processing.ts +90 -0
- package/lib/db/schema/api-keys.ts +61 -0
- package/lib/db/schema/attachments.ts +48 -0
- package/lib/db/schema/auth.ts +111 -0
- package/lib/db/schema/comments.ts +74 -0
- package/lib/db/schema/duplicates.ts +80 -0
- package/lib/db/schema/feedback.ts +88 -0
- package/lib/db/schema/github-integrations.ts +66 -0
- package/lib/db/schema/index.ts +35 -0
- package/lib/db/schema/invitations.ts +32 -0
- package/lib/db/schema/notifications.ts +85 -0
- package/lib/db/schema/organization-members.ts +37 -0
- package/lib/db/schema/organization-settings.ts +134 -0
- package/lib/db/schema/organizations.ts +30 -0
- package/lib/db/schema/projects.ts +145 -0
- package/lib/db/schema/status-history.ts +63 -0
- package/lib/db/schema/tags.ts +194 -0
- package/lib/db/schema/user-profiles.ts +31 -0
- package/lib/db/schema/votes.ts +60 -0
- package/lib/db/schema/webhooks.ts +106 -0
- package/lib/feedback/filters.ts +28 -0
- package/lib/feedback/find-similar.ts +49 -0
- package/lib/feedback/get-feedback-by-id.ts +159 -0
- package/lib/feedback/prefill.ts +51 -0
- package/lib/http/get-request-url.ts +28 -0
- package/lib/integrations/github.ts +159 -0
- package/lib/invitations.ts +22 -0
- package/lib/logger.test.ts +31 -0
- package/lib/logger.ts +58 -0
- package/lib/middleware/api-key.ts +126 -0
- package/lib/middleware/rate-limit-keys.ts +47 -0
- package/lib/middleware/rate-limit.ts +148 -0
- package/lib/middleware/rbac.ts +39 -0
- package/lib/middleware/request-id.test.ts +28 -0
- package/lib/middleware/request-id.ts +30 -0
- package/lib/middleware/request-logger.test.ts +36 -0
- package/lib/middleware/request-logger.ts +41 -0
- package/lib/middleware/with-rate-limit.ts +33 -0
- package/lib/portal/analytics.ts +20 -0
- package/lib/portal/contributors.ts +27 -0
- package/lib/portal/i18n.ts +20 -0
- package/lib/portal/leaderboard-settings.ts +20 -0
- package/lib/portal/modules.ts +20 -0
- package/lib/portal/portal-copy.ts +20 -0
- package/lib/portal/public-context.tsx +110 -0
- package/lib/portal/seo.ts +20 -0
- package/lib/portal/settings-context.ts +56 -0
- package/lib/portal/sharing.ts +20 -0
- package/lib/portal/sorting.ts +20 -0
- package/lib/portal/theme.ts +20 -0
- package/lib/services/ai/classifier.ts +296 -0
- package/lib/services/ai/duplicate-detector.ts +255 -0
- package/lib/services/ai/tag-suggester.ts +108 -0
- package/lib/services/api-keys.ts +164 -0
- package/lib/services/backup.ts +173 -0
- package/lib/services/email/templates.ts +158 -0
- package/lib/services/email.ts +68 -0
- package/lib/services/github-sync.ts +205 -0
- package/lib/services/notifications/index.ts +224 -0
- package/lib/services/portal-settings.ts +157 -0
- package/lib/swagger/config.ts +296 -0
- package/lib/swagger/generate.ts +400 -0
- package/lib/upload/file-validator.ts +52 -0
- package/lib/upload/storage.ts +59 -0
- package/lib/utils/format.ts +26 -0
- package/lib/utils/slug.ts +28 -0
- package/lib/utils.ts +23 -0
- package/lib/validations/auth.ts +56 -0
- package/lib/validations/comment.ts +44 -0
- package/lib/validations/feedback.ts +51 -0
- package/lib/validations/invitations.ts +23 -0
- package/lib/validations/organizations.ts +34 -0
- package/lib/validations/projects.ts +49 -0
- package/lib/validators/feedback.ts +57 -0
- package/lib/validators/index.ts +18 -0
- package/lib/webhooks/events.ts +73 -0
- package/lib/webhooks/index.ts +21 -0
- package/lib/webhooks/retry.ts +188 -0
- package/lib/webhooks/sender.ts +183 -0
- package/lib/webhooks/verify.ts +37 -0
- package/lib/workers/feedback-processor.ts +255 -0
- package/messages/en.json +965 -0
- package/messages/jp.json +862 -0
- package/messages/zh-CN.json +855 -0
- package/next-env.d.ts +6 -0
- package/next.config.ts +66 -0
- package/package.json +84 -0
- package/playwright.config.ts +44 -0
- package/postcss.config.mjs +7 -0
- package/proxy.test.ts +131 -0
- package/proxy.ts +190 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/logo-64.svg +5 -0
- package/public/logo.svg +5 -0
- package/public/next.svg +1 -0
- package/public/openapi.json +673 -0
- package/public/uploads/.gitkeep +0 -0
- package/public/uploads/02695701-ded0-4c81-8a21-9326c1d65448.pdf +1 -0
- package/public/uploads/178843ea-2780-48ef-8988-f4cba442e4cb.pdf +1 -0
- package/public/uploads/24b0a9ef-da93-49da-934f-637f89c7871d.pdf +1 -0
- package/public/uploads/7a11626d-a8e4-4b91-a8eb-20b6213b0a5a.pdf +1 -0
- package/public/uploads/b0703f4d-6e7b-4aab-8191-1a7b15f1b8ee.pdf +1 -0
- package/public/uploads/c8de0aed-4d3a-44aa-83bb-6594b7a2ddb3.pdf +1 -0
- package/public/uploads/e4cce295-0d85-4525-a1b0-a61c45722e26.pdf +1 -0
- package/public/uploads/eb4df45e-563c-48b8-9c68-c18212312426.pdf +1 -0
- package/public/vercel.svg +1 -0
- package/public/widget/embed.js +249 -0
- package/public/window.svg +1 -0
- package/scripts/backup-db.sh +57 -0
- package/scripts/backup-db.ts +24 -0
- package/scripts/generate-openapi.ts +22 -0
- package/scripts/migration-helper.ts +39 -0
- package/scripts/pre-deploy.ts +75 -0
- package/scripts/restore-db.sh +60 -0
- package/scripts/rollback.ts +72 -0
- package/scripts/seed-tags.ts +48 -0
- package/tests/api/feedback-bulk.test.ts +47 -0
- package/tests/api/feedback-by-id.test.ts +67 -0
- package/tests/api/feedback-comments-route-import.test.ts +26 -0
- package/tests/api/feedback-create.test.ts +71 -0
- package/tests/api/feedback-delete.test.ts +160 -0
- package/tests/api/feedback-filter.test.ts +250 -0
- package/tests/api/feedback-list.test.ts +234 -0
- package/tests/api/feedback-route-assignee-condition.test.ts +32 -0
- package/tests/api/feedback-similar.test.ts +46 -0
- package/tests/api/feedback-sort.test.ts +261 -0
- package/tests/api/feedback-status-enum.test.ts +49 -0
- package/tests/api/feedback-status-filter.test.ts +117 -0
- package/tests/api/feedback-submit-on-behalf.test.ts +269 -0
- package/tests/api/feedback.test.ts +175 -0
- package/tests/api/identify-jwt.test.ts +25 -0
- package/tests/api/invitation-accept.test.ts +213 -0
- package/tests/api/organization-invitations.test.ts +186 -0
- package/tests/api/organization-members-list.test.ts +79 -0
- package/tests/api/organization-members.test.ts +340 -0
- package/tests/api/organizations.test.ts +149 -0
- package/tests/api/register.test.ts +112 -0
- package/tests/api/upload.test.ts +103 -0
- package/tests/api/vote.test.ts +82 -0
- package/tests/app/admin-feedback-detail-page.test.tsx +25 -0
- package/tests/app/admin-feedback-list-page.test.tsx +25 -0
- package/tests/app/admin-feedback-new-page.test.tsx +25 -0
- package/tests/app/health-route-helpers.test.ts +27 -0
- package/tests/app/login-page.test.ts +26 -0
- package/tests/app/portal-page.test.ts +29 -0
- package/tests/app/project-portal-overview.test.tsx +25 -0
- package/tests/app/widget-page-import.test.ts +25 -0
- package/tests/components/create-post-dialog-defaults.test.ts +43 -0
- package/tests/components/feedback/duplicate-suggestions-inline.test.tsx +27 -0
- package/tests/components/feedback/embedded-feedback-form.test.tsx +96 -0
- package/tests/components/feedback/feedback-detail.test.tsx +25 -0
- package/tests/components/feedback/feedback-stats.test.tsx +49 -0
- package/tests/components/feedback-bulk-actions.test.tsx +39 -0
- package/tests/components/feedback-i18n-keys.test.ts +70 -0
- package/tests/components/feedback-list-controls-compile.test.ts +25 -0
- package/tests/components/feedback-list-controls.test.tsx +204 -0
- package/tests/components/feedback-list-item.test.tsx +67 -0
- package/tests/components/landing/hero.test.tsx +46 -0
- package/tests/components/layout/language-switcher.test.tsx +25 -0
- package/tests/components/layout/sidebar.test.tsx +157 -0
- package/tests/components/login-form.test.ts +25 -0
- package/tests/components/organization-form.test.ts +32 -0
- package/tests/components/organization-switcher.test.ts +25 -0
- package/tests/components/pagination.test.tsx +43 -0
- package/tests/components/portal-overview.test.tsx +25 -0
- package/tests/components/profile-form.test.tsx +139 -0
- package/tests/components/role-selector.test.ts +31 -0
- package/tests/components/status-chart.test.tsx +90 -0
- package/tests/e2e/auth.e2e.ts +323 -0
- package/tests/e2e/feedback-actions.e2e.ts +471 -0
- package/tests/e2e/feedback-attachment.e2e.ts +168 -0
- package/tests/e2e/feedback-customer.e2e.ts +226 -0
- package/tests/e2e/feedback-management.e2e.ts +565 -0
- package/tests/e2e/feedback-submit.e2e.ts +133 -0
- package/tests/e2e/feedback-view.e2e.ts +297 -0
- package/tests/e2e/fixtures/test-data.ts +235 -0
- package/tests/e2e/health-check.e2e.ts +230 -0
- package/tests/e2e/helpers/test-utils-helpers.test.ts +43 -0
- package/tests/e2e/helpers/test-utils.ts +298 -0
- package/tests/e2e/integration-placeholders.e2e.ts +199 -0
- package/tests/e2e/organization.e2e.ts +292 -0
- package/tests/e2e/permissions.e2e.ts +424 -0
- package/tests/e2e/project-widget.e2e.ts +63 -0
- package/tests/feedback/filters.test.ts +29 -0
- package/tests/hooks/use-permissions.test.ts +52 -0
- package/tests/lib/ai/classifier.test.ts +104 -0
- package/tests/lib/ai/duplicate-detector.test.ts +234 -0
- package/tests/lib/attachments-schema.test.ts +30 -0
- package/tests/lib/auth/session.test.ts +49 -0
- package/tests/lib/auth-client.test.ts +37 -0
- package/tests/lib/auth-config.test.ts +26 -0
- package/tests/lib/feedback-prefill.test.ts +52 -0
- package/tests/lib/feedback-processor.test.ts +41 -0
- package/tests/lib/feedback-schema.test.ts +33 -0
- package/tests/lib/file-validator.test.ts +48 -0
- package/tests/lib/get-feedback-by-id.test.ts +37 -0
- package/tests/lib/invitations.test.ts +35 -0
- package/tests/lib/login-schema.test.ts +36 -0
- package/tests/lib/org-context.test.ts +95 -0
- package/tests/lib/organization-access.test.ts +44 -0
- package/tests/lib/organization-member-role-schema.test.ts +41 -0
- package/tests/lib/permissions.test.ts +88 -0
- package/tests/lib/portal-analytics.test.ts +25 -0
- package/tests/lib/portal-contributors.test.ts +25 -0
- package/tests/lib/portal-copy.test.ts +27 -0
- package/tests/lib/portal-i18n.test.ts +30 -0
- package/tests/lib/portal-leaderboard-settings.test.ts +25 -0
- package/tests/lib/portal-modules.test.ts +25 -0
- package/tests/lib/portal-seo.test.ts +25 -0
- package/tests/lib/portal-sharing.test.ts +25 -0
- package/tests/lib/portal-sorting.test.ts +25 -0
- package/tests/lib/portal-theme.test.ts +25 -0
- package/tests/lib/rate-limit.test.ts +142 -0
- package/tests/lib/resolve-locale.test.ts +34 -0
- package/tests/lib/services/backup.test.ts +145 -0
- package/tests/lib/user-organizations.test.ts +42 -0
- package/tests/lib/user-role-schema.test.ts +33 -0
- package/tests/lib/user-schema.test.ts +25 -0
- package/tests/setup.ts +74 -0
- package/tsconfig.json +34 -0
- package/types/bun-test.d.ts +31 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
# 多语言支持(i18n)检查报告
|
|
2
|
+
|
|
3
|
+
## 检查日期
|
|
4
|
+
2026-01-17
|
|
5
|
+
|
|
6
|
+
## 项目概况
|
|
7
|
+
- **项目名称**: Echo
|
|
8
|
+
- **技术栈**: Next.js 16.1.1 + React 19 + TypeScript
|
|
9
|
+
- **国际化方案**: next-intl
|
|
10
|
+
- **支持语言**: en, zh-CN, jp
|
|
11
|
+
|
|
12
|
+
## 配置检查 ✅
|
|
13
|
+
|
|
14
|
+
### 1. i18n 配置文件
|
|
15
|
+
- `/i18n/config.ts` - 完整配置,包含默认语言、支持的语言列表等
|
|
16
|
+
- `/i18n/request.ts` - next-intl 请求配置
|
|
17
|
+
- `/i18n/resolve-locale.ts` - 语言解析逻辑
|
|
18
|
+
|
|
19
|
+
### 2. 语言文件
|
|
20
|
+
- `/messages/en.json` - 英文翻译(498行)
|
|
21
|
+
- `/messages/zh-CN.json` - 中文翻译(491行)
|
|
22
|
+
- `/messages/jp.json` - 日文翻译
|
|
23
|
+
|
|
24
|
+
## 组件检查结果
|
|
25
|
+
|
|
26
|
+
### 已实现 i18n 的组件(27个)
|
|
27
|
+
✅ 使用了 `useTranslations` 或 `getTranslations` 的组件:
|
|
28
|
+
- `/components/dashboard/stats-cards.tsx`
|
|
29
|
+
- `/components/shared/pagination.tsx`
|
|
30
|
+
- `/components/feedback/vote-button.tsx`
|
|
31
|
+
- `/components/integrations/github-config.tsx`
|
|
32
|
+
- `/components/dashboard/status-chart.tsx`
|
|
33
|
+
- `/components/feedback/feedback-detail-view.tsx`
|
|
34
|
+
- `/components/feedback/feedback-filters.tsx`
|
|
35
|
+
- `/components/feedback/feedback-list-item.tsx`
|
|
36
|
+
- `/components/feedback/feedback-bulk-actions.tsx`
|
|
37
|
+
- `/components/dashboard/recent-feedback-list.tsx`
|
|
38
|
+
- `/components/feedback/feedback-list-controls.tsx`
|
|
39
|
+
- `/components/feedback/feedback-edit-form.tsx`
|
|
40
|
+
- `/components/feedback/auto-classification-badge.tsx`
|
|
41
|
+
- `/components/feedback/feedback-list.tsx`
|
|
42
|
+
- `/components/feedback/processing-status.tsx`
|
|
43
|
+
- `/components/layout/sidebar.tsx`
|
|
44
|
+
- `/components/layout/language-switcher.tsx`
|
|
45
|
+
- `/components/layout/mobile-sidebar.tsx`
|
|
46
|
+
- `/components/auth/register-form.tsx`
|
|
47
|
+
- `/components/auth/login-form.tsx`
|
|
48
|
+
- `/components/widget/widget-form.tsx`
|
|
49
|
+
- `/components/portal/contributors-sidebar.tsx`
|
|
50
|
+
- `/components/settings/notification-preferences.tsx`
|
|
51
|
+
- `/components/settings/settings-sidebar.tsx`
|
|
52
|
+
- `/components/settings/profile-form.tsx`
|
|
53
|
+
- `/components/settings/appearance-form.tsx`
|
|
54
|
+
- `/components/settings/api-keys-list.tsx`
|
|
55
|
+
|
|
56
|
+
### ❌ 未实现 i18n 的组件(59个)
|
|
57
|
+
|
|
58
|
+
#### 1. 包含硬编码中文文本的组件
|
|
59
|
+
|
|
60
|
+
**`/components/landing/hero.tsx`**
|
|
61
|
+
- 硬编码文本:"开源产品反馈管理平台"、"专为初创公司设计"等
|
|
62
|
+
- 导航链接:"登录"、"免费注册"等
|
|
63
|
+
|
|
64
|
+
**`/components/dashboard/quick-actions.tsx`**
|
|
65
|
+
- 硬编码文本:"提交新反馈"、"查看全部反馈"、"设置"、"组织设置"
|
|
66
|
+
|
|
67
|
+
**`/components/feedback/embedded-feedback-form.tsx`**
|
|
68
|
+
- 导出的常量包含中文:
|
|
69
|
+
```typescript
|
|
70
|
+
export const FEEDBACK_TRIGGER_LABEL = "反馈";
|
|
71
|
+
export const FEEDBACK_DIALOG_TITLE = "提交反馈";
|
|
72
|
+
export const FEEDBACK_TITLE_LABEL = "标题";
|
|
73
|
+
// ... 更多
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**`/components/portal/portal-modules-panel.tsx`**
|
|
77
|
+
- 硬编码文本:"Portal 模块开关"、"控制门户中展示的功能模块"、"反馈"、"允许用户提交和浏览反馈"等
|
|
78
|
+
|
|
79
|
+
**`/components/portal/settings-forms/copy-form.tsx`**
|
|
80
|
+
- 默认值包含中文:
|
|
81
|
+
```typescript
|
|
82
|
+
title: initialData?.title ?? "反馈中心",
|
|
83
|
+
ctaLabel: initialData?.ctaLabel ?? "提交反馈",
|
|
84
|
+
// ... 更多
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**`/components/settings/organization-form.tsx`**
|
|
88
|
+
- 硬编码文本:"组织设置"、"创建新组织"
|
|
89
|
+
|
|
90
|
+
**`/components/feedback/submit-on-behalf-form.tsx`**
|
|
91
|
+
- 硬编码文本:"提交中..."、"提交反馈"
|
|
92
|
+
|
|
93
|
+
**`/components/feedback/file-upload.tsx`**
|
|
94
|
+
- 硬编码文本:"请先提交反馈"
|
|
95
|
+
|
|
96
|
+
#### 2. 示例和演示组件
|
|
97
|
+
- `/components/component-example.tsx` - 包含大量硬编码英文文本
|
|
98
|
+
- `/components/example.tsx` - 基础组件,无显示文本
|
|
99
|
+
|
|
100
|
+
#### 3. 其他需要检查的组件
|
|
101
|
+
- `/components/api-keys/api-key-manager.tsx`
|
|
102
|
+
- `/components/comment/` 目录下的所有组件
|
|
103
|
+
- `/components/dashboard/organization-switcher.tsx`
|
|
104
|
+
- `/components/feedback/` 目录下的大部分组件
|
|
105
|
+
- `/components/integrations/` 目录下的组件
|
|
106
|
+
- `/components/portal/` 目录下的组件
|
|
107
|
+
- `/components/widget/` 目录下的组件
|
|
108
|
+
|
|
109
|
+
## 页面检查结果
|
|
110
|
+
|
|
111
|
+
### 已实现 i18n 的页面(67个)
|
|
112
|
+
✅ 使用了 `useTranslations` 或 `getTranslations` 的页面已正确实现
|
|
113
|
+
|
|
114
|
+
### ❌ 需要检查的页面(35个)
|
|
115
|
+
|
|
116
|
+
#### 1. 公共页面
|
|
117
|
+
- `/app/(public)/page.tsx` - 仅引用 Hero 组件
|
|
118
|
+
- `/app/(public)/docs/page.tsx` - API 文档页面,包含硬编码文本
|
|
119
|
+
|
|
120
|
+
#### 2. 认证页面
|
|
121
|
+
- `/app/(auth)/login/page.tsx`
|
|
122
|
+
- `/app/(auth)/register/page.tsx`
|
|
123
|
+
- `/app/(auth)/sign-in/page.tsx`
|
|
124
|
+
|
|
125
|
+
#### 3. 设置页面
|
|
126
|
+
- `/app/(dashboard)/settings/` 目录下的多个子页面
|
|
127
|
+
|
|
128
|
+
## 建议修复方案
|
|
129
|
+
|
|
130
|
+
### 1. 立即修复(高优先级)
|
|
131
|
+
|
|
132
|
+
#### `/components/landing/hero.tsx`
|
|
133
|
+
```typescript
|
|
134
|
+
// 添加导入
|
|
135
|
+
import { useTranslations } from "next-intl";
|
|
136
|
+
|
|
137
|
+
export function Hero() {
|
|
138
|
+
const t = useTranslations("hero");
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<div className="min-h-screen bg-linear-to-br from-slate-50 via-white to-slate-100">
|
|
142
|
+
<header className="container mx-auto flex items-center justify-between px-4 py-6">
|
|
143
|
+
<div className="flex items-center gap-2">
|
|
144
|
+
<MessageSquare className="size-8 text-primary" />
|
|
145
|
+
<span className="text-2xl font-bold text-slate-900">{t("title")}</span>
|
|
146
|
+
</div>
|
|
147
|
+
<nav className="flex items-center gap-4">
|
|
148
|
+
<LanguageSwitcher variant="icon" />
|
|
149
|
+
<Button variant="ghost" asChild>
|
|
150
|
+
<Link href="/login">{t("login")}</Link>
|
|
151
|
+
</Button>
|
|
152
|
+
<Button asChild>
|
|
153
|
+
<Link href="/register">{t("register")}</Link>
|
|
154
|
+
</Button>
|
|
155
|
+
</nav>
|
|
156
|
+
</header>
|
|
157
|
+
// ... 更多
|
|
158
|
+
</div>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
需要在语言文件中添加:
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"hero": {
|
|
167
|
+
"title": "Echo",
|
|
168
|
+
"login": "登录",
|
|
169
|
+
"register": "免费注册",
|
|
170
|
+
"headline": "开源产品反馈管理平台",
|
|
171
|
+
"description": "专为初创公司设计,让团队能够集中管理产品反馈、发现洞察并做出明智的产品决策。",
|
|
172
|
+
"cta1": "开始使用",
|
|
173
|
+
"cta2": "查看文档",
|
|
174
|
+
"coreValues": "核心价值"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### `/components/dashboard/quick-actions.tsx`
|
|
180
|
+
```typescript
|
|
181
|
+
import { useTranslations } from "next-intl";
|
|
182
|
+
|
|
183
|
+
export function QuickActions() {
|
|
184
|
+
const t = useTranslations("dashboard.quickActions");
|
|
185
|
+
|
|
186
|
+
return (
|
|
187
|
+
<div className="flex flex-wrap gap-3">
|
|
188
|
+
<Button asChild>
|
|
189
|
+
<Link href="/admin/feedback/new">
|
|
190
|
+
<Plus className="mr-2 h-4 w-4" />
|
|
191
|
+
{t("submitFeedback")}
|
|
192
|
+
</Link>
|
|
193
|
+
</Button>
|
|
194
|
+
// ... 更多
|
|
195
|
+
</div>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 2. 中期修复(中优先级)
|
|
201
|
+
|
|
202
|
+
1. **所有 feedback 相关组件**
|
|
203
|
+
- 将导出的常量改为使用 useTranslations
|
|
204
|
+
- 创建统一的翻译键命名空间
|
|
205
|
+
|
|
206
|
+
2. **所有 portal 相关组件**
|
|
207
|
+
- 为门户设置创建专门的翻译节
|
|
208
|
+
- 确保所有用户可见文本都支持多语言
|
|
209
|
+
|
|
210
|
+
3. **所有 settings 相关组件**
|
|
211
|
+
- 统一设置页面的翻译键结构
|
|
212
|
+
- 注意表单标签和提示信息
|
|
213
|
+
|
|
214
|
+
### 3. 长期优化(低优先级)
|
|
215
|
+
|
|
216
|
+
1. **创建翻译键命名规范**
|
|
217
|
+
- 建议使用点分隔的命名空间:`section.component.field`
|
|
218
|
+
- 避免过深的嵌套
|
|
219
|
+
|
|
220
|
+
2. **建立翻译检查流程**
|
|
221
|
+
- 在 CI/CD 中添加翻译完整性检查
|
|
222
|
+
- 确保新增的文本都包含翻译
|
|
223
|
+
|
|
224
|
+
3. **优化翻译文件结构**
|
|
225
|
+
- 考虑按功能模块拆分翻译文件
|
|
226
|
+
- 减少单个文件的复杂度
|
|
227
|
+
|
|
228
|
+
## 缺失的翻译键示例
|
|
229
|
+
|
|
230
|
+
基于检查结果,以下是一些需要添加的翻译键:
|
|
231
|
+
|
|
232
|
+
```json
|
|
233
|
+
{
|
|
234
|
+
"hero": { ... },
|
|
235
|
+
"dashboard": {
|
|
236
|
+
"quickActions": {
|
|
237
|
+
"submitFeedback": "提交新反馈",
|
|
238
|
+
"viewAllFeedback": "查看全部反馈",
|
|
239
|
+
"settings": "设置",
|
|
240
|
+
"organizationSettings": "组织设置"
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
"feedback": {
|
|
244
|
+
"trigger": "反馈",
|
|
245
|
+
"dialogTitle": "提交反馈",
|
|
246
|
+
"title": "标题",
|
|
247
|
+
"description": "描述",
|
|
248
|
+
"type": "反馈类型",
|
|
249
|
+
"priority": "优先级",
|
|
250
|
+
"submit": "提交",
|
|
251
|
+
"cancel": "取消",
|
|
252
|
+
"success": "反馈提交成功",
|
|
253
|
+
"trackingLink": "跟踪链接"
|
|
254
|
+
},
|
|
255
|
+
"portal": {
|
|
256
|
+
"modules": {
|
|
257
|
+
"title": "Portal 模块开关",
|
|
258
|
+
"description": "控制门户中展示的功能模块",
|
|
259
|
+
"feedback": "反馈",
|
|
260
|
+
"feedbackDescription": "允许用户提交和浏览反馈",
|
|
261
|
+
"roadmap": "路线图",
|
|
262
|
+
"roadmapDescription": "展示产品开发计划和进度",
|
|
263
|
+
"changelog": "更新日志",
|
|
264
|
+
"changelogDescription": "发布产品更新和改进说明"
|
|
265
|
+
},
|
|
266
|
+
"copy": {
|
|
267
|
+
"title": "反馈中心",
|
|
268
|
+
"ctaLabel": "提交反馈",
|
|
269
|
+
"emptyState": "还没有反馈,成为第一个分享想法的人!",
|
|
270
|
+
"success": "感谢您的反馈!我们会认真阅读。"
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
"settings": {
|
|
274
|
+
"organization": {
|
|
275
|
+
"title": "组织设置",
|
|
276
|
+
"create": "创建新组织"
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## 总结
|
|
283
|
+
|
|
284
|
+
- ✅ **已完成**: 27个组件和67个页面已正确实现 i18n
|
|
285
|
+
- ❌ **需要修复**: 59个组件和35个页面需要添加 i18n 支持
|
|
286
|
+
- 📊 **完成度**: 约 55%
|
|
287
|
+
|
|
288
|
+
**建议优先级**:
|
|
289
|
+
1. 先修复包含硬编码中文的组件(高优先级)
|
|
290
|
+
2. 再修复其他用户可见的组件(中优先级)
|
|
291
|
+
3. 最后优化和规范化(低优先级)
|
|
292
|
+
|
|
293
|
+
**注意事项**:
|
|
294
|
+
- 修复时确保所有三种语言(en、zh-CN、jp)都有对应翻译
|
|
295
|
+
- 测试语言切换功能是否正常工作
|
|
296
|
+
- 注意动态内容(如日期、数字)的本地化
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Project Documentation Index
|
|
2
|
+
|
|
3
|
+
**Project:** Echo
|
|
4
|
+
**Type:** Monolith Web Application
|
|
5
|
+
**Primary Language:** TypeScript
|
|
6
|
+
**Architecture:** Next.js App Router + React Server Components
|
|
7
|
+
**Last Updated:** 2025-12-31
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Project Overview
|
|
12
|
+
|
|
13
|
+
- **Type:** Monolith
|
|
14
|
+
- **Primary Language:** TypeScript 5.x
|
|
15
|
+
- **Primary Framework:** Next.js 16.1.1 + React 19.2.3
|
|
16
|
+
- **Architecture Pattern:** App Router + React Server Components
|
|
17
|
+
- **Package Manager:** Bun
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Quick Reference
|
|
22
|
+
|
|
23
|
+
| 属性 | 值 |
|
|
24
|
+
|------|-----|
|
|
25
|
+
| **项目名称** | Echo |
|
|
26
|
+
| **项目类型** | Web 应用 - 用户反馈系统 |
|
|
27
|
+
| **主语言** | TypeScript 5.x (strict mode) |
|
|
28
|
+
| **框架** | Next.js 16.1.1 + React 19.2.3 |
|
|
29
|
+
| **入口点** | `app/page.tsx` |
|
|
30
|
+
| **架构模式** | App Router + React Server Components |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Generated Documentation
|
|
35
|
+
|
|
36
|
+
### Core Documentation
|
|
37
|
+
|
|
38
|
+
- [Project Overview](./project-overview.md) - 项目概览和快速参考
|
|
39
|
+
- [Architecture](./architecture.md) - 系统架构详细说明
|
|
40
|
+
- [Source Tree Analysis](./source-tree-analysis.md) - 源代码树结构
|
|
41
|
+
- [Component Inventory](./component-inventory.md) - 组件清单和使用指南
|
|
42
|
+
- [Development Guide](./development-guide.md) - 开发设置和工作流程
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Existing Documentation
|
|
47
|
+
|
|
48
|
+
- [README.md](../README.md) - Next.js 标准启动文档
|
|
49
|
+
- [CLAUDE.md](../CLAUDE.md) - Claude Code 项目指令
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Technology Stack
|
|
54
|
+
|
|
55
|
+
### Core Framework
|
|
56
|
+
|
|
57
|
+
| 技术 | 版本 | 用途 |
|
|
58
|
+
|------|------|------|
|
|
59
|
+
| Next.js | 16.1.1 | React 框架(App Router)|
|
|
60
|
+
| React | 19.2.3 | UI 库(RSC enabled)|
|
|
61
|
+
| TypeScript | 5.x | 类型系统(strict mode)|
|
|
62
|
+
|
|
63
|
+
### Styling & Components
|
|
64
|
+
|
|
65
|
+
| 技术 | 版本 | 用途 |
|
|
66
|
+
|------|------|------|
|
|
67
|
+
| Tailwind CSS | 4.x | 实用优先的 CSS 框架 |
|
|
68
|
+
| Shadcn/ui | 3.6.2 | 组件系统 |
|
|
69
|
+
| Radix UI | 1.4.3 | 无障碍基础组件 |
|
|
70
|
+
| Base UI | 1.0.0 | React 基础组件 |
|
|
71
|
+
| Lucide React | 0.562.0 | 图标库 |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Repository Structure
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
echo/
|
|
79
|
+
├── app/ # Next.js App Router ⭐
|
|
80
|
+
│ ├── layout.tsx # 根布局组件
|
|
81
|
+
│ ├── page.tsx # 首页
|
|
82
|
+
│ └── globals.css # 全局样式 + Tailwind 配置
|
|
83
|
+
├── components/ # React 组件 ⭐
|
|
84
|
+
│ ├── ui/ # Shadcn/ui 基础组件(14 个)
|
|
85
|
+
│ ├── component-example.tsx
|
|
86
|
+
│ └── example.tsx
|
|
87
|
+
├── lib/ # 工具函数 ⭐
|
|
88
|
+
│ └── utils.ts # cn() 函数等
|
|
89
|
+
├── docs/ # 项目文档
|
|
90
|
+
├── public/ # 静态资源
|
|
91
|
+
├── package.json # 项目配置 ⭐
|
|
92
|
+
├── tsconfig.json # TypeScript 配置 ⭐
|
|
93
|
+
└── components.json # Shadcn/ui 配置 ⭐
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Import Aliases
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
@/components → components/
|
|
102
|
+
@/lib → lib/
|
|
103
|
+
@/components/ui → components/ui
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Getting Started
|
|
109
|
+
|
|
110
|
+
### Prerequisites
|
|
111
|
+
|
|
112
|
+
- Bun (最新版)
|
|
113
|
+
- Node.js 20.x
|
|
114
|
+
|
|
115
|
+
### Installation
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# 安装依赖
|
|
119
|
+
bun install
|
|
120
|
+
|
|
121
|
+
# 启动开发服务器
|
|
122
|
+
bun dev
|
|
123
|
+
|
|
124
|
+
# 访问 http://localhost:3000
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Available Scripts
|
|
128
|
+
|
|
129
|
+
| 命令 | 说明 |
|
|
130
|
+
|------|------|
|
|
131
|
+
| `bun dev` | 启动开发服务器 |
|
|
132
|
+
| `bun run build` | 生产构建 |
|
|
133
|
+
| `bun start` | 启动生产服务器 |
|
|
134
|
+
| `bun run lint` | 运行代码检查 |
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Component Library
|
|
139
|
+
|
|
140
|
+
### Shadcn/ui Components (14 个)
|
|
141
|
+
|
|
142
|
+
**Form Components:** Input, Textarea, Label, Field, Input Group, Select, Combobox
|
|
143
|
+
**Action Components:** Button, Dropdown Menu, Alert Dialog
|
|
144
|
+
**Layout Components:** Card, Separator
|
|
145
|
+
**Display Components:** Badge
|
|
146
|
+
|
|
147
|
+
详见:[Component Inventory](./component-inventory.md)
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Current Implementation Status
|
|
152
|
+
|
|
153
|
+
### ✅ 已实现
|
|
154
|
+
|
|
155
|
+
- Next.js 项目结构
|
|
156
|
+
- Shadcn/ui 组件库(14 个基础组件)
|
|
157
|
+
- Tailwind CSS 主题配置
|
|
158
|
+
- TypeScript 类型检查
|
|
159
|
+
- ESLint 代码规范
|
|
160
|
+
|
|
161
|
+
### ❌ 未实现
|
|
162
|
+
|
|
163
|
+
- API 路由
|
|
164
|
+
- 数据库/数据模型
|
|
165
|
+
- 状态管理
|
|
166
|
+
- 用户认证
|
|
167
|
+
- 测试套件
|
|
168
|
+
- CI/CD 配置
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Architecture Notes
|
|
173
|
+
|
|
174
|
+
- **路由系统:** Next.js App Router(文件系统路由)
|
|
175
|
+
- **渲染模式:** React Server Components + Client Components
|
|
176
|
+
- **样式方案:** Tailwind CSS v4(inline config)
|
|
177
|
+
- **组件系统:** Shadcn/ui(Radix UI primitives)
|
|
178
|
+
- **类型系统:** TypeScript 5.x(strict mode)
|
|
179
|
+
- **色彩空间:** OKLCH(感知上均匀的颜色)
|
|
180
|
+
- **暗黑模式:** 自定义实现(`.dark` class selector)
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Documentation for AI-Assisted Development
|
|
185
|
+
|
|
186
|
+
当使用 AI 辅助开发时,请参考以下文档:
|
|
187
|
+
|
|
188
|
+
1. **新功能规划** - 参考 [Architecture](./architecture.md) 了解系统设计
|
|
189
|
+
2. **组件开发** - 参考 [Component Inventory](./component-inventory.md) 了解可用组件
|
|
190
|
+
3. **代码规范** - 参考 [Development Guide](./development-guide.md) 了解开发流程
|
|
191
|
+
4. **项目结构** - 参考 [Source Tree Analysis](./source-tree-analysis.md) 了解代码组织
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Project Status
|
|
196
|
+
|
|
197
|
+
**阶段:** 初始化/脚手架
|
|
198
|
+
**最后更新:** 2025-12-31
|
|
199
|
+
|
|
200
|
+
项目处于早期开发阶段,已建立基础架构和开发环境。
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## BMad Method Workflow
|
|
205
|
+
|
|
206
|
+
本项目使用 BMad Method 工作流进行规划。
|
|
207
|
+
|
|
208
|
+
**工作流状态:** `_bmad-output/planning-artifacts/bmm-workflow-status.yaml`
|
|
209
|
+
|
|
210
|
+
**下一步:** document-project → brainstorm-project → PRD
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
*此文档由 BMad Document Project 工作流自动生成*
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Echo Business Logic Chain
|
|
2
|
+
|
|
3
|
+
## Registration and Organization Bootstrap
|
|
4
|
+
- Register user -> create organization -> add admin member -> create profile
|
|
5
|
+
- Entry: app/api/auth/register/handler.ts
|
|
6
|
+
- Models: user, organizations, organization_members, user_profiles
|
|
7
|
+
|
|
8
|
+
## Organization and Membership
|
|
9
|
+
- Create organization (admin-only)
|
|
10
|
+
- Manage members (remove, change role, keep at least one admin)
|
|
11
|
+
- Invitations (admin-only, email invite, token expiry)
|
|
12
|
+
- Entry: app/api/organizations/handler.ts
|
|
13
|
+
- Entry: app/api/organizations/[orgId]/members/[memberId]/handler.ts
|
|
14
|
+
- Entry: app/api/organizations/[orgId]/invitations/handler.ts
|
|
15
|
+
- Models: organizations, organization_members, invitations
|
|
16
|
+
|
|
17
|
+
## Organization Settings (Portal/Widget)
|
|
18
|
+
- Read/update portal config for organization
|
|
19
|
+
- Widget config resolves from organization_settings with URL overrides
|
|
20
|
+
- Entry: lib/services/portal-settings.ts
|
|
21
|
+
- Entry: app/widget/[organizationId]/page.tsx
|
|
22
|
+
- Models: organization_settings
|
|
23
|
+
|
|
24
|
+
## Feedback Lifecycle
|
|
25
|
+
- Create feedback (validation, optional submit-on-behalf, auto-classify)
|
|
26
|
+
- List feedback (filters, pagination, vote count)
|
|
27
|
+
- Get feedback detail (attachments, votes, status history)
|
|
28
|
+
- Update status (status_history append + notify)
|
|
29
|
+
- Soft delete feedback
|
|
30
|
+
- Entry: app/api/feedback/route.ts
|
|
31
|
+
- Entry: app/api/feedback/handler.ts
|
|
32
|
+
- Entry: app/api/feedback/[id]/route.ts
|
|
33
|
+
- Entry: lib/feedback/get-feedback-by-id.ts
|
|
34
|
+
- Models: feedback, status_history, attachments, votes
|
|
35
|
+
|
|
36
|
+
## Comments
|
|
37
|
+
- Auth user comment (internal allowed for org members)
|
|
38
|
+
- Guest comment (public only, guest token cookie)
|
|
39
|
+
- Notify feedback submitter for public comments
|
|
40
|
+
- Entry: app/api/feedback/[id]/comments/route.ts
|
|
41
|
+
- Models: comments
|
|
42
|
+
|
|
43
|
+
## Votes
|
|
44
|
+
- Vote add/remove with visitorId or userId
|
|
45
|
+
- Entry: app/api/feedback/[id]/vote/route.ts
|
|
46
|
+
- Models: votes
|
|
47
|
+
|
|
48
|
+
## Tags
|
|
49
|
+
- Suggest tags from AI
|
|
50
|
+
- Apply tags to feedback
|
|
51
|
+
- Sync predefined tag into tags table
|
|
52
|
+
- Entry: app/api/feedback/[id]/suggest-tags/route.ts
|
|
53
|
+
- Entry: app/api/tags/sync/route.ts
|
|
54
|
+
- Models: tags, feedback_tags
|
|
55
|
+
|
|
56
|
+
## AI Processing
|
|
57
|
+
- Async classification, tag suggestions, duplicate detection
|
|
58
|
+
- Persist ai_processing_results and duplicate_feedback
|
|
59
|
+
- Update feedback processingStatus/processedAt
|
|
60
|
+
- Entry: lib/workers/feedback-processor.ts
|
|
61
|
+
- Entry: app/api/feedback/[id]/processing-status/route.ts
|
|
62
|
+
- Models: ai_processing_results, duplicate_feedback, feedback
|
|
63
|
+
|
|
64
|
+
## Notifications
|
|
65
|
+
- Status change -> notify submitter
|
|
66
|
+
- Public comment -> notify submitter (except author)
|
|
67
|
+
- Email delivery + notification status updates
|
|
68
|
+
- Entry: lib/services/notifications/index.ts
|
|
69
|
+
- Models: notifications, notification_preferences
|
|
70
|
+
|
|
71
|
+
## Webhooks
|
|
72
|
+
- CRUD webhooks for organization
|
|
73
|
+
- Event delivery with signature, retries, and webhook_events tracking
|
|
74
|
+
- Entry: app/api/webhooks/route.ts
|
|
75
|
+
- Entry: app/api/webhooks/[webhookId]/route.ts
|
|
76
|
+
- Entry: lib/webhooks/sender.ts
|
|
77
|
+
- Entry: lib/webhooks/retry.ts
|
|
78
|
+
- Models: webhooks, webhook_events
|
|
79
|
+
|
|
80
|
+
## GitHub Integration
|
|
81
|
+
- Configure integration and webhook secret
|
|
82
|
+
- Sync feedback to GitHub issue
|
|
83
|
+
- Sync issue state back to feedback status
|
|
84
|
+
- Entry: app/api/integrations/github/route.ts
|
|
85
|
+
- Entry: lib/services/github-sync.ts
|
|
86
|
+
- Entry: app/api/webhooks/github/route.ts
|
|
87
|
+
- Models: github_integrations, feedback
|
|
88
|
+
|
|
89
|
+
## API Keys
|
|
90
|
+
- Create/list/toggle/delete API keys
|
|
91
|
+
- Verify API key and attach org context
|
|
92
|
+
- Entry: lib/services/api-keys.ts
|
|
93
|
+
- Entry: lib/middleware/api-key.ts
|
|
94
|
+
- Models: api_keys
|