@etus/bhono-app 0.1.5 → 0.1.7
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/dist/index.js +0 -0
- package/package.json +7 -2
- package/templates/base/.claude/commands/check-skill-rules.md +112 -29
- package/templates/base/.claude/commands/linear/implement-issue.md +383 -55
- package/templates/base/.claude/commands/ship.md +77 -13
- package/templates/base/.claude/hooks/package-lock.json +0 -419
- package/templates/base/.claude/hooks/skill-activation-prompt.ts +185 -113
- package/templates/base/.claude/hooks/skill-tool-guard.sh +6 -0
- package/templates/base/.claude/hooks/skill-tool-guard.ts +198 -0
- package/templates/base/.claude/scripts/validate-skill-rules.sh +55 -32
- package/templates/base/.claude/settings.json +18 -11
- package/templates/base/.claude/skills/skill-rules.json +326 -173
- package/templates/base/.env.example +3 -0
- package/templates/base/CLAUDE.md +5 -5
- package/templates/base/README.md +40 -27
- package/templates/base/config/eslint.config.js +1 -0
- package/templates/base/config/wrangler.json +16 -17
- package/templates/base/docs/SETUP-GUIDE.md +566 -0
- package/templates/base/docs/app_spec.txt +13 -10
- package/templates/base/docs/architecture/README.md +162 -5
- package/templates/base/docs/architecture/api-catalog.md +575 -0
- package/templates/base/docs/architecture/c4-component.md +309 -0
- package/templates/base/docs/architecture/c4-container.md +183 -0
- package/templates/base/docs/architecture/c4-context.md +106 -0
- package/templates/base/docs/architecture/data-requirements.md +4 -3
- package/templates/base/docs/architecture/db-bootstrap.md +39 -0
- package/templates/base/docs/architecture/dependencies.md +327 -0
- package/templates/base/docs/architecture/drizzle-migration-plan.md +125 -0
- package/templates/base/docs/architecture/erd.md +1 -1
- package/templates/base/docs/architecture/sql-standards.md +100 -0
- package/templates/base/docs/architecture/tech-debt.md +184 -0
- package/templates/base/docs/testing.md +36 -29
- package/templates/base/package.json +26 -20
- package/templates/base/schema.sql +84 -0
- package/templates/base/scripts/capture-prod-session.ts +2 -2
- package/templates/base/scripts/init.sh +244 -59
- package/templates/base/scripts/sync-template.sh +104 -0
- package/templates/base/src/client/hooks/use-auth.ts +5 -0
- package/templates/base/src/client/routes/_authenticated/dashboard.tsx +1 -1
- package/templates/base/src/client/routes/index.tsx +1 -1
- package/templates/base/src/server/db/client.ts +3 -5
- package/templates/base/src/server/db/records.ts +81 -0
- package/templates/base/src/server/db/seed.ts +3 -2
- package/templates/base/src/server/db/sql.ts +116 -0
- package/templates/base/src/server/index.ts +17 -2
- package/templates/base/src/server/lib/audit.ts +74 -26
- package/templates/base/src/server/lib/audited-db.ts +219 -109
- package/templates/base/src/server/lib/transaction.ts +10 -16
- package/templates/base/src/server/middleware/account.ts +9 -16
- package/templates/base/src/server/middleware/auth.ts +102 -38
- package/templates/base/src/server/middleware/rate-limit.ts +8 -6
- package/templates/base/src/server/routes/accounts/handlers.ts +18 -6
- package/templates/base/src/server/routes/audits/handlers.ts +3 -1
- package/templates/base/src/server/routes/auth/handlers.ts +15 -10
- package/templates/base/src/server/routes/auth/test-login.ts +99 -45
- package/templates/base/src/server/routes/health/handlers.ts +4 -4
- package/templates/base/src/server/routes/index.ts +9 -0
- package/templates/base/src/server/routes/invitations/handlers.ts +9 -6
- package/templates/base/src/server/routes/openapi.ts +1 -1
- package/templates/base/src/server/routes/users/handlers.ts +21 -14
- package/templates/base/src/server/services/accounts.ts +242 -217
- package/templates/base/src/server/services/audits.ts +114 -61
- package/templates/base/src/server/services/auth.ts +310 -180
- package/templates/base/src/server/services/invitations.ts +282 -222
- package/templates/base/src/server/services/users.ts +383 -293
- package/templates/base/src/server/types/index.ts +1 -2
- package/templates/base/src/shared/types/api.ts +66 -198
- package/templates/base/tests/e2e/auth.setup.ts +1 -1
- package/templates/base/{src/server/__tests__/fixtures.ts → tests/fixtures/server.ts} +3 -3
- package/templates/base/{src/client/__tests__/setup-browser.ts → tests/helpers/client-setup-browser.ts} +2 -2
- package/templates/base/{src/client/__tests__/setup.ts → tests/helpers/client-setup.ts} +1 -1
- package/templates/base/{src/client/__tests__/test-utils.tsx → tests/helpers/client-test-utils.tsx} +2 -2
- package/templates/base/{src/server/__tests__/setup.ts → tests/helpers/server.ts} +9 -9
- package/templates/base/tests/integration/accounts/crud.test.ts +2 -11
- package/templates/base/tests/integration/audits/list.test.ts +2 -11
- package/templates/base/tests/integration/auth/auth-service.test.ts +1 -10
- package/templates/base/tests/integration/auth/invitation-token.test.ts +2 -11
- package/templates/base/tests/integration/auth/logout.test.ts +2 -11
- package/templates/base/tests/integration/auth/oauth.test.ts +23 -42
- package/templates/base/tests/integration/auth/refresh-token.test.ts +1 -9
- package/templates/base/tests/integration/auth/session-expiry.test.ts +1 -9
- package/templates/base/tests/integration/auth/session.test.ts +2 -11
- package/templates/base/tests/integration/auth/super-admin.test.ts +1 -9
- package/templates/base/tests/integration/authorization/analytics-role.test.ts +2 -11
- package/templates/base/tests/integration/authorization/billing-role.test.ts +2 -11
- package/templates/base/tests/integration/authorization/guards-roles.test.ts +1 -9
- package/templates/base/tests/integration/authorization/multi-tenancy.test.ts +2 -11
- package/templates/base/tests/integration/authorization/roles.test.ts +2 -11
- package/templates/base/tests/integration/config/production-behavior.test.ts +2 -11
- package/templates/base/tests/integration/health/health.test.ts +25 -44
- package/templates/base/tests/integration/invitations/crud.test.ts +2 -11
- package/templates/base/tests/integration/invitations/email.test.ts +1 -9
- package/templates/base/tests/integration/middleware/auth.test.ts +3 -12
- package/templates/base/tests/integration/middleware/request-logger.test.ts +1 -9
- package/templates/base/tests/integration/performance/response-times.test.ts +1 -9
- package/templates/base/tests/integration/security/cookie-security.test.ts +2 -11
- package/templates/base/tests/integration/security/csrf-protection.test.ts +2 -11
- package/templates/base/tests/integration/security/log-sanitization.test.ts +1 -9
- package/templates/base/tests/integration/security/rate-limiting.test.ts +1 -9
- package/templates/base/tests/integration/security/sql-injection.test.ts +7 -18
- package/templates/base/tests/integration/security/xss-prevention.test.ts +2 -11
- package/templates/base/tests/integration/setup.ts +13 -90
- package/templates/base/tests/integration/smoke.test.ts +3 -2
- package/templates/base/tests/integration/storage/upload.test.ts +2 -11
- package/templates/base/tests/integration/storage/validation.test.ts +2 -11
- package/templates/base/tests/integration/users/crud.test.ts +2 -11
- package/templates/base/tests/integration/users/list.test.ts +2 -11
- package/templates/base/tests/integration/vitest.config.ts +2 -9
- package/templates/base/{src/server/__tests__ → tests}/mocks/db.ts +1 -1
- package/templates/base/{src/server/__tests__ → tests}/mocks/index.ts +1 -1
- package/templates/base/{src/server/__tests__ → tests}/mocks/kv.ts +1 -1
- package/templates/base/{src/server/__tests__ → tests}/mocks/r2.ts +1 -1
- package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/sidebar.test.tsx +1 -1
- package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/avatar.test.tsx +1 -1
- package/templates/base/{src/client/__tests__ → tests/unit/client/components/ui}/button.test.tsx +1 -1
- package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/card.test.tsx +1 -1
- package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/dialog.test.tsx +1 -1
- package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/input.test.tsx +1 -1
- package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/loading-skeleton.test.tsx +1 -1
- package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/skeleton.test.tsx +1 -1
- package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/sonner.test.tsx +1 -1
- package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/tabs.test.tsx +1 -1
- package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/account.test.tsx +1 -1
- package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/integrations.test.tsx +1 -1
- package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/settings.test.tsx +1 -1
- package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/team.test.tsx +1 -1
- package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/authenticated-layout.test.tsx +1 -1
- package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/dashboard.test.tsx +1 -1
- package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/invite.test.tsx +1 -1
- package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/login.test.tsx +1 -1
- package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/navigation.test.tsx +1 -1
- package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/root-layout.test.tsx +1 -1
- package/templates/base/{src/server/auth/__tests__ → tests/unit/server/auth}/guards.test.ts +2 -2
- package/templates/base/{src → tests/unit}/server/auth/permissions.test.ts +1 -1
- package/templates/base/{src → tests/unit}/server/auth/roles.test.ts +1 -1
- package/templates/base/tests/unit/server/db/sql.test.ts +68 -0
- package/templates/base/{src → tests/unit}/server/env.test.ts +1 -1
- package/templates/base/tests/unit/server/lib/audited-db.test.ts +78 -0
- package/templates/base/{src → tests/unit}/server/lib/email.test.ts +1 -1
- package/templates/base/{src → tests/unit}/server/lib/errors.test.ts +1 -1
- package/templates/base/{src → tests/unit}/server/lib/oauth.test.ts +1 -1
- package/templates/base/{src → tests/unit}/server/lib/pagination.test.ts +1 -1
- package/templates/base/{src → tests/unit}/server/lib/password.test.ts +1 -1
- package/templates/base/{src → tests/unit}/server/lib/providers.test.ts +1 -1
- package/templates/base/{src → tests/unit}/server/lib/r2-storage.test.ts +2 -2
- package/templates/base/{src → tests/unit}/server/lib/session.test.ts +2 -2
- package/templates/base/{src → tests/unit}/server/lib/tokens.test.ts +1 -1
- package/templates/base/{src → tests/unit}/server/lib/transaction.test.ts +5 -14
- package/templates/base/{src → tests/unit}/server/middleware/account.test.ts +16 -24
- package/templates/base/tests/unit/server/middleware/auth.test.ts +647 -0
- package/templates/base/{src → tests/unit}/server/middleware/cors.test.ts +1 -1
- package/templates/base/{src → tests/unit}/server/middleware/error-handler.test.ts +2 -2
- package/templates/base/{src → tests/unit}/server/middleware/rate-limit.test.ts +3 -2
- package/templates/base/{src → tests/unit}/server/middleware/request-context.test.ts +1 -1
- package/templates/base/{src → tests/unit}/server/middleware/request-logger.test.ts +1 -1
- package/templates/base/{src/server/__tests__/mocks/__tests__ → tests/unit/server/mocks}/db.test.ts +1 -1
- package/templates/base/{src/server/__tests__/mocks/__tests__ → tests/unit/server/mocks}/kv.test.ts +1 -1
- package/templates/base/{src/server/__tests__/mocks/__tests__ → tests/unit/server/mocks}/r2.test.ts +1 -1
- package/templates/base/{src/server/routes/accounts/__tests__ → tests/unit/server/routes/accounts}/handlers.test.ts +12 -12
- package/templates/base/{src/server/routes/audits/__tests__ → tests/unit/server/routes/audits}/handlers.test.ts +11 -11
- package/templates/base/{src/server/routes/auth/__tests__ → tests/unit/server/routes/auth}/handlers.test.ts +124 -13
- package/templates/base/{src/server/routes/health/__tests__ → tests/unit/server/routes/health}/handlers.test.ts +27 -23
- package/templates/base/{src/server/routes/invitations/__tests__ → tests/unit/server/routes/invitations}/handlers.test.ts +14 -17
- package/templates/base/{src/server/routes/storage/__tests__ → tests/unit/server/routes/storage}/handlers.test.ts +6 -6
- package/templates/base/{src/server/routes/users/__tests__ → tests/unit/server/routes/users}/handlers.test.ts +81 -17
- package/templates/base/tests/unit/server/services/accounts.test.ts +406 -0
- package/templates/base/tests/unit/server/services/audits.test.ts +360 -0
- package/templates/base/tests/unit/server/services/auth.test.ts +656 -0
- package/templates/base/tests/unit/server/services/invitations.test.ts +343 -0
- package/templates/base/tests/unit/server/services/users.test.ts +706 -0
- package/templates/base/{src/shared/schemas/__tests__ → tests/unit/shared}/schemas.test.ts +1 -1
- package/templates/base/tsconfig.json +2 -1
- package/templates/base/vite.config.ts +3 -1
- package/templates/base/vitest.config.browser.ts +3 -2
- package/templates/base/vitest.config.frontend.ts +3 -2
- package/templates/base/vitest.config.ts +7 -14
- package/templates/base/.claude/settings.local.json +0 -11
- package/templates/base/.github/workflows/test.yml +0 -127
- package/templates/base/auth-setup-error.png +0 -0
- package/templates/base/config/drizzle.config.ts +0 -10
- package/templates/base/pnpm-lock.yaml +0 -8175
- package/templates/base/src/server/db/schema/accounts.ts +0 -20
- package/templates/base/src/server/db/schema/audit-logs.ts +0 -26
- package/templates/base/src/server/db/schema/index.ts +0 -7
- package/templates/base/src/server/db/schema/invitations.ts +0 -30
- package/templates/base/src/server/db/schema/refresh-tokens.ts +0 -22
- package/templates/base/src/server/db/schema/user-accounts.ts +0 -25
- package/templates/base/src/server/db/schema/users.ts +0 -33
- package/templates/base/src/server/lib/audited-db.test.ts +0 -107
- package/templates/base/src/server/lib/schema-helpers.ts +0 -16
- package/templates/base/src/server/middleware/auth.test.ts +0 -345
- package/templates/base/src/server/services/__tests__/accounts.test.ts +0 -764
- package/templates/base/src/server/services/__tests__/audits.test.ts +0 -235
- package/templates/base/src/server/services/__tests__/auth.test.ts +0 -765
- package/templates/base/src/server/services/__tests__/invitations.test.ts +0 -704
- package/templates/base/src/server/services/__tests__/users.test.ts +0 -755
- package/templates/base/tests/e2e/_auth/.gitkeep +0 -0
- package/templates/base/tests/integration/lib/schema-helpers.test.ts +0 -129
- package/templates/base/tsconfig.tsbuildinfo +0 -1
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-can-be-collapsed-by-default-1.png +0 -0
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-expands-when-collapsed-and-expand-button-is-clicked-1.png +0 -0
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-handles-logout-button-click-1.png +0 -0
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-handles-navigation-clicks-1.png +0 -0
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-hides-navigation-labels-when-collapsed-1.png +0 -0
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-highlights-active-route-1.png +0 -0
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-renders-sidebar-navigation-items-1.png +0 -0
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-shows-keyboard-shortcut-hint-when-expanded-1.png +0 -0
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-shows-user-info-when-authenticated-1.png +0 -0
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/__screenshots__/sidebar.test.tsx/Sidebar-shows-user-initials-in-avatar-fallback-1.png +0 -0
- /package/templates/base/{src/client/components/__tests__ → tests/unit/client/components}/error-boundary.test.tsx +0 -0
- /package/templates/base/{src/client/components/ui/__tests__ → tests/unit/client/components/ui}/error-fallback.test.tsx +0 -0
- /package/templates/base/{src/client/hooks/__tests__ → tests/unit/client/hooks}/use-auth.test.tsx +0 -0
- /package/templates/base/{src/client/hooks/__tests__ → tests/unit/client/hooks}/use-theme.test.tsx +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-dashboard-stats-cards-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-quick-action-cards-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-recent-activity-section-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-user-first-name-in-welcome-message-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-display-user-information-in-sidebar-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-render-dashboard-when-authenticated-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-authenticated-should-show-navigation-sidebar-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/dashboard.test.tsx/Dashboard-Page-when-unauthenticated-should-redirect-to-login-when-not-authenticated-1.png +0 -0
- /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-accept-invitation-button-1.png +0 -0
- /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-decline-button-linking-to-homepage-1.png +0 -0
- /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-display-invitation-details--email--workspace--role--1.png +0 -0
- /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-have-a-logo-link-to-homepage-1.png +0 -0
- /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-render-invitation-page-with-inviter-name-and-workspace-1.png +0 -0
- /package/templates/base/{src/client/routes/__tests__ → tests/unit/client/routes}/__screenshots__/invite.test.tsx/Invite-Token-Page-pending-invitation-state-should-show-terms-of-service-and-privacy-policy-links-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-display-Google-OAuth-login-button-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-have-a-link-back-to-home-page-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-render-login-content-without-waiting-for-authentication-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-render-login-page-at--login-route-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-show-Terms-of-Service-and-Privacy-Policy-links-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/login.test.tsx/Login-Page-should-trigger-OAuth-flow-when-clicking-login-button-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-display-404-text-on-not-found-page-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-have-navigation-options-on-404-page-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-404-handling-should-render-404-page-for-unknown-routes-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-account-page-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-integrations-page-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-settings-page-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-authenticated-navigation-should-navigate-from-dashboard-to-team-page-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-home-page-navigation-should-display-navigation-links-on-home-page-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-home-page-navigation-should-have-correct-link-destinations-on-home-page-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-allow-access-to-home-page-without-authentication-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-allow-access-to-login-page-without-authentication-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-dashboard-to-login-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-settings-to-login-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/__screenshots__/navigation.test.tsx/Navigation-unauthenticated-navigation-should-redirect-unauthenticated-users-from-team-to-login-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-render-Active-Sessions-section-with-session-cards-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-render-page-with-correct-title--Account--1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-show-API-Access-section-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-show-Connected-Accounts-section-with-Google-connected-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-show-Danger-Zone-section-with-delete-button-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/account.test.tsx/Account-Page-should-show-Security-section-with-Two-Factor-Authentication-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-API-documentation-section-should-display-API-documentation-link-section-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-Create-Webhook-Dialog-should-have-Add-Webhook-trigger-button-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-category-filters-should-display-all-category-buttons-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-display-all-integration-cards-with-names-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-display-category-badges-on-cards-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Configure-button-for-connected-integrations-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Connect-button-for-not-connected-integrations-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-integration-cards-should-show-Connected-badge-for-connected-integrations-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-Available-Integrations-section-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-Webhooks-section-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-connected-count-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-page-description-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-display-search-input-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-page-rendering-should-render-with-correct-title--Integrations--1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-filter-integrations-based-on-search-query-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-search-by-description-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-search-functionality-should-show-no-results-message-when-search-has-no-matches-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-existing-webhook-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-events-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-last-delivery-info-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-display-webhook-success-status-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/integrations.test.tsx/Integrations-Page-webhooks-section-should-have-Add-Webhook-button-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Account-tab-should-display-connected-accounts-section-with-Google-provider-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Account-tab-should-display-sessions-and-danger-zone-sections-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-all-notification-toggle-options-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-email-notifications-section-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-display-toggle-switches-for-notification-options-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Notifications-tab-should-have-toggles-checked-by-default-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display--Save-Changes--button-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-personal-information-form-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-profile-picture-section-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-email-in-disabled-email-input-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-initials-in-avatar-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-Profile-tab-should-display-user-name-in-the-name-input-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-display-all-three-tabs-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-display-page-description-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-page-rendering-should-render-with-correct-title--Settings--1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-show-Profile-tab-as-default-active-tab-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-switch-to-Account-tab-when-clicked-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/settings.test.tsx/Settings-Page-tab-navigation-should-switch-to-Notifications-tab-when-clicked-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-display-Active-Members-section-with-member-count-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-display-Pending-Invitations-section-with-invitation-details-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-have-invite-member-button-that-can-be-clicked-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-render-page-with-correct-title-and-description-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-render-search-input-that-filters-team-members-1.png +0 -0
- /package/templates/base/{src/client/routes/_authenticated/__tests__ → tests/unit/client/routes/_authenticated}/__screenshots__/team.test.tsx/Team-Page-should-show-current-user-with---you---indicator-and-role-badge-1.png +0 -0
- /package/templates/base/{src/client/__tests__ → tests/unit/client}/routes/error-components.test.tsx +0 -0
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
# Module Dependencies - BHono Platform
|
|
2
|
+
|
|
3
|
+
> Service and module dependency map showing how components interact.
|
|
4
|
+
|
|
5
|
+
## Dependency Overview
|
|
6
|
+
|
|
7
|
+
```mermaid
|
|
8
|
+
graph TD
|
|
9
|
+
subgraph "Entry Points"
|
|
10
|
+
ServerEntry[src/server/index.ts]
|
|
11
|
+
ClientEntry[src/client/main.tsx]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
subgraph "Server Layer"
|
|
15
|
+
Middleware[middleware/]
|
|
16
|
+
Routes[routes/]
|
|
17
|
+
Services[services/]
|
|
18
|
+
Auth[auth/]
|
|
19
|
+
DB[db/]
|
|
20
|
+
Lib[lib/]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
subgraph "Client Layer"
|
|
24
|
+
Router[router.ts]
|
|
25
|
+
ClientRoutes[routes/]
|
|
26
|
+
Components[components/]
|
|
27
|
+
Hooks[hooks/]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
subgraph "Shared Layer"
|
|
31
|
+
Schemas[shared/schemas/]
|
|
32
|
+
Types[shared/types/]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
subgraph "External"
|
|
36
|
+
D1[(D1 Database)]
|
|
37
|
+
KV[(KV Store)]
|
|
38
|
+
R2[(R2 Storage)]
|
|
39
|
+
Google[Google OAuth]
|
|
40
|
+
SendGrid[SendGrid]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
ServerEntry --> Middleware
|
|
44
|
+
ServerEntry --> Routes
|
|
45
|
+
Middleware --> Auth
|
|
46
|
+
Middleware --> Lib
|
|
47
|
+
Routes --> Services
|
|
48
|
+
Routes --> Schemas
|
|
49
|
+
Services --> DB
|
|
50
|
+
Services --> Lib
|
|
51
|
+
Auth --> DB
|
|
52
|
+
DB --> D1
|
|
53
|
+
Lib --> KV
|
|
54
|
+
Lib --> R2
|
|
55
|
+
Lib --> Google
|
|
56
|
+
Lib --> SendGrid
|
|
57
|
+
|
|
58
|
+
ClientEntry --> Router
|
|
59
|
+
Router --> ClientRoutes
|
|
60
|
+
ClientRoutes --> Components
|
|
61
|
+
ClientRoutes --> Hooks
|
|
62
|
+
Components --> Types
|
|
63
|
+
Hooks --> Types
|
|
64
|
+
Hooks --> Schemas
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Server Dependencies [HIGH]
|
|
70
|
+
|
|
71
|
+
### Middleware Layer
|
|
72
|
+
|
|
73
|
+
| Module | Dependencies | Purpose |
|
|
74
|
+
|--------|--------------|---------|
|
|
75
|
+
| `error-handler.ts` | `lib/errors` | Global error handling |
|
|
76
|
+
| `request-context.ts` | `uuidv7` | Transaction ID generation |
|
|
77
|
+
| `request-logger.ts` | `request-context` | Structured logging |
|
|
78
|
+
| `cors.ts` | `hono/cors` | CORS configuration |
|
|
79
|
+
| `rate-limit.ts` | None | In-memory rate limiting |
|
|
80
|
+
| `auth.ts` | `lib/session`, `auth/guards` | Session validation |
|
|
81
|
+
| `account.ts` | `db/sql`, `auth/guards` | Account context |
|
|
82
|
+
|
|
83
|
+
```mermaid
|
|
84
|
+
graph LR
|
|
85
|
+
Request[Request] --> EH[Error Handler]
|
|
86
|
+
EH --> RC[Request Context]
|
|
87
|
+
RC --> RL[Request Logger]
|
|
88
|
+
RL --> CORS[CORS]
|
|
89
|
+
CORS --> Rate[Rate Limiter]
|
|
90
|
+
Rate --> Auth[Session Auth]
|
|
91
|
+
Auth --> Acc[Account Context]
|
|
92
|
+
Acc --> Handler[Route Handler]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Routes Layer
|
|
96
|
+
|
|
97
|
+
| Route Module | Service Dependencies | Schema Dependencies |
|
|
98
|
+
|--------------|---------------------|---------------------|
|
|
99
|
+
| `auth/` | `AuthService` | `auth/schemas` |
|
|
100
|
+
| `users/` | `UsersService` | `users/schemas`, `shared/schemas/user` |
|
|
101
|
+
| `accounts/` | `AccountsService` | `accounts/schemas`, `shared/schemas/account` |
|
|
102
|
+
| `invitations/` | `InvitationsService` | `invitations/schemas`, `shared/schemas/invitation` |
|
|
103
|
+
| `audits/` | `AuditsService` | `audits/schemas` |
|
|
104
|
+
| `storage/` | R2 direct | `storage/schemas` |
|
|
105
|
+
| `health/` | D1 direct | None |
|
|
106
|
+
|
|
107
|
+
### Services Layer
|
|
108
|
+
|
|
109
|
+
| Service | Dependencies | External |
|
|
110
|
+
|---------|--------------|----------|
|
|
111
|
+
| `AuthService` | `db/sql`, `lib/oauth`, `lib/session`, `lib/tokens` | Google OAuth, KV |
|
|
112
|
+
| `UsersService` | `db/sql`, `lib/audit` | D1 |
|
|
113
|
+
| `AccountsService` | `db/sql`, `lib/audit` | D1 |
|
|
114
|
+
| `InvitationsService` | `db/sql`, `lib/email`, `lib/tokens` | D1, SendGrid |
|
|
115
|
+
| `AuditsService` | `db/sql` | D1 |
|
|
116
|
+
|
|
117
|
+
### Library Layer
|
|
118
|
+
|
|
119
|
+
| Library | Dependencies | External Services |
|
|
120
|
+
|---------|--------------|-------------------|
|
|
121
|
+
| `oauth.ts` | None | Google OAuth APIs |
|
|
122
|
+
| `session.ts` | None | Cloudflare KV |
|
|
123
|
+
| `tokens.ts` | `crypto` | None |
|
|
124
|
+
| `email.ts` | None | SendGrid API |
|
|
125
|
+
| `audit.ts` | `db/sql` | D1 |
|
|
126
|
+
| `pagination.ts` | None | None |
|
|
127
|
+
| `errors.ts` | None | None |
|
|
128
|
+
| `r2-storage.ts` | None | Cloudflare R2 |
|
|
129
|
+
|
|
130
|
+
### Auth Layer
|
|
131
|
+
|
|
132
|
+
| Module | Dependencies | Purpose |
|
|
133
|
+
|--------|--------------|---------|
|
|
134
|
+
| `roles.ts` | None | Role hierarchy definition |
|
|
135
|
+
| `permissions.ts` | `roles` | Permission constants |
|
|
136
|
+
| `guards.ts` | `roles`, `permissions` | Authorization checks |
|
|
137
|
+
|
|
138
|
+
```mermaid
|
|
139
|
+
graph TD
|
|
140
|
+
Guards[guards.ts] --> Roles[roles.ts]
|
|
141
|
+
Guards --> Permissions[permissions.ts]
|
|
142
|
+
Permissions --> Roles
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Database Layer
|
|
146
|
+
|
|
147
|
+
| Module | Dependencies | Purpose |
|
|
148
|
+
|--------|--------------|---------|
|
|
149
|
+
| `sql.ts` | D1 binding | Query helpers |
|
|
150
|
+
| `records.ts` | None | Type definitions |
|
|
151
|
+
| `client.ts` | D1 binding | Client wrapper |
|
|
152
|
+
| `seed.ts` | `sql.ts` | Test data generation |
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Client Dependencies [HIGH]
|
|
157
|
+
|
|
158
|
+
### Route Dependencies
|
|
159
|
+
|
|
160
|
+
| Route | Component Dependencies | Hook Dependencies |
|
|
161
|
+
|-------|----------------------|-------------------|
|
|
162
|
+
| `__root.tsx` | `Sonner`, `ErrorBoundary` | `useTheme` |
|
|
163
|
+
| `_authenticated.tsx` | `Sidebar`, `LoadingSkeleton` | `useAuth` |
|
|
164
|
+
| `login.tsx` | `Button`, `Card`, `Icons` | None |
|
|
165
|
+
| `dashboard.tsx` | `Card`, `Badge` | `useAuth` |
|
|
166
|
+
| `team.tsx` | `Card`, `Dialog`, `Avatar` | `useAuth` |
|
|
167
|
+
| `settings.tsx` | `Tabs`, `Form`, `Input` | `useAuth` |
|
|
168
|
+
| `account.tsx` | `Card`, `Badge` | `useAuth` |
|
|
169
|
+
| `integrations.tsx` | `Card`, `Dialog`, `Badge` | `useAuth` |
|
|
170
|
+
|
|
171
|
+
### Component Dependencies
|
|
172
|
+
|
|
173
|
+
| Component | External Dependencies |
|
|
174
|
+
|-----------|----------------------|
|
|
175
|
+
| `Button` | `class-variance-authority`, `@radix-ui/react-slot` |
|
|
176
|
+
| `Dialog` | `@radix-ui/react-dialog` |
|
|
177
|
+
| `Tabs` | `@radix-ui/react-tabs` |
|
|
178
|
+
| `Avatar` | `@radix-ui/react-avatar` |
|
|
179
|
+
| `Form` | `react-hook-form`, `@hookform/resolvers/zod` |
|
|
180
|
+
| `Sonner` | `sonner` |
|
|
181
|
+
| `Sidebar` | `lucide-react` |
|
|
182
|
+
|
|
183
|
+
### Hook Dependencies
|
|
184
|
+
|
|
185
|
+
| Hook | Dependencies |
|
|
186
|
+
|------|--------------|
|
|
187
|
+
| `useAuth` | `@tanstack/react-query`, `shared/types/auth` |
|
|
188
|
+
| `useTheme` | React Context |
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Shared Dependencies [HIGH]
|
|
193
|
+
|
|
194
|
+
### Schemas
|
|
195
|
+
|
|
196
|
+
| Schema | Used By |
|
|
197
|
+
|--------|---------|
|
|
198
|
+
| `user.ts` | `server/routes/users`, `client/hooks/use-auth` |
|
|
199
|
+
| `account.ts` | `server/routes/accounts`, `client/routes/account` |
|
|
200
|
+
| `invitation.ts` | `server/routes/invitations`, `client/routes/team` |
|
|
201
|
+
| `profile.ts` | `server/routes/users`, `client/routes/settings` |
|
|
202
|
+
| `webhook.ts` | `client/routes/integrations` |
|
|
203
|
+
|
|
204
|
+
### Types
|
|
205
|
+
|
|
206
|
+
| Type Module | Used By |
|
|
207
|
+
|-------------|---------|
|
|
208
|
+
| `auth.ts` | Server auth, client hooks |
|
|
209
|
+
| `user.ts` | Server services, client routes |
|
|
210
|
+
| `account.ts` | Server services, client routes |
|
|
211
|
+
| `api.ts` | Server routes, client API calls |
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## External Dependencies [HIGH]
|
|
216
|
+
|
|
217
|
+
### NPM Packages
|
|
218
|
+
|
|
219
|
+
#### Backend
|
|
220
|
+
|
|
221
|
+
| Package | Version | Purpose |
|
|
222
|
+
|---------|---------|---------|
|
|
223
|
+
| `hono` | 4.11.x | Web framework |
|
|
224
|
+
| `@hono/zod-openapi` | 1.2.x | OpenAPI integration |
|
|
225
|
+
| `@hono/swagger-ui` | 0.5.x | API documentation |
|
|
226
|
+
| `zod` | 4.3.x | Schema validation |
|
|
227
|
+
| `uuidv7` | 1.1.x | UUID generation |
|
|
228
|
+
|
|
229
|
+
#### Frontend
|
|
230
|
+
|
|
231
|
+
| Package | Version | Purpose |
|
|
232
|
+
|---------|---------|---------|
|
|
233
|
+
| `react` | 19.x | UI library |
|
|
234
|
+
| `@tanstack/react-router` | 1.144.x | File-based routing |
|
|
235
|
+
| `@tanstack/react-query` | 5.90.x | Data fetching |
|
|
236
|
+
| `react-hook-form` | 7.70.x | Form handling |
|
|
237
|
+
| `tailwindcss` | 4.1.x | Styling |
|
|
238
|
+
| `@radix-ui/*` | 1.x | UI primitives |
|
|
239
|
+
| `lucide-react` | 0.562.x | Icons |
|
|
240
|
+
| `sonner` | 2.0.x | Toast notifications |
|
|
241
|
+
|
|
242
|
+
### Cloudflare Services
|
|
243
|
+
|
|
244
|
+
| Service | Binding | Purpose |
|
|
245
|
+
|---------|---------|---------|
|
|
246
|
+
| D1 | `DB` | SQLite database |
|
|
247
|
+
| KV | `SESSIONS` | Session storage |
|
|
248
|
+
| R2 | `R2_BUCKET` | File storage |
|
|
249
|
+
|
|
250
|
+
### External APIs
|
|
251
|
+
|
|
252
|
+
| Service | Protocol | Purpose |
|
|
253
|
+
|---------|----------|---------|
|
|
254
|
+
| Google OAuth | OAuth 2.0 | Authentication |
|
|
255
|
+
| SendGrid | REST API | Email delivery |
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Dependency Rules
|
|
260
|
+
|
|
261
|
+
### Allowed Dependencies
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
┌─────────────────────────────────────────────────────────┐
|
|
265
|
+
│ Routes │
|
|
266
|
+
│ ┌─────────────────────────────────────────────────┐ │
|
|
267
|
+
│ │ Services │ │
|
|
268
|
+
│ │ ┌─────────────────────────────────────────┐ │ │
|
|
269
|
+
│ │ │ Auth/Lib │ │ │
|
|
270
|
+
│ │ │ ┌─────────────────────────────────┐ │ │ │
|
|
271
|
+
│ │ │ │ DB │ │ │ │
|
|
272
|
+
│ │ │ └─────────────────────────────────┘ │ │ │
|
|
273
|
+
│ │ └─────────────────────────────────────────┘ │ │
|
|
274
|
+
│ └─────────────────────────────────────────────────┘ │
|
|
275
|
+
└─────────────────────────────────────────────────────────┘
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Rules**:
|
|
279
|
+
1. Routes → Services → DB (never skip layers)
|
|
280
|
+
2. Middleware can access Auth and Lib
|
|
281
|
+
3. Services can access DB and Lib
|
|
282
|
+
4. Auth can access DB for role lookups
|
|
283
|
+
5. Shared schemas/types accessible by all layers
|
|
284
|
+
|
|
285
|
+
### Forbidden Dependencies
|
|
286
|
+
|
|
287
|
+
| Layer | Cannot Import |
|
|
288
|
+
|-------|---------------|
|
|
289
|
+
| DB | Services, Routes, Middleware |
|
|
290
|
+
| Lib | Services, Routes |
|
|
291
|
+
| Auth | Services, Routes |
|
|
292
|
+
| Services | Routes, Middleware |
|
|
293
|
+
| Shared | Any server/client specific code |
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Import Aliases
|
|
298
|
+
|
|
299
|
+
| Alias | Maps To | Usage |
|
|
300
|
+
|-------|---------|-------|
|
|
301
|
+
| `@/*` | `src/client/*` | Client-only imports |
|
|
302
|
+
| `@server/*` | `src/server/*` | Server-only imports |
|
|
303
|
+
| `@shared/*` | `src/shared/*` | Shared imports |
|
|
304
|
+
|
|
305
|
+
**Example**:
|
|
306
|
+
```typescript
|
|
307
|
+
// In client code
|
|
308
|
+
import { Button } from '@/components/ui/button'
|
|
309
|
+
import { userSchema } from '@shared/schemas/user'
|
|
310
|
+
|
|
311
|
+
// In server code
|
|
312
|
+
import { UsersService } from '@server/services/users'
|
|
313
|
+
import { userSchema } from '@shared/schemas/user'
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## Circular Dependency Prevention
|
|
319
|
+
|
|
320
|
+
The architecture prevents circular dependencies through:
|
|
321
|
+
|
|
322
|
+
1. **Layered architecture**: Lower layers cannot import higher layers
|
|
323
|
+
2. **Shared types**: Common types in `shared/` break potential cycles
|
|
324
|
+
3. **Dependency injection**: Services receive dependencies via constructor
|
|
325
|
+
4. **Interface segregation**: Guards expose minimal interfaces
|
|
326
|
+
|
|
327
|
+
**Build-time checks**: TypeScript's `noImplicitAny` and path aliases enforce boundaries.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Mapeamento do Drizzle e plano de migracao para SQL puro
|
|
2
|
+
|
|
3
|
+
> Status: Drizzle removido (PDB-823, Jan 2026). Este documento permanece como historico do plano.
|
|
4
|
+
|
|
5
|
+
Contexto canonico: `docs/app_spec.txt`.
|
|
6
|
+
|
|
7
|
+
## Objetivo
|
|
8
|
+
|
|
9
|
+
Documentar onde o Drizzle e utilizado hoje e propor uma sequencia de migracao para SQL puro (D1/SQLite) com menor risco.
|
|
10
|
+
|
|
11
|
+
## Inventario de uso do Drizzle
|
|
12
|
+
|
|
13
|
+
### Tooling e configuracao
|
|
14
|
+
|
|
15
|
+
- `config/drizzle.config.ts`
|
|
16
|
+
- `package.json` (scripts `db:push`, `db:generate`, `db:studio`; dependencias `drizzle-orm`, `drizzle-kit`)
|
|
17
|
+
- `packages/bhono-app/templates/base/config/drizzle.config.ts`
|
|
18
|
+
- `packages/bhono-app/templates/base/package.json` (mesmos scripts/dependencias)
|
|
19
|
+
|
|
20
|
+
### Schema e helpers
|
|
21
|
+
|
|
22
|
+
- `src/server/db/schema/index.ts`
|
|
23
|
+
- `src/server/db/schema/*.ts` (users, accounts, user-accounts, invitations, refresh-tokens, audit-logs)
|
|
24
|
+
- `src/server/lib/schema-helpers.ts`
|
|
25
|
+
- `packages/bhono-app/templates/base/src/server/db/schema/*`
|
|
26
|
+
- `packages/bhono-app/templates/base/src/server/lib/schema-helpers.ts`
|
|
27
|
+
|
|
28
|
+
### Client e cross-cutting
|
|
29
|
+
|
|
30
|
+
- `src/server/db/client.ts` (createDb com `drizzle-orm/d1`)
|
|
31
|
+
- `src/server/lib/transaction.ts` (types baseados em `Database['transaction']`)
|
|
32
|
+
- `src/server/lib/audited-db.ts` (Table/SQL do Drizzle, `.returning()`)
|
|
33
|
+
- `src/server/lib/audit.ts` (grava em `audit_logs` usando `db.insert`)
|
|
34
|
+
- `packages/bhono-app/templates/base/src/server/db/client.ts`
|
|
35
|
+
- `packages/bhono-app/templates/base/src/server/lib/transaction.ts`
|
|
36
|
+
- `packages/bhono-app/templates/base/src/server/lib/audited-db.ts`
|
|
37
|
+
- `packages/bhono-app/templates/base/src/server/lib/audit.ts`
|
|
38
|
+
|
|
39
|
+
### Services (queries principais)
|
|
40
|
+
|
|
41
|
+
- `src/server/services/auth.ts` (insert/update/returning, tokens, refresh)
|
|
42
|
+
- `src/server/services/users.ts` (filtros, subquery IN, soft delete, paginacao)
|
|
43
|
+
- `src/server/services/accounts.ts` (filtros, subquery IN, soft delete, paginacao)
|
|
44
|
+
- `src/server/services/invitations.ts` (joins, expiracao, create/accept)
|
|
45
|
+
- `src/server/services/audits.ts` (filtros, paginacao)
|
|
46
|
+
- `packages/bhono-app/templates/base/src/server/services/*` (espelho)
|
|
47
|
+
|
|
48
|
+
### Middleware e rotas
|
|
49
|
+
|
|
50
|
+
- `src/server/middleware/auth.ts` (select por id + soft delete)
|
|
51
|
+
- `src/server/middleware/account.ts` (select por membership)
|
|
52
|
+
- `src/server/routes/health/handlers.ts` (db.run com `sql` do Drizzle)
|
|
53
|
+
- `src/server/routes/auth/test-login.ts` (select simples)
|
|
54
|
+
- `packages/bhono-app/templates/base/src/server/middleware/*`
|
|
55
|
+
- `packages/bhono-app/templates/base/src/server/routes/*`
|
|
56
|
+
|
|
57
|
+
### Testes
|
|
58
|
+
|
|
59
|
+
- `tests/integration/setup.ts` (drizzle + better-sqlite3, schema SQL inline)
|
|
60
|
+
- `packages/bhono-app/templates/base/tests/integration/*` (espelho com drizzle)
|
|
61
|
+
- `packages/bhono-app/templates/base/tests/integration/security/*.test.ts` (comentarios e wrappers de drizzle)
|
|
62
|
+
|
|
63
|
+
## Padroes de query usados hoje
|
|
64
|
+
|
|
65
|
+
- Select simples por id + soft delete (`deleted_at IS NULL`).
|
|
66
|
+
- Select com join (`invitations` + `users`/`accounts`).
|
|
67
|
+
- Subquery com `IN` (multi-tenancy em users/accounts).
|
|
68
|
+
- Paginacao com `LIMIT/OFFSET` + `count(*)`.
|
|
69
|
+
- `LIKE` para filtros por nome/email/dominio.
|
|
70
|
+
- Inserts/updates com `returning()`.
|
|
71
|
+
- Soft delete (update de `deleted_at` e audit).
|
|
72
|
+
- Transacoes (create user + account + membership; depende de `db.transaction`).
|
|
73
|
+
- Uso pontual de SQL raw (`sql\`SELECT 1\`` na healthcheck).
|
|
74
|
+
|
|
75
|
+
## Sequencia recomendada de migracao
|
|
76
|
+
|
|
77
|
+
1) Padroes e convencoes de SQL puro (PDB-813)
|
|
78
|
+
- Definir placeholders, naming, soft delete, mapeamento/validacao, tratamento de erros.
|
|
79
|
+
|
|
80
|
+
2) Helper SQL para D1 (PDB-814)
|
|
81
|
+
- API de execucao (queryOne/queryAll/exec), bind de parametros e typing.
|
|
82
|
+
- Confirmar comportamento de transacoes no D1 (ex.: `batch`) antes de migrar flows criticos.
|
|
83
|
+
|
|
84
|
+
3) Camadas cross-cutting (PDB-815)
|
|
85
|
+
- Reimplementar `audited-db` e `audit` com SQL puro.
|
|
86
|
+
- Ajustar `transaction.ts` para o novo helper.
|
|
87
|
+
|
|
88
|
+
4) Modulos de negocio (PDB-816 a PDB-821)
|
|
89
|
+
- Auth -> Users -> Accounts -> Invitations -> Audits -> Middleware.
|
|
90
|
+
- Sempre migrar junto com testes afetados.
|
|
91
|
+
|
|
92
|
+
5) Estrategia sem migrations (PDB-822)
|
|
93
|
+
- Consolidar `schema.sql` versionado e bootstrap/reset com `wrangler d1 execute`.
|
|
94
|
+
- Alinhar `tests/integration/setup.ts` com `schema.sql`.
|
|
95
|
+
|
|
96
|
+
6) Remocao de Drizzle (PDB-823)
|
|
97
|
+
- Limpar dependencias, scripts e tipos remanescentes.
|
|
98
|
+
|
|
99
|
+
## Riscos e mitigacoes
|
|
100
|
+
|
|
101
|
+
- Consistencia multi-tenant: garantir `account_id` em todas as queries.
|
|
102
|
+
- Mitigacao: helper com scoping obrigatorio e testes de autorizacao.
|
|
103
|
+
|
|
104
|
+
- Perda de audit trail: `audited-*` depende de `returning()`.
|
|
105
|
+
- Mitigacao: selecionar estado anterior antes do update e usar `RETURNING` quando suportado.
|
|
106
|
+
|
|
107
|
+
- SQL injection: migracao aumenta risco manual.
|
|
108
|
+
- Mitigacao: prepared statements, helpers obrigatorios e proibicao de string interpolation.
|
|
109
|
+
|
|
110
|
+
- Diferencas de comportamento entre D1 e sqlite local.
|
|
111
|
+
- Mitigacao: alinhar `schema.sql` e tests com D1 (usar `wrangler d1` para smoke tests).
|
|
112
|
+
|
|
113
|
+
- Quebra de testes e mocks.
|
|
114
|
+
- Mitigacao: atualizar `tests/integration/setup.ts` e mocks ao mesmo tempo que cada modulo.
|
|
115
|
+
|
|
116
|
+
## Entregaveis desta etapa (PDB-812)
|
|
117
|
+
|
|
118
|
+
- Inventario de arquivos e padroes de query.
|
|
119
|
+
- Sequencia recomendada e dependencias entre modulos.
|
|
120
|
+
- Riscos e mitigacoes para orientar as proximas issues.
|
|
121
|
+
|
|
122
|
+
## Notas
|
|
123
|
+
|
|
124
|
+
- Tudo que for alterado no `src/` deve ser espelhado em `packages/bhono-app/templates/base/`.
|
|
125
|
+
- O seed ja gera SQL puro; pode ser mantido e ajustado conforme o `schema.sql`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ERD - Hono Boilerplate (D1/SQLite)
|
|
2
2
|
|
|
3
3
|
## Visao geral
|
|
4
|
-
Este documento descreve o modelo relacional atual utilizado no banco D1 (SQLite) do projeto. Ele foi derivado diretamente
|
|
4
|
+
Este documento descreve o modelo relacional atual utilizado no banco D1 (SQLite) do projeto. Ele foi derivado diretamente de `schema.sql`.
|
|
5
5
|
|
|
6
6
|
## Diagrama (Mermaid)
|
|
7
7
|
```mermaid
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Padrao de SQL puro e mapeamento de resultados
|
|
2
|
+
|
|
3
|
+
Contexto canonico: `docs/app_spec.txt`.
|
|
4
|
+
|
|
5
|
+
## Objetivo
|
|
6
|
+
|
|
7
|
+
Definir convencoes para SQL puro no D1/SQLite, incluindo bind de parametros,
|
|
8
|
+
mapa de resultados e tratamento de erros para manter consistencia e seguranca.
|
|
9
|
+
|
|
10
|
+
## Escopo
|
|
11
|
+
|
|
12
|
+
- SQL usado no backend (services, middleware, lib).
|
|
13
|
+
- Mapeamento de resultados para tipos de dominio.
|
|
14
|
+
- Soft delete, multi-tenancy, auditoria e paginacao.
|
|
15
|
+
|
|
16
|
+
## Convencoes de SQL
|
|
17
|
+
|
|
18
|
+
### Estilo
|
|
19
|
+
|
|
20
|
+
- Keywords em UPPERCASE (SELECT, FROM, WHERE).
|
|
21
|
+
- Tabelas e colunas em snake_case (como no schema atual).
|
|
22
|
+
- Evitar `SELECT *`: listar colunas para mapear explicitamente.
|
|
23
|
+
- Preferir alias curtos (`users u`, `accounts a`) quando houver join.
|
|
24
|
+
|
|
25
|
+
### Parametros e seguranca
|
|
26
|
+
|
|
27
|
+
- Nunca interpolar strings diretamente em SQL.
|
|
28
|
+
- Usar placeholders posicionais `?` com `stmt.bind(...)`.
|
|
29
|
+
- Proibir concatenacao de SQL com valores de usuario.
|
|
30
|
+
|
|
31
|
+
### Soft delete
|
|
32
|
+
|
|
33
|
+
- Queries de leitura devem sempre filtrar `deleted_at IS NULL` quando aplicavel.
|
|
34
|
+
- Remocoes devem ser soft delete (update de `deleted_at`, `deleted_by_id`, `updated_at`).
|
|
35
|
+
- Restauracao deve limpar `deleted_at` e `deleted_by_id`.
|
|
36
|
+
|
|
37
|
+
### Multi-tenancy
|
|
38
|
+
|
|
39
|
+
- Toda query de dados multi-tenant deve filtrar `account_id`.
|
|
40
|
+
- Para super-admin, permitir bypass explicito em query (flag de contexto).
|
|
41
|
+
|
|
42
|
+
### Paginacao e filtros
|
|
43
|
+
|
|
44
|
+
- Paginacao via `LIMIT`/`OFFSET`.
|
|
45
|
+
- Contagem total via `SELECT count(*)`.
|
|
46
|
+
- Filtros textuais com `LIKE` e `%`.
|
|
47
|
+
|
|
48
|
+
### Datas e tipos
|
|
49
|
+
|
|
50
|
+
- Datas em TEXT ISO (ex.: `created_at`) ou INTEGER unix (ex.: `refresh_tokens`).
|
|
51
|
+
- Mapear `INTEGER` para boolean quando necessario (0/1).
|
|
52
|
+
- Campos JSON em TEXT devem ser parseados ao ler.
|
|
53
|
+
|
|
54
|
+
## Mapeamento de resultados
|
|
55
|
+
|
|
56
|
+
### Regra geral
|
|
57
|
+
|
|
58
|
+
- Toda query deve ter um mapper explicito (funcao ou schema) que:
|
|
59
|
+
- valida shape (preferencialmente com Zod),
|
|
60
|
+
- converte tipos (INTEGER -> boolean, TEXT JSON -> objeto),
|
|
61
|
+
- normaliza campos opcionais.
|
|
62
|
+
|
|
63
|
+
### Exemplo (conceitual)
|
|
64
|
+
|
|
65
|
+
- Query retorna `is_super_admin` (INTEGER).
|
|
66
|
+
- Mapper converte para boolean e retorna `isSuperAdmin`.
|
|
67
|
+
- Campo `provider_ids` (TEXT JSON) vira `string[]`.
|
|
68
|
+
|
|
69
|
+
## Erros e tratamento
|
|
70
|
+
|
|
71
|
+
- `NotFoundError` quando `SELECT` nao retorna registros esperados.
|
|
72
|
+
- `ConflictError` quando violar unicidade (dominio/email/token).
|
|
73
|
+
- `ForbiddenError` para acesso indevido a `account_id`.
|
|
74
|
+
- Propagar erro de SQL com mensagem generica (evitar leak de detalhes).
|
|
75
|
+
|
|
76
|
+
## Transacoes
|
|
77
|
+
|
|
78
|
+
- D1 nao oferece transacoes nativas. Operacoes multi-step devem ser planejadas
|
|
79
|
+
para serem idempotentes ou dividir em `batch` quando possivel.
|
|
80
|
+
- Para fluxos criticos, validar resultados intermediarios e registrar auditoria
|
|
81
|
+
com `transaction_id` compartilhado.
|
|
82
|
+
|
|
83
|
+
## Auditoria
|
|
84
|
+
|
|
85
|
+
- Toda mutacao relevante deve registrar `audit_logs`.
|
|
86
|
+
- Usar `transaction_id` comum para agrupar operacoes.
|
|
87
|
+
- Registrar `changes` apenas com campos relevantes.
|
|
88
|
+
|
|
89
|
+
## Checklist de migracao por modulo
|
|
90
|
+
|
|
91
|
+
- Listar queries atuais.
|
|
92
|
+
- Reescrever SQL com bind e filtros `account_id`/`deleted_at`.
|
|
93
|
+
- Adicionar mapper/validator.
|
|
94
|
+
- Atualizar testes afetados.
|
|
95
|
+
|
|
96
|
+
## Referencias
|
|
97
|
+
|
|
98
|
+
- `docs/architecture/erd.md`
|
|
99
|
+
- `docs/architecture/data-requirements.md`
|
|
100
|
+
- `docs/architecture/drizzle-migration-plan.md`
|