- Create @reviq/frontend-utils package for frontend-specific utilities
- Add OrgAvatar component with size variants (xs, sm, md, lg, xl)
- Display org initials with deterministic colors when no logo available
- Add getOrgInitials and getOrgColor utility functions
- Update org-switcher and all org display pages to use OrgAvatar
- Add noNonNullAssertion lint rule as error in biome.jsonc
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create gotoLogin() helper for login redirects with search params
- Add /terms and /privacy public routes with Tailwind typography
- Update auth-guard to allow unauthenticated access to public pages
- Fix resolve() usage across navigation components using as const pattern
- Fix eslint-disable-next-line placement for svelte/no-navigation-without-resolve
- Document SvelteKit resolve() patterns in CLAUDE.md
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Create new @reviq/common package with environment-agnostic utilities:
- Date formatting: formatDate, formatDateTime, formatLongDate,
formatRelativeDate, formatRelativeTime
- User utilities: getUserInitials, formatRole
Consolidate date formatting from publisher-dashboard into shared package.
All utilities include comprehensive test coverage with bun:test.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add reviq auth login --token <token> command for CLI authentication
- Create /account/api-tokens page for token management (superuser only)
- Add me.apiTokens endpoints (list, create, delete)
- Require superuser status and trusted session for token creation
- Show API Tokens nav link only for superusers
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Combines testing improvements with org invites feature:
- Sessions and devices now use subrouter structure (me.sessions.*, me.devices.*)
- Added me.invites subrouter for org invitations
- Updated test scripts to include coverage and unit tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update API contract to use nested router structure for sessions and devices
(me.sessions.list, me.devices.getInfo, etc.)
- Update frontend Svelte components to use new nested API paths
- Fix test assertion patterns for consistency (remove async () => wrappers)
- Fix test-db.ts findRepoRoot to use existsSync for directory checking
(Bun.file().exists() returns false for directories)
- Add ESLint config override for test files to handle expect().rejects patterns
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- Add me.invites endpoints (list, get, accept, decline) to API contract
- Create invites procedures for fetching user's pending invites
- Only show invites if email matches and is verified
- Refactor me routes into me/_routes.ts for consistency
Frontend:
- Add pending invitations section to /dashboard page
- Create /account/org-invites/[inviteId] page for accept/decline
- Show invite details (org, role, inviter, dates)
- Redirect to org dashboard after accepting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add successResponseSchema to common.ts for explicit success responses
- Update all auth, me, orgs, and admin procedures to return { success: true }
- Update contract.ts to use successResponseSchema instead of z.void()
- Add ast-grep rule to prevent future z.void() usage in contracts
- Add build:packages script to root package.json
- Fix test file lint errors with eslint-disable comments
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create packages/utils/src/generate-base58-token.ts with typed prefix support
- Function returns `${TPrefix}${string}` for type-safe prefixed tokens
- Add isBase58() validator and parseBase58Token() helper
- Add comprehensive tests (13 test cases)
- Update login request tokens to use "login_" prefix
- Fix login-password.ts to not replace token (cookie/DB mismatch bug)
- Migrate all token generation from generateSecureToken (hex) to
generateSecureBase58Token (base58)
- Remove duplicate token generation from api-server/utils/crypto.ts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Allows re-running bootstrap to delete and recreate the superuser and
reviq org. Deletes all related records (tokens, sessions, passkeys, etc.)
before recreating.
Also configures stricli to use kebab-case for CLI flags globally.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use executeBootstrap helper from @reviq/db for CLI bootstrap
- Update @reviq/db to use @reviq/utils for PBKDF2-SHA256 password hashing
(Cloudflare Workers compatible)
- Keep @scure/base for base58 token encoding
- Remove redundant password.ts from @reviq/db (import directly from @reviq/utils)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create @reviq/utils package with PBKDF2-SHA256 password hashing
compatible with Cloudflare Workers (uses crypto.subtle)
- Update api-server and CLI to use new utils package for consistent
password hashing format across the codebase
- Add pino logging to api-server for better request debugging
- Make login request tokens cryptographically secure base58 strings
instead of database IDs
- Add migration to make login_requests.token non-nullable with unique
constraint
- Fix RPCLink URL construction for client-side API calls
- Add db:codegen script to root package.json
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change token format to reviq_<base58> prefix instead of raw hex
- Add me.authStatus API endpoint for detailed auth information
- Enhance CLI `reviq auth status` to show token details from API
- Add comprehensive tests for token generation (18 tests)
- Extract bootstrap logic to @reviq/db for reusability and testing
- Remove default db export; callers must use createDb() directly
Token changes:
- New format: reviq_<base58-encoded-32-bytes>
- Added parseToken() for validation
- Added isValidTokenFormat() helper
Auth status endpoint returns:
- User profile information
- Auth method (api_token or session)
- Token/session details (name, expiration, last used)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Enhanced createRegistrationOptions to look up existing users
- Added virtual-authenticator testing package
- Added WebAuthn e2e and unit tests
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create @reviq/virtual-authenticator package with cryptographically valid
WebAuthn credential generation for testing
- Add e2e tests for WebAuthn registration, authentication, passkey management
- Add unit tests for passkey-helpers and VirtualAuthenticator
- Add security tests for counter replay and tampered responses
- Configure test database environment in devenv.nix
- Add turbo.json test tasks and workspace configuration
Test results: 98 tests passing (54 virtual-authenticator, 25 e2e, 19 unit)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add me.get procedure returning user profile with needsSetup flag
- Add me.setupProfile procedure for initial profile setup after signup
- Add nonEmptyString/optionalString schema helpers with tests
- Use Web Crypto API (SubtleCrypto) for Cloudflare Workers compatibility
- Use @formatjs/intl-durationformat for duration formatting
- Remove node:crypto dependency from crypto utilities
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use proper TypeScript types from @simplewebauthn/types instead of
z.any() for WebAuthn-related schemas:
- PublicKeyCredentialCreationOptionsJSON
- PublicKeyCredentialRequestOptionsJSON
- RegistrationResponseJSON
- AuthenticationResponseJSON
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Applied ast-grep rule to convert named zod imports to namespace imports
across the api-contract package for consistency.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Vite proxy to forward /api/v1/rpc to API server (port 9861)
- Create oRPC client in src/lib/api/client.ts
- Add @orpc/client and @orpc/contract dependencies
- Add @reviq/api-contract workspace dependency
- Extract DEFAULT_PORT constant to api-server/src/constants.ts
- Change API server default port from 3001 to 9861
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ESLint:
- Add @macalinao/eslint-config and eslint to all packages/apps
- Add lint scripts to all package.json files
- Create eslint.config.js for all apps
- Add lint task to turbo.json
- Add @macalinao/eslint-config and @types/bun to catalog
Biome:
- Exclude docs/ from biome checks
CLI Reorganization:
- Restructure CLI to use route maps with one command per file
- Move commands to routes/ directory structure
- Use func property instead of async loaders
- Route maps in _command.ts files for each directory
Environment:
- Use Bun.env instead of process.env for env vars
- Add DATABASE_URL and PORT to turbo.json globalEnv
Lint Fixes:
- Fix nullish coalescing operator usage
- Update deprecated Zod API (z.email() instead of .string().email())
- Fix import sorting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add explicit type annotations for isolatedDeclarations
- Export Database type alias from db-schema
- Fix import paths and add proper type exports
- Update common schemas with better exports
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add api-server process to devenv.nix
- Add dbmate and kysely-codegen scripts
- Configure PostgreSQL with localhost listener
- Update publisher-dashboard package to @apps/publisher-dashboard
- Fix deprecated asChild prop in mobile-nav component
- Remove unused publisher-utils package
- Update bun.lock with new dependencies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Turborepo + Bun monorepo with:
- apps/publisher-dashboard: Svelte 5 SPA with SvelteKit, Tailwind CSS v4, shadcn-svelte
- packages/publisher-utils: Shared TypeScript utilities
Features:
- Performance dashboard page with metrics, charts, and data tables
- shadcn-svelte UI components with OKLCH color system
- Biome for linting/formatting with Svelte-specific overrides
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>