docs: add design whys document#4
Merged
viniciusdacal merged 2 commits intomainfrom Feb 4, 2026
Merged
Conversation
Answers the natural "why?" questions developers ask when reading Vertz code and conventions. Each entry traces a specific design choice back to the manifesto's beliefs — no restated principles, just reasoning. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
viniciusdacal
commented
Feb 4, 2026
| Not a single file with all schemas, and not inline in the router. Separate files because: | ||
| - An LLM generating a new endpoint creates one file — clear scope | ||
| - Code review shows exactly what changed per endpoint | ||
| - No merge conflicts from multiple people editing the same schema file |
Contributor
Author
There was a problem hiding this comment.
It's also because we would need to split schema files when it gets big enough, which often happens, then we would have two patterns of organizing schemas, and we want to avoid ambiguity
Contributor
Author
There was a problem hiding this comment.
Added as the first bullet point — a single schema file inevitably grows large enough to split, which creates two organizational patterns. Starting with one file per endpoint avoids that fork entirely. aaddb6a
viniciusdacal
added a commit
that referenced
this pull request
Feb 4, 2026
Moved to its own PR (#4) as vertz-design-whys.md. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
A single schema file inevitably grows large enough to need splitting, which creates two organizational patterns. Starting with one file per endpoint avoids that fork entirely. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
viniciusdacal
added a commit
that referenced
this pull request
Feb 5, 2026
- #4: Define BootSequence contract — ServiceFactory type, example compiler output showing JS module with live imports (not JSON manifest) - #5: Document HEAD (auto-generated from GET) and OPTIONS (handled by CORS) - #6: Explicitly state no AsyncLocalStorage — services receive request data via function arguments only - #7: Add reserved ctx property names with runtime guard in dev mode - #8: Clarify testing lives in @vertz/core, packages/testing/ superseded - #9: Add app.handler getter for edge runtimes with usage examples - Address deepFreeze concern: skip freeze in production, rely on dev proxy - Address Object.assign for middleware state accumulation performance - Address native .env loading: use Node/Bun native support, minimal fallback Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4 tasks
vertz-tech-lead Bot
pushed a commit
that referenced
this pull request
Feb 11, 2026
- Rename find() to findOne() for clarity (Josh #1) - Separate read/write visibility: $insert includes .hidden() columns (Josh #2, Ben C3) - Fix select union type with never-keyed branches for mutual exclusivity (Ben B4) - Move cache-readiness primitives to v1.1 preview section (PM scope creep) - Fix Non-Goal #7 to not claim v1 ships cache primitives (PM) - Add exhaustiveness guarantee for error hierarchy with Assert pattern (Ben B1) - Add type error quality section with branded error messages (Ben B2) - Flag d.ref.many().through() as unvalidated, cap depth at 1 (Ben B3) - Fix E2E type test assertions to match actual type semantics (Josh #3) - Fix first example to compile under strict mode with ! assertion (Josh #4) - Add vertz db init onboarding flow (Josh #5) - Document zero-match behavior for all mutation methods (Josh #8) - Add SQL injection prevention / parameter binding note (PM minor) - Add dry-run mode for migrations (PM minor) - Clarify d.email() is metadata-only, no runtime validation (Josh #6, Ben N4) - Add vertz.env() pattern for type-safe DATABASE_URL access Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
viniciusdacal
pushed a commit
that referenced
this pull request
Feb 11, 2026
* docs(db): add @vertz/db v1 API design plan Comprehensive design doc for the thin ORM layer covering schema definitions, type inference, query builder, relations, migrations, error hierarchy, and metadata-only multi-tenancy markers. Based on approved roadmap, POC 1 results (28.5% of budget), and all exploration research. Includes self-review notes from Josh (DX), Ben (feasibility), and PM (scope). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(db-design): address review feedback from Josh, Ben, and PM - Rename find() to findOne() for clarity (Josh #1) - Separate read/write visibility: $insert includes .hidden() columns (Josh #2, Ben C3) - Fix select union type with never-keyed branches for mutual exclusivity (Ben B4) - Move cache-readiness primitives to v1.1 preview section (PM scope creep) - Fix Non-Goal #7 to not claim v1 ships cache primitives (PM) - Add exhaustiveness guarantee for error hierarchy with Assert pattern (Ben B1) - Add type error quality section with branded error messages (Ben B2) - Flag d.ref.many().through() as unvalidated, cap depth at 1 (Ben B3) - Fix E2E type test assertions to match actual type semantics (Josh #3) - Fix first example to compile under strict mode with ! assertion (Josh #4) - Add vertz db init onboarding flow (Josh #5) - Document zero-match behavior for all mutation methods (Josh #8) - Add SQL injection prevention / parameter binding note (PM minor) - Add dry-run mode for migrations (PM minor) - Clarify d.email() is metadata-only, no runtime validation (Josh #6, Ben N4) - Add vertz.env() pattern for type-safe DATABASE_URL access Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: vertz-tech-lead[bot] <2828099+vertz-tech-lead[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: vertz-dev-dx[bot] <260432280+vertz-dev-dx[bot]@users.noreply.github.com>
7 tasks
10 tasks
This was referenced Feb 12, 2026
5 tasks
5 tasks
vertz-dev-front Bot
pushed a commit
that referenced
this pull request
Feb 12, 2026
Address mike's review on PR #222 — all 3 blocking issues: 1. Created public barrel files (router/public.ts, form/public.ts, query/public.ts, css/public.ts) that export only the curated public API. Internal symbols (matchRoute, executeLoaders, matchPath, MemoryCache, deriveKey, generateClassName, compileTheme, etc.) are no longer leaked through subpath imports. 2. Rewrote tests with exhaustive assertions: Object.keys(mod).sort() matched against expected list catches both missing exports and unexpected leaks. Added reference identity checks (subpath.X === main.X) per non-blocking suggestion #4. 3. Added minor changeset for @vertz/ui (new public API surface). Also addressed non-blocking #5: reordered types before import in all exports map entries for correct TS moduleResolution behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
github-actions Bot
pushed a commit
that referenced
this pull request
Feb 12, 2026
Address mike's review on PR #222 — all 3 blocking issues: 1. Created public barrel files (router/public.ts, form/public.ts, query/public.ts, css/public.ts) that export only the curated public API. Internal symbols (matchRoute, executeLoaders, matchPath, MemoryCache, deriveKey, generateClassName, compileTheme, etc.) are no longer leaked through subpath imports. 2. Rewrote tests with exhaustive assertions: Object.keys(mod).sort() matched against expected list catches both missing exports and unexpected leaks. Added reference identity checks (subpath.X === main.X) per non-blocking suggestion #4. 3. Added minor changeset for @vertz/ui (new public API surface). Also addressed non-blocking #5: reordered types before import in all exports map entries for correct TS moduleResolution behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
github-actions Bot
pushed a commit
that referenced
this pull request
Feb 12, 2026
Address mike's review on PR #222 — all 3 blocking issues: 1. Created public barrel files (router/public.ts, form/public.ts, query/public.ts, css/public.ts) that export only the curated public API. Internal symbols (matchRoute, executeLoaders, matchPath, MemoryCache, deriveKey, generateClassName, compileTheme, etc.) are no longer leaked through subpath imports. 2. Rewrote tests with exhaustive assertions: Object.keys(mod).sort() matched against expected list catches both missing exports and unexpected leaks. Added reference identity checks (subpath.X === main.X) per non-blocking suggestion #4. 3. Added minor changeset for @vertz/ui (new public API surface). Also addressed non-blocking #5: reordered types before import in all exports map entries for correct TS moduleResolution behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
github-actions Bot
pushed a commit
that referenced
this pull request
Feb 12, 2026
Address mike's review on PR #222 — all 3 blocking issues: 1. Created public barrel files (router/public.ts, form/public.ts, query/public.ts, css/public.ts) that export only the curated public API. Internal symbols (matchRoute, executeLoaders, matchPath, MemoryCache, deriveKey, generateClassName, compileTheme, etc.) are no longer leaked through subpath imports. 2. Rewrote tests with exhaustive assertions: Object.keys(mod).sort() matched against expected list catches both missing exports and unexpected leaks. Added reference identity checks (subpath.X === main.X) per non-blocking suggestion #4. 3. Added minor changeset for @vertz/ui (new public API surface). Also addressed non-blocking #5: reordered types before import in all exports map entries for correct TS moduleResolution behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
viniciusdacal
pushed a commit
that referenced
this pull request
Feb 12, 2026
* feat(ui): add subpath exports for router/form/query/css [UI-029]
Add focused subpath imports so developers can do:
- import { Router } from '@vertz/ui/router'
- import { Form } from '@vertz/ui/form'
- import { query } from '@vertz/ui/query'
- import { css } from '@vertz/ui/css'
Changes:
- Add ./router, ./form, ./query, ./css to package.json exports map
- Add corresponding entry points to bunup.config.ts build config
- Add subpath-exports.test.ts verifying all exports resolve correctly
- Main barrel (@vertz/ui) continues to re-export everything (backward compat)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(ui): curate subpath export barrels, add changeset [UI-029]
Address mike's review on PR #222 — all 3 blocking issues:
1. Created public barrel files (router/public.ts, form/public.ts,
query/public.ts, css/public.ts) that export only the curated public
API. Internal symbols (matchRoute, executeLoaders, matchPath,
MemoryCache, deriveKey, generateClassName, compileTheme, etc.) are
no longer leaked through subpath imports.
2. Rewrote tests with exhaustive assertions: Object.keys(mod).sort()
matched against expected list catches both missing exports and
unexpected leaks. Added reference identity checks (subpath.X ===
main.X) per non-blocking suggestion #4.
3. Added minor changeset for @vertz/ui (new public API surface).
Also addressed non-blocking #5: reordered types before import in all
exports map entries for correct TS moduleResolution behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: vertz-dev-front[bot] <2828126+vertz-dev-front[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
vertz-tech-lead Bot
pushed a commit
that referenced
this pull request
Feb 14, 2026
TDD RED → GREEN cycle #4: - Add test for aliased imports (query as fetchData) - Add test for plain properties (refetch) - already passes - Implement buildImportAliasMap to track import aliases - Update ReactivityAnalyzer to resolve aliases before checking signal APIs - All tests pass (232 tests total) Edge cases covered: import aliases, plain vs signal property distinction.
github-actions Bot
pushed a commit
that referenced
this pull request
Feb 14, 2026
TDD RED → GREEN cycle #4: - Add test for aliased imports (query as fetchData) - Add test for plain properties (refetch) - already passes - Implement buildImportAliasMap to track import aliases - Update ReactivityAnalyzer to resolve aliases before checking signal APIs - All tests pass (232 tests total) Edge cases covered: import aliases, plain vs signal property distinction.
viniciusdacal
pushed a commit
that referenced
this pull request
Feb 14, 2026
…rap (#283) * test(ui-compiler): add test for query().data auto-unwrap TDD RED → GREEN cycle #1: - Write test expecting tasks.data → tasks.data.value - Implement signal API registry (query with data property) - Update ReactivityAnalyzer to detect signal API calls - Update SignalTransformer to auto-unwrap signal properties - Test passes, typecheck passes, lint passes Part of signal auto-unwrap feature to eliminate .value from public API. * test(ui-compiler): add test for query().loading auto-unwrap TDD RED → GREEN cycle #2: - Write test expecting tasks.loading → tasks.loading.value - Add 'loading' to query signal properties - Test passes, all quality gates pass Expanding signal auto-unwrap coverage. * feat(ui-compiler): complete signal auto-unwrap for query, form, createLoader TDD RED → GREEN cycle #3: - Add tests for .error property on query() - Add tests for form() with submitting, errors, values - Add tests for createLoader() with data, loading, error - Update signal API registry with all properties - All tests pass (230 tests total) Feature complete: Auto-unwrap eliminates .value from public API for all three signal-returning functions. * feat(ui-compiler): support aliased imports for signal auto-unwrap TDD RED → GREEN cycle #4: - Add test for aliased imports (query as fetchData) - Add test for plain properties (refetch) - already passes - Implement buildImportAliasMap to track import aliases - Update ReactivityAnalyzer to resolve aliases before checking signal APIs - All tests pass (232 tests total) Edge cases covered: import aliases, plain vs signal property distinction. * docs(ui-compiler): document plain properties in signal API registry Add plainProperties field to SignalApiConfig to explicitly document which properties are NOT signals (refetch, reset, submit, handleSubmit). This improves code clarity and serves as documentation for developers. The implementation already handles these correctly - they're not unwrapped because they're not in the signalProperties set. No functional change, just documentation. * chore: add changeset for signal auto-unwrap feature * fix: prevent double .value bug + classify as MAJOR (TDD: RED→GREEN) **TDD Cycle:** 1. RED: Add test for double .value case (migration) — fails as expected 2. GREEN: Add guard logic in signal-transformer to skip when .value exists — test passes **Changes:** - Add guard in transformSignalApiProperties() to detect existing .value - Add test: 'should NOT double-unwrap when .value already exists' - Change changeset from minor → major (BREAKING CHANGE) - Add comprehensive migration guide to changeset - Document Set<string> serialization limitation in VariableInfo type **Addresses reviewer feedback:** ✅ Fix double .value bug with guard logic ✅ Add TDD test FIRST (RED), then fix (GREEN) ✅ Reclassify as major breaking change ✅ Add migration docs ✅ Document Set<string> non-serializable concern All 233 tests pass (8/8 signal-unwrap tests). * fix: use vitest import instead of bun:test for CI compatibility CI uses vitest runner, not bun:test. Changed import to fix module resolution error. --------- Co-authored-by: auditor <auditor@vertz.dev>
This was referenced Feb 18, 2026
viniciusdacal
added a commit
that referenced
this pull request
Feb 22, 2026
Moved to its own PR (#4) as vertz-design-whys.md. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
viniciusdacal
added a commit
that referenced
this pull request
Feb 22, 2026
docs: add design whys document
viniciusdacal
added a commit
that referenced
this pull request
Feb 22, 2026
- #4: Define BootSequence contract — ServiceFactory type, example compiler output showing JS module with live imports (not JSON manifest) - #5: Document HEAD (auto-generated from GET) and OPTIONS (handled by CORS) - #6: Explicitly state no AsyncLocalStorage — services receive request data via function arguments only - #7: Add reserved ctx property names with runtime guard in dev mode - #8: Clarify testing lives in @vertz/core, packages/testing/ superseded - #9: Add app.handler getter for edge runtimes with usage examples - Address deepFreeze concern: skip freeze in production, rely on dev proxy - Address Object.assign for middleware state accumulation performance - Address native .env loading: use Node/Bun native support, minimal fallback Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
viniciusdacal
pushed a commit
that referenced
this pull request
Feb 22, 2026
* docs(db): add @vertz/db v1 API design plan Comprehensive design doc for the thin ORM layer covering schema definitions, type inference, query builder, relations, migrations, error hierarchy, and metadata-only multi-tenancy markers. Based on approved roadmap, POC 1 results (28.5% of budget), and all exploration research. Includes self-review notes from Josh (DX), Ben (feasibility), and PM (scope). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(db-design): address review feedback from Josh, Ben, and PM - Rename find() to findOne() for clarity (Josh #1) - Separate read/write visibility: $insert includes .hidden() columns (Josh #2, Ben C3) - Fix select union type with never-keyed branches for mutual exclusivity (Ben B4) - Move cache-readiness primitives to v1.1 preview section (PM scope creep) - Fix Non-Goal #7 to not claim v1 ships cache primitives (PM) - Add exhaustiveness guarantee for error hierarchy with Assert pattern (Ben B1) - Add type error quality section with branded error messages (Ben B2) - Flag d.ref.many().through() as unvalidated, cap depth at 1 (Ben B3) - Fix E2E type test assertions to match actual type semantics (Josh #3) - Fix first example to compile under strict mode with ! assertion (Josh #4) - Add vertz db init onboarding flow (Josh #5) - Document zero-match behavior for all mutation methods (Josh #8) - Add SQL injection prevention / parameter binding note (PM minor) - Add dry-run mode for migrations (PM minor) - Clarify d.email() is metadata-only, no runtime validation (Josh #6, Ben N4) - Add vertz.env() pattern for type-safe DATABASE_URL access Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: vertz-tech-lead[bot] <2828099+vertz-tech-lead[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: vertz-dev-dx[bot] <260432280+vertz-dev-dx[bot]@users.noreply.github.com>
viniciusdacal
pushed a commit
that referenced
this pull request
Feb 22, 2026
* feat(ui): add subpath exports for router/form/query/css [UI-029]
Add focused subpath imports so developers can do:
- import { Router } from '@vertz/ui/router'
- import { Form } from '@vertz/ui/form'
- import { query } from '@vertz/ui/query'
- import { css } from '@vertz/ui/css'
Changes:
- Add ./router, ./form, ./query, ./css to package.json exports map
- Add corresponding entry points to bunup.config.ts build config
- Add subpath-exports.test.ts verifying all exports resolve correctly
- Main barrel (@vertz/ui) continues to re-export everything (backward compat)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(ui): curate subpath export barrels, add changeset [UI-029]
Address mike's review on PR #222 — all 3 blocking issues:
1. Created public barrel files (router/public.ts, form/public.ts,
query/public.ts, css/public.ts) that export only the curated public
API. Internal symbols (matchRoute, executeLoaders, matchPath,
MemoryCache, deriveKey, generateClassName, compileTheme, etc.) are
no longer leaked through subpath imports.
2. Rewrote tests with exhaustive assertions: Object.keys(mod).sort()
matched against expected list catches both missing exports and
unexpected leaks. Added reference identity checks (subpath.X ===
main.X) per non-blocking suggestion #4.
3. Added minor changeset for @vertz/ui (new public API surface).
Also addressed non-blocking #5: reordered types before import in all
exports map entries for correct TS moduleResolution behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: vertz-dev-front[bot] <2828126+vertz-dev-front[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
viniciusdacal
pushed a commit
that referenced
this pull request
Feb 22, 2026
…rap (#283) * test(ui-compiler): add test for query().data auto-unwrap TDD RED → GREEN cycle #1: - Write test expecting tasks.data → tasks.data.value - Implement signal API registry (query with data property) - Update ReactivityAnalyzer to detect signal API calls - Update SignalTransformer to auto-unwrap signal properties - Test passes, typecheck passes, lint passes Part of signal auto-unwrap feature to eliminate .value from public API. * test(ui-compiler): add test for query().loading auto-unwrap TDD RED → GREEN cycle #2: - Write test expecting tasks.loading → tasks.loading.value - Add 'loading' to query signal properties - Test passes, all quality gates pass Expanding signal auto-unwrap coverage. * feat(ui-compiler): complete signal auto-unwrap for query, form, createLoader TDD RED → GREEN cycle #3: - Add tests for .error property on query() - Add tests for form() with submitting, errors, values - Add tests for createLoader() with data, loading, error - Update signal API registry with all properties - All tests pass (230 tests total) Feature complete: Auto-unwrap eliminates .value from public API for all three signal-returning functions. * feat(ui-compiler): support aliased imports for signal auto-unwrap TDD RED → GREEN cycle #4: - Add test for aliased imports (query as fetchData) - Add test for plain properties (refetch) - already passes - Implement buildImportAliasMap to track import aliases - Update ReactivityAnalyzer to resolve aliases before checking signal APIs - All tests pass (232 tests total) Edge cases covered: import aliases, plain vs signal property distinction. * docs(ui-compiler): document plain properties in signal API registry Add plainProperties field to SignalApiConfig to explicitly document which properties are NOT signals (refetch, reset, submit, handleSubmit). This improves code clarity and serves as documentation for developers. The implementation already handles these correctly - they're not unwrapped because they're not in the signalProperties set. No functional change, just documentation. * chore: add changeset for signal auto-unwrap feature * fix: prevent double .value bug + classify as MAJOR (TDD: RED→GREEN) **TDD Cycle:** 1. RED: Add test for double .value case (migration) — fails as expected 2. GREEN: Add guard logic in signal-transformer to skip when .value exists — test passes **Changes:** - Add guard in transformSignalApiProperties() to detect existing .value - Add test: 'should NOT double-unwrap when .value already exists' - Change changeset from minor → major (BREAKING CHANGE) - Add comprehensive migration guide to changeset - Document Set<string> serialization limitation in VariableInfo type **Addresses reviewer feedback:** ✅ Fix double .value bug with guard logic ✅ Add TDD test FIRST (RED), then fix (GREEN) ✅ Reclassify as major breaking change ✅ Add migration docs ✅ Document Set<string> non-serializable concern All 233 tests pass (8/8 signal-unwrap tests). * fix: use vitest import instead of bun:test for CI compatibility CI uses vitest runner, not bun:test. Changed import to fix module resolution error. --------- Co-authored-by: auditor <auditor@vertz.dev>
This was referenced Feb 22, 2026
This was referenced Mar 3, 2026
viniciusdacal
pushed a commit
that referenced
this pull request
Mar 13, 2026
Replace hand-written auth patterns with framework abstractions: - ProtectedRoute replaces AuthGuard component (#1214) - OAuthButton replaces hardcoded OAuth URL + GitHub icon (#1215) - sessionResolver added to dev server for SSR session injection (#1216) - Update auth-ui-framework-gaps.md to mark gaps #1, #2, #4 as done Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
viniciusdacal
added a commit
that referenced
this pull request
Mar 13, 2026
… fixes (#1208) * feat(auth): per-provider mapProfile callback for OAuth user creation Add typed mapProfile callbacks to OAuth providers so provider-specific data (name, avatarUrl, custom fields) flows through to the created user. - OAuthProviderConfig<TProfile> generic with typed mapProfile callback - OAuthUserInfo.raw passes full provider API response - OAuthProvider.mapProfile required on provider instances - Typed profiles: GithubProfile, GoogleProfile, DiscordProfile - Secure spread: framework fields (id, email, emailVerified, role, createdAt, updatedAt) always override mapProfile output - mapProfile errors redirect with ?error=profile_mapping_failed - Non-object mapProfile returns treated as empty Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(auth): onUserCreated callback and auth-entity bridge Replace mapProfile with onUserCreated callback that fires after auth user creation. Developers populate their own entity tables in the callback instead of mapping profile data into auth_users. - Add onUserCreated to AuthConfig with discriminated union payload (OAuth: { user, provider, profile }, email: { user, signUpData }) - Add deleteUser to UserStore for rollback on callback failure - Wire entity registry proxy via _entityProxy in createServer - Remove mapProfile from OAuthProvider, OAuthProviderConfig, providers - Remove name/avatarUrl from OAuthUserInfo (raw carries full profile) - Close AuthUser interface (remove [key: string]: unknown) - Remove safeFields spread into AuthUser on email sign-up - Add 'general' to AuthValidationError.field for callback errors - Rollback with error logging on both OAuth and email/password paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(auth): correctly append error params to OAuth error redirect URLs The OAuth callback handler was naively appending `?error=...` to the error redirect URL without checking if it already contained query parameters. When oauthErrorRedirect was set to `/login?error=oauth`, the resulting URL was `/login?error=oauth?error=token_exchange_failed` (double `?`). Added an `errorUrl()` helper that uses `&` when `?` already exists. Also improved GitHub provider to surface token exchange errors instead of silently swallowing them, and added DOM shim stubs for addEventListener/removeEventListener needed during SSR. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(auth): resolve OAuth login flow bugs across server and client Server fixes: - Auto-wire DbOAuthAccountStore in createServer (was missing, OAuth accounts never persisted) - Fix cookie maxAge to match JWT TTL (was using hardcoded value causing premature expiry) - Fix db-session-store findActiveSessionById to use raw SQL (ORM gt operator broken) Client fixes: - Move useAuth from signal-api to reactive-source in compiler registry and reactivity.json (compiler was adding .value on top of wrapSignalProps getters, causing undefined) - Defer refresh() via setTimeout(0) when no SSR session exists (SSR flushes microtasks, so status stayed idle during server render instead of redirecting) - Update auth-context tests to match deferred-refresh behavior Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(auth): remove unused SessionRecord type and recordToSession method Leftover from switching findActiveSessionById to raw SQL. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test(auth): update DbSessionStore tests for raw SQL findActiveSessionById Tests were mocking the ORM-based auth_sessions.get() path, but the implementation now uses db.query() with raw SQL. Updated mocks to match the new interface. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs(auth): self-review of auth UI framework gaps from Linear clone Identifies 7 patterns hand-written in the Linear example that should be framework-level: ProtectedRoute, OAuth buttons, dev server handler composition, SSR session injection, sign-out redirect, user profile helpers, and router initialPath auto-detection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(auth): address review findings — race condition and conditional auto-wiring - Cancel deferred refresh timer when signIn/signUp is called, preventing a race where refresh() could overwrite authenticated status with unauthenticated (the refresh cookie isn't set yet from the sign-in) - Only auto-wire DbOAuthAccountStore when OAuth providers are configured - Only create entity registry proxy when onUserCreated callback exists Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * review(auth): adversarial review for OAuth login flow fixes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(server): remove erroneous OrgPlan re-export from rebase conflict Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(auth): add issue reference for raw SQL workaround in DbSessionStore (#1209) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(auth): revert raw SQL workaround in DbSessionStore to ORM get() Now that #1212 fixed null handling in where clauses (IS NULL instead of = NULL), all three session lookup methods use the ORM consistently. Restores recordToSession and SessionRecord for ORM camelCase records. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(auth): use signOut({ redirectTo }) from #1213 in Linear clone Now that the framework supports signOut with redirect, use it instead of relying on AuthGuard's implicit redirect. Updated framework gaps doc to mark item #5 as done. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(linear): adopt framework auth components (#1214, #1215, #1216) Replace hand-written auth patterns with framework abstractions: - ProtectedRoute replaces AuthGuard component (#1214) - OAuthButton replaces hardcoded OAuth URL + GitHub icon (#1215) - sessionResolver added to dev server for SSR session injection (#1216) - Update auth-ui-framework-gaps.md to mark gaps #1, #2, #4 as done Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(linear): adopt createRouter auto-detect (#1219), fix error redirect test - Remove initialPath boilerplate from router.tsx — createRouter now auto-detects - Update error redirect test to match URL constructor behavior from #1218 - Mark gap #7 (initialPath auto-detect) as done in framework gaps doc Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(linear): use app.requestHandler for unified routing (#1221) Replace manual if/else auth+entity routing with framework's requestHandler getter. Mark gap #3 as done in framework gaps doc. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(linear): add Linear clone example app files Commit all Linear clone example files that were previously untracked. The bun.lock already references examples/linear — CI fails with --frozen-lockfile because the package.json wasn't committed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: vertz-dev-front[bot] <2828126+vertz-dev-front[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This was referenced Apr 18, 2026
4 tasks
3 tasks
viniciusdacal
added a commit
that referenced
this pull request
Apr 22, 2026
Design doc at plans/agent-store-entity-bridge.md for bridging AgentStore with Vertz entities so agent sessions/messages become queryable with RLS from app code. Resolves Gap #4 of plans/open-agents-clone.md. Rev 6 after three rounds of adversarial review (DX, Product, Technical) per .claude/rules/design-and-planning.md. All reviewers approved. Awaits human final sign-off. Key design decisions settled: - Entities are a READ-VIEW over the store's tables. Writes stay on memoryStore/sqliteStore/d1Store; entity RLS applies to app-side reads. - defineAgentEntities(db) factory + column packs (no extend API, no sugar helpers). Custom fields via normal d.table() spread. - AgentStore.appendMessages gains session parameter (matches appendMessagesAtomic). Pre-v1 breaking change. - agent_messages denormalizes userId/tenantId for flat rules.where(). Non-adopter breaking change acknowledged explicitly. - before.create hook injects ctx.userId/ctx.tenantId (ctx wins over input to prevent silent impersonation). - Hook-bypass on agent-loop writes tracked as follow-up #2957. - state/toolCalls → d.jsonb<T>() migration tracked as #2958. Closes: none yet (design-only PR). Refs: #2847, #2957, #2958, plans/open-agents-clone.md Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
plans/vertz-design-whys.md— a document that answers the natural "why?" questions developers ask when reading Vertz code and conventionsRelationship to other docs
Test plan
🤖 Generated with Claude Code