ui-syncup 0.3.13 → 0.4.0-beta.1
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/.agents/skills/ai-spec-workflow/SKILL.md +58 -0
- package/.agents/skills/ai-spec-workflow/references/AI_SPECIFICATION_WORKFLOW.md +1434 -0
- package/.agents/skills/ai-spec-workflow/references/templates/design-template.md +729 -0
- package/.agents/skills/ai-spec-workflow/references/templates/requirements-template.md +179 -0
- package/.agents/skills/ai-spec-workflow/references/templates/tasks-template.md +501 -0
- package/.agents/skills/animation-designer/SKILL.md +688 -0
- package/.agents/skills/animation-designer/manifest.yaml +44 -0
- package/.agents/skills/brainstorming/SKILL.md +54 -0
- package/.agents/skills/contract-driven-ui/SKILL.md +270 -0
- package/.agents/skills/dispatching-parallel-agents/SKILL.md +180 -0
- package/.agents/skills/executing-plans/SKILL.md +76 -0
- package/.agents/skills/executing-specs/SKILL.md +53 -0
- package/.agents/skills/finishing-a-development-branch/SKILL.md +200 -0
- package/.agents/skills/github-workflow-automation/SKILL.md +846 -0
- package/.agents/skills/react-best-practices/AGENTS.md +2249 -0
- package/.agents/skills/react-best-practices/README.md +123 -0
- package/.agents/skills/react-best-practices/SKILL.md +121 -0
- package/.agents/skills/react-best-practices/metadata.json +15 -0
- package/.agents/skills/react-best-practices/rules/_sections.md +46 -0
- package/.agents/skills/react-best-practices/rules/_template.md +28 -0
- package/.agents/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/.agents/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/.agents/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/.agents/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/.agents/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/.agents/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/.agents/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/.agents/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/.agents/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/.agents/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/.agents/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/.agents/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/.agents/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/.agents/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/.agents/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/.agents/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/.agents/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/.agents/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/.agents/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/.agents/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/.agents/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/.agents/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/.agents/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/.agents/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/.agents/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/.agents/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/.agents/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/.agents/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/.agents/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/.agents/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/.agents/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/.agents/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/.agents/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/.agents/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/.agents/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/.agents/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/.agents/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/.agents/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/.agents/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/.agents/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/.agents/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/.agents/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/.agents/skills/react-best-practices/rules/server-cache-react.md +26 -0
- package/.agents/skills/react-best-practices/rules/server-parallel-fetching.md +79 -0
- package/.agents/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/.agents/skills/react-ui-patterns/SKILL.md +289 -0
- package/.agents/skills/receiving-code-review/SKILL.md +213 -0
- package/.agents/skills/requesting-code-review/SKILL.md +105 -0
- package/.agents/skills/requesting-code-review/code-reviewer.md +146 -0
- package/.agents/skills/reviewing-code/SKILL.md +28 -0
- package/.agents/skills/shadcn/SKILL.md +240 -0
- package/.agents/skills/shadcn/agents/openai.yml +5 -0
- package/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
- package/.agents/skills/shadcn/assets/shadcn.png +0 -0
- package/.agents/skills/shadcn/cli.md +255 -0
- package/.agents/skills/shadcn/customization.md +202 -0
- package/.agents/skills/shadcn/evals/evals.json +47 -0
- package/.agents/skills/shadcn/mcp.md +94 -0
- package/.agents/skills/shadcn/rules/base-vs-radix.md +306 -0
- package/.agents/skills/shadcn/rules/composition.md +195 -0
- package/.agents/skills/shadcn/rules/forms.md +192 -0
- package/.agents/skills/shadcn/rules/icons.md +101 -0
- package/.agents/skills/shadcn/rules/styling.md +162 -0
- package/.agents/skills/steering-creation/SKILL.md +221 -0
- package/.agents/skills/steering-creation/references/STEERING_CREATION_INSTRUCTION.md +850 -0
- package/.agents/skills/subagent-driven-development/SKILL.md +240 -0
- package/.agents/skills/subagent-driven-development/code-quality-reviewer-prompt.md +20 -0
- package/.agents/skills/subagent-driven-development/implementer-prompt.md +78 -0
- package/.agents/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/.agents/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/.agents/skills/systematic-debugging/SKILL.md +296 -0
- package/.agents/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/.agents/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/.agents/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/.agents/skills/systematic-debugging/find-polluter.sh +63 -0
- package/.agents/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/.agents/skills/systematic-debugging/test-academic.md +14 -0
- package/.agents/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/.agents/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/.agents/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/.agents/skills/test-driven-development/SKILL.md +371 -0
- package/.agents/skills/test-driven-development/testing-anti-patterns.md +299 -0
- package/.agents/skills/using-git-worktrees/SKILL.md +217 -0
- package/.agents/skills/using-superpowers/SKILL.md +87 -0
- package/.agents/skills/verification-before-completion/SKILL.md +139 -0
- package/.agents/skills/web-design-guidelines/SKILL.md +36 -0
- package/.agents/skills/writing-plans/SKILL.md +116 -0
- package/.agents/skills/writing-skills/SKILL.md +655 -0
- package/.agents/skills/writing-skills/anthropic-best-practices.md +1150 -0
- package/.agents/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/.agents/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/.agents/skills/writing-skills/persuasion-principles.md +187 -0
- package/.agents/skills/writing-skills/render-graphs.js +168 -0
- package/.agents/skills/writing-skills/testing-skills-with-subagents.md +384 -0
- package/.ai/steering/product.md +51 -0
- package/.ai/steering/structure.md +275 -0
- package/.ai/steering/tech.md +188 -0
- package/.claude/agents/database-architect.md +96 -0
- package/.claude/agents/deployment-pipeline-architect.md +122 -0
- package/.claude/agents/nextjs-expert.md +69 -0
- package/.claude/agents/ui-design-expert.md +106 -0
- package/.claudeignore +69 -0
- package/.dockerignore +8 -0
- package/.env.development +86 -0
- package/.env.example +171 -0
- package/.env.production +139 -0
- package/.env.test +58 -0
- package/.gitattributes +2 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +33 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +20 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +23 -0
- package/.github/workflows/ci.yml +64 -0
- package/.github/workflows/release.yml +131 -0
- package/.nvmrc +1 -0
- package/.releaserc.json +18 -0
- package/.vercelignore +73 -0
- package/AGENTS.md +544 -0
- package/CHANGELOG.md +37 -0
- package/CODE_OF_CONDUCT.md +21 -0
- package/CONTRIBUTING.md +32 -0
- package/Dockerfile +84 -0
- package/LICENSE +21 -0
- package/README.md +328 -59
- package/SECURITY.md +16 -0
- package/bun.lock +3853 -0
- package/cli/README.md +94 -0
- package/cli/bun.lock +306 -0
- package/cli/index.ts +96 -0
- package/cli/package-lock.json +2157 -0
- package/cli/package.json +30 -0
- package/cli/src/commands/backup.ts +78 -0
- package/cli/src/commands/doctor.ts +82 -0
- package/cli/src/commands/init.ts +234 -0
- package/cli/src/commands/logs.ts +26 -0
- package/cli/src/commands/open.ts +23 -0
- package/cli/src/commands/remove.ts +44 -0
- package/cli/src/commands/restart.ts +21 -0
- package/cli/src/commands/restore.ts +90 -0
- package/cli/src/commands/start.ts +26 -0
- package/cli/src/commands/status.ts +25 -0
- package/cli/src/commands/stop.ts +20 -0
- package/cli/src/commands/upgrade.ts +28 -0
- package/cli/src/lib/docker.ts +40 -0
- package/cli/src/lib/env.ts +42 -0
- package/cli/src/lib/ui.ts +43 -0
- package/cli/tsconfig.json +13 -0
- package/cli/tsup.config.ts +12 -0
- package/components.json +24 -0
- package/docker/README.md +430 -0
- package/docker/compose.dev-minio.yml +30 -0
- package/docker/compose.dev.yml +39 -0
- package/docker/compose.local.yml +84 -0
- package/docker/compose.yml +153 -0
- package/docs/VERSIONING.md +117 -0
- package/docs/database/DRIZZLE_COMMANDS_EXPLAINED.md +1779 -0
- package/docs/database/DRIZZLE_ZOD_POSTGRESQL_INSTRUCTION.md +646 -0
- package/docs/database/MIGRATION_BEST_PRACTICES.md +601 -0
- package/docs/database/MIGRATION_ROLLBACK.md +1080 -0
- package/docs/database/MIGRATION_SYSTEM.md +165 -0
- package/docs/database/MIGRATION_TROUBLESHOOTING.md +881 -0
- package/docs/development/ENVIRONMENT_CONFIG.md +896 -0
- package/docs/development/LOCAL_DEVELOPMENT.md +456 -0
- package/docs/development/REMOTE_DATABASE_SETUP.md +786 -0
- package/docs/development/STORAGE_SETUP.md +207 -0
- package/docs/development/SUPABASE_LOCAL_SETUP.md +178 -0
- package/docs/development/TESTING.md +714 -0
- package/docs/feature-architectures/LOADING_ARCHITECTURE.md +343 -0
- package/docs/feature-architectures/NOTIFICATION_ARCHITECTURE.md +858 -0
- package/docs/feature-architectures/RATE_LIMIT_RESET.md +147 -0
- package/docs/feature-architectures/RBAC.md +1132 -0
- package/docs/feature-architectures/RESOURCE_LIMITS.md +69 -0
- package/docs/feature-architectures/SECURITY.md +284 -0
- package/docs/feature-architectures/WORKSPACES.md +278 -0
- package/docs/plans/admin-setup-wizard-routing-plan.md +623 -0
- package/drizzle/0000_purple_wilson_fisk.sql +360 -0
- package/drizzle/0001_drop_instance_public_url.sql +1 -0
- package/drizzle/meta/0000_snapshot.json +3118 -0
- package/drizzle/meta/_journal.json +20 -0
- package/drizzle.config.ts +13 -0
- package/eslint.config.mjs +44 -0
- package/install.sh +180 -0
- package/next.config.ts +91 -0
- package/package.json +128 -22
- package/playwright.config.ts +70 -0
- package/postcss.config.mjs +7 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/logo.svg +11 -0
- package/public/next.svg +1 -0
- package/public/playground/CPM-101/as-is-image.jpg +0 -0
- package/public/playground/CPM-101/to-be-image.jpg +0 -0
- package/public/playground/TEST-1/LinkedIn-skeleton-screen.png +0 -0
- package/public/playground/TEST-1/https___dev-to-uploads.s3.amazonaws.com_uploads_articles_vuahe90ka1mkx9aepmea.webp +0 -0
- package/public/playground/TEST-1/linkedin_skeletonscreen.jpg +0 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/scripts/__tests__/migrate.integration.test.ts +642 -0
- package/scripts/__tests__/migrate.property.test.ts +1714 -0
- package/scripts/__tests__/migrate.test.ts +536 -0
- package/scripts/admin-reset-password.ts +114 -0
- package/scripts/check-email-queue.ts +99 -0
- package/scripts/check-sessions.ts +50 -0
- package/scripts/db-pull-data.sh +73 -0
- package/scripts/force-verify-email.sh +13 -0
- package/scripts/migrate.ts +693 -0
- package/scripts/process-email-queue.ts +26 -0
- package/scripts/reset-db.ts +47 -0
- package/scripts/reset-rate-limit.sh +26 -0
- package/scripts/reset-remote-db.sql +31 -0
- package/scripts/retry-failed-emails.ts +67 -0
- package/scripts/seed.ts +605 -0
- package/scripts/setup-monitoring.sh +440 -0
- package/scripts/sync-migration-tracking.ts +113 -0
- package/scripts/test-ci-error-handling.sh +237 -0
- package/scripts/test-ci-workflow.sh +200 -0
- package/scripts/test-migration.sh +151 -0
- package/scripts/validate-env.ts +25 -0
- package/scripts/validate-migration-system.ts +566 -0
- package/scripts/verify-ci-status-reporting.sh +206 -0
- package/scripts/verify-user-email.sql +22 -0
- package/scripts/verify-vercel-integration.ts +292 -0
- package/seed_data.md +54 -0
- package/src/app/(protected)/(team)/(routes)/[projectSlug]/error.tsx +89 -0
- package/src/app/(protected)/(team)/(routes)/[projectSlug]/loading.tsx +101 -0
- package/src/app/(protected)/(team)/(routes)/[projectSlug]/page.tsx +91 -0
- package/src/app/(protected)/(team)/(routes)/issue/[issueKey]/README.md +192 -0
- package/src/app/(protected)/(team)/(routes)/issue/[issueKey]/error.tsx +58 -0
- package/src/app/(protected)/(team)/(routes)/issue/[issueKey]/loading.tsx +14 -0
- package/src/app/(protected)/(team)/(routes)/issue/[issueKey]/not-found.tsx +47 -0
- package/src/app/(protected)/(team)/(routes)/issue/[issueKey]/page.tsx +91 -0
- package/src/app/(protected)/(team)/projects/page.tsx +16 -0
- package/src/app/(protected)/(team)/team/settings/(section)/instance/page.tsx +52 -0
- package/src/app/(protected)/(team)/team/settings/(section)/integrations/loading.tsx +5 -0
- package/src/app/(protected)/(team)/team/settings/(section)/integrations/page.tsx +23 -0
- package/src/app/(protected)/(team)/team/settings/(section)/members/loading.tsx +5 -0
- package/src/app/(protected)/(team)/team/settings/(section)/members/page.tsx +35 -0
- package/src/app/(protected)/(team)/team/settings/layout.tsx +72 -0
- package/src/app/(protected)/(team)/team/settings/loading.tsx +5 -0
- package/src/app/(protected)/(team)/team/settings/page.tsx +71 -0
- package/src/app/(protected)/dev/auth/README.md +151 -0
- package/src/app/(protected)/dev/auth/page.tsx +590 -0
- package/src/app/(protected)/layout.test.tsx +209 -0
- package/src/app/(protected)/layout.tsx +28 -0
- package/src/app/(protected)/onboarding/page.tsx +27 -0
- package/src/app/(protected)/settings/integrations/page.tsx +23 -0
- package/src/app/(protected)/settings/layout.tsx +26 -0
- package/src/app/(protected)/settings/notifications/page.tsx +26 -0
- package/src/app/(protected)/settings/other/page.tsx +23 -0
- package/src/app/(protected)/settings/page.tsx +23 -0
- package/src/app/(protected)/settings/preferences/page.tsx +23 -0
- package/src/app/(protected)/settings/security/page.tsx +37 -0
- package/src/app/(public)/forgot-password/page.tsx +20 -0
- package/src/app/(public)/invite/project/[token]/error.tsx +50 -0
- package/src/app/(public)/invite/project/[token]/loading.tsx +39 -0
- package/src/app/(public)/invite/project/[token]/page.tsx +156 -0
- package/src/app/(public)/layout.tsx +9 -0
- package/src/app/(public)/privacy-policy/page.tsx +12 -0
- package/src/app/(public)/reset-password/page.tsx +37 -0
- package/src/app/(public)/setup/__tests__/page.test.tsx +30 -0
- package/src/app/(public)/setup/page.tsx +17 -0
- package/src/app/(public)/share/issue/[token]/page.tsx +51 -0
- package/src/app/(public)/sign-in/page.tsx +55 -0
- package/src/app/(public)/sign-up/page.tsx +23 -0
- package/src/app/(public)/verify-email/page.tsx +22 -0
- package/src/app/(public)/verify-email-confirm/page.tsx +40 -0
- package/src/app/api/auth/[...all]/route.ts +6 -0
- package/src/app/api/auth/delete-account/route.ts +134 -0
- package/src/app/api/auth/dev/force-verify/route.ts +180 -0
- package/src/app/api/auth/dev/reset-rate-limit/route.ts +144 -0
- package/src/app/api/auth/dev/sessions/route.ts +172 -0
- package/src/app/api/auth/forgot-password/__tests__/forgot-password.property.test.ts +397 -0
- package/src/app/api/auth/forgot-password/route.ts +277 -0
- package/src/app/api/auth/logout/route.ts +115 -0
- package/src/app/api/auth/me/route.ts +123 -0
- package/src/app/api/auth/providers/__tests__/route.test.ts +236 -0
- package/src/app/api/auth/providers/route.ts +119 -0
- package/src/app/api/auth/resend-verification/route.ts +262 -0
- package/src/app/api/auth/reset-password/__tests__/reset-password.property.test.ts +493 -0
- package/src/app/api/auth/reset-password/__tests__/route.test.ts +284 -0
- package/src/app/api/auth/reset-password/route.ts +251 -0
- package/src/app/api/auth/verify-email/route.ts +232 -0
- package/src/app/api/example-cors/route.ts +61 -0
- package/src/app/api/health/route.ts +14 -0
- package/src/app/api/invite/project/[token]/__tests__/accept-invitation.integration.test.ts +348 -0
- package/src/app/api/invite/project/[token]/decline/route.ts +99 -0
- package/src/app/api/invite/project/[token]/route.ts +269 -0
- package/src/app/api/issues/[issueId]/activities/route.ts +213 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/annotations/[annotationId]/comments/[commentId]/route.ts +486 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/annotations/[annotationId]/comments/route.ts +283 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/annotations/[annotationId]/read/route.ts +242 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/annotations/[annotationId]/route.ts +534 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/annotations/route.ts +514 -0
- package/src/app/api/issues/[issueId]/attachments/[attachmentId]/route.ts +161 -0
- package/src/app/api/issues/[issueId]/attachments/route.ts +376 -0
- package/src/app/api/issues/[issueId]/route.ts +516 -0
- package/src/app/api/notifications/[id]/read/route.ts +131 -0
- package/src/app/api/notifications/__tests__/notifications.integration.test.ts +350 -0
- package/src/app/api/notifications/read-all/route.ts +72 -0
- package/src/app/api/notifications/route.ts +148 -0
- package/src/app/api/notifications/unread-count/route.ts +77 -0
- package/src/app/api/projects/[id]/activities/route.ts +174 -0
- package/src/app/api/projects/[id]/invitations/[invitationId]/resend/route.ts +99 -0
- package/src/app/api/projects/[id]/invitations/[invitationId]/route.ts +96 -0
- package/src/app/api/projects/[id]/invitations/route.ts +254 -0
- package/src/app/api/projects/[id]/issues/route.ts +452 -0
- package/src/app/api/projects/[id]/join/route.ts +207 -0
- package/src/app/api/projects/[id]/members/[memberId]/route.ts +364 -0
- package/src/app/api/projects/[id]/members/me/route.ts +121 -0
- package/src/app/api/projects/[id]/members/route.ts +129 -0
- package/src/app/api/projects/[id]/route.ts +476 -0
- package/src/app/api/projects/route.ts +394 -0
- package/src/app/api/setup/admin/route.ts +255 -0
- package/src/app/api/setup/complete/__tests__/route.test.ts +60 -0
- package/src/app/api/setup/complete/route.ts +244 -0
- package/src/app/api/setup/config/route.ts +195 -0
- package/src/app/api/setup/export/route.ts +111 -0
- package/src/app/api/setup/health/route.ts +74 -0
- package/src/app/api/setup/import/route.ts +154 -0
- package/src/app/api/setup/status/route.ts +82 -0
- package/src/app/api/setup/workspace/route.ts +252 -0
- package/src/app/api/teams/[teamId]/export/route.ts +115 -0
- package/src/app/api/teams/[teamId]/invitations/[invitationId]/resend/route.ts +132 -0
- package/src/app/api/teams/[teamId]/invitations/[invitationId]/route.ts +117 -0
- package/src/app/api/teams/[teamId]/invitations/route.ts +363 -0
- package/src/app/api/teams/[teamId]/members/[userId]/route.ts +335 -0
- package/src/app/api/teams/[teamId]/members/route.ts +184 -0
- package/src/app/api/teams/[teamId]/members/search/route.ts +202 -0
- package/src/app/api/teams/[teamId]/route.ts +423 -0
- package/src/app/api/teams/[teamId]/switch/route.ts +140 -0
- package/src/app/api/teams/[teamId]/transfer-ownership/route.ts +212 -0
- package/src/app/api/teams/invitations/[token]/accept/route.ts +140 -0
- package/src/app/api/teams/invitations/by-id/[id]/accept/route.ts +98 -0
- package/src/app/api/teams/invitations/by-id/[id]/decline/route.ts +90 -0
- package/src/app/api/teams/route.ts +278 -0
- package/src/app/api/uploads/media/route.ts +118 -0
- package/src/app/api/uploads/presigned/route.ts +49 -0
- package/src/app/api/user/linked-accounts/route.ts +35 -0
- package/src/app/email-preview/page.tsx +11 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/global-error.tsx +21 -0
- package/src/app/layout.tsx +50 -0
- package/src/app/page.tsx +5 -0
- package/src/components/icons/atlassian-icon.tsx +22 -0
- package/src/components/icons/index.ts +1 -0
- package/src/components/layout/SIDEBAR_LAYOUT_BEST_PRACTICES.md +240 -0
- package/src/components/layout/app-shell-header-store.tsx +20 -0
- package/src/components/layout/app-shell-skeleton.tsx +89 -0
- package/src/components/layout/app-shell-wrapper.tsx +32 -0
- package/src/components/layout/app-shell.test.tsx +155 -0
- package/src/components/layout/app-shell.tsx +100 -0
- package/src/components/shared/headers/app-header-configurator.tsx +42 -0
- package/src/components/shared/headers/app-header.tsx +103 -0
- package/src/components/shared/headers/header-user-menu.tsx +247 -0
- package/src/components/shared/headers/index.ts +44 -0
- package/src/components/shared/headers/page-header.tsx +25 -0
- package/src/components/shared/notifications/__tests__/notification-bell.test.tsx +159 -0
- package/src/components/shared/notifications/__tests__/notification-dropdown.test.tsx +296 -0
- package/src/components/shared/notifications/__tests__/notification-item.test.tsx +328 -0
- package/src/components/shared/notifications/index.ts +45 -0
- package/src/components/shared/notifications/notification-actions.tsx +295 -0
- package/src/components/shared/notifications/notification-bell-button.tsx +77 -0
- package/src/components/shared/notifications/notification-dropdown.tsx +160 -0
- package/src/components/shared/notifications/notification-group-item.tsx +268 -0
- package/src/components/shared/notifications/notification-item.tsx +193 -0
- package/src/components/shared/notifications/notification-load-more.tsx +50 -0
- package/src/components/shared/notifications/notification-panel.tsx +49 -0
- package/src/components/shared/notifications/utils.tsx +127 -0
- package/src/components/shared/permission-guard/index.ts +1 -0
- package/src/components/shared/permission-guard/permission-tooltip.tsx +45 -0
- package/src/components/shared/relative-time.tsx +53 -0
- package/src/components/shared/section-container.tsx +32 -0
- package/src/components/shared/service-status-banner.tsx +121 -0
- package/src/components/shared/settings-sidebar/index.ts +2 -0
- package/src/components/shared/settings-sidebar/team-setting-aside.tsx +97 -0
- package/src/components/shared/settings-sidebar/user-settings-aside.tsx +66 -0
- package/src/components/shared/sidebar/app-sidebar.tsx +146 -0
- package/src/components/shared/sidebar/index.ts +36 -0
- package/src/components/shared/sidebar/sidebar-main.tsx +81 -0
- package/src/components/shared/sidebar/sidebar-project.tsx +61 -0
- package/src/components/shared/sidebar/sidebar-team-avatar.tsx +126 -0
- package/src/components/shared/sidebar/sidebar-team-switcher.tsx +185 -0
- package/src/components/shared/sidebar/type.ts +97 -0
- package/src/components/ui/alert-dialog.tsx +157 -0
- package/src/components/ui/alert.tsx +66 -0
- package/src/components/ui/avatar-upload.tsx +147 -0
- package/src/components/ui/avatar.tsx +53 -0
- package/src/components/ui/badge.tsx +46 -0
- package/src/components/ui/breadcrumb.tsx +109 -0
- package/src/components/ui/button.tsx +60 -0
- package/src/components/ui/card.tsx +92 -0
- package/src/components/ui/checkbox.tsx +32 -0
- package/src/components/ui/collapsible.tsx +33 -0
- package/src/components/ui/command.tsx +184 -0
- package/src/components/ui/dialog.tsx +143 -0
- package/src/components/ui/dropdown-menu.tsx +257 -0
- package/src/components/ui/empty.tsx +104 -0
- package/src/components/ui/field.tsx +244 -0
- package/src/components/ui/image-cropper-dialog.tsx +167 -0
- package/src/components/ui/input.tsx +21 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/optimized-image.tsx +220 -0
- package/src/components/ui/pagination.tsx +127 -0
- package/src/components/ui/popover.tsx +48 -0
- package/src/components/ui/progress.tsx +31 -0
- package/src/components/ui/radio-group.tsx +45 -0
- package/src/components/ui/scroll-area.tsx +58 -0
- package/src/components/ui/select.tsx +187 -0
- package/src/components/ui/separator.tsx +28 -0
- package/src/components/ui/sheet.tsx +139 -0
- package/src/components/ui/sidebar.tsx +733 -0
- package/src/components/ui/skeleton.tsx +13 -0
- package/src/components/ui/sonner.tsx +40 -0
- package/src/components/ui/spinner.tsx +16 -0
- package/src/components/ui/switch.tsx +31 -0
- package/src/components/ui/table.tsx +116 -0
- package/src/components/ui/tabs.tsx +66 -0
- package/src/components/ui/textarea.tsx +23 -0
- package/src/components/ui/tooltip.tsx +61 -0
- package/src/config/__tests__/workspace.property.test.ts +40 -0
- package/src/config/auth.ts +62 -0
- package/src/config/integrations.ts +126 -0
- package/src/config/quotas.ts +20 -0
- package/src/config/roles.ts +463 -0
- package/src/config/settings-nav.ts +39 -0
- package/src/config/team-settings-nav.ts +37 -0
- package/src/config/user-settings-nav.ts +42 -0
- package/src/config/version.ts +1 -0
- package/src/config/workspace.ts +64 -0
- package/src/features/annotations/README.md +283 -0
- package/src/features/annotations/api/annotations-api.ts +194 -0
- package/src/features/annotations/api/comments-api.ts +147 -0
- package/src/features/annotations/api/index.ts +71 -0
- package/src/features/annotations/api/save-annotation.ts +150 -0
- package/src/features/annotations/api/schemas.ts +142 -0
- package/src/features/annotations/components/annotated-attachment-view.tsx +576 -0
- package/src/features/annotations/components/annotation-action-sheet.tsx +140 -0
- package/src/features/annotations/components/annotation-annotations-panel.tsx +213 -0
- package/src/features/annotations/components/annotation-box.tsx +539 -0
- package/src/features/annotations/components/annotation-canvas.tsx +534 -0
- package/src/features/annotations/components/annotation-comment-input.tsx +145 -0
- package/src/features/annotations/components/annotation-context-menu.tsx +164 -0
- package/src/features/annotations/components/annotation-drawer.tsx +231 -0
- package/src/features/annotations/components/annotation-layer.tsx +271 -0
- package/src/features/annotations/components/annotation-pin.tsx +318 -0
- package/src/features/annotations/components/annotation-popover.tsx +562 -0
- package/src/features/annotations/components/annotation-thread-panel.tsx +485 -0
- package/src/features/annotations/components/annotation-thread-preview.tsx +195 -0
- package/src/features/annotations/components/annotation-toolbar.tsx +244 -0
- package/src/features/annotations/components/keyboard-shortcuts-modal.tsx +79 -0
- package/src/features/annotations/docs/ANNOTATIONS_ARCHITECTURE.md +67 -0
- package/src/features/annotations/docs/ANNOTATION_SAVE_ARCHITECTURE.md +422 -0
- package/src/features/annotations/docs/ANNOTATION_SAVE_FEATURE.md +408 -0
- package/src/features/annotations/docs/BOX_ANNOTATION_GUIDE.md +542 -0
- package/src/features/annotations/docs/NEXTSTEP.md +28 -0
- package/src/features/annotations/docs/STALE_CLOSURE_FIX.md +344 -0
- package/src/features/annotations/docs/UNDO_REDO_QUICK_START.md +545 -0
- package/src/features/annotations/docs/local_first_canvas_autosave_architecture.md +674 -0
- package/src/features/annotations/examples/complete-example.tsx +266 -0
- package/src/features/annotations/examples/save-annotation-example.tsx +309 -0
- package/src/features/annotations/hooks/__tests__/use-annotation-permissions.property.test.tsx +493 -0
- package/src/features/annotations/hooks/index.ts +36 -0
- package/src/features/annotations/hooks/use-annotation-batch-save.ts +109 -0
- package/src/features/annotations/hooks/use-annotation-comments.ts +353 -0
- package/src/features/annotations/hooks/use-annotation-drafts.ts +137 -0
- package/src/features/annotations/hooks/use-annotation-edit-state.ts +99 -0
- package/src/features/annotations/hooks/use-annotation-history-tracker.ts +159 -0
- package/src/features/annotations/hooks/use-annotation-integration.ts +916 -0
- package/src/features/annotations/hooks/use-annotation-permissions.ts +210 -0
- package/src/features/annotations/hooks/use-annotation-popover.ts +175 -0
- package/src/features/annotations/hooks/use-annotation-save.ts +208 -0
- package/src/features/annotations/hooks/use-annotation-tools.ts +237 -0
- package/src/features/annotations/hooks/use-annotations-with-history.ts +332 -0
- package/src/features/annotations/hooks/use-auto-save.ts +94 -0
- package/src/features/annotations/index.ts +111 -0
- package/src/features/annotations/types/annotation.ts +201 -0
- package/src/features/annotations/types/index.ts +28 -0
- package/src/features/annotations/utils/history-manager.ts +73 -0
- package/src/features/annotations/utils/index.ts +2 -0
- package/src/features/annotations/utils/map-attachments-to-threads.ts +28 -0
- package/src/features/annotations/utils/position-comment-input.ts +136 -0
- package/src/features/annotations/utils/re-sequence-labels.ts +92 -0
- package/src/features/annotations/utils/validate-annotation-label.ts +120 -0
- package/src/features/auth/api/types.ts +101 -0
- package/src/features/auth/components/__tests__/role-gate.test.tsx +448 -0
- package/src/features/auth/components/__tests__/social-login-buttons.test.tsx +313 -0
- package/src/features/auth/components/auth-card.tsx +36 -0
- package/src/features/auth/components/forgot-password-form.tsx +115 -0
- package/src/features/auth/components/index.ts +14 -0
- package/src/features/auth/components/invite-code-input.tsx +155 -0
- package/src/features/auth/components/invited-user-form.tsx +309 -0
- package/src/features/auth/components/onboarding-form.tsx +195 -0
- package/src/features/auth/components/password-strength-indicator.tsx +113 -0
- package/src/features/auth/components/reset-password-form.tsx +138 -0
- package/src/features/auth/components/role-gate.tsx +124 -0
- package/src/features/auth/components/self-registration-choice.tsx +153 -0
- package/src/features/auth/components/sign-in-form.tsx +159 -0
- package/src/features/auth/components/sign-up-form.tsx +158 -0
- package/src/features/auth/components/social-login-buttons.tsx +219 -0
- package/src/features/auth/hooks/__tests__/use-onboarding.test.tsx +109 -0
- package/src/features/auth/hooks/__tests__/use-session.test.tsx +160 -0
- package/src/features/auth/hooks/index.ts +15 -0
- package/src/features/auth/hooks/use-accept-invitation.ts +194 -0
- package/src/features/auth/hooks/use-delete-account.ts +86 -0
- package/src/features/auth/hooks/use-force-verify.ts +89 -0
- package/src/features/auth/hooks/use-forgot-password.ts +144 -0
- package/src/features/auth/hooks/use-link-account.ts +78 -0
- package/src/features/auth/hooks/use-linked-accounts.ts +88 -0
- package/src/features/auth/hooks/use-onboarding.ts +159 -0
- package/src/features/auth/hooks/use-resend-verification.ts +139 -0
- package/src/features/auth/hooks/use-reset-password.ts +151 -0
- package/src/features/auth/hooks/use-reset-rate-limit.ts +56 -0
- package/src/features/auth/hooks/use-self-registration.ts +202 -0
- package/src/features/auth/hooks/use-session.ts +81 -0
- package/src/features/auth/hooks/use-sessions.ts +59 -0
- package/src/features/auth/hooks/use-sign-in.ts +234 -0
- package/src/features/auth/hooks/use-sign-out.ts +88 -0
- package/src/features/auth/hooks/use-sign-up.ts +194 -0
- package/src/features/auth/hooks/use-unlink-account.ts +100 -0
- package/src/features/auth/hooks/use-verify-email-token.ts +125 -0
- package/src/features/auth/index.ts +75 -0
- package/src/features/auth/screens/forgot-password-screen.tsx +33 -0
- package/src/features/auth/screens/index.ts +7 -0
- package/src/features/auth/screens/onboarding-screen.tsx +49 -0
- package/src/features/auth/screens/reset-password-screen.tsx +33 -0
- package/src/features/auth/screens/sign-in-screen.tsx +61 -0
- package/src/features/auth/screens/sign-up-screen.tsx +37 -0
- package/src/features/auth/screens/verify-email-confirm-screen.tsx +286 -0
- package/src/features/auth/screens/verify-email-screen.tsx +146 -0
- package/src/features/auth/types/index.ts +14 -0
- package/src/features/auth/utils/__tests__/validators.test.ts +331 -0
- package/src/features/auth/utils/password-strength.ts +129 -0
- package/src/features/auth/utils/validators.ts +124 -0
- package/src/features/email-preview/actions/render-email.ts +21 -0
- package/src/features/email-preview/screens/email-preview-screen.tsx +81 -0
- package/src/features/folder-scaffold-template/index.ts +0 -0
- package/src/features/instance-settings/components/index.ts +6 -0
- package/src/features/instance-settings/components/instance-settings-form.tsx +180 -0
- package/src/features/instance-settings/components/instance-status-display.tsx +158 -0
- package/src/features/instance-settings/index.ts +7 -0
- package/src/features/instance-settings/screens/index.ts +5 -0
- package/src/features/instance-settings/screens/instance-settings-screen.tsx +59 -0
- package/src/features/issues/README.md +330 -0
- package/src/features/issues/api/create-issue.ts +19 -0
- package/src/features/issues/api/delete-issue.ts +27 -0
- package/src/features/issues/api/get-issue-activities.ts +58 -0
- package/src/features/issues/api/get-issue-details.ts +25 -0
- package/src/features/issues/api/get-project-issues-server.ts +44 -0
- package/src/features/issues/api/get-project-issues.ts +21 -0
- package/src/features/issues/api/index.ts +44 -0
- package/src/features/issues/api/update-issue.ts +31 -0
- package/src/features/issues/api/upload-attachment.ts +81 -0
- package/src/features/issues/components/activity-timeline.tsx +440 -0
- package/src/features/issues/components/canvas-state-indicator.tsx +90 -0
- package/src/features/issues/components/centered-canvas-view.tsx +739 -0
- package/src/features/issues/components/image-selector.tsx +123 -0
- package/src/features/issues/components/image-upload-zone.tsx +262 -0
- package/src/features/issues/components/infinite-canvas-background.tsx +163 -0
- package/src/features/issues/components/inline-editable-select.tsx +173 -0
- package/src/features/issues/components/inline-editable-text.tsx +225 -0
- package/src/features/issues/components/inline-editable-textarea.tsx +219 -0
- package/src/features/issues/components/inline-editable-user-select.tsx +202 -0
- package/src/features/issues/components/issue-deletion-dialog.tsx +142 -0
- package/src/features/issues/components/issue-details-panel.tsx +101 -0
- package/src/features/issues/components/issues-create-dialog.tsx +578 -0
- package/src/features/issues/components/issues-list-filter.tsx +312 -0
- package/src/features/issues/components/issues-list.tsx +151 -0
- package/src/features/issues/components/issues-priority-badge.tsx +77 -0
- package/src/features/issues/components/issues-status-badge.tsx +100 -0
- package/src/features/issues/components/metadata-section.tsx +389 -0
- package/src/features/issues/components/optimized-attachment-view.tsx +528 -0
- package/src/features/issues/components/optimized-image.tsx +257 -0
- package/src/features/issues/components/panel-header.tsx +186 -0
- package/src/features/issues/components/preload.ts +31 -0
- package/src/features/issues/components/priority-selector.tsx +101 -0
- package/src/features/issues/components/responsive-issue-layout-skeleton.tsx +139 -0
- package/src/features/issues/components/responsive-issue-layout.tsx +617 -0
- package/src/features/issues/components/status-selector.tsx +320 -0
- package/src/features/issues/components/type-selector.tsx +102 -0
- package/src/features/issues/components/upload-progress-overlay.tsx +35 -0
- package/src/features/issues/components/uploaded-image-preview.tsx +173 -0
- package/src/features/issues/components/workflow-control.tsx +318 -0
- package/src/features/issues/components/zoom-controls.tsx +150 -0
- package/src/features/issues/config/index.ts +47 -0
- package/src/features/issues/config/options.ts +323 -0
- package/src/features/issues/config/workflow.ts +102 -0
- package/src/features/issues/docs/ARCHITECTURE_DIAGRAM.md +321 -0
- package/src/features/issues/docs/BACKEND_ARCHITECTURE.md +194 -0
- package/src/features/issues/docs/IMAGE_COMPONENTS_ARCHITECTURE.md +363 -0
- package/src/features/issues/docs/IMAGE_COMPONENTS_IMPORTS.md +412 -0
- package/src/features/issues/docs/IMPLEMENTATION_CHECKLIST.md +210 -0
- package/src/features/issues/docs/ROUTE_SETUP_COMPLETE.md +242 -0
- package/src/features/issues/hooks/index.ts +78 -0
- package/src/features/issues/hooks/use-canvas-transform.ts +255 -0
- package/src/features/issues/hooks/use-create-issue.ts +28 -0
- package/src/features/issues/hooks/use-elastic-scroll.ts +296 -0
- package/src/features/issues/hooks/use-issue-activities.ts +71 -0
- package/src/features/issues/hooks/use-issue-delete.ts +84 -0
- package/src/features/issues/hooks/use-issue-details.ts +70 -0
- package/src/features/issues/hooks/use-issue-filters.ts +50 -0
- package/src/features/issues/hooks/use-issue-update.ts +93 -0
- package/src/features/issues/hooks/use-keyboard-shortcuts.ts +104 -0
- package/src/features/issues/hooks/use-optimized-image.ts +228 -0
- package/src/features/issues/hooks/use-project-issues.ts +14 -0
- package/src/features/issues/index.ts +65 -0
- package/src/features/issues/screens/issue-details-screen.tsx +207 -0
- package/src/features/issues/screens/issue-details-skeletons.tsx +295 -0
- package/src/features/issues/screens/issue-share-screen.tsx +56 -0
- package/src/features/issues/types/index.ts +48 -0
- package/src/features/issues/types/issue.ts +291 -0
- package/src/features/issues/utils/filter-issues.ts +141 -0
- package/src/features/issues/utils/index.ts +14 -0
- package/src/features/legal/index.ts +1 -0
- package/src/features/legal/screens/privacy-policy-screen.tsx +307 -0
- package/src/features/notifications/api/get-notifications.ts +58 -0
- package/src/features/notifications/api/get-unread-count.ts +37 -0
- package/src/features/notifications/api/index.ts +35 -0
- package/src/features/notifications/api/mark-all-as-read.ts +37 -0
- package/src/features/notifications/api/mark-as-read.ts +41 -0
- package/src/features/notifications/api/types.ts +109 -0
- package/src/features/notifications/hooks/__tests__/use-notification-subscription.test.ts +206 -0
- package/src/features/notifications/hooks/index.ts +28 -0
- package/src/features/notifications/hooks/use-mark-all-as-read.ts +106 -0
- package/src/features/notifications/hooks/use-mark-as-read.ts +106 -0
- package/src/features/notifications/hooks/use-notification-subscription.ts +244 -0
- package/src/features/notifications/hooks/use-notification-toast.ts +161 -0
- package/src/features/notifications/hooks/use-notifications.ts +80 -0
- package/src/features/notifications/hooks/use-unread-count.ts +60 -0
- package/src/features/notifications/index.ts +48 -0
- package/src/features/notifications/utils/group-notifications.ts +152 -0
- package/src/features/notifications/utils/index.ts +9 -0
- package/src/features/projects/api/create-invitation.ts +45 -0
- package/src/features/projects/api/create-project.ts +64 -0
- package/src/features/projects/api/delete-project.ts +50 -0
- package/src/features/projects/api/get-project-activities.ts +43 -0
- package/src/features/projects/api/get-project-members.ts +53 -0
- package/src/features/projects/api/get-project.ts +49 -0
- package/src/features/projects/api/get-projects.ts +61 -0
- package/src/features/projects/api/index.ts +27 -0
- package/src/features/projects/api/join-project.ts +52 -0
- package/src/features/projects/api/leave-project.ts +51 -0
- package/src/features/projects/api/list-invitations.ts +36 -0
- package/src/features/projects/api/remove-member.ts +60 -0
- package/src/features/projects/api/resend-invitation.ts +36 -0
- package/src/features/projects/api/revoke-invitation.ts +36 -0
- package/src/features/projects/api/types.ts +286 -0
- package/src/features/projects/api/update-member-role.ts +70 -0
- package/src/features/projects/api/update-project.ts +69 -0
- package/src/features/projects/components/__tests__/project-detail-activity-feed.test.tsx +106 -0
- package/src/features/projects/components/__tests__/project-invitation-dialog.test.tsx +211 -0
- package/src/features/projects/components/__tests__/project-member-manager-dialog.test.tsx +254 -0
- package/src/features/projects/components/index.ts +21 -0
- package/src/features/projects/components/project-actions.tsx +248 -0
- package/src/features/projects/components/project-create-dialog.tsx +410 -0
- package/src/features/projects/components/project-detail-activity-feed.tsx +206 -0
- package/src/features/projects/components/project-detail-header.tsx +103 -0
- package/src/features/projects/components/project-detail-overview.tsx +128 -0
- package/src/features/projects/components/project-icon-selector.test.tsx +49 -0
- package/src/features/projects/components/project-icon-selector.tsx +76 -0
- package/src/features/projects/components/project-invitation-dialog.tsx +368 -0
- package/src/features/projects/components/project-issues.tsx +128 -0
- package/src/features/projects/components/project-leave-button.tsx +69 -0
- package/src/features/projects/components/project-list-card.tsx +246 -0
- package/src/features/projects/components/project-list-filters.tsx +320 -0
- package/src/features/projects/components/project-member-manager-dialog.tsx +419 -0
- package/src/features/projects/components/project-settings-dialog.tsx +204 -0
- package/src/features/projects/components/project-stats.tsx +46 -0
- package/src/features/projects/components/project-title-section.tsx +78 -0
- package/src/features/projects/config/icons.ts +91 -0
- package/src/features/projects/hooks/index.ts +28 -0
- package/src/features/projects/hooks/use-create-invitation.ts +83 -0
- package/src/features/projects/hooks/use-create-project.ts +77 -0
- package/src/features/projects/hooks/use-delete-project.ts +84 -0
- package/src/features/projects/hooks/use-join-project.ts +43 -0
- package/src/features/projects/hooks/use-leave-project.ts +84 -0
- package/src/features/projects/hooks/use-project-activities.ts +39 -0
- package/src/features/projects/hooks/use-project-filters.ts +86 -0
- package/src/features/projects/hooks/use-project-invitations.ts +66 -0
- package/src/features/projects/hooks/use-project-members.ts +57 -0
- package/src/features/projects/hooks/use-project.ts +67 -0
- package/src/features/projects/hooks/use-projects.ts +49 -0
- package/src/features/projects/hooks/use-recent-projects.ts +58 -0
- package/src/features/projects/hooks/use-remove-member.ts +89 -0
- package/src/features/projects/hooks/use-resend-invitation.ts +68 -0
- package/src/features/projects/hooks/use-revoke-invitation.ts +71 -0
- package/src/features/projects/hooks/use-team-member-suggestions.ts +133 -0
- package/src/features/projects/hooks/use-update-member-role.ts +92 -0
- package/src/features/projects/hooks/use-update-project.ts +88 -0
- package/src/features/projects/index.ts +91 -0
- package/src/features/projects/screens/index.ts +3 -0
- package/src/features/projects/screens/invitation-acceptance-screen.tsx +320 -0
- package/src/features/projects/screens/project-detail-screen-wrapper.tsx +47 -0
- package/src/features/projects/screens/project-detail-screen.tsx +661 -0
- package/src/features/projects/screens/projects-list-screen.tsx +161 -0
- package/src/features/projects/types/index.ts +59 -0
- package/src/features/projects/utils/format-helpers.ts +16 -0
- package/src/features/projects/utils/index.ts +2 -0
- package/src/features/projects/utils/role-helpers.ts +25 -0
- package/src/features/setup/api/complete-setup.ts +21 -0
- package/src/features/setup/api/create-admin.ts +21 -0
- package/src/features/setup/api/create-first-workspace.ts +21 -0
- package/src/features/setup/api/get-instance-status.ts +12 -0
- package/src/features/setup/api/get-service-health.ts +12 -0
- package/src/features/setup/api/index.ts +44 -0
- package/src/features/setup/api/save-instance-config.ts +21 -0
- package/src/features/setup/api/types.ts +122 -0
- package/src/features/setup/components/__tests__/setup-wizard-ui.test.tsx +362 -0
- package/src/features/setup/components/admin-account-step.tsx +205 -0
- package/src/features/setup/components/first-workspace-step.tsx +120 -0
- package/src/features/setup/components/index.ts +9 -0
- package/src/features/setup/components/instance-config-step.tsx +107 -0
- package/src/features/setup/components/mail-config-step.tsx +205 -0
- package/src/features/setup/components/sample-data-step.tsx +131 -0
- package/src/features/setup/components/service-health-step.tsx +180 -0
- package/src/features/setup/components/service-status-badge.tsx +50 -0
- package/src/features/setup/components/setup-progress.tsx +103 -0
- package/src/features/setup/components/setup-wizard.tsx +169 -0
- package/src/features/setup/hooks/index.ts +12 -0
- package/src/features/setup/hooks/use-complete-setup.ts +23 -0
- package/src/features/setup/hooks/use-create-admin.ts +25 -0
- package/src/features/setup/hooks/use-create-first-workspace.ts +24 -0
- package/src/features/setup/hooks/use-instance-status.ts +21 -0
- package/src/features/setup/hooks/use-save-instance-config.ts +23 -0
- package/src/features/setup/hooks/use-service-health.ts +21 -0
- package/src/features/setup/hooks/use-setup-wizard.ts +152 -0
- package/src/features/setup/hooks/use-workspace-mode.ts +19 -0
- package/src/features/setup/index.ts +30 -0
- package/src/features/setup/screens/index.ts +1 -0
- package/src/features/setup/screens/setup-screen.tsx +40 -0
- package/src/features/setup/types/index.ts +69 -0
- package/src/features/setup/utils/index.ts +78 -0
- package/src/features/team-settings/components/index.ts +39 -0
- package/src/features/team-settings/components/loading-states.tsx +296 -0
- package/src/features/team-settings/components/permission-guard.tsx +23 -0
- package/src/features/team-settings/components/settings-card.tsx +22 -0
- package/src/features/team-settings/components/settings-context-provider.tsx +51 -0
- package/src/features/team-settings/components/settings-error-boundary.tsx +366 -0
- package/src/features/team-settings/components/settings-navigation.tsx +87 -0
- package/src/features/team-settings/components/settings-section.tsx +23 -0
- package/src/features/team-settings/components/team-danger-zone.tsx +275 -0
- package/src/features/team-settings/components/team-information-form.tsx +116 -0
- package/src/features/team-settings/components/team-invitations-list.tsx +463 -0
- package/src/features/team-settings/components/team-members-list.tsx +342 -0
- package/src/features/team-settings/components/team-permission-guard.tsx +56 -0
- package/src/features/team-settings/components/team-setting-integrations.tsx +27 -0
- package/src/features/team-settings/components/team-setting-member.tsx +28 -0
- package/src/features/team-settings/components/team-settings-general.tsx +131 -0
- package/src/features/team-settings/components/transfer-ownership-modal.tsx +164 -0
- package/src/features/team-settings/components/unauthorized-access.tsx +52 -0
- package/src/features/team-settings/hooks/__tests__/use-team-settings.test.tsx +139 -0
- package/src/features/team-settings/hooks/index.ts +1 -0
- package/src/features/team-settings/hooks/use-team-settings.ts +148 -0
- package/src/features/team-settings/hooks/use-transfer-ownership.ts +45 -0
- package/src/features/team-settings/index.ts +25 -0
- package/src/features/team-settings/screens/index.ts +1 -0
- package/src/features/team-settings/screens/team-settings-screen.tsx +33 -0
- package/src/features/team-settings/types/index.ts +78 -0
- package/src/features/team-settings/utils/index.ts +6 -0
- package/src/features/team-settings/utils/mock-data.ts +40 -0
- package/src/features/teams/api/cancel-invitation.ts +25 -0
- package/src/features/teams/api/create-invitation.ts +28 -0
- package/src/features/teams/api/create-team.ts +14 -0
- package/src/features/teams/api/delete-team.ts +19 -0
- package/src/features/teams/api/get-invitations.ts +25 -0
- package/src/features/teams/api/get-team-members.ts +25 -0
- package/src/features/teams/api/get-team.ts +13 -0
- package/src/features/teams/api/get-teams.ts +19 -0
- package/src/features/teams/api/index.ts +49 -0
- package/src/features/teams/api/leave-team.ts +22 -0
- package/src/features/teams/api/remove-member.ts +25 -0
- package/src/features/teams/api/resend-invitation.ts +26 -0
- package/src/features/teams/api/switch-team.ts +13 -0
- package/src/features/teams/api/types.ts +122 -0
- package/src/features/teams/api/update-member-roles.ts +28 -0
- package/src/features/teams/api/update-team.ts +17 -0
- package/src/features/teams/components/create-team-dialog.tsx +105 -0
- package/src/features/teams/hooks/__tests__/cache-invalidation.property.test.tsx +268 -0
- package/src/features/teams/hooks/index.ts +35 -0
- package/src/features/teams/hooks/use-can-manage-members.ts +21 -0
- package/src/features/teams/hooks/use-can-manage-team.ts +21 -0
- package/src/features/teams/hooks/use-cancel-invitation.ts +52 -0
- package/src/features/teams/hooks/use-create-invitation.ts +59 -0
- package/src/features/teams/hooks/use-create-team.ts +38 -0
- package/src/features/teams/hooks/use-delete-team.ts +43 -0
- package/src/features/teams/hooks/use-invitations.ts +31 -0
- package/src/features/teams/hooks/use-leave-team.ts +43 -0
- package/src/features/teams/hooks/use-remove-member.ts +58 -0
- package/src/features/teams/hooks/use-resend-invitation.ts +52 -0
- package/src/features/teams/hooks/use-switch-team.ts +41 -0
- package/src/features/teams/hooks/use-team-members.ts +31 -0
- package/src/features/teams/hooks/use-team-permissions.ts +102 -0
- package/src/features/teams/hooks/use-team.ts +30 -0
- package/src/features/teams/hooks/use-teams.ts +26 -0
- package/src/features/teams/hooks/use-update-member-roles.ts +64 -0
- package/src/features/teams/hooks/use-update-team.ts +47 -0
- package/src/features/teams/index.ts +111 -0
- package/src/features/user-settings/actions/set-password.ts +63 -0
- package/src/features/user-settings/api/index.ts +16 -0
- package/src/features/user-settings/components/__tests__/security-settings.test.tsx +125 -0
- package/src/features/user-settings/components/delete-account-dialog.tsx +185 -0
- package/src/features/user-settings/components/index.ts +13 -0
- package/src/features/user-settings/components/integrations-list.tsx +152 -0
- package/src/features/user-settings/components/notification-preferences.tsx +112 -0
- package/src/features/user-settings/components/other-settings.tsx +126 -0
- package/src/features/user-settings/components/password-section.tsx +297 -0
- package/src/features/user-settings/components/security-settings.tsx +184 -0
- package/src/features/user-settings/components/user-preferences.tsx +146 -0
- package/src/features/user-settings/hooks/index.ts +8 -0
- package/src/features/user-settings/hooks/use-notification-preferences.ts +65 -0
- package/src/features/user-settings/hooks/use-user-preferences.ts +52 -0
- package/src/features/user-settings/index.ts +22 -0
- package/src/features/user-settings/screens/index.ts +11 -0
- package/src/features/user-settings/screens/integrations-screen.tsx +24 -0
- package/src/features/user-settings/screens/notifications-screen.tsx +29 -0
- package/src/features/user-settings/screens/other-settings-screen.tsx +24 -0
- package/src/features/user-settings/screens/setting-preferences-screen.tsx +24 -0
- package/src/features/user-settings/screens/user-settings-screen.tsx +23 -0
- package/src/features/user-settings/types/index.ts +42 -0
- package/src/features/user-settings/utils/index.ts +8 -0
- package/src/hooks/use-long-press.ts +196 -0
- package/src/hooks/use-media-upload.ts +95 -0
- package/src/hooks/use-mobile.ts +19 -0
- package/src/hooks/use-team.ts +32 -0
- package/src/instrumentation.ts +14 -0
- package/src/lib/__tests__/auth-config.test.ts +166 -0
- package/src/lib/__tests__/config.test.ts +42 -0
- package/src/lib/__tests__/db.test.ts +101 -0
- package/src/lib/__tests__/env.property.test.ts +197 -0
- package/src/lib/__tests__/env.test.ts +177 -0
- package/src/lib/__tests__/health-check.test.ts +87 -0
- package/src/lib/__tests__/oauth-errors.test.ts +184 -0
- package/src/lib/__tests__/oauth-redirect.test.ts +224 -0
- package/src/lib/__tests__/oauth-scopes.test.ts +268 -0
- package/src/lib/__tests__/storage.test.ts +58 -0
- package/src/lib/__tests__/url-validator.test.ts +232 -0
- package/src/lib/api-client.ts +93 -0
- package/src/lib/auth-client.ts +5 -0
- package/src/lib/auth-config.ts +146 -0
- package/src/lib/auth.ts +209 -0
- package/src/lib/config.ts +228 -0
- package/src/lib/cors.ts +96 -0
- package/src/lib/date.ts +16 -0
- package/src/lib/db.ts +88 -0
- package/src/lib/env.ts +489 -0
- package/src/lib/feedback.ts +29 -0
- package/src/lib/health-check.ts +229 -0
- package/src/lib/logger.ts +204 -0
- package/src/lib/oauth-errors.ts +138 -0
- package/src/lib/performance.ts +367 -0
- package/src/lib/query-server.ts +35 -0
- package/src/lib/query.tsx +43 -0
- package/src/lib/resend.ts +36 -0
- package/src/lib/security-headers.ts +165 -0
- package/src/lib/setup-status.ts +34 -0
- package/src/lib/storage.ts +150 -0
- package/src/lib/supabase-client.ts +58 -0
- package/src/lib/testing/test-db.ts +75 -0
- package/src/lib/url-validator.ts +168 -0
- package/src/lib/utils.ts +6 -0
- package/src/mocks/README.md +42 -0
- package/src/mocks/activity.fixtures.ts +281 -0
- package/src/mocks/annotation.fixtures.ts +325 -0
- package/src/mocks/attachment.fixtures.ts +80 -0
- package/src/mocks/email.fixtures.ts +61 -0
- package/src/mocks/index.ts +33 -0
- package/src/mocks/issue.fixtures.ts +364 -0
- package/src/mocks/landing.fixtures.ts +118 -0
- package/src/mocks/notification.fixtures.ts +111 -0
- package/src/mocks/project-activity.fixtures.ts +69 -0
- package/src/mocks/project-invitation.fixtures.ts +95 -0
- package/src/mocks/project-member.fixtures.ts +93 -0
- package/src/mocks/project.fixtures.ts +249 -0
- package/src/mocks/settings.fixtures.ts +56 -0
- package/src/mocks/share.fixtures.ts +48 -0
- package/src/mocks/team-member.fixtures.ts +147 -0
- package/src/mocks/team.fixtures.ts +35 -0
- package/src/mocks/user-settings.fixtures.ts +77 -0
- package/src/mocks/user.fixtures.ts +21 -0
- package/src/providers/theme-provider.tsx +11 -0
- package/src/proxy/__tests__/proxy-setup-gate.test.ts +43 -0
- package/src/proxy.ts +169 -0
- package/src/server/annotations/__tests__/annotation-limit.property.test.ts +291 -0
- package/src/server/annotations/__tests__/attachment-deletion-cascade.property.test.ts +385 -0
- package/src/server/annotations/__tests__/comment-delete-authorization.property.test.ts +419 -0
- package/src/server/annotations/__tests__/sanitize.property.test.ts +302 -0
- package/src/server/annotations/annotation-service.ts +305 -0
- package/src/server/annotations/comment-service.ts +288 -0
- package/src/server/annotations/index.ts +61 -0
- package/src/server/annotations/permission-utils.ts +125 -0
- package/src/server/annotations/sanitize.ts +134 -0
- package/src/server/annotations/types.ts +161 -0
- package/src/server/audit/audit-service.ts +85 -0
- package/src/server/audit/index.ts +11 -0
- package/src/server/audit/types.ts +75 -0
- package/src/server/auth/__tests__/README.md +368 -0
- package/src/server/auth/__tests__/account-linking.integration.test.ts +410 -0
- package/src/server/auth/__tests__/auth-integration.test.ts +811 -0
- package/src/server/auth/__tests__/cookies.test.ts +337 -0
- package/src/server/auth/__tests__/login.property.test.ts +428 -0
- package/src/server/auth/__tests__/oauth-integration.test.ts +555 -0
- package/src/server/auth/__tests__/password.test.ts +194 -0
- package/src/server/auth/__tests__/rate-limiter.test.ts +450 -0
- package/src/server/auth/__tests__/rbac.test.ts +474 -0
- package/src/server/auth/__tests__/session.test.ts +599 -0
- package/src/server/auth/__tests__/signup.property.test.ts +224 -0
- package/src/server/auth/__tests__/token-encryption.test.ts +171 -0
- package/src/server/auth/__tests__/tokens.test.ts +476 -0
- package/src/server/auth/__tests__/verify-email.property.test.ts +372 -0
- package/src/server/auth/cookies.ts +184 -0
- package/src/server/auth/password.ts +94 -0
- package/src/server/auth/rate-limiter.ts +257 -0
- package/src/server/auth/rbac.ts +1168 -0
- package/src/server/auth/session.ts +392 -0
- package/src/server/auth/token-encryption.ts +201 -0
- package/src/server/auth/tokens.ts +397 -0
- package/src/server/db/schema/account.ts +21 -0
- package/src/server/db/schema/annotation-read-status.ts +57 -0
- package/src/server/db/schema/better-auth-verifications.ts +27 -0
- package/src/server/db/schema/email-jobs.ts +24 -0
- package/src/server/db/schema/index.ts +20 -0
- package/src/server/db/schema/instance-settings.ts +42 -0
- package/src/server/db/schema/issue-activities.ts +97 -0
- package/src/server/db/schema/issue-attachments.ts +101 -0
- package/src/server/db/schema/issues.ts +139 -0
- package/src/server/db/schema/notifications.ts +119 -0
- package/src/server/db/schema/project-activities.ts +116 -0
- package/src/server/db/schema/project-invitations.ts +34 -0
- package/src/server/db/schema/project-members.ts +29 -0
- package/src/server/db/schema/projects.ts +46 -0
- package/src/server/db/schema/sessions.ts +17 -0
- package/src/server/db/schema/team-invitations.ts +22 -0
- package/src/server/db/schema/team-members.ts +18 -0
- package/src/server/db/schema/teams.ts +15 -0
- package/src/server/db/schema/user-roles.ts +14 -0
- package/src/server/db/schema/users.ts +17 -0
- package/src/server/db/schema/verification-tokens.ts +15 -0
- package/src/server/email/README.md +258 -0
- package/src/server/email/__tests__/client.property.test.ts +218 -0
- package/src/server/email/__tests__/payload.property.test.ts +205 -0
- package/src/server/email/__tests__/queue.test.ts +407 -0
- package/src/server/email/__tests__/render-template.test.tsx +172 -0
- package/src/server/email/client.ts +70 -0
- package/src/server/email/index.ts +20 -0
- package/src/server/email/providers/console-provider.ts +43 -0
- package/src/server/email/providers/index.ts +5 -0
- package/src/server/email/providers/resend-provider.ts +59 -0
- package/src/server/email/providers/smtp-provider.ts +65 -0
- package/src/server/email/queue.ts +365 -0
- package/src/server/email/render-template.tsx +117 -0
- package/src/server/email/templates/layout.tsx +66 -0
- package/src/server/email/templates/ownership-transfer-email.tsx +75 -0
- package/src/server/email/templates/password-reset-email.tsx +72 -0
- package/src/server/email/templates/project-invitation-email.tsx +70 -0
- package/src/server/email/templates/security-alert-email.tsx +161 -0
- package/src/server/email/templates/team-invitation-email.tsx +68 -0
- package/src/server/email/templates/verification-email.tsx +61 -0
- package/src/server/email/templates/welcome-email.tsx +60 -0
- package/src/server/email/worker.ts +182 -0
- package/src/server/issues/activity-service.ts +422 -0
- package/src/server/issues/attachment-service.ts +379 -0
- package/src/server/issues/index.ts +68 -0
- package/src/server/issues/issue-service.ts +569 -0
- package/src/server/issues/types.ts +233 -0
- package/src/server/notifications/__tests__/notification-service.integration.test.ts +405 -0
- package/src/server/notifications/index.ts +13 -0
- package/src/server/notifications/notification-service.ts +526 -0
- package/src/server/notifications/types.ts +234 -0
- package/src/server/projects/__tests__/activity-logging.integration.test.ts +319 -0
- package/src/server/projects/__tests__/invitation-email.integration.test.ts +258 -0
- package/src/server/projects/__tests__/invitation-service.integration.test.ts +651 -0
- package/src/server/projects/__tests__/member-service.property.test.ts +397 -0
- package/src/server/projects/__tests__/project-service.property.test.ts +116 -0
- package/src/server/projects/activity-service.ts +548 -0
- package/src/server/projects/index.ts +11 -0
- package/src/server/projects/invitation-service.ts +773 -0
- package/src/server/projects/member-service.ts +458 -0
- package/src/server/projects/project-service.ts +491 -0
- package/src/server/projects/schemas.ts +310 -0
- package/src/server/projects/types.ts +166 -0
- package/src/server/projects/utils.ts +128 -0
- package/src/server/setup/__tests__/health-check.property.test.ts +70 -0
- package/src/server/setup/__tests__/sample-data.property.test.ts +82 -0
- package/src/server/setup/__tests__/setup.property.test.ts +95 -0
- package/src/server/setup/health-check-service.ts +294 -0
- package/src/server/setup/index.ts +35 -0
- package/src/server/setup/sample-data-service.ts +233 -0
- package/src/server/setup/setup-service.ts +229 -0
- package/src/server/setup/types.ts +96 -0
- package/src/server/teams/__tests__/export.property.test.ts +542 -0
- package/src/server/teams/__tests__/get-members.integration.test.ts +105 -0
- package/src/server/teams/__tests__/invitation-flow.integration.test.ts +402 -0
- package/src/server/teams/__tests__/invitations.property.test.ts +235 -0
- package/src/server/teams/__tests__/member-management-flow.integration.test.ts +306 -0
- package/src/server/teams/__tests__/members.property.test.ts +180 -0
- package/src/server/teams/__tests__/ownership-transfer.property.test.ts +173 -0
- package/src/server/teams/__tests__/resource-limits.property.test.ts +382 -0
- package/src/server/teams/__tests__/team-context-management.integration.test.ts +396 -0
- package/src/server/teams/__tests__/team-context.property.test.ts +854 -0
- package/src/server/teams/__tests__/team-creation-flow.integration.test.ts +310 -0
- package/src/server/teams/__tests__/team-creation.property.test.ts +280 -0
- package/src/server/teams/errors.ts +396 -0
- package/src/server/teams/export-service.ts +383 -0
- package/src/server/teams/index.ts +10 -0
- package/src/server/teams/invitation-service.ts +708 -0
- package/src/server/teams/member-service.ts +334 -0
- package/src/server/teams/resource-limits.ts +211 -0
- package/src/server/teams/slug.ts +58 -0
- package/src/server/teams/team-context.ts +648 -0
- package/src/server/teams/team-service.ts +660 -0
- package/src/server/teams/types.ts +81 -0
- package/src/server/teams/validation.ts +209 -0
- package/src/styles/globals.css +160 -0
- package/src/types/deployment.ts +39 -0
- package/supabase/config.toml +357 -0
- package/supabase/seed.sql +480 -0
- package/tests/e2e/.gitkeep +0 -0
- package/tests/e2e/QUICK_START.md +98 -0
- package/tests/e2e/README.md +301 -0
- package/tests/e2e/auth.spec.ts +583 -0
- package/tests/e2e/global-setup.ts +23 -0
- package/tests/e2e/global-teardown.ts +23 -0
- package/tests/e2e/helpers/auth-helpers.ts +310 -0
- package/tests/e2e/helpers/test-fixtures.ts +286 -0
- package/tests/e2e/smoke-test.spec.ts +330 -0
- package/tsconfig.json +48 -0
- package/vitest.config.ts +50 -0
- package/vitest.setup.ts +56 -0
- package/dist/index.js +0 -778
|
@@ -0,0 +1,729 @@
|
|
|
1
|
+
# Design Specification
|
|
2
|
+
|
|
3
|
+
## Architecture Overview
|
|
4
|
+
[High-level system design and component relationships - include diagram or ASCII art if helpful]
|
|
5
|
+
|
|
6
|
+
**Example:**
|
|
7
|
+
```
|
|
8
|
+
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
|
|
9
|
+
│ Client │─────▶│ Auth API │─────▶│ Database │
|
|
10
|
+
│ (React) │◀─────│ (Express) │◀─────│ (Postgres) │
|
|
11
|
+
└─────────────┘ └──────────────┘ └─────────────┘
|
|
12
|
+
│
|
|
13
|
+
▼
|
|
14
|
+
┌──────────────┐
|
|
15
|
+
│ Redis │
|
|
16
|
+
│ (Sessions) │
|
|
17
|
+
└──────────────┘
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Architecture Pattern:** Three-tier architecture with presentation, business logic, and data layers
|
|
21
|
+
**Communication:** RESTful API with JSON payloads
|
|
22
|
+
**Authentication Flow:** JWT-based stateless authentication with Redis for token blacklist
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Technical Approach
|
|
27
|
+
[Technologies, frameworks, patterns to be used - be specific with versions]
|
|
28
|
+
|
|
29
|
+
**Frontend:**
|
|
30
|
+
- React 18.2+ with TypeScript
|
|
31
|
+
- React Router for navigation
|
|
32
|
+
- Axios for HTTP requests
|
|
33
|
+
- Context API for auth state management
|
|
34
|
+
- React Hook Form for form validation
|
|
35
|
+
|
|
36
|
+
**Backend:**
|
|
37
|
+
- Node.js 18+ with Express 4.18+
|
|
38
|
+
- TypeScript for type safety
|
|
39
|
+
- JWT for token generation (jsonwebtoken 9.0+)
|
|
40
|
+
- bcrypt for password hashing (bcrypt 5.1+)
|
|
41
|
+
- express-validator for input validation
|
|
42
|
+
|
|
43
|
+
**Database:**
|
|
44
|
+
- PostgreSQL 14+ for user data
|
|
45
|
+
- Redis 7+ for token blacklist and rate limiting
|
|
46
|
+
|
|
47
|
+
**Design Patterns:**
|
|
48
|
+
- Repository pattern for data access
|
|
49
|
+
- Middleware pattern for authentication checks
|
|
50
|
+
- Factory pattern for token generation
|
|
51
|
+
- Strategy pattern for different auth methods (future OAuth)
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Component Design
|
|
56
|
+
[Detailed design of major components - describe responsibility and interactions]
|
|
57
|
+
|
|
58
|
+
### Frontend Components
|
|
59
|
+
|
|
60
|
+
#### AuthProvider (Context)
|
|
61
|
+
**Responsibility:** Manage global authentication state
|
|
62
|
+
**State:**
|
|
63
|
+
```typescript
|
|
64
|
+
{
|
|
65
|
+
user: User | null,
|
|
66
|
+
token: string | null,
|
|
67
|
+
isAuthenticated: boolean,
|
|
68
|
+
isLoading: boolean
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
**Methods:**
|
|
72
|
+
- `login(email, password)` - Authenticate user
|
|
73
|
+
- `logout()` - Clear auth state
|
|
74
|
+
- `register(email, password)` - Create new account
|
|
75
|
+
- `resetPassword(email)` - Initiate password reset
|
|
76
|
+
|
|
77
|
+
#### LoginForm Component
|
|
78
|
+
**Responsibility:** Render login UI and handle submission
|
|
79
|
+
**Props:** `onSuccess?: () => void`
|
|
80
|
+
**State:** `{ email, password, errors, isSubmitting }`
|
|
81
|
+
**Validation:** Email format, password min length
|
|
82
|
+
|
|
83
|
+
#### RegisterForm Component
|
|
84
|
+
**Responsibility:** Render registration UI with validation
|
|
85
|
+
**Props:** `onSuccess?: () => void`
|
|
86
|
+
**State:** `{ email, password, confirmPassword, errors, isSubmitting }`
|
|
87
|
+
**Validation:** Email format, password strength, password match
|
|
88
|
+
|
|
89
|
+
#### ProtectedRoute Component
|
|
90
|
+
**Responsibility:** Wrap routes requiring authentication
|
|
91
|
+
**Props:** `{ children: ReactNode, redirectTo?: string }`
|
|
92
|
+
**Behavior:** Redirect to login if not authenticated
|
|
93
|
+
|
|
94
|
+
### Backend Components
|
|
95
|
+
|
|
96
|
+
#### AuthController
|
|
97
|
+
**Responsibility:** Handle HTTP requests for auth endpoints
|
|
98
|
+
**Methods:**
|
|
99
|
+
- `register(req, res)` - Create new user
|
|
100
|
+
- `login(req, res)` - Authenticate and issue token
|
|
101
|
+
- `logout(req, res)` - Invalidate token
|
|
102
|
+
- `resetPassword(req, res)` - Send reset email
|
|
103
|
+
- `confirmReset(req, res)` - Update password with token
|
|
104
|
+
|
|
105
|
+
#### AuthService
|
|
106
|
+
**Responsibility:** Business logic for authentication
|
|
107
|
+
**Methods:**
|
|
108
|
+
- `createUser(email, password)` - Hash password, save user
|
|
109
|
+
- `validateCredentials(email, password)` - Check credentials
|
|
110
|
+
- `generateToken(userId)` - Create JWT
|
|
111
|
+
- `verifyToken(token)` - Validate JWT
|
|
112
|
+
- `blacklistToken(token)` - Add to Redis blacklist
|
|
113
|
+
|
|
114
|
+
#### UserRepository
|
|
115
|
+
**Responsibility:** Database operations for users
|
|
116
|
+
**Methods:**
|
|
117
|
+
- `create(userData)` - Insert new user
|
|
118
|
+
- `findByEmail(email)` - Query user by email
|
|
119
|
+
- `findById(id)` - Query user by ID
|
|
120
|
+
- `updatePassword(id, hashedPassword)` - Update password
|
|
121
|
+
|
|
122
|
+
#### AuthMiddleware
|
|
123
|
+
**Responsibility:** Protect routes requiring authentication
|
|
124
|
+
**Behavior:**
|
|
125
|
+
- Extract token from Authorization header
|
|
126
|
+
- Verify token signature and expiration
|
|
127
|
+
- Check token not in blacklist
|
|
128
|
+
- Attach user to request object
|
|
129
|
+
- Return 401 if invalid
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Data Models
|
|
134
|
+
[Database schemas, data structures, types - include all fields with types and constraints]
|
|
135
|
+
|
|
136
|
+
### Database Schema
|
|
137
|
+
|
|
138
|
+
#### users table
|
|
139
|
+
```sql
|
|
140
|
+
CREATE TABLE users (
|
|
141
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
142
|
+
email VARCHAR(255) UNIQUE NOT NULL,
|
|
143
|
+
password_hash VARCHAR(255) NOT NULL,
|
|
144
|
+
email_verified BOOLEAN DEFAULT FALSE,
|
|
145
|
+
verification_token VARCHAR(255),
|
|
146
|
+
reset_token VARCHAR(255),
|
|
147
|
+
reset_token_expires TIMESTAMP,
|
|
148
|
+
created_at TIMESTAMP DEFAULT NOW(),
|
|
149
|
+
updated_at TIMESTAMP DEFAULT NOW(),
|
|
150
|
+
last_login TIMESTAMP
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
CREATE INDEX idx_users_email ON users(email);
|
|
154
|
+
CREATE INDEX idx_users_verification_token ON users(verification_token);
|
|
155
|
+
CREATE INDEX idx_users_reset_token ON users(reset_token);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### TypeScript Interfaces
|
|
159
|
+
|
|
160
|
+
#### User Model
|
|
161
|
+
```typescript
|
|
162
|
+
interface User {
|
|
163
|
+
id: string;
|
|
164
|
+
email: string;
|
|
165
|
+
passwordHash: string;
|
|
166
|
+
emailVerified: boolean;
|
|
167
|
+
verificationToken?: string;
|
|
168
|
+
resetToken?: string;
|
|
169
|
+
resetTokenExpires?: Date;
|
|
170
|
+
createdAt: Date;
|
|
171
|
+
updatedAt: Date;
|
|
172
|
+
lastLogin?: Date;
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### User DTO (Data Transfer Object)
|
|
177
|
+
```typescript
|
|
178
|
+
interface UserDTO {
|
|
179
|
+
id: string;
|
|
180
|
+
email: string;
|
|
181
|
+
emailVerified: boolean;
|
|
182
|
+
createdAt: Date;
|
|
183
|
+
lastLogin?: Date;
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
#### Auth Request/Response Types
|
|
188
|
+
```typescript
|
|
189
|
+
interface RegisterRequest {
|
|
190
|
+
email: string;
|
|
191
|
+
password: string;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
interface LoginRequest {
|
|
195
|
+
email: string;
|
|
196
|
+
password: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
interface AuthResponse {
|
|
200
|
+
token: string;
|
|
201
|
+
user: UserDTO;
|
|
202
|
+
expiresIn: number;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
interface ResetPasswordRequest {
|
|
206
|
+
email: string;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
interface ConfirmResetRequest {
|
|
210
|
+
token: string;
|
|
211
|
+
newPassword: string;
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Redis Data Structures
|
|
216
|
+
|
|
217
|
+
#### Token Blacklist
|
|
218
|
+
```
|
|
219
|
+
Key: blacklist:{token}
|
|
220
|
+
Value: userId
|
|
221
|
+
TTL: 24 hours (token expiration)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
#### Rate Limiting
|
|
225
|
+
```
|
|
226
|
+
Key: ratelimit:login:{ip}
|
|
227
|
+
Value: attempt count
|
|
228
|
+
TTL: 60 seconds
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## API Design
|
|
234
|
+
[Endpoints, interfaces, contracts - include full request/response examples]
|
|
235
|
+
|
|
236
|
+
### Base URL
|
|
237
|
+
`/api/v1/auth`
|
|
238
|
+
|
|
239
|
+
### Endpoints
|
|
240
|
+
|
|
241
|
+
#### POST /register
|
|
242
|
+
**Description:** Create new user account
|
|
243
|
+
**Request:**
|
|
244
|
+
```json
|
|
245
|
+
{
|
|
246
|
+
"email": "user@example.com",
|
|
247
|
+
"password": "SecurePass123"
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
**Response (201):**
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"message": "Registration successful. Please check your email.",
|
|
254
|
+
"userId": "123e4567-e89b-12d3-a456-426614174000"
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
**Errors:**
|
|
258
|
+
- 400: Invalid email format or weak password
|
|
259
|
+
- 409: Email already registered
|
|
260
|
+
|
|
261
|
+
#### POST /login
|
|
262
|
+
**Description:** Authenticate user and receive token
|
|
263
|
+
**Request:**
|
|
264
|
+
```json
|
|
265
|
+
{
|
|
266
|
+
"email": "user@example.com",
|
|
267
|
+
"password": "SecurePass123"
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
**Response (200):**
|
|
271
|
+
```json
|
|
272
|
+
{
|
|
273
|
+
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
274
|
+
"user": {
|
|
275
|
+
"id": "123e4567-e89b-12d3-a456-426614174000",
|
|
276
|
+
"email": "user@example.com",
|
|
277
|
+
"emailVerified": true,
|
|
278
|
+
"createdAt": "2026-01-15T10:30:00Z"
|
|
279
|
+
},
|
|
280
|
+
"expiresIn": 86400
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
**Errors:**
|
|
284
|
+
- 400: Missing email or password
|
|
285
|
+
- 401: Invalid credentials
|
|
286
|
+
- 429: Too many login attempts
|
|
287
|
+
|
|
288
|
+
#### POST /logout
|
|
289
|
+
**Description:** Invalidate current token
|
|
290
|
+
**Headers:** `Authorization: Bearer {token}`
|
|
291
|
+
**Response (200):**
|
|
292
|
+
```json
|
|
293
|
+
{
|
|
294
|
+
"message": "Logout successful"
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
#### POST /reset-password
|
|
299
|
+
**Description:** Request password reset email
|
|
300
|
+
**Request:**
|
|
301
|
+
```json
|
|
302
|
+
{
|
|
303
|
+
"email": "user@example.com"
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
**Response (200):**
|
|
307
|
+
```json
|
|
308
|
+
{
|
|
309
|
+
"message": "If email exists, reset link has been sent"
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
#### POST /reset-password/confirm
|
|
314
|
+
**Description:** Complete password reset with token
|
|
315
|
+
**Request:**
|
|
316
|
+
```json
|
|
317
|
+
{
|
|
318
|
+
"token": "reset-token-from-email",
|
|
319
|
+
"newPassword": "NewSecurePass123"
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
**Response (200):**
|
|
323
|
+
```json
|
|
324
|
+
{
|
|
325
|
+
"message": "Password reset successful"
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
**Errors:**
|
|
329
|
+
- 400: Invalid or expired token
|
|
330
|
+
- 400: Weak password
|
|
331
|
+
|
|
332
|
+
#### GET /verify-email/:token
|
|
333
|
+
**Description:** Verify email address
|
|
334
|
+
**Response (200):**
|
|
335
|
+
```json
|
|
336
|
+
{
|
|
337
|
+
"message": "Email verified successfully"
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## Integration Points
|
|
344
|
+
[How this connects with other systems - be specific about data flow]
|
|
345
|
+
|
|
346
|
+
### Email Service Integration
|
|
347
|
+
**Service:** SendGrid API
|
|
348
|
+
**Purpose:** Send verification and password reset emails
|
|
349
|
+
**Trigger:** User registration, password reset request
|
|
350
|
+
**Data Flow:**
|
|
351
|
+
1. Auth service generates verification/reset token
|
|
352
|
+
2. Token stored in database with expiration
|
|
353
|
+
3. Email service called with template and token
|
|
354
|
+
4. User clicks link in email
|
|
355
|
+
5. Frontend calls verify/reset endpoint with token
|
|
356
|
+
|
|
357
|
+
### User Profile Service
|
|
358
|
+
**Integration:** Auth token passed in Authorization header
|
|
359
|
+
**Data Flow:**
|
|
360
|
+
1. User logs in via auth service
|
|
361
|
+
2. Receives JWT token
|
|
362
|
+
3. Frontend includes token in requests to profile service
|
|
363
|
+
4. Profile service validates token (shared secret or public key)
|
|
364
|
+
5. Profile service extracts userId from token
|
|
365
|
+
|
|
366
|
+
### Admin Dashboard
|
|
367
|
+
**Integration:** Protected routes using auth middleware
|
|
368
|
+
**Data Flow:**
|
|
369
|
+
1. Admin logs in, receives token with admin role claim
|
|
370
|
+
2. Dashboard routes check for valid token + admin role
|
|
371
|
+
3. Middleware validates token and checks role
|
|
372
|
+
4. Access granted/denied based on role
|
|
373
|
+
|
|
374
|
+
**File References:**
|
|
375
|
+
#[[file:src/services/email/templates/verification.html]]
|
|
376
|
+
#[[file:src/services/email/templates/password-reset.html]]
|
|
377
|
+
#[[file:docs/api-gateway-config.yaml]]
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## Security Considerations
|
|
382
|
+
[Authentication, authorization, data protection - specific implementation details]
|
|
383
|
+
|
|
384
|
+
### Password Security
|
|
385
|
+
- Hash with bcrypt, salt rounds: 12
|
|
386
|
+
- Minimum length: 8 characters
|
|
387
|
+
- Require: 1 uppercase, 1 lowercase, 1 number
|
|
388
|
+
- Reject common passwords (use list of 10k most common)
|
|
389
|
+
- Never log or display passwords
|
|
390
|
+
|
|
391
|
+
### Token Security
|
|
392
|
+
- JWT signed with HS256 algorithm
|
|
393
|
+
- Secret key: 256-bit random string from environment variable
|
|
394
|
+
- Token expiration: 24 hours
|
|
395
|
+
- Include claims: userId, email, issuedAt, expiresAt
|
|
396
|
+
- Blacklist tokens on logout (store in Redis)
|
|
397
|
+
|
|
398
|
+
### API Security
|
|
399
|
+
- Rate limiting: 5 requests/minute per IP for login
|
|
400
|
+
- CORS: Whitelist specific origins only
|
|
401
|
+
- Helmet.js for security headers
|
|
402
|
+
- Input validation on all endpoints
|
|
403
|
+
- SQL injection prevention via parameterized queries
|
|
404
|
+
- XSS prevention via input sanitization
|
|
405
|
+
|
|
406
|
+
### Data Protection
|
|
407
|
+
- HTTPS required for all endpoints
|
|
408
|
+
- Passwords never stored in plain text
|
|
409
|
+
- Sensitive data (tokens) not logged
|
|
410
|
+
- Database credentials in environment variables
|
|
411
|
+
- Regular security audits and dependency updates
|
|
412
|
+
|
|
413
|
+
### GDPR Compliance
|
|
414
|
+
- User consent for data storage
|
|
415
|
+
- Right to data export (future)
|
|
416
|
+
- Right to deletion (future)
|
|
417
|
+
- Data retention policy: 2 years inactive accounts
|
|
418
|
+
|
|
419
|
+
---
|
|
420
|
+
|
|
421
|
+
## Performance Considerations
|
|
422
|
+
[Optimization strategies, caching, scaling - with specific metrics]
|
|
423
|
+
|
|
424
|
+
### Database Optimization
|
|
425
|
+
- Index on email column for fast lookups
|
|
426
|
+
- Connection pooling: max 20 connections
|
|
427
|
+
- Query timeout: 5 seconds
|
|
428
|
+
- Use prepared statements for repeated queries
|
|
429
|
+
|
|
430
|
+
### Caching Strategy
|
|
431
|
+
- Redis for token blacklist (in-memory, fast lookup)
|
|
432
|
+
- Cache user data after login (TTL: 5 minutes)
|
|
433
|
+
- Rate limit counters in Redis (TTL: 60 seconds)
|
|
434
|
+
|
|
435
|
+
### API Performance
|
|
436
|
+
- Response time target: < 2 seconds for login
|
|
437
|
+
- Async password hashing (don't block event loop)
|
|
438
|
+
- Batch email sending for multiple verifications
|
|
439
|
+
- Compression middleware for responses
|
|
440
|
+
|
|
441
|
+
### Scaling Strategy
|
|
442
|
+
- Stateless API (JWT tokens, no server sessions)
|
|
443
|
+
- Horizontal scaling: multiple API instances behind load balancer
|
|
444
|
+
- Database read replicas for high read load
|
|
445
|
+
- Redis cluster for distributed caching
|
|
446
|
+
|
|
447
|
+
### Monitoring
|
|
448
|
+
- Log response times for all endpoints
|
|
449
|
+
- Alert if login time > 3 seconds
|
|
450
|
+
- Track failed login attempts
|
|
451
|
+
- Monitor database connection pool usage
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## Error Handling
|
|
456
|
+
[How errors are caught, logged, and handled - include error codes and messages]
|
|
457
|
+
|
|
458
|
+
### Error Response Format
|
|
459
|
+
```typescript
|
|
460
|
+
interface ErrorResponse {
|
|
461
|
+
error: {
|
|
462
|
+
code: string;
|
|
463
|
+
message: string;
|
|
464
|
+
details?: any;
|
|
465
|
+
};
|
|
466
|
+
timestamp: string;
|
|
467
|
+
path: string;
|
|
468
|
+
}
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Error Codes
|
|
472
|
+
|
|
473
|
+
#### Client Errors (4xx)
|
|
474
|
+
- `AUTH_001`: Invalid email format
|
|
475
|
+
- `AUTH_002`: Weak password
|
|
476
|
+
- `AUTH_003`: Email already registered
|
|
477
|
+
- `AUTH_004`: Invalid credentials
|
|
478
|
+
- `AUTH_005`: Token expired
|
|
479
|
+
- `AUTH_006`: Token invalid
|
|
480
|
+
- `AUTH_007`: Rate limit exceeded
|
|
481
|
+
- `AUTH_008`: Email not verified
|
|
482
|
+
|
|
483
|
+
#### Server Errors (5xx)
|
|
484
|
+
- `AUTH_500`: Database connection failed
|
|
485
|
+
- `AUTH_501`: Email service unavailable
|
|
486
|
+
- `AUTH_502`: Token generation failed
|
|
487
|
+
|
|
488
|
+
### Error Handling Strategy
|
|
489
|
+
|
|
490
|
+
**Frontend:**
|
|
491
|
+
- Display user-friendly error messages
|
|
492
|
+
- Log detailed errors to console (dev mode)
|
|
493
|
+
- Show generic message for 5xx errors
|
|
494
|
+
- Retry logic for network failures (max 3 attempts)
|
|
495
|
+
|
|
496
|
+
**Backend:**
|
|
497
|
+
- Try-catch blocks around all async operations
|
|
498
|
+
- Global error handler middleware
|
|
499
|
+
- Log errors with context (userId, endpoint, timestamp)
|
|
500
|
+
- Never expose stack traces in production
|
|
501
|
+
- Send 5xx errors to error tracking service (Sentry)
|
|
502
|
+
|
|
503
|
+
**Example Error Handler:**
|
|
504
|
+
```typescript
|
|
505
|
+
app.use((err, req, res, next) => {
|
|
506
|
+
logger.error({
|
|
507
|
+
error: err.message,
|
|
508
|
+
stack: err.stack,
|
|
509
|
+
path: req.path,
|
|
510
|
+
method: req.method,
|
|
511
|
+
userId: req.user?.id
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
const statusCode = err.statusCode || 500;
|
|
515
|
+
const errorCode = err.code || 'AUTH_500';
|
|
516
|
+
|
|
517
|
+
res.status(statusCode).json({
|
|
518
|
+
error: {
|
|
519
|
+
code: errorCode,
|
|
520
|
+
message: err.message || 'Internal server error'
|
|
521
|
+
},
|
|
522
|
+
timestamp: new Date().toISOString(),
|
|
523
|
+
path: req.path
|
|
524
|
+
});
|
|
525
|
+
});
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
## Testing Strategy
|
|
531
|
+
[Unit, integration, e2e testing approach - include coverage targets]
|
|
532
|
+
|
|
533
|
+
### Unit Tests
|
|
534
|
+
**Target Coverage:** 80%+
|
|
535
|
+
**Tools:** Jest, React Testing Library
|
|
536
|
+
|
|
537
|
+
**Frontend Tests:**
|
|
538
|
+
- Component rendering with different props
|
|
539
|
+
- Form validation logic
|
|
540
|
+
- Auth context state management
|
|
541
|
+
- Error handling in components
|
|
542
|
+
|
|
543
|
+
**Backend Tests:**
|
|
544
|
+
- AuthService methods (token generation, validation)
|
|
545
|
+
- Password hashing and comparison
|
|
546
|
+
- Input validation functions
|
|
547
|
+
- Repository methods (mocked database)
|
|
548
|
+
|
|
549
|
+
**Example:**
|
|
550
|
+
```typescript
|
|
551
|
+
describe('AuthService', () => {
|
|
552
|
+
it('should hash password with bcrypt', async () => {
|
|
553
|
+
const password = 'SecurePass123';
|
|
554
|
+
const hash = await authService.hashPassword(password);
|
|
555
|
+
expect(hash).not.toBe(password);
|
|
556
|
+
expect(await bcrypt.compare(password, hash)).toBe(true);
|
|
557
|
+
});
|
|
558
|
+
});
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Integration Tests
|
|
562
|
+
**Target Coverage:** Key user flows
|
|
563
|
+
**Tools:** Supertest, Jest
|
|
564
|
+
|
|
565
|
+
**Test Scenarios:**
|
|
566
|
+
- Complete registration flow (POST /register → verify email)
|
|
567
|
+
- Login flow (POST /login → receive token)
|
|
568
|
+
- Protected route access (with/without valid token)
|
|
569
|
+
- Password reset flow (request → confirm)
|
|
570
|
+
- Token expiration and refresh
|
|
571
|
+
|
|
572
|
+
**Example:**
|
|
573
|
+
```typescript
|
|
574
|
+
describe('POST /api/v1/auth/login', () => {
|
|
575
|
+
it('should return token for valid credentials', async () => {
|
|
576
|
+
const response = await request(app)
|
|
577
|
+
.post('/api/v1/auth/login')
|
|
578
|
+
.send({ email: 'test@example.com', password: 'SecurePass123' });
|
|
579
|
+
|
|
580
|
+
expect(response.status).toBe(200);
|
|
581
|
+
expect(response.body).toHaveProperty('token');
|
|
582
|
+
expect(response.body.user.email).toBe('test@example.com');
|
|
583
|
+
});
|
|
584
|
+
});
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
### E2E Tests
|
|
588
|
+
**Target Coverage:** Critical paths
|
|
589
|
+
**Tools:** Playwright or Cypress
|
|
590
|
+
|
|
591
|
+
**Test Scenarios:**
|
|
592
|
+
- User registers, verifies email, logs in
|
|
593
|
+
- User logs in, accesses protected page, logs out
|
|
594
|
+
- User forgets password, resets via email, logs in with new password
|
|
595
|
+
- Invalid login attempts trigger rate limiting
|
|
596
|
+
|
|
597
|
+
### Security Tests
|
|
598
|
+
- Penetration testing for common vulnerabilities
|
|
599
|
+
- SQL injection attempts
|
|
600
|
+
- XSS attack vectors
|
|
601
|
+
- Brute force login attempts
|
|
602
|
+
- Token manipulation attempts
|
|
603
|
+
|
|
604
|
+
### Performance Tests
|
|
605
|
+
**Tools:** Artillery or k6
|
|
606
|
+
- Load test: 1000 concurrent users logging in
|
|
607
|
+
- Stress test: Gradual increase to find breaking point
|
|
608
|
+
- Spike test: Sudden traffic surge
|
|
609
|
+
- Target: < 2s response time under normal load
|
|
610
|
+
|
|
611
|
+
---
|
|
612
|
+
|
|
613
|
+
## Trade-offs and Decisions
|
|
614
|
+
[Key technical decisions and their rationale - document why choices were made]
|
|
615
|
+
|
|
616
|
+
### Decision 1: JWT vs Session-Based Auth
|
|
617
|
+
**Chosen:** JWT (stateless tokens)
|
|
618
|
+
**Rationale:**
|
|
619
|
+
- ✅ Easier horizontal scaling (no shared session store)
|
|
620
|
+
- ✅ Works well with microservices architecture
|
|
621
|
+
- ✅ Reduces database queries for auth checks
|
|
622
|
+
- ❌ Cannot invalidate tokens without blacklist
|
|
623
|
+
- ❌ Larger payload size than session IDs
|
|
624
|
+
|
|
625
|
+
**Mitigation:** Use Redis blacklist for logout, keep token expiration short (24h)
|
|
626
|
+
|
|
627
|
+
### Decision 2: bcrypt vs Argon2 for Password Hashing
|
|
628
|
+
**Chosen:** bcrypt
|
|
629
|
+
**Rationale:**
|
|
630
|
+
- ✅ Battle-tested, widely used
|
|
631
|
+
- ✅ Good library support in Node.js
|
|
632
|
+
- ✅ Team familiarity
|
|
633
|
+
- ❌ Argon2 is newer and potentially more secure
|
|
634
|
+
|
|
635
|
+
**Future:** Consider migrating to Argon2 in next major version
|
|
636
|
+
|
|
637
|
+
### Decision 3: Email Verification Required vs Optional
|
|
638
|
+
**Chosen:** Required
|
|
639
|
+
**Rationale:**
|
|
640
|
+
- ✅ Prevents fake accounts
|
|
641
|
+
- ✅ Ensures valid email for password reset
|
|
642
|
+
- ✅ Reduces spam/abuse
|
|
643
|
+
- ❌ Adds friction to signup process
|
|
644
|
+
- ❌ Requires email service dependency
|
|
645
|
+
|
|
646
|
+
**Mitigation:** Clear messaging, resend verification option
|
|
647
|
+
|
|
648
|
+
### Decision 4: Password Strength Requirements
|
|
649
|
+
**Chosen:** Min 8 chars, 1 uppercase, 1 number
|
|
650
|
+
**Rationale:**
|
|
651
|
+
- ✅ Balances security and usability
|
|
652
|
+
- ✅ Industry standard
|
|
653
|
+
- ❌ More complex rules frustrate users
|
|
654
|
+
|
|
655
|
+
**Alternative Considered:** Passphrase-based (4+ words) - may implement as option
|
|
656
|
+
|
|
657
|
+
### Decision 5: Token Storage Location (Frontend)
|
|
658
|
+
**Chosen:** localStorage
|
|
659
|
+
**Rationale:**
|
|
660
|
+
- ✅ Simple implementation
|
|
661
|
+
- ✅ Persists across browser sessions
|
|
662
|
+
- ❌ Vulnerable to XSS attacks
|
|
663
|
+
- ❌ Not accessible from different subdomains
|
|
664
|
+
|
|
665
|
+
**Mitigation:** Strict CSP headers, input sanitization
|
|
666
|
+
**Alternative:** httpOnly cookies (more secure but requires CSRF protection)
|
|
667
|
+
|
|
668
|
+
### Decision 6: Rate Limiting Strategy
|
|
669
|
+
**Chosen:** IP-based with Redis
|
|
670
|
+
**Rationale:**
|
|
671
|
+
- ✅ Prevents brute force attacks
|
|
672
|
+
- ✅ Fast lookup with Redis
|
|
673
|
+
- ❌ Can block legitimate users behind shared IP (corporate networks)
|
|
674
|
+
|
|
675
|
+
**Mitigation:** Higher limit (5/min), clear error message, manual override for support
|
|
676
|
+
|
|
677
|
+
---
|
|
678
|
+
|
|
679
|
+
## Deployment Architecture
|
|
680
|
+
[How this will be deployed and scaled]
|
|
681
|
+
|
|
682
|
+
**Environment:**
|
|
683
|
+
- Development: Local Docker containers
|
|
684
|
+
- Staging: AWS ECS with RDS and ElastiCache
|
|
685
|
+
- Production: AWS ECS with Multi-AZ RDS and ElastiCache cluster
|
|
686
|
+
|
|
687
|
+
**Infrastructure:**
|
|
688
|
+
- Load balancer: AWS ALB
|
|
689
|
+
- API instances: 2-10 (auto-scaling based on CPU)
|
|
690
|
+
- Database: PostgreSQL RDS (Multi-AZ)
|
|
691
|
+
- Cache: Redis ElastiCache (cluster mode)
|
|
692
|
+
- Email: SendGrid API
|
|
693
|
+
|
|
694
|
+
**CI/CD:**
|
|
695
|
+
- GitHub Actions for automated testing
|
|
696
|
+
- Deploy to staging on merge to develop
|
|
697
|
+
- Deploy to production on merge to main (with approval)
|
|
698
|
+
|
|
699
|
+
---
|
|
700
|
+
|
|
701
|
+
## Monitoring and Observability
|
|
702
|
+
[How to monitor system health and debug issues]
|
|
703
|
+
|
|
704
|
+
**Metrics to Track:**
|
|
705
|
+
- Login success/failure rate
|
|
706
|
+
- Registration rate
|
|
707
|
+
- Token validation time
|
|
708
|
+
- Database query time
|
|
709
|
+
- Email delivery rate
|
|
710
|
+
- API response times (p50, p95, p99)
|
|
711
|
+
|
|
712
|
+
**Logging:**
|
|
713
|
+
- Structured JSON logs
|
|
714
|
+
- Log levels: ERROR, WARN, INFO, DEBUG
|
|
715
|
+
- Include: timestamp, userId, endpoint, duration, statusCode
|
|
716
|
+
- Centralized logging: CloudWatch or ELK stack
|
|
717
|
+
|
|
718
|
+
**Alerts:**
|
|
719
|
+
- Login failure rate > 20%
|
|
720
|
+
- API response time > 3s
|
|
721
|
+
- Database connection errors
|
|
722
|
+
- Email service failures
|
|
723
|
+
- Rate limit triggers > 100/min
|
|
724
|
+
|
|
725
|
+
**Dashboards:**
|
|
726
|
+
- Real-time auth metrics
|
|
727
|
+
- Error rate trends
|
|
728
|
+
- User registration funnel
|
|
729
|
+
- Performance metrics
|