Commit Graph

47 Commits

Author SHA1 Message Date
igm
5a2e0297e5 Merge branch 'more-spec'
Some checks failed
CI / ci (push) Has been cancelled
2026-01-12 15:23:25 +08:00
igm
c9de0b1ac5 Add sideEffects: false to all library packages
Enables tree-shaking for bundlers by marking all library packages
as side-effect-free.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 15:22:24 +08:00
igm
0f50291490 Add @types/bun to api-contract for test file compilation
The test file imports from bun:test which requires bun types. Added
@types/bun dependency and configured tsconfig to include bun types.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 15:20:21 +08:00
igm
9c6694cad4 Auto-skip e2e tests when TEST_DATABASE_URL is not configured
Some checks failed
CI / ci (push) Has been cancelled
Previously, e2e tests would fail with a confusing URL parse error when
TEST_DATABASE_URL was not set. Now SKIP_DB_TESTS automatically becomes
true when the database URL is missing, gracefully skipping these tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 15:15:15 +08:00
igm
16f827e8f0 Merge branch 'test-coverage'
Some checks failed
CI / ci (push) Has been cancelled
Add test utilities and ast-grep rules for code quality.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 15:05:07 +08:00
igm
947c73dbdc Remove unnecessary exclude from tsconfig files
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>
2026-01-12 15:02:55 +08:00
igm
2baf10b0cd Replace String() calls with .toString()/.toLocaleString() per ast-grep rule
- 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>
2026-01-12 15:02:46 +08:00
igm
8b081d5ba8 Remove unnecessary testing/README.md
Sub-packages test-helpers and virtual-authenticator have their own READMEs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 14:57:28 +08:00
igm
01f1e1c9e3 Add READMEs for remaining packages
- db-schema: Database schema types from kysely-codegen
- db: Database client and helper functions
- testing: Overview of testing packages
- test-helpers: Database testing utilities
- virtual-authenticator: WebAuthn virtual authenticator

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 13:59:34 +08:00
igm
26d10d452f Rename @reviq/utils to @reviq/server-utils and add package READMEs
- 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>
2026-01-12 13:57:28 +08:00
igm
94b6de5970 Merge branch 'test-coverage'
Some checks failed
CI / ci (push) Has been cancelled
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>
2026-01-12 13:43:28 +08:00
igm
b2fba6e150 Add test infrastructure with coverage and DB test skipping
- 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>
2026-01-12 13:03:41 +08:00
igm
61fdd3329f Add OrgAvatar component and frontend-utils package
Some checks failed
CI / ci (push) Has been cancelled
- 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>
2026-01-12 12:34:23 +08:00
igm
44a480179b Merge remote-tracking branch 'origin/master'
Some checks failed
CI / ci (push) Has been cancelled
2026-01-11 14:19:58 +08:00
igm
628b01f4d8 Add type-safe navigation helpers and public pages
- 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>
2026-01-11 14:19:33 +08:00
igm
b1d07626f3 Add packages/common for shared utilities
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>
2026-01-11 12:34:10 +08:00
igm
9a119da96e Update db and db-schema packages to export from dist/
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:22:04 +08:00
igm
8f3a1f2962 Merge origin/master into reviq-auth-login-command
Resolved conflicts:
- apps/api-server/src/router.ts: Use meRoutes from master
- packages/api-contract/src/contract.ts: Keep master's nested sessions/devices/invites structure, add apiTokens

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 19:03:37 +08:00
igm
a7d6beaf5a Add API token management for CLI authentication
- 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>
2026-01-10 18:58:27 +08:00
RevIQ
40df74fdd0 Merge branch 'testing-improvements'
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>
2026-01-10 17:24:51 +08:00
RevIQ
d824cf4116 Refactor API to use nested sessions/devices routers and fix test infrastructure
- 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>
2026-01-10 17:17:50 +08:00
RevIQ
39863bd947 Add org invites section to dashboard with accept/decline flow
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>
2026-01-10 17:11:22 +08:00
RevIQ
1bf05465c3 Replace void returns with { success: true } across all API endpoints
- 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>
2026-01-10 16:30:22 +08:00
RevIQ
72fa560648 Merge branch 'master' into testing-improvements 2026-01-10 15:31:37 +08:00
RevIQ
2c2556a5ea Add e2e tests for me.* procedures and fix code review issues
- Add comprehensive e2e tests for me.get, me.authStatus, me.setupProfile,
  me.updateProfile, me.setPassword, and me.delete (21 tests)
- Make createDb require explicit connection string (no default env lookup)
- Add database name validation to prevent SQL injection in CREATE DATABASE
- Fix getTestDatabaseUrl to throw instead of returning empty string
- Replace brittle relative path with findRepoRoot() function
- Extract magic numbers (SESSION_EXPIRY_MS, API_TOKEN_EXPIRY_MS, ONE_DAY_MS)
- Consolidate duplicate createAPIContext functions
- Add hasPassword field to meAuthStatus and toUserResponse

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 15:24:42 +08:00
RevIQ
ddd7c0c03b Add generateSecureBase58Token to shared utils with login_ prefix
- 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>
2026-01-09 19:31:30 +08:00
RevIQ
93ef5c3942 Merge branch 'cli-destroy' 2026-01-09 19:13:21 +08:00
RevIQ
3031c88148 Add --dangerously-overwrite-existing flag to bootstrap command
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>
2026-01-09 19:09:09 +08:00
RevIQ
60bcbeffb3 hash pasword types fix 2026-01-09 18:44:56 +08:00
RevIQ
d4e20d41b5 Merge branch 'cli-improvements-1' with @reviq/utils password hashing
- 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>
2026-01-09 18:17:45 +08:00
RevIQ
cfe26c8820 Merge branch 'workstream-i' 2026-01-09 18:12:45 +08:00
RevIQ
c1afc39062 Add utils package with Web Crypto password hashing
- 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>
2026-01-09 18:12:33 +08:00
RevIQ
1083cde9b7 Implement Workstream I: Account pages with code review fixes
Add account management UI with profile settings, authentication options,
device/passkey management, and session management pages.

Key changes:
- Add account pages: profile, auth, devices, sessions
- Add dialog components: confirm, add-passkey, change-password, rename-passkey
- Return passkeyId from verifyRegistration to fix race condition
- Add hasPassword field to user schema
- Add aria-label to dialog close button for accessibility
- Add avatar URL validation and fix phone input styling
- Add comprehensive test plan documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 18:04:02 +08:00
RevIQ
6b9b04d1d0 Improve API token format and enhance auth status command
- 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>
2026-01-09 17:59:02 +08:00
RevIQ
2655c57b9e Merge branch 'wt3': WebAuthn enhancements and virtual authenticator
- 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>
2026-01-09 16:55:14 +08:00
RevIQ
bd9be3e441 Add comprehensive WebAuthn e2e/unit tests and virtual authenticator package
- 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>
2026-01-09 16:46:02 +08:00
RevIQ
860d791125 Implement Workstream F1: me.get and me.setupProfile procedures
- 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>
2026-01-09 16:29:41 +08:00
RevIQ
30ee35b25c Restructure passkey routes to me.passkeys namespace
- Remove createPasskey since verifyRegistration handles adding passkeys
- Move listPasskeys → me.passkeys.list
- Move renamePasskey → me.passkeys.rename
- Move deletePasskey → me.passkeys.delete

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 12:38:07 +08:00
RevIQ
a4dff188eb Replace z.any() with z.custom<T>() for WebAuthn types
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>
2026-01-09 12:17:29 +08:00
RevIQ
b6bce41092 Fix zod imports with ast-grep namespace import rule
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>
2026-01-09 12:14:19 +08:00
RevIQ
2e9ea74bc9 Connect frontend to oRPC server
- 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>
2026-01-09 12:09:03 +08:00
RevIQ
8f3f711af0 Add ESLint to all packages and reorganize CLI
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>
2026-01-09 12:01:41 +08:00
RevIQ
5eeef44850 Fix TypeScript compilation issues in packages
- 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>
2026-01-09 11:46:11 +08:00
RevIQ
aee22ae454 Update devenv and cleanup packages
- 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>
2026-01-09 11:45:13 +08:00
RevIQ
cc5fba0fc7 Add oRPC API contract with Zod schemas
- Create @reviq/api-contract package
- Define Zod schemas for all input/output types:
  - Auth schemas (signup, login, password reset, WebAuthn)
  - User/profile schemas
  - Organization schemas (CRUD, members, invites)
  - Admin procedure schemas
- Define oRPC contract with full procedure signatures:
  - auth.* (signup, login, password reset, WebAuthn)
  - me.* (profile, sessions, devices, passkeys)
  - orgs.* (CRUD, members, invites, sites)
  - admin.* (orgs, users, auth management)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 11:44:52 +08:00
RevIQ
392d976812 Add database schema and Kysely packages
- Create initial database migration with full auth schema:
  - users, sessions, passkeys, devices tables
  - orgs, org_members, org_sites, org_invites tables
  - email_verifications, password_resets, login_requests tables
  - Indexes for common lookups and cleanup jobs
- Add @reviq/db-schema package with kysely-codegen
- Add @reviq/db package with Kysely client

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 11:44:36 +08:00
RevIQ
a1db9ca3c5 Initial commit: Publisher dashboard monorepo
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>
2026-01-06 17:25:21 +08:00