feat(db): Support custom PostgreSQL schema via DATABASE_URL (Vibe Kanban)#3
Open
jtomaszewski wants to merge 1 commit intodevelopfrom
Open
feat(db): Support custom PostgreSQL schema via DATABASE_URL (Vibe Kanban)#3jtomaszewski wants to merge 1 commit intodevelopfrom
jtomaszewski wants to merge 1 commit intodevelopfrom
Conversation
Use PostgreSQL's built-in current_schema() function everywhere instead
of a custom getDbSchema() utility. The database connection's search_path
(set via DATABASE_URL?options=-c%20search_path=custom_schema) becomes
the single source of truth.
Changes:
- Replace hardcoded 'public' schema with current_schema() in all SQL
- Use whereRaw('table_schema = current_schema()') for Knex queries
- Migration already uses current_schema() for automatic resolution
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
22fd8e1 to
dee2817
Compare
jtomaszewski
pushed a commit
that referenced
this pull request
Apr 11, 2026
…cato#988) (open-mercato#1051) * fix(customer_accounts): address customer portal UX feedback (open-mercato#988) - Account settings section now uses 2-column layout to save space - Added portal access info banners with URL and demo credentials on list and detail pages - CRM links (person/company) are now editable with async search and unlink buttons - Added "Send Reset Link" button and API endpoint to generate shareable password reset links - Improved role permissions UI with feature descriptions, card-based groups in 2-column grid - Fixed bug where role permission changes were silently dropped (now saves via ACL endpoint) - Portal title no longer falls back to raw org slug — always uses DB-resolved name Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(customer_accounts): implement remaining portal UX changes (open-mercato#988) - Enhanced account-status widget: "Invite to Portal" button on CRM person profile when no portal account exists, with inline form for email, name, and role selection - Created portal settings page at /backend/customer_accounts/settings with portal URL info, demo credentials, org slug guidance, and quick links - Fixed portal logo colors: removed dark:invert filter that distorted the gradient - Converted role create page to CrudForm for UMES extensibility - Converted role detail/edit page to CrudForm with custom permissions editor component Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(customer_accounts): address security and code quality findings Critical: - C1: Remove raw auth tokens from event bus payloads — tokens must never travel through events where any subscriber can intercept them - C2: Magic link request now emits `magic_link.requested` instead of incorrectly emitting `login.success` before authentication - C3: Email verification nativeUpdate now scopes by tenantId as defense-in-depth; event payload includes tenantId Medium: - M1: Replace raw SQL (em.getConnection().execute) with ORM queries in autoLinkCrm and autoLinkCrmReverse subscribers - M5: Deduplicate readCookieFromHeader — 3 local copies replaced with import from customerAuth.ts Low: - L3: Remove unused batchSize parameter from cleanup workers Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(customer_accounts): remove static cross-module entity import (H1) Replace static import of Organization entity from directory module with a raw SQL existence check. This eliminates compile-time coupling between customer_accounts and directory modules. The CRM link subscribers (autoLinkCrm, autoLinkCrmReverse) already use dynamic imports (await import(...)) which is the accepted pattern for cross-module access in event subscribers — no compile-time coupling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve ISSUE-001, ISSUE-002, ISSUE-004, ISSUE-005 from ISSUE_LOG - ISSUE-001: Auto-resolve orgSlug in portal injected menu item hrefs so widgets can use simple `/portal/...` paths without manual slug resolution - ISSUE-002: Clear MikroORM MetadataStorage between module iterations in dbGenerate to prevent polluted migrations for new modules - ISSUE-004: Add secondary table name lookup in resolveEntityTableName (scan ORM metadata by candidate table names) + warning log on fallback - ISSUE-005: Only reject system role name changes when the value actually differs from the current name, not when it's merely present in the payload - Update standalone app template to use `yarn mercato db generate/migrate` Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(create-app): improve standalone AI guides for icons, pagination, and context loading - Add CRITICAL rule #5: mandatory guide loading before writing code - Strengthen Task → Context Map intro with STOP-and-Read gate - Add sidebar icon guidance (lucide-react, not React.createElement) to module-scaffold skill and troubleshooter - Add DataTable pagination props guidance to backend-ui-design skill - Add icon and pagination error patterns to troubleshooter diagnostics Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: resolve framework issues #3, #4, #5, open-mercato#8 from hackathon report - #5 (HIGH): Include QueryProvider in AppShell so backend pages can use React Query hooks without crashing - #4 (HIGH): Improve command handler error message to list same-module registered commands and suggest side-effect import in index.ts - #3 (HIGH): Fix old-style backend route path duplication — skip modId prefix when directory segments already start with it - open-mercato#8 (MEDIUM): Add ID and href deduplication to mergeMenuItems to prevent duplicate portal sidebar entries Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(enterprise): add missing @simplewebauthn/types dependency Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ui): provide global fetch stub in AppShell test to prevent infinite recursion jsdom lacks a native fetch API, so QueryProvider's ensureGlobalFetchInterception saved undefined as __omOriginalFetch. When apiFetch fell back to globalThis.fetch (now the patched wrapper), it recursed infinitely. Adding a fetch stub in beforeAll gives the interception a real function to delegate to. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (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
This PR adds support for custom PostgreSQL schemas specified via the
DATABASE_URLquery parameter. Users can now configure a custom schema using the standard PostgreSQL format:Changes Made
Problem
The codebase had 8 hardcoded references to the
'public'schema across 5 files, which prevented users from deploying to databases with custom schemas.Solution
Use PostgreSQL's built-in
current_schema()function everywhere. The database connection'ssearch_path(set viaDATABASE_URL) becomes the single source of truth.Files Modified
packages/cli/src/lib/db/commands.tscurrent_schema()in raw SQL querypackages/cli/src/mercato.tscurrent_schema()for table listing andto_regclass()packages/core/src/modules/catalog/migrations/Migration20251116191744.tstable_schema = 'public'withcurrent_schema()packages/core/src/modules/customers/cli.ts.whereRaw('table_schema = current_schema()')packages/core/src/modules/query_index/lib/coverage.ts.whereRaw('table_schema = current_schema()')Why This Approach
search_pathdetermines the schemaDATABASE_URLformatgetDbSchema()utilityRelated Discussion
See PR #685 discussion for context on why this change was needed.
This PR was written using Vibe Kanban