- Create packages/emails/ with EmailClient interface abstraction
- Wrap Postmark ServerClient in adapter for clean typing
- Add createLoggingEmailClient for dev mode (logs to console)
- Split email templates into individual files with full test coverage
- Update api-server to use new package via context injection
- Remove EMAIL_DEV_MODE - now uses POSTMARK_API_KEY presence
- Delete apps/api-server/src/utils/email.ts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
TypeScript excludes node_modules by default, and dist is handled
by outDir or include patterns.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add formatError() helper in CLI to safely handle unknown error types
- Add uniqueTestId() helper for generating unique test identifiers
- Replace String(id) with id.toString() for database ID conversions
- Replace String(n) with n.toLocaleString() for user-facing number formatting
- Fix TypeScript errors in test files (undefined checks, unused variables)
- Update lint commands to include ast-grep scanning
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename packages/utils/ to packages/server-utils/
- Update all imports and package.json references
- Add READMEs for frontend-utils, server-utils, and common packages
- Update main README with new package structure
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prefer .toString() or .toLocaleString() over String() for
more predictable behavior and consistency.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update zod-namespace-import snapshot (semicolon fix)
- Add test cases for no-countall-number rule
- Update rule pattern to match method calls on objects
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add @reviq/test-helpers package with e2e tests for admin, auth, orgs, and webauthn.
Move test utilities to shared package.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix template literal expressions: wrap Date.now() in String()
- Add missing afterAll import in admin.test.ts
- Fix countOwners to use countAll() without misleading <number> type
- Add ast-grep rule to prevent countAll<number>() usage
- Fix formatting issues from merge conflict resolution
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Resolve merge conflicts in auth.test.ts, me.test.ts, db/schema.sql
- Merge new loginRequestMiddleware tests into auth.test.ts describeE2E wrapper
- Merge new authMiddleware tests into me.test.ts describeE2E wrapper
- Add me.apiTokens and me.invites tests in separate describeE2E block
- Migrate admin.test.ts to use describeE2E and @reviq/test-helpers
- Migrate orgs.test.ts to use describeE2E and @reviq/test-helpers
All e2e tests now properly use the describeE2E helper which enables
SKIP_DB_TESTS environment variable support.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create @reviq/test-helpers package with shared test utilities
- Add describeE2E helper that auto-prefixes test names with [e2e]
- Support SKIP_DB_TESTS=1 to skip database-dependent tests
- Add unix socket support for TEST_DATABASE_URL
- Add root commands: test:unit, test:all, test:cov, test:unit:cov
- Configure bunfig.toml to exclude dist/ from coverage reports
- Clean up tsconfig.json files to remove redundant settings
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
PostgreSQL 17.6+ adds random \restrict/\unrestrict tokens to pg_dump
output (CVE-2025-8714 security fix), causing schema.sql to appear
changed on every dump even when the schema hasn't changed.
These wrapper scripts run dbmate and strip the \restrict lines from
the output to keep schema.sql stable.
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>
- Pin tea CLI to 0.10.1 to avoid TTY bug in 0.11.x
- Add .claude/skills/gitea for PR creation workflow
- Document tea CLI usage 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 type assertions for dynamic route paths in goto() and resolve()
- Add missing key attributes to {#each} blocks
- Wrap navigation hrefs with resolve() for SvelteKit compatibility
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Configure eslint-plugin-svelte with TypeScript parser support
- Add keys to all {#each} blocks for proper reactivity
- Wrap navigation paths with resolve() from $app/paths
- Remove unnecessary children snippets and useless mustaches
- Add @typescript-eslint/parser and svelte-eslint-parser dependencies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add left nav with descriptions on desktop and horizontal tabs on mobile,
consistent with the organization settings layout pattern.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace table truncation with transaction rollback for test isolation.
Each test now runs in a transaction that auto-rolls back, improving
test performance and isolation. Tests that call procedures with internal
transactions use getSharedDb() directly with appropriate comments.
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>
- Add dbip-city-lite package to devenv for GeoIP testing
- Set GEOIP_DATABASE_PATH env var to point to the MMDB database
- Add tests for initGeoReader double-init and error handling
- Add real database tests for IP lookups (US, AU, DE, GB)
- Make real database tests conditional with describe.skipIf
- Improve test coverage from ~97% to 98.82%
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create SettingsLayout component with left sidebar nav (desktop) and
horizontal scroll nav (mobile)
- Add settings gear icon to sidebar (Lucide icon, only in org context)
- Fix home icon highlighting to only match exact org home path
- Create /settings/members route with full member management
- Create /settings/sites placeholder route
- Update general settings to use new SettingsLayout
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The extractClientIP() function only checked proxy headers (X-Forwarded-For,
CF-Connecting-IP, etc.) which don't exist when running locally without a proxy.
Changes:
- Add clientIP field to APIContext
- Use Bun's server.requestIP() to get client IP from direct socket connection
- Update getGeoInfo() to accept fallback IP parameter
- Pass context.clientIP to getGeoInfo() in auth procedures
Now sessions will have IP address set even for local development (::1 or 127.0.0.1).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>