Skip to content

Add SQLite SQL connector support#104

Open
hetsaraiya wants to merge 1 commit into
rapidaai:mainfrom
hetsaraiya:issue-78-sqlite-support
Open

Add SQLite SQL connector support#104
hetsaraiya wants to merge 1 commit into
rapidaai:mainfrom
hetsaraiya:issue-78-sqlite-support

Conversation

@hetsaraiya

@hetsaraiya hetsaraiya commented Apr 17, 2026

Copy link
Copy Markdown

Summary

Adds SQLite support for Go services alongside Postgres.

Resolves #78.

Changes

  • add SQLite config and connector support
  • select exactly one SQL backend: Postgres or SQLite
  • reject ambiguous multi-SQL config
  • skip bundled migrations when SQLite is selected because current migrations are Postgres-specific
  • rename shared connector type usage to SQLConnector

Validation

  • go test -p 1 ./pkg/configs ./pkg/connectors ./api/integration-api/config ./api/endpoint-api/config ./api/assistant-api/config ./api/web-api/config

Summary by CodeRabbit

Release Notes

  • New Features

    • Added SQLite database support as an alternative to PostgreSQL for local development and demo setups. Configure via SQLITE__* environment variables (e.g., SQLITE__PATH, SQLITE__MAX_IDLE_CONNECTION).
  • Documentation

    • Added SQLite setup guide under Local Development section with example configuration and migration caveats.

@coderabbitai

coderabbitai Bot commented Apr 17, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This pull request introduces SQLite support alongside PostgreSQL by making the database connector abstraction database-agnostic. It renames PostgresConnector to SQLConnector, implements a SQLite connector, adds a SQLConfig interface for unified database configuration, updates all API services and routers to use the generic SQL connector, and includes migration logic that handles both database backends appropriately.

Changes

Cohort / File(s) Summary
SQL Configuration Abstraction
pkg/configs/sql_config.go, pkg/configs/sql_config_test.go, pkg/configs/sqlite_config.go
New SQLConfig interface with ResolveSQLConfig and SelectedSQLConfig functions. Added SQLiteConfig struct and implemented DriverName(), MigrationDSN(), and helper methods on both PostgresConfig and SQLiteConfig. Tests verify configuration resolution, mutual exclusivity enforcement, and driver detection.
Connector Abstraction & Implementation
pkg/connectors/postgres.go, pkg/connectors/postgres_test.go, pkg/connectors/sql.go, pkg/connectors/sqlite.go, pkg/connectors/sqlite_test.go
Renamed PostgresConnector interface to SQLConnector. Added NewSQLConnector factory function that dispatches to appropriate connector based on config type. Implemented new sqliteConnector with full lifecycle management including directory creation, connection pooling, foreign key pragma setup, and connection validation.
Assistant API Configuration
api/assistant-api/config/config.go, api/assistant-api/config/config_test.go
Made PostgresConfig pointer-type and optional, added SQLiteConfig pointer field. Updated GetApplicationConfig to call ResolveSQLConfig and enforce exclusive selection. Added SQLConfig() method. Tests verify Postgres-only, SQLite-only, and error scenarios for multiple SQL configs.
Assistant API Services
api/assistant-api/api/assistant*.go, api/assistant-api/api/knowledge/*.go, api/assistant-api/api/talk/*.go
Updated all API constructors and service structs (NewAssistantGRPCApi, NewKnowledgeGRPCApi, NewConversationGRPCApi, etc.) to accept SQLConnector instead of PostgresConnector.
Assistant Internal Services
api/assistant-api/internal/services/assistant/*.go, api/assistant-api/internal/services/knowledge/*.go
Changed all internal service constructors (NewAssistantService, NewKnowledgeService, etc.) and struct fields to use SQLConnector instead of PostgresConnector.
Assistant Router & Support
api/assistant-api/router/assistant.go, api/assistant-api/router/knowledge.go, api/assistant-api/router/health-check.go, api/assistant-api/sip/sip.go, api/assistant-api/socket/*.go, api/assistant-api/internal/adapters/*.go, api/assistant-api/internal/callcontext/store.go
Updated all router functions and supporting classes to accept SQLConnector. Includes SIP engine, WebSocket pipeline, and call context store updates.
Endpoint API Configuration & Services
api/endpoint-api/config/config.go, api/endpoint-api/config/config_test.go, api/endpoint-api/api/*.go, api/endpoint-api/internal/service/*.go, api/endpoint-api/router/*.go
Applied same pattern: optional PostgresConfig pointer, new SQLiteConfig pointer, ResolveSQLConfig in configuration loading, SQLConfig() method. Updated all endpoint API constructors and routers.
Integration API Configuration & Services
api/integration-api/config/config.go, api/integration-api/config/config_test.go, api/integration-api/api/*.go, api/integration-api/internal/service/*.go, api/integration-api/router/*.go
Applied same configuration pattern and updated all integration API constructors and service dependencies to SQLConnector.
Web API Configuration & Services
api/web-api/config/config.go, api/web-api/config/config_test.go, api/web-api/api/*.go, api/web-api/api/proxy/*.go
Applied same configuration pattern. Updated all web API constructors, proxy constructors, and service dependencies to SQLConnector.
Web API Internal Services & Connectors
api/web-api/internal/service/*.go, api/web-api/internal/connect/*.go, api/web-api/authenticator/authenticator.go, api/web-api/router/*.go
Updated service constructors (user, organization, project, vault, notification), external connectors (Atlassian, GitHub, GitLab, Google, HubSpot, LinkedIn, Microsoft, Notion, Slack), and authenticators to accept SQLConnector.
Application Entry Points
cmd/assistant/assistant.go, cmd/endpoint/endpoint.go, cmd/integration/integration.go, cmd/web/web.go
Updated AppRunner.Postgres field to SQLConnector type. Changed connector construction to use NewSQLConnector(g.Cfg.SQLConfig()). Updated Migrate() to derive DSN from sqlConfig.MigrationDSN() and skip migrations for SQLite with warning.
Utilities & Authenticators
pkg/authenticators/service_authenticator.go
Updated constructor to accept SQLConnector instead of PostgresConnector.
Documentation
README.md
Added section documenting SQLite support via environment variables, minimal example with go run command, and caveat that checked-in migrations are PostgreSQL-specific and skipped for SQLite.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hopping through schemas with newfound grace,
SQLite now joins Postgres's place,
One interface to rule them all,
From PostgreSQL to SQLite's call,
Database choices, both great and small! 🗄️✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.90% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'Add SQLite SQL connector support' accurately and directly describes the primary change: introducing SQLite support alongside a new SQL connector abstraction layer.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
api/assistant-api/internal/callcontext/store.go (1)

83-107: ⚠️ Potential issue | 🟡 Minor

Rename postgresStore to reflect backend-agnostic abstraction; RETURNING is supported in mattn/go-sqlite3 v1.14.22.

The struct on line 45 is named postgresStore but now abstracts over connectors.SQLConnector, which supports both PostgreSQL and SQLite. Rename to sqlStore or similar to accurately reflect the abstraction.

SQLite compatibility is verified: mattn/go-sqlite3 v1.14.22 (Feb 2024) includes SQLite well after version 3.35.0 (Mar 2021) when RETURNING was introduced, so the query is safe. The db.Raw(...).Scan(...) pattern on UPDATE ... RETURNING will work consistently across drivers for this setup.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/assistant-api/internal/callcontext/store.go` around lines 83 - 107,
Rename the backend-specific type name postgresStore to a neutral name like
sqlStore throughout the file to reflect it's using connectors.SQLConnector;
update the receiver names on methods such as Claim(ctx context.Context,
contextID string) (*CallContext, error) and any references to s.postgres to use
the new struct field name as needed so the method implementation (including the
UPDATE ... RETURNING query and db.Raw(...).Scan(&cc)) continues to compile and
reference the correct struct and connector; ensure the struct declaration and
all method receivers (e.g., Claim) and any constructor/new function are updated
consistently.
api/web-api/internal/service/vault/service.go (1)

65-71: ⚠️ Potential issue | 🟡 Minor

Pre-existing: Debugf format string missing argument (unrelated to this PR, but visible in diff context).

vs.logger.Debugf("unable to delete vault %v") has a %v verb with no argument. Likely meant tx.Error. Not introduced here, so feel free to defer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/web-api/internal/service/vault/service.go` around lines 65 - 71, The
Debugf call in the vault update/delete flow uses a "%v" verb with no argument;
update the logging in the block that checks tx.Error (the if err := tx.Error;
err != nil { ... } branch) to include the actual error (err or tx.Error) in the
Debugf message (e.g., pass err as the format argument) so the format string
matches the provided value; locate the code around tx :=
db.Where(...).Updates(vlt) and the subsequent if err := tx.Error check in
service.go and fix vS.logger.Debugf to include the error variable.
cmd/web/web.go (1)

312-313: ⚠️ Potential issue | 🟠 Major

Pre-existing risk worth addressing in this PR: DSN logged at info level can leak credentials.

Line 313 logs the full migration DSN. For PostgreSQL the DSN contains the password in the userinfo portion (postgres://user:pass@host:port/db?...). While this log line is not newly introduced, the migration wiring around it changed in this PR — consider redacting before logging, e.g. parsing with net/url and clearing URL.User, or logging host/db only.

🛡️ Suggested redaction
import "net/url"

func safeDSN(dsn string) string {
    u, err := url.Parse(dsn)
    if err != nil {
        return "<unparseable dsn>"
    }
    if u.User != nil {
        u.User = url.User(u.User.Username()) // drop password
    }
    return u.Redacted() // Go ≥1.15 also works
}
// ...
app.Logger.Infof("Using DSN for migration: %s", safeDSN(dsn))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/web/web.go` around lines 312 - 313, The migration DSN is being logged in
app.Logger.Infof("Using DSN for migration: %s", dsn) which can leak credentials;
add a helper (e.g., safeDSN) that parses the DSN with net/url, clears the
password via u.User = url.User(u.User.Username()) (or equivalent) and returns
u.Redacted() or "<unparseable dsn>" on parse error, then replace the direct dsn
usage in the Logger call with safeDSN(dsn) to ensure passwords are not written
to logs.
pkg/connectors/postgres_test.go (2)

114-138: ⚠️ Potential issue | 🟡 Minor

mock.ExpectExec registered after the call it's meant to stub.

In TestSQLConnector_Query_ErrorHandling, connector.Query(...) runs on line 135, but mock.ExpectExec("SELECT 1")... is only set up on line 136 — after the query. The expectation never applies, and the assertion only passes incidentally. Also, Query uses Raw(...).Scan(...) which maps to ExpectQuery, not ExpectExec. Move the expectation before the call and use ExpectQuery if you intend to stub the query.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/connectors/postgres_test.go` around lines 114 - 138, The test
TestSQLConnector_Query_ErrorHandling registers the sqlmock expectation after
calling connector.Query and uses ExpectExec, but connector.Query uses
Raw(...).Scan(...) so you must set the mock expectation before invoking
connector.Query and use mock.ExpectQuery(...) (not ExpectExec) with appropriate
returned rows or error; update the setup around the mock variable
(mock.ExpectQuery("SELECT 1")... or mock.ExpectQuery(regexp).WillReturnRows(...)
/ WillReturnError(...)) before calling connector.Query(ctx, "SELECT 1", &dest)
so the expectation actually stubs the query and the assertion validates the
intended error path.

140-163: ⚠️ Potential issue | 🟡 Minor

Misleading subtest names in TestSQLConnector_EdgeCases.

The subtests "disconnect with nil db" and "db with nil db" both construct the connector with a non-nil gormDB, so they don't actually exercise the nil-db path their names advertise. Consider either setting db: nil in these connectors or renaming the subtests to reflect what's being tested.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/connectors/postgres_test.go` around lines 140 - 163, The subtests in
TestSQLConnector_EdgeCases are misnamed because they construct postgresConnector
with db: gormDB (non-nil) but claim to test "nil db" behavior; update the test
by either setting connector.db = nil when testing Disconnect and any "db with
nil db" cases or rename the subtests to reflect they're testing behavior with an
initialized gormDB; locate the postgresConnector creation in
TestSQLConnector_EdgeCases and adjust the db field or test names accordingly
(e.g., set db: nil for postgresConnector used with connector.Disconnect(ctx) or
change the t.Run names).
🧹 Nitpick comments (21)
api/assistant-api/internal/callcontext/store.go (1)

45-55: Nit: rename postgresStore now that the backend is generic.

The struct is still called postgresStore despite depending on connectors.SQLConnector. Consider sqlStore (and matching NewStore remains unchanged) to avoid misleading readers into thinking this is Postgres-only.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/assistant-api/internal/callcontext/store.go` around lines 45 - 55, Rename
the concrete type postgresStore to sqlStore to reflect that it depends on
connectors.SQLConnector; update the type declaration (postgresStore ->
sqlStore), the NewStore constructor to return &sqlStore{...} (keeping NewStore
name/signature unchanged), and update all method receivers that reference
postgresStore to use sqlStore so tests and usages continue to compile (e.g., any
methods with receiver (p *postgresStore) should become (s *sqlStore)).
pkg/authenticators/service_authenticator.go (1)

22-26: LGTM — parameter is accepted but unused.

Note the postgres parameter is still not stored on the struct (same as before the rename). If service auth is expected to query DB later, this is a no-op placeholder; otherwise consider dropping the parameter entirely to simplify the call sites.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/authenticators/service_authenticator.go` around lines 22 - 26, The
NewServiceAuthenticator function accepts a postgres connectors.SQLConnector
parameter but does not store or use it; either persist it on the
serviceAuthenticator struct or remove the unused parameter from the signature
and all call sites. To keep DB access available later, add a field (e.g.,
postgres connectors.SQLConnector) to the serviceAuthenticator type and set it in
NewServiceAuthenticator (assign postgres to that field); otherwise remove the
postgres parameter from NewServiceAuthenticator and update any callers to stop
passing it. Ensure references use the serviceAuthenticator type and
NewServiceAuthenticator constructor name when making edits.
pkg/configs/sqlite_config.go (1)

8-12: Consider SQLite-specific tuning knobs.

For SQLite, a single writer is the common pattern (MaxOpenConns=1) and WAL/journal/busy-timeout settings materially affect correctness under concurrency. Consider also exposing journal_mode, busy_timeout_ms, and foreign_keys via this config so the connector can apply them at open time, rather than hardcoding in NewSQLiteConnector.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/configs/sqlite_config.go` around lines 8 - 12, The SQLiteConfig struct
lacks SQLite-specific tuning knobs; add fields to SQLiteConfig (e.g.,
JournalMode string `mapstructure:"journal_mode"`, BusyTimeoutMS int
`mapstructure:"busy_timeout_ms"`, ForeignKeys bool
`mapstructure:"foreign_keys"`) and update validation tags as needed, then modify
NewSQLiteConnector to use these config values when opening/initializing the DB:
set PRAGMA journal_mode, PRAGMA foreign_keys, and PRAGMA busy_timeout (or append
them to the DSN) and ensure MaxOpenConnection is applied (recommend setting
MaxOpenConnection to 1 by default for single-writer scenarios) so the connector
uses config-driven settings rather than hardcoded values.
api/endpoint-api/router/endpoint.go (1)

13-32: LGTM — both route constructors now take the generic SQLConnector; gRPC registrations unchanged.

Same optional rename consideration applies to the Postgres parameter name (see note on the assistant services); safe to defer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/endpoint-api/router/endpoint.go` around lines 13 - 32, Parameter name
Postgres is misleading because both EndpointReaderApiRoute and InvokeApiRoute
accept the generic connectors.SQLConnector; rename the Postgres parameter to a
neutral name like sqlConnector or db in EndpointReaderApiRoute and
InvokeApiRoute (and update all call sites) so the signature matches the type and
intent, leaving the protos.RegisterEndpointServiceServer and
protos.RegisterDeploymentServer gRPC registrations unchanged.
api/web-api/config/config_test.go (1)

242-245: Minor: brittle substring assertion on error text.

strings.Contains(err.Error(), "set only one") couples the test to the exact wording of ResolveSQLConfig's error. If you later expose a sentinel error (e.g., configs.ErrMultipleSQLBackends), prefer errors.Is for a more stable assertion. Not blocking.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/web-api/config/config_test.go` around lines 242 - 245, The test in
GetApplicationConfig error assertion is brittle; change the assertion to use
errors.Is(err, configs.ErrMultipleSQLBackends) instead of substring matching and
ensure the resolver returns the sentinel error (configs.ErrMultipleSQLBackends)
from ResolveSQLConfig (or whatever function constructs that validation error) so
the test can reliably use errors.Is; update the test after the call to
GetApplicationConfig(vConfig) to assert errors.Is(err,
configs.ErrMultipleSQLBackends) and, if needed, make ResolveSQLConfig return
that sentinel error where it currently builds the "set only one" message.
api/assistant-api/internal/services/assistant/tool.impl.service.go (1)

31-31: Optional: rename postgres field now that the type is generic.

The field is now a generic SQLConnector (Postgres or SQLite). Consider renaming to sql/db across services in a follow-up to avoid misleading readers. Not blocking — many call sites, best done as a single rename PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/assistant-api/internal/services/assistant/tool.impl.service.go` at line
31, Rename the struct field currently named `postgres` (type
connectors.SQLConnector) to a neutral name like `sql` or `db` in the tool
implementation (e.g., in the struct declared in tool.impl.service.go) and update
all usages and constructors accordingly (e.g., replace `s.postgres` with
`s.sql`/`s.db`, update NewToolService parameter and assignment, and any methods
that call the connector) so the name reflects the generic SQLConnector type
rather than Postgres; perform the same rename consistently across related
services and call sites in this package.
api/assistant-api/config/config_test.go (1)

150-152: Minor: error formatter prints a pointer address.

When PostgresConfig is non-nil but DBName mismatches, %v of appConfig.PostgresConfig prints the pointer. Consider *appConfig.PostgresConfig (guarded by the nil check already in the condition) or just appConfig.PostgresConfig.DBName for readable failure output.

Proposed tweak
-	if appConfig.PostgresConfig == nil || appConfig.PostgresConfig.DBName != "assistant_db" {
-		t.Errorf("Expected PostgresConfig.DBName to be 'assistant_db', but got %v", appConfig.PostgresConfig)
-	}
+	if appConfig.PostgresConfig == nil {
+		t.Errorf("Expected PostgresConfig to be populated, got nil")
+	} else if appConfig.PostgresConfig.DBName != "assistant_db" {
+		t.Errorf("Expected PostgresConfig.DBName to be 'assistant_db', but got %q", appConfig.PostgresConfig.DBName)
+	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/assistant-api/config/config_test.go` around lines 150 - 152, The test's
failure message prints the pointer address because t.Errorf uses %v on
appConfig.PostgresConfig; change the error call in the test to print the actual
DBName (appConfig.PostgresConfig.DBName) or dereference the struct
(*appConfig.PostgresConfig) since the preceding nil check ensures it's
safe—update the t.Errorf invocation to include the readable value instead of the
pointer.
api/web-api/api/proxy/activity.go (1)

24-46: Consider renaming the postgres field to db / sql.

Now that the type is the generic SQLConnector, the field name postgres is misleading (it could be SQLite). A rename across the struct and wiring would improve readability, but it's purely cosmetic — feel free to defer. Same applies to assistant.impl.service.go, analysis.impl.service.go, endpoint.go, sip.go, and external.go.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/web-api/api/proxy/activity.go` around lines 24 - 46, Rename the
misleading field named `postgres` (type connectors.SQLConnector) to a more
generic name such as `db` or `sql` across the webActivityApi struct and its
usages: update the field declaration in the struct, the initializer in
NewActivityGRPC (replace `postgres: postgres,` with `db: postgres` or `sql:
postgres`), the argument passed to web_api.NewWebApi (currently `postgres`) and
any calls that use that field such as
internal_vault_service.NewVaultService(logger, postgres) to use the new name
(e.g., `internal_vault_service.NewVaultService(logger, db)`); apply the same
rename pattern in the other files mentioned (assistant.impl.service.go,
analysis.impl.service.go, endpoint.go, sip.go, external.go) to keep names
consistent.
api/integration-api/config/config_test.go (1)

130-207: Good coverage for success + fallback + selection behavior.

TestGetApplicationConfig_SQLite asserts the SQLite-populated / Postgres-nil path, and TestGetApplicationConfig_MultipleSQLConfigs asserts the mutual-exclusion validation error. This matches the backend-tests guideline of covering success, fallback, and factory/selection behavior.

One small suggestion: the "set only one" substring match is brittle — if the validation message in pkg/configs/sql_config.go is ever reworded, this test silently drifts. Consider exporting a sentinel error (e.g. ErrMultipleSQLConfigs) and using errors.Is instead of string matching.

As per coding guidelines: "Include at least a success path, fallback/error path, and factory/selection behavior assertion in backend tests".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/integration-api/config/config_test.go` around lines 130 - 207, The test's
brittle string-match should be replaced with an exported sentinel error from the
SQL config validation and checked with errors.Is: add/export
ErrMultipleSQLConfigs in pkg/configs/sql_config.go where the "set only one"
error is created, ensure GetApplicationConfig returns that error on multiple DB
configs, then update TestGetApplicationConfig_MultipleSQLConfigs to assert
errors.Is(err, configs.ErrMultipleSQLConfigs) (and keep the existing success
assertions in TestGetApplicationConfig_SQLite unchanged).
pkg/connectors/postgres.go (2)

34-36: Constructor name no longer matches return type — consider noting this in a follow-up.

NewPostgresConnector now returns the generic SQLConnector, which is fine, but future SQLite/other constructors will share the same return type. If a NewSQLConnector factory (or driver-selection helper) already exists in sql.go (as implied by the AI summary), consider whether NewPostgresConnector should remain public or be demoted to an internal helper invoked by the factory to avoid two parallel construction paths.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/connectors/postgres.go` around lines 34 - 36, The constructor
NewPostgresConnector currently returns the generic SQLConnector which can
conflict with a centralized factory; change the public API by making
NewPostgresConnector an internal helper (rename to newPostgresConnector) and
update the factory function (e.g., NewSQLConnector in sql.go) to call
newPostgresConnector when the Postgres driver is selected, or alternatively keep
NewPostgresConnector exported but add a one-line doc note pointing callers to
NewSQLConnector for typical usage; update any references to NewPostgresConnector
to use the new name or the factory accordingly and ensure postgresConnector and
SQLConnector symbols remain unchanged.

22-26: Move SQLConnector interface from postgres.go to sql.go for improved discoverability and better separation of concerns.

Both sqlite.go and postgres.go implement this backend-agnostic interface. Defining it in sql.go alongside the factory function NewSQLConnector() co-locates the interface with its dispatcher entry point and removes the tight coupling to the PostgreSQL implementation file.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/connectors/postgres.go` around lines 22 - 26, Move the SQLConnector
interface declaration out of postgres.go and into sql.go next to the factory
NewSQLConnector(): remove the type SQLConnector { Connector; Query(ctx
context.Context, qry string, dest interface{}) error; DB(ctx context.Context)
*gorm.DB } from postgres.go and add the identical interface definition in sql.go
so both sqlite.go and postgres.go can import/implement it; ensure package
declaration and imports are correct and run go vet/build to catch any missing
references.
cmd/assistant/assistant.go (1)

49-49: Stale name: Postgres field now holds a SQLConnector.

The field (and downstream locals/params like postgres in NewAssistantDeploymentGRPCApi, NewKnowledgeGRPCApi, newSessionPipeline, WebApi.postgres) is no longer postgres-specific. Consider renaming to SQL / sql (or DB/db) in a follow-up sweep; leaving the old name is a readability hazard for newcomers reasoning about SQLite deployments.

Also applies to: 227-227

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/assistant/assistant.go` at line 49, Rename the stale Postgres field to a
neutral name (e.g., SQL or DB) throughout the codebase: change the struct field
Postgres (type connectors.SQLConnector) to SQL (or DB), then update all
identifiers and usages that refer to it — specifically the parameters/locals
named postgres in NewAssistantDeploymentGRPCApi, NewKnowledgeGRPCApi,
newSessionPipeline, WebApi.postgres and any other references (including the
occurrence noted around line 227). Ensure constructor signatures, assignments,
method receivers and internal references are updated to the new name so
compilation and semantics remain correct.
pkg/configs/sql_config_test.go (2)

13-42: Minor: redundant viper Set calls in the postgres subtest.

v.Set(...) values are written but ResolveSQLConfig is invoked with a fully-populated &PostgresConfig{...} literal, so the viper state has no effect on the assertion. Either drive the config from viper (e.g., via v.Unmarshal) to exercise the viper→struct path, or drop the v.Set calls to keep the test minimal. Same applies to the sqlite subtest.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/configs/sql_config_test.go` around lines 13 - 42, The postgres subtest
currently sets many viper keys via v.Set but then calls ResolveSQLConfig with a
fully-populated &PostgresConfig literal so the viper state is unused; fix by
either removing the redundant v.Set calls to keep the test minimal, or change
the test to build the expected config by unmarshalling v into a PostgresConfig
(using v.Unmarshal or by passing v-derived config into ResolveSQLConfig) so the
viper→struct path is exercised; apply the same change pattern to the sqlite
subtest; look for symbols viper.NewWithOptions, v.Set, ResolveSQLConfig, and
PostgresConfig to locate the code to update.

66-78: Use errors.Is instead of != for sentinel comparisons.

The tests at lines 66 and 77 currently use direct != comparisons, which will break if ResolveSQLConfig wraps these sentinel errors with fmt.Errorf(...%w...) (as required by the repo's error-wrapping guideline). Replace with errors.Is(err, ErrNoSQLConfigConfigured) and errors.Is(err, ErrMultipleSQLConfigsDetected) to make the tests robust for future error-wrapping changes. Remember to add "errors" to the import block.

Proposed change
-		if err != ErrNoSQLConfigConfigured {
+		if !errors.Is(err, ErrNoSQLConfigConfigured) {
 			t.Fatalf("ResolveSQLConfig() error = %v, want %v", err, ErrNoSQLConfigConfigured)
 		}
@@
-		if err != ErrMultipleSQLConfigsDetected {
+		if !errors.Is(err, ErrMultipleSQLConfigsDetected) {
 			t.Fatalf("ResolveSQLConfig() error = %v, want %v", err, ErrMultipleSQLConfigsDetected)
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/configs/sql_config_test.go` around lines 66 - 78, The test compares
sentinel errors with != which breaks if ResolveSQLConfig wraps errors; change
the comparisons to use errors.Is(err, ErrNoSQLConfigConfigured) and
errors.Is(err, ErrMultipleSQLConfigsDetected) in the two failing asserts, and
add the "errors" package to the test file imports so the tests correctly detect
wrapped errors returned by ResolveSQLConfig.
api/web-api/api/proxy/endpoint.go (1)

22-42: LGTM.

Type swap to connectors.SQLConnector propagates cleanly into web_api.NewWebApi. Consider renaming the postgres field/parameter to something backend-agnostic (e.g., sql/db) in a follow-up — not blocking.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/web-api/api/proxy/endpoint.go` around lines 22 - 42, The code uses the
name postgres for a SQL connector parameter and struct field even though the
type is connectors.SQLConnector; rename the parameter/field to a
backend-agnostic name (e.g., sql or db) to reflect the general type. Update the
NewEndpointGRPC function signature parameter name, the webEndpointApi struct
literal field, and the webEndpointGRPCApi/webEndpointApi definitions/usages
(e.g., postgres -> sql) and ensure every reference (including the call to
web_api.NewWebApi and any other placements of postgres) is renamed consistently
across this diff so compilation and calls still match.
api/assistant-api/config/config.go (1)

94-108: DRY: extract shared SQL-backend selection helper.

This ResolveSQLConfig → type switch → exclusivity nil-out block is duplicated verbatim in api/web-api/config/config.go (lines 94–106), and will need to be repeated for every future service config (endpoint-api, etc.). Consider moving it into pkg/configs (e.g., configs.ApplySelectedSQL(&cfg.PostgresConfig, &cfg.SQLiteConfig, v, validate)) so each service just calls a single helper.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/assistant-api/config/config.go` around lines 94 - 108, The code repeats a
type-switch that applies the result of configs.ResolveSQLConfig to set either
config.PostgresConfig or config.SQLiteConfig and nil-out the other; extract this
logic into a shared helper in pkg/configs (e.g., configs.ApplySelectedSQL) that
accepts pointers to the two config fields plus the resolved value and performs
the type switch and exclusivity assignments, then replace the duplicated block
in config.go with a call to that new helper using ResolveSQLConfig's returned
sqlConfig, keeping the existing error handling and validator usage (symbols to
update: configs.ResolveSQLConfig, config.PostgresConfig, config.SQLiteConfig,
and add configs.ApplySelectedSQL).
api/assistant-api/internal/services/assistant/conversaction.impl.service.go (1)

28-43: LGTM — connector type swap only.

assistantConversationService.postgres field and NewAssistantConversationService constructor correctly updated to connectors.SQLConnector; no behavior changes.

Nit (out of scope): the filename conversaction.impl.service.go looks like a typo (conversactionconversation) from a previous change and does not follow the <domain>.<qualifier>.<entity>.go convention cleanly. Worth renaming in a follow-up PR.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/assistant-api/internal/services/assistant/conversaction.impl.service.go`
around lines 28 - 43, The file name contains a typo
"conversaction.impl.service.go" that should be renamed to follow the convention
and fix spelling; rename the file to "conversation.impl.service.go" and update
any references or build constraints so the package still compiles (ensure
imports, go:generate or test files refer to the new filename), verifying symbols
assistantConversationService and NewAssistantConversationService remain
reachable and tests/build succeed after the rename.
cmd/integration/integration.go (1)

295-300: Consider replacing the magic "sqlite" string with a typed constant or capability method.

Comparing sqlConfig.DriverName() == "sqlite" couples this bootstrap code to a string literal that must stay in sync with whatever SQLiteConfig.DriverName() returns. If the SQL abstraction later adds more backends (or the driver name canonicalization changes), this check silently drifts. A configs.DriverSQLite constant or a sqlConfig.SupportsBundledMigrations() helper on the SQLConfig interface would make intent explicit and prevent divergence.

♻️ Example refactor
-	if sqlConfig.DriverName() == "sqlite" {
+	if sqlConfig.DriverName() == configs.DriverSQLite {
 		app.Logger.Warnf("Skipping migrations for %s: bundled migrations are PostgreSQL-specific today.", sqlConfig.DisplayName())
 		return nil
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/integration/integration.go` around lines 295 - 300, Replace the
hard-coded "sqlite" comparison with a typed capability check: add a
SupportsBundledMigrations() bool method to the SQLConfig interface (or
alternatively define a configs.DriverSQLite constant and use that instead of the
literal), implement SupportsBundledMigrations() on the SQLiteConfig to return
false, and change the code in integration.go to call
sqlConfig.SupportsBundledMigrations() (or compare to configs.DriverSQLite)
instead of sqlConfig.DriverName() == "sqlite" so the intent is explicit and
future driver name changes won't break this check.
pkg/connectors/postgres_test.go (1)

61-84: TestSQLConnector_Disconnect ignores the returned error.

err = connector.Disconnect(ctx) is assigned but never asserted. Consider assert.NoError(t, err) (or the expected error) alongside the existing assert.Nil(t, connector.db) so the test actually validates Disconnect's contract.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/connectors/postgres_test.go` around lines 61 - 84, The test
TestSQLConnector_Disconnect currently assigns the result of
connector.Disconnect(ctx) to err but never asserts it; update the test to assert
the expected outcome of the disconnect call (e.g., assert.NoError(t, err) if
disconnect should succeed or the appropriate assert for an expected error) in
addition to the existing assert.Nil(t, connector.db) so Disconnect's contract is
validated; locate the call to connector.Disconnect in
TestSQLConnector_Disconnect and add the error assertion immediately after the
call.
api/web-api/internal/connect/microsoft.go (1)

59-99: Parameter name postgres is now misleading.

The type was generalized to connectors.SQLConnector, but the parameter is still named postgres in all three constructors. Consider renaming to sqlConn (or similar) for clarity — purely cosmetic, feel free to defer.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/web-api/internal/connect/microsoft.go` around lines 59 - 99, Rename the
misleading parameter name "postgres" to something generic like "sqlConn" in the
three constructors NewMicrosoftAuthenticationConnect,
NewMicrosoftSharepointConnect, and NewMicrosoftOnedriveConnect; update the
function signatures and all uses inside each function (notably the
NewExternalConnect(...) call that currently passes "postgres") to use "sqlConn"
so the parameter name matches its type connectors.SQLConnector and improves
clarity.
pkg/connectors/sqlite.go (1)

56-58: SetConnMaxLifetime is hardcoded to 1 hour in both SQLite and PostgreSQL connectors.

Neither SQLiteConfig nor PostgresConfig expose a lifetime configuration field. If connection lifetime configurability is needed, add a field to both config structs and wire it through; otherwise, extract the hardcoded time.Hour to a named constant for consistency across connectors.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/connectors/sqlite.go` around lines 56 - 58, The connectors currently
hardcode sqlDB.SetConnMaxLifetime(time.Hour) in sqlite.go (and likewise in the
Postgres connector) but neither SQLiteConfig nor PostgresConfig expose a
lifetime field; either add a Lifetime (or ConnMaxLifetime) time.Duration field
to both SQLiteConfig and PostgresConfig and wire it into the code path that
creates sqlDB (use sqlt.cfg.ConnMaxLifetime / postgresCfg.ConnMaxLifetime when
calling SetConnMaxLifetime), or if configurability is not desired, extract the
literal time.Hour into a single named package-level constant (e.g.,
defaultConnMaxLifetime) and use that constant in both sqlite.go and the Postgres
connector for consistency.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@api/integration-api/config/config_test.go`:
- Around line 119-121: The test's failure message prints the pointer address
because it logs appConfig.PostgresConfig with %v; change the error message to
dereference and/or print the actual DBName field (guarding for nil) so the
output shows the value. Specifically, in the failing assertion around
appConfig.PostgresConfig and PostgresConfig.DBName, update the t.Errorf to check
nil first and then include appConfig.PostgresConfig.DBName (or use
fmt.Sprintf("%+v", *appConfig.PostgresConfig) after nil-check) so the error
shows the struct contents or the DBName value rather than a pointer address.

In `@pkg/configs/sql_config.go`:
- Around line 107-125: The prefix detection currently inspects os.Environ()
causing false positives; update hasConfigPrefix (and thus detectSQLPrefixes) to
stop scanning process env and instead rely on Viper-only data: iterate
v.AllKeys() (normalize keys as already done) and return true only when a
normalized key starts with the target prefix AND v.IsSet(originalKey) (or
otherwise confirmed by Viper), so only configuration known to this Viper
instance triggers detection; remove the os.Environ() loop and any reliance on
global environment variables in hasConfigPrefix.
- Around line 97-105: SelectedSQLConfig currently can return a non-nil interface
holding a typed nil and panics when both configs are provided; change its
signature to SelectedSQLConfig(postgres *PostgresConfig, sqlite *SQLiteConfig)
(SQLConfig, error) and return explicit errors instead of panicking: if both
postgres and sqlite are non-nil return (nil, errors.New("requires exactly one
SQL config; both provided")), if both are nil return (nil, nil) or better (nil,
errors.New("no SQL config provided")) to avoid a typed-nil SQLConfig, and when
exactly one is set return that concrete config and nil error (ensure you return
the concrete sqlite or postgres value directly, not a nil pointer wrapped in the
interface); follow ResolveSQLConfig's error-returning pattern and import errors
as needed.
- Around line 38-48: The MigrationDSN builds the Postgres URL with fmt.Sprintf
which doesn't escape special characters in PostgresConfig.Auth.User and
.Password; change MigrationDSN to construct the URL using net/url (e.g.,
url.UserPassword or url.User and url.URL) so username/password are
percent-encoded and set Scheme="postgres", Host as fmt.Sprintf("%s:%d", c.Host,
c.Port), Path="/"+c.DBName, and RawQuery to include sslmode=c.SslMode; update
imports to include "net/url" and return url.String() from MigrationDSN.
- Around line 62-63: Add the sqlite3 database driver import and tests: import
the side-effect driver `_
"github.com/golang-migrate/migrate/v4/database/sqlite3"` into each command
entrypoint that constructs migrations (files using migrate.New():
cmd/web/web.go, cmd/integration/integration.go, cmd/endpoint/endpoint.go,
cmd/assistant/assistant.go) so the sqlite3 driver is registered at runtime; and
update sql_config_test.go to add test cases asserting
SQLiteConfig.MigrationDSN() returns "sqlite3://"+Path and that
PostgresConfig.MigrationDSN() still returns the expected Postgres DSN format
(use the existing PostgresConfig and SQLiteConfig constructors/fields in the
tests to validate their MigrationDSN() outputs).

In `@pkg/configs/sqlite_config.go`:
- Around line 8-12: Rename the typo'd fields and tags in both SQLiteConfig and
PostgresConfig: change MaxIdealConnection -> MaxIdleConnection and
mapstructure:"max_ideal_connection" -> "max_idle_connection" (and update any
references to these struct fields), then update tests and README accordingly
(notably pkg/configs/sql_config_test.go and any env/config examples); also
replace validate:"required" on the int fields MaxIdleConnection and
MaxOpenConnection with validate:"gte=0" (or remove the required tag and ensure
sensible defaults are applied) so zero is allowed by validation and database/sql
semantics are preserved.

In `@pkg/connectors/sql.go`:
- Around line 13-22: The NewSQLConnector function currently returns nil on
unknown config types which leads to silent nil-pointer panics; change its
signature to return (SQLConnector, error) (or at minimum log.Fatal/error in the
default branch) and update callers to handle the error. Inside NewSQLConnector,
switch on config types as before (case *configs.PostgresConfig ->
NewPostgresConnector, case *configs.SQLiteConfig -> NewSQLiteConnector) but on
the default path return a descriptive error (e.g., fmt.Errorf("unsupported SQL
config type: %T", config)) instead of nil; ensure all call sites that call
NewSQLConnector are updated to check the returned error and stop startup on
failure.

In `@pkg/connectors/sqlite_test.go`:
- Around line 16-60: Add missing negative and idempotency coverage: add a test
that constructs NewSQLiteConnector (or via NewSQLConnector) with an invalid
config (e.g., Path: "" or a non-writable path) and assert that
connector.Connect(ctx) returns an error; add an assertion that Disconnect is
idempotent by calling connector.Disconnect(ctx) twice (or calling Disconnect on
a never-connected connector) and ensuring no panic and appropriate error/no-op
behavior; and extend TestNewSQLConnector_SQLite to call connector.Connect(ctx)
and assert connector.Name() (e.g., equals "SQLITE sqlite3://...") to verify
factory selection dispatched the SQLite implementation. Reference
NewSQLiteConnector, NewSQLConnector, Connect, Disconnect, Name, and
ensureSQLiteParentDir when adding these checks.

In `@pkg/connectors/sqlite.go`:
- Around line 33-35: The DB(ctx) method on sqliteConnector may dereference nil
when sqlt.db is unset; add a nil guard in sqliteConnector.DB that checks if
sqlt.db == nil and, if so, returns a *gorm.DB whose Error field is set to a
descriptive error (e.g., using errors.New("sqlite connector not connected"))
instead of calling WithContext; otherwise return sqlt.db.WithContext(ctx).
Reference the sqliteConnector.DB method and set the Error on the returned
*gorm.DB so callers can check .Error safely.
- Around line 89-102: Disconnect currently dereferences sqlt.db without checking
for nil and will panic if Connect never succeeded; update
sqliteConnector.Disconnect to first check if sqlt.db == nil and return nil (or a
clear error) before calling sqlt.db.DB(), and only then call db.Close(); also
fix the logger messages in Disconnect (replace ambiguous "Disconnecting sqlite
client %s." with clearer text like "Failed to get underlying DB: %v" for the
DB() error and "Failed to close sqlite client: %v" for Close() error) so the
logged messages accurately describe the failures.

In `@README.md`:
- Around line 189-190: The README and config struct use a typo "Ideal" instead
of "Idle": rename the struct field MaxIdealConnection to MaxIdleConnection and
update its mapstructure tag from "max_ideal_connection" to
"max_idle_connection", then update all references/usages and example env vars
(change SQLITE__MAX_IDEAL_CONNECTION to SQLITE__MAX_IDLE_CONNECTION) to keep the
env-var contract consistent; ensure any code that reads the old tag/name
(parsing/config loading, tests, docs) is updated to use the new symbol and tag
so the change is applied project-wide.

---

Outside diff comments:
In `@api/assistant-api/internal/callcontext/store.go`:
- Around line 83-107: Rename the backend-specific type name postgresStore to a
neutral name like sqlStore throughout the file to reflect it's using
connectors.SQLConnector; update the receiver names on methods such as Claim(ctx
context.Context, contextID string) (*CallContext, error) and any references to
s.postgres to use the new struct field name as needed so the method
implementation (including the UPDATE ... RETURNING query and
db.Raw(...).Scan(&cc)) continues to compile and reference the correct struct and
connector; ensure the struct declaration and all method receivers (e.g., Claim)
and any constructor/new function are updated consistently.

In `@api/web-api/internal/service/vault/service.go`:
- Around line 65-71: The Debugf call in the vault update/delete flow uses a "%v"
verb with no argument; update the logging in the block that checks tx.Error (the
if err := tx.Error; err != nil { ... } branch) to include the actual error (err
or tx.Error) in the Debugf message (e.g., pass err as the format argument) so
the format string matches the provided value; locate the code around tx :=
db.Where(...).Updates(vlt) and the subsequent if err := tx.Error check in
service.go and fix vS.logger.Debugf to include the error variable.

In `@cmd/web/web.go`:
- Around line 312-313: The migration DSN is being logged in
app.Logger.Infof("Using DSN for migration: %s", dsn) which can leak credentials;
add a helper (e.g., safeDSN) that parses the DSN with net/url, clears the
password via u.User = url.User(u.User.Username()) (or equivalent) and returns
u.Redacted() or "<unparseable dsn>" on parse error, then replace the direct dsn
usage in the Logger call with safeDSN(dsn) to ensure passwords are not written
to logs.

In `@pkg/connectors/postgres_test.go`:
- Around line 114-138: The test TestSQLConnector_Query_ErrorHandling registers
the sqlmock expectation after calling connector.Query and uses ExpectExec, but
connector.Query uses Raw(...).Scan(...) so you must set the mock expectation
before invoking connector.Query and use mock.ExpectQuery(...) (not ExpectExec)
with appropriate returned rows or error; update the setup around the mock
variable (mock.ExpectQuery("SELECT 1")... or
mock.ExpectQuery(regexp).WillReturnRows(...) / WillReturnError(...)) before
calling connector.Query(ctx, "SELECT 1", &dest) so the expectation actually
stubs the query and the assertion validates the intended error path.
- Around line 140-163: The subtests in TestSQLConnector_EdgeCases are misnamed
because they construct postgresConnector with db: gormDB (non-nil) but claim to
test "nil db" behavior; update the test by either setting connector.db = nil
when testing Disconnect and any "db with nil db" cases or rename the subtests to
reflect they're testing behavior with an initialized gormDB; locate the
postgresConnector creation in TestSQLConnector_EdgeCases and adjust the db field
or test names accordingly (e.g., set db: nil for postgresConnector used with
connector.Disconnect(ctx) or change the t.Run names).

---

Nitpick comments:
In `@api/assistant-api/config/config_test.go`:
- Around line 150-152: The test's failure message prints the pointer address
because t.Errorf uses %v on appConfig.PostgresConfig; change the error call in
the test to print the actual DBName (appConfig.PostgresConfig.DBName) or
dereference the struct (*appConfig.PostgresConfig) since the preceding nil check
ensures it's safe—update the t.Errorf invocation to include the readable value
instead of the pointer.

In `@api/assistant-api/config/config.go`:
- Around line 94-108: The code repeats a type-switch that applies the result of
configs.ResolveSQLConfig to set either config.PostgresConfig or
config.SQLiteConfig and nil-out the other; extract this logic into a shared
helper in pkg/configs (e.g., configs.ApplySelectedSQL) that accepts pointers to
the two config fields plus the resolved value and performs the type switch and
exclusivity assignments, then replace the duplicated block in config.go with a
call to that new helper using ResolveSQLConfig's returned sqlConfig, keeping the
existing error handling and validator usage (symbols to update:
configs.ResolveSQLConfig, config.PostgresConfig, config.SQLiteConfig, and add
configs.ApplySelectedSQL).

In `@api/assistant-api/internal/callcontext/store.go`:
- Around line 45-55: Rename the concrete type postgresStore to sqlStore to
reflect that it depends on connectors.SQLConnector; update the type declaration
(postgresStore -> sqlStore), the NewStore constructor to return &sqlStore{...}
(keeping NewStore name/signature unchanged), and update all method receivers
that reference postgresStore to use sqlStore so tests and usages continue to
compile (e.g., any methods with receiver (p *postgresStore) should become (s
*sqlStore)).

In `@api/assistant-api/internal/services/assistant/conversaction.impl.service.go`:
- Around line 28-43: The file name contains a typo
"conversaction.impl.service.go" that should be renamed to follow the convention
and fix spelling; rename the file to "conversation.impl.service.go" and update
any references or build constraints so the package still compiles (ensure
imports, go:generate or test files refer to the new filename), verifying symbols
assistantConversationService and NewAssistantConversationService remain
reachable and tests/build succeed after the rename.

In `@api/assistant-api/internal/services/assistant/tool.impl.service.go`:
- Line 31: Rename the struct field currently named `postgres` (type
connectors.SQLConnector) to a neutral name like `sql` or `db` in the tool
implementation (e.g., in the struct declared in tool.impl.service.go) and update
all usages and constructors accordingly (e.g., replace `s.postgres` with
`s.sql`/`s.db`, update NewToolService parameter and assignment, and any methods
that call the connector) so the name reflects the generic SQLConnector type
rather than Postgres; perform the same rename consistently across related
services and call sites in this package.

In `@api/endpoint-api/router/endpoint.go`:
- Around line 13-32: Parameter name Postgres is misleading because both
EndpointReaderApiRoute and InvokeApiRoute accept the generic
connectors.SQLConnector; rename the Postgres parameter to a neutral name like
sqlConnector or db in EndpointReaderApiRoute and InvokeApiRoute (and update all
call sites) so the signature matches the type and intent, leaving the
protos.RegisterEndpointServiceServer and protos.RegisterDeploymentServer gRPC
registrations unchanged.

In `@api/integration-api/config/config_test.go`:
- Around line 130-207: The test's brittle string-match should be replaced with
an exported sentinel error from the SQL config validation and checked with
errors.Is: add/export ErrMultipleSQLConfigs in pkg/configs/sql_config.go where
the "set only one" error is created, ensure GetApplicationConfig returns that
error on multiple DB configs, then update
TestGetApplicationConfig_MultipleSQLConfigs to assert errors.Is(err,
configs.ErrMultipleSQLConfigs) (and keep the existing success assertions in
TestGetApplicationConfig_SQLite unchanged).

In `@api/web-api/api/proxy/activity.go`:
- Around line 24-46: Rename the misleading field named `postgres` (type
connectors.SQLConnector) to a more generic name such as `db` or `sql` across the
webActivityApi struct and its usages: update the field declaration in the
struct, the initializer in NewActivityGRPC (replace `postgres: postgres,` with
`db: postgres` or `sql: postgres`), the argument passed to web_api.NewWebApi
(currently `postgres`) and any calls that use that field such as
internal_vault_service.NewVaultService(logger, postgres) to use the new name
(e.g., `internal_vault_service.NewVaultService(logger, db)`); apply the same
rename pattern in the other files mentioned (assistant.impl.service.go,
analysis.impl.service.go, endpoint.go, sip.go, external.go) to keep names
consistent.

In `@api/web-api/api/proxy/endpoint.go`:
- Around line 22-42: The code uses the name postgres for a SQL connector
parameter and struct field even though the type is connectors.SQLConnector;
rename the parameter/field to a backend-agnostic name (e.g., sql or db) to
reflect the general type. Update the NewEndpointGRPC function signature
parameter name, the webEndpointApi struct literal field, and the
webEndpointGRPCApi/webEndpointApi definitions/usages (e.g., postgres -> sql) and
ensure every reference (including the call to web_api.NewWebApi and any other
placements of postgres) is renamed consistently across this diff so compilation
and calls still match.

In `@api/web-api/config/config_test.go`:
- Around line 242-245: The test in GetApplicationConfig error assertion is
brittle; change the assertion to use errors.Is(err,
configs.ErrMultipleSQLBackends) instead of substring matching and ensure the
resolver returns the sentinel error (configs.ErrMultipleSQLBackends) from
ResolveSQLConfig (or whatever function constructs that validation error) so the
test can reliably use errors.Is; update the test after the call to
GetApplicationConfig(vConfig) to assert errors.Is(err,
configs.ErrMultipleSQLBackends) and, if needed, make ResolveSQLConfig return
that sentinel error where it currently builds the "set only one" message.

In `@api/web-api/internal/connect/microsoft.go`:
- Around line 59-99: Rename the misleading parameter name "postgres" to
something generic like "sqlConn" in the three constructors
NewMicrosoftAuthenticationConnect, NewMicrosoftSharepointConnect, and
NewMicrosoftOnedriveConnect; update the function signatures and all uses inside
each function (notably the NewExternalConnect(...) call that currently passes
"postgres") to use "sqlConn" so the parameter name matches its type
connectors.SQLConnector and improves clarity.

In `@cmd/assistant/assistant.go`:
- Line 49: Rename the stale Postgres field to a neutral name (e.g., SQL or DB)
throughout the codebase: change the struct field Postgres (type
connectors.SQLConnector) to SQL (or DB), then update all identifiers and usages
that refer to it — specifically the parameters/locals named postgres in
NewAssistantDeploymentGRPCApi, NewKnowledgeGRPCApi, newSessionPipeline,
WebApi.postgres and any other references (including the occurrence noted around
line 227). Ensure constructor signatures, assignments, method receivers and
internal references are updated to the new name so compilation and semantics
remain correct.

In `@cmd/integration/integration.go`:
- Around line 295-300: Replace the hard-coded "sqlite" comparison with a typed
capability check: add a SupportsBundledMigrations() bool method to the SQLConfig
interface (or alternatively define a configs.DriverSQLite constant and use that
instead of the literal), implement SupportsBundledMigrations() on the
SQLiteConfig to return false, and change the code in integration.go to call
sqlConfig.SupportsBundledMigrations() (or compare to configs.DriverSQLite)
instead of sqlConfig.DriverName() == "sqlite" so the intent is explicit and
future driver name changes won't break this check.

In `@pkg/authenticators/service_authenticator.go`:
- Around line 22-26: The NewServiceAuthenticator function accepts a postgres
connectors.SQLConnector parameter but does not store or use it; either persist
it on the serviceAuthenticator struct or remove the unused parameter from the
signature and all call sites. To keep DB access available later, add a field
(e.g., postgres connectors.SQLConnector) to the serviceAuthenticator type and
set it in NewServiceAuthenticator (assign postgres to that field); otherwise
remove the postgres parameter from NewServiceAuthenticator and update any
callers to stop passing it. Ensure references use the serviceAuthenticator type
and NewServiceAuthenticator constructor name when making edits.

In `@pkg/configs/sql_config_test.go`:
- Around line 13-42: The postgres subtest currently sets many viper keys via
v.Set but then calls ResolveSQLConfig with a fully-populated &PostgresConfig
literal so the viper state is unused; fix by either removing the redundant v.Set
calls to keep the test minimal, or change the test to build the expected config
by unmarshalling v into a PostgresConfig (using v.Unmarshal or by passing
v-derived config into ResolveSQLConfig) so the viper→struct path is exercised;
apply the same change pattern to the sqlite subtest; look for symbols
viper.NewWithOptions, v.Set, ResolveSQLConfig, and PostgresConfig to locate the
code to update.
- Around line 66-78: The test compares sentinel errors with != which breaks if
ResolveSQLConfig wraps errors; change the comparisons to use errors.Is(err,
ErrNoSQLConfigConfigured) and errors.Is(err, ErrMultipleSQLConfigsDetected) in
the two failing asserts, and add the "errors" package to the test file imports
so the tests correctly detect wrapped errors returned by ResolveSQLConfig.

In `@pkg/configs/sqlite_config.go`:
- Around line 8-12: The SQLiteConfig struct lacks SQLite-specific tuning knobs;
add fields to SQLiteConfig (e.g., JournalMode string
`mapstructure:"journal_mode"`, BusyTimeoutMS int
`mapstructure:"busy_timeout_ms"`, ForeignKeys bool
`mapstructure:"foreign_keys"`) and update validation tags as needed, then modify
NewSQLiteConnector to use these config values when opening/initializing the DB:
set PRAGMA journal_mode, PRAGMA foreign_keys, and PRAGMA busy_timeout (or append
them to the DSN) and ensure MaxOpenConnection is applied (recommend setting
MaxOpenConnection to 1 by default for single-writer scenarios) so the connector
uses config-driven settings rather than hardcoded values.

In `@pkg/connectors/postgres_test.go`:
- Around line 61-84: The test TestSQLConnector_Disconnect currently assigns the
result of connector.Disconnect(ctx) to err but never asserts it; update the test
to assert the expected outcome of the disconnect call (e.g., assert.NoError(t,
err) if disconnect should succeed or the appropriate assert for an expected
error) in addition to the existing assert.Nil(t, connector.db) so Disconnect's
contract is validated; locate the call to connector.Disconnect in
TestSQLConnector_Disconnect and add the error assertion immediately after the
call.

In `@pkg/connectors/postgres.go`:
- Around line 34-36: The constructor NewPostgresConnector currently returns the
generic SQLConnector which can conflict with a centralized factory; change the
public API by making NewPostgresConnector an internal helper (rename to
newPostgresConnector) and update the factory function (e.g., NewSQLConnector in
sql.go) to call newPostgresConnector when the Postgres driver is selected, or
alternatively keep NewPostgresConnector exported but add a one-line doc note
pointing callers to NewSQLConnector for typical usage; update any references to
NewPostgresConnector to use the new name or the factory accordingly and ensure
postgresConnector and SQLConnector symbols remain unchanged.
- Around line 22-26: Move the SQLConnector interface declaration out of
postgres.go and into sql.go next to the factory NewSQLConnector(): remove the
type SQLConnector { Connector; Query(ctx context.Context, qry string, dest
interface{}) error; DB(ctx context.Context) *gorm.DB } from postgres.go and add
the identical interface definition in sql.go so both sqlite.go and postgres.go
can import/implement it; ensure package declaration and imports are correct and
run go vet/build to catch any missing references.

In `@pkg/connectors/sqlite.go`:
- Around line 56-58: The connectors currently hardcode
sqlDB.SetConnMaxLifetime(time.Hour) in sqlite.go (and likewise in the Postgres
connector) but neither SQLiteConfig nor PostgresConfig expose a lifetime field;
either add a Lifetime (or ConnMaxLifetime) time.Duration field to both
SQLiteConfig and PostgresConfig and wire it into the code path that creates
sqlDB (use sqlt.cfg.ConnMaxLifetime / postgresCfg.ConnMaxLifetime when calling
SetConnMaxLifetime), or if configurability is not desired, extract the literal
time.Hour into a single named package-level constant (e.g.,
defaultConnMaxLifetime) and use that constant in both sqlite.go and the Postgres
connector for consistency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 939a718d-9839-4447-a479-7e022eea3a2a

📥 Commits

Reviewing files that changed from the base of the PR and between 8fee7fb and 8c1a5b7.

📒 Files selected for processing (91)
  • README.md
  • api/assistant-api/api/assistant-deployment/assistant_deployment.go
  • api/assistant-api/api/assistant/assistant.go
  • api/assistant-api/api/knowledge/indexer.go
  • api/assistant-api/api/knowledge/knowledge.go
  • api/assistant-api/api/talk/talk.go
  • api/assistant-api/config/config.go
  • api/assistant-api/config/config_test.go
  • api/assistant-api/internal/adapters/internal/requestor.go
  • api/assistant-api/internal/adapters/request.go
  • api/assistant-api/internal/adapters/request_test.go
  • api/assistant-api/internal/callcontext/store.go
  • api/assistant-api/internal/services/assistant/analysis.impl.service.go
  • api/assistant-api/internal/services/assistant/assistant.deployment.impl.service.go
  • api/assistant-api/internal/services/assistant/assistant.impl.service.go
  • api/assistant-api/internal/services/assistant/conversaction.impl.service.go
  • api/assistant-api/internal/services/assistant/knowledge.impl.service.go
  • api/assistant-api/internal/services/assistant/telemetry.impl.service.go
  • api/assistant-api/internal/services/assistant/tool.impl.service.go
  • api/assistant-api/internal/services/assistant/webhook.impl.service.go
  • api/assistant-api/internal/services/knowledge/document.impl.service.go
  • api/assistant-api/internal/services/knowledge/knowledge.impl.service.go
  • api/assistant-api/router/assistant.go
  • api/assistant-api/router/health-check.go
  • api/assistant-api/router/knowledge.go
  • api/assistant-api/sip/sip.go
  • api/assistant-api/socket/pipeline.go
  • api/assistant-api/socket/socket.go
  • api/endpoint-api/api/endpoint.go
  • api/endpoint-api/api/invoker-endpoint.go
  • api/endpoint-api/config/config.go
  • api/endpoint-api/config/config_test.go
  • api/endpoint-api/internal/service/endpoint/service.go
  • api/endpoint-api/internal/service/log/service.go
  • api/endpoint-api/router/endpoint.go
  • api/endpoint-api/router/health-check.go
  • api/integration-api/api/audit_logging.go
  • api/integration-api/api/integration.go
  • api/integration-api/api/unified_provider.go
  • api/integration-api/config/config.go
  • api/integration-api/config/config_test.go
  • api/integration-api/internal/service/audit/service.go
  • api/integration-api/router/health-check.go
  • api/integration-api/router/provider.go
  • api/web-api/api/auth.go
  • api/web-api/api/connect.go
  • api/web-api/api/notification.go
  • api/web-api/api/organization.go
  • api/web-api/api/project.go
  • api/web-api/api/proxy/activity.go
  • api/web-api/api/proxy/assistant.go
  • api/web-api/api/proxy/assistant_deployment.go
  • api/web-api/api/proxy/document.go
  • api/web-api/api/proxy/endpoint.go
  • api/web-api/api/proxy/invoke.go
  • api/web-api/api/proxy/knowledge.go
  • api/web-api/api/vault.go
  • api/web-api/api/web.go
  • api/web-api/authenticator/authenticator.go
  • api/web-api/config/config.go
  • api/web-api/config/config_test.go
  • api/web-api/internal/connect/atlassian.go
  • api/web-api/internal/connect/external.go
  • api/web-api/internal/connect/github.go
  • api/web-api/internal/connect/gitlab.go
  • api/web-api/internal/connect/google.go
  • api/web-api/internal/connect/hubspot.go
  • api/web-api/internal/connect/linkedin.go
  • api/web-api/internal/connect/microsoft.go
  • api/web-api/internal/connect/notion.go
  • api/web-api/internal/connect/slack.go
  • api/web-api/internal/service/notification/service.go
  • api/web-api/internal/service/organization/service.go
  • api/web-api/internal/service/project/service.go
  • api/web-api/internal/service/user/service.go
  • api/web-api/internal/service/vault/service.go
  • api/web-api/router/health-check.go
  • api/web-api/router/web.go
  • cmd/assistant/assistant.go
  • cmd/endpoint/endpoint.go
  • cmd/integration/integration.go
  • cmd/web/web.go
  • pkg/authenticators/service_authenticator.go
  • pkg/configs/sql_config.go
  • pkg/configs/sql_config_test.go
  • pkg/configs/sqlite_config.go
  • pkg/connectors/postgres.go
  • pkg/connectors/postgres_test.go
  • pkg/connectors/sql.go
  • pkg/connectors/sqlite.go
  • pkg/connectors/sqlite_test.go

Comment on lines +119 to 121
if appConfig.PostgresConfig == nil || appConfig.PostgresConfig.DBName != "endpoint_db" {
t.Errorf("Expected PostgresConfig.DBName to be 'endpoint_db', but got %v", appConfig.PostgresConfig)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Nit: error message prints a pointer address, not struct contents.

appConfig.PostgresConfig is a *PostgresConfig; %v will render the pointer (e.g. 0xc0001…) rather than the struct fields, which defeats the purpose of the debug output. Dereference (guarded) or print DBName explicitly.

Proposed tweak
-	if appConfig.PostgresConfig == nil || appConfig.PostgresConfig.DBName != "endpoint_db" {
-		t.Errorf("Expected PostgresConfig.DBName to be 'endpoint_db', but got %v", appConfig.PostgresConfig)
-	}
+	if appConfig.PostgresConfig == nil {
+		t.Errorf("Expected PostgresConfig to be populated, got nil")
+	} else if appConfig.PostgresConfig.DBName != "endpoint_db" {
+		t.Errorf("Expected PostgresConfig.DBName to be 'endpoint_db', but got %q", appConfig.PostgresConfig.DBName)
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if appConfig.PostgresConfig == nil || appConfig.PostgresConfig.DBName != "endpoint_db" {
t.Errorf("Expected PostgresConfig.DBName to be 'endpoint_db', but got %v", appConfig.PostgresConfig)
}
if appConfig.PostgresConfig == nil {
t.Errorf("Expected PostgresConfig to be populated, got nil")
} else if appConfig.PostgresConfig.DBName != "endpoint_db" {
t.Errorf("Expected PostgresConfig.DBName to be 'endpoint_db', but got %q", appConfig.PostgresConfig.DBName)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api/integration-api/config/config_test.go` around lines 119 - 121, The test's
failure message prints the pointer address because it logs
appConfig.PostgresConfig with %v; change the error message to dereference and/or
print the actual DBName field (guarding for nil) so the output shows the value.
Specifically, in the failing assertion around appConfig.PostgresConfig and
PostgresConfig.DBName, update the t.Errorf to check nil first and then include
appConfig.PostgresConfig.DBName (or use fmt.Sprintf("%+v",
*appConfig.PostgresConfig) after nil-check) so the error shows the struct
contents or the DBName value rather than a pointer address.

Comment thread pkg/configs/sql_config.go
Comment on lines +38 to +48
func (c *PostgresConfig) MigrationDSN() string {
return fmt.Sprintf(
"postgres://%s:%s@%s:%d/%s?sslmode=%s",
c.Auth.User,
c.Auth.Password,
c.Host,
c.Port,
c.DBName,
c.SslMode,
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

URL-encode Postgres credentials in MigrationDSN.

The DSN is built via raw fmt.Sprintf, so any @, :, /, ?, #, or space in User/Password will produce a malformed URL and either fail to parse or connect to the wrong host/DB. Build via net/url instead.

🛡️ Proposed fix
-func (c *PostgresConfig) MigrationDSN() string {
-	return fmt.Sprintf(
-		"postgres://%s:%s@%s:%d/%s?sslmode=%s",
-		c.Auth.User,
-		c.Auth.Password,
-		c.Host,
-		c.Port,
-		c.DBName,
-		c.SslMode,
-	)
-}
+func (c *PostgresConfig) MigrationDSN() string {
+	u := url.URL{
+		Scheme: "postgres",
+		User:   url.UserPassword(c.Auth.User, c.Auth.Password),
+		Host:   fmt.Sprintf("%s:%d", c.Host, c.Port),
+		Path:   c.DBName,
+	}
+	q := url.Values{}
+	q.Set("sslmode", c.SslMode)
+	u.RawQuery = q.Encode()
+	return u.String()
+}

(also add "net/url" to imports)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/configs/sql_config.go` around lines 38 - 48, The MigrationDSN builds the
Postgres URL with fmt.Sprintf which doesn't escape special characters in
PostgresConfig.Auth.User and .Password; change MigrationDSN to construct the URL
using net/url (e.g., url.UserPassword or url.User and url.URL) so
username/password are percent-encoded and set Scheme="postgres", Host as
fmt.Sprintf("%s:%d", c.Host, c.Port), Path="/"+c.DBName, and RawQuery to include
sslmode=c.SslMode; update imports to include "net/url" and return url.String()
from MigrationDSN.

Comment thread pkg/configs/sql_config.go
Comment on lines +62 to +63
func (c *SQLiteConfig) MigrationDSN() string {
return "sqlite3://" + c.Path

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find where MigrationDSN is consumed and which migrate driver is imported.
rg -nP -C3 '\bMigrationDSN\s*\('
rg -nP -C2 'golang-migrate|migrate/database/sqlite3|migrate/source'

Repository: rapidaai/voice-ai

Length of output: 6262


🏁 Script executed:

# Look at the code around where MigrationDSN is used, specifically the migrate.New call
rg -A10 'dsn := sqlConfig.MigrationDSN\(\)' cmd/web/web.go | head -30

Repository: rapidaai/voice-ai

Length of output: 472


🏁 Script executed:

# Check if sqlite3 database driver is imported anywhere
rg 'database/sqlite3' --

Repository: rapidaai/voice-ai

Length of output: 43


🏁 Script executed:

# Look for test files in pkg/configs to understand the expected behavior
fd -e '*_test.go' pkg/configs

Repository: rapidaai/voice-ai

Length of output: 410


🏁 Script executed:

# Check go.mod to see what sqlite3-related packages might be there
rg 'sqlite|mattn' go.mod

Repository: rapidaai/voice-ai

Length of output: 239


🏁 Script executed:

# Find test files in pkg/configs directory properly
fd . pkg/configs -e _test.go

Repository: rapidaai/voice-ai

Length of output: 43


🏁 Script executed:

# Verify the exact import path needed for sqlite3 driver in golang-migrate/v4
rg 'database/sqlite' --

Repository: rapidaai/voice-ai

Length of output: 43


🏁 Script executed:

# Check if there are any mentions of SQLite in test files throughout the repo
rg -l 'SQLiteConfig|sqlite' --include='*_test.go'

Repository: rapidaai/voice-ai

Length of output: 502


🏁 Script executed:

# Look at the full context of how migrate.New is used in all cmd files
rg -B5 -A15 'migrate\.New' cmd/

Repository: rapidaai/voice-ai

Length of output: 4848


🏁 Script executed:

# Check if MigrationDSN is used elsewhere besides migration setup
rg 'MigrationDSN' -A2 -B2

Repository: rapidaai/voice-ai

Length of output: 1641


🏁 Script executed:

# Look at pkg/configs/sql_config.go to see the full file and interface
cat pkg/configs/sql_config.go

Repository: rapidaai/voice-ai

Length of output: 3220


🏁 Script executed:

# Check if there's a sql_config_test.go file
ls -la pkg/configs/*test* 2>/dev/null || echo "No test files found"

Repository: rapidaai/voice-ai

Length of output: 982


🏁 Script executed:

# Check the sql_config_test.go to see if SQLiteConfig is tested
cat pkg/configs/sql_config_test.go

Repository: rapidaai/voice-ai

Length of output: 3236


🏁 Script executed:

# Verify what the golang-migrate sqlite3 driver expects by checking the actual driver
# Search web for golang-migrate sqlite3 DSN format
web_search
golang-migrate v4 sqlite3 driver DSN format

Repository: rapidaai/voice-ai

Length of output: 164


🌐 Web query:

golang-migrate v4 sqlite3 database driver DSN format documentation

💡 Result:

The DSN format for the golang-migrate v4 sqlite3 database driver is sqlite3://path/to/database?query-parameters. Key details: - Scheme: sqlite3:// - Path: The database file path (e.g., /path/to/database.db or :memory: for in-memory). - Query parameters: - x-migrations-table: Name of the migrations table (defaults to schema_migrations). - x-no-tx-wrap: Set to true to disable implicit transaction wrapping (allows explicit BEGIN/COMMIT in migrations). - Additional query parameters supported by the underlying github.com/mattn/go-sqlite3 driver (e.g., _busy_timeout, _journal_mode) can be used, as they are passed through. - Example: sqlite3:///tmp/mydb.db?x-migrations-table=my_migrations&x-no-tx-wrap=true - The driver uses github.com/mattn/go-sqlite3 (requires CGO) and automatically wraps migrations in transactions by default (migrations should not contain explicit BEGIN/COMMIT unless x-no-tx-wrap=true). Official documentation is in the package README at pkg.go.dev/github.com/golang-migrate/migrate/v4/database/sqlite3 and source code confirms parsing logic: strips "sqlite3://" prefix, uses remaining as go-sqlite3 DSN after filtering custom params.

Citations:


🏁 Script executed:

# Check if there are test files that actually test MigrationDSN for SQLiteConfig
rg -A 5 'MigrationDSN|sqlite3://' pkg/configs/sql_config_test.go

Repository: rapidaai/voice-ai

Length of output: 43


🏁 Script executed:

# Look for any mentions of how migrations are tested with SQLite
rg -l 'MigrationDSN|migrate\.New' --type go | head -20

Repository: rapidaai/voice-ai

Length of output: 184


Add missing sqlite3 driver import and test coverage for MigrationDSN().

The DSN format sqlite3:// + path is correct for golang-migrate v4's sqlite3 driver. However, two issues need to be addressed:

  1. Missing driver import: The sqlite3 database driver is not imported in cmd/web/web.go, cmd/integration/integration.go, cmd/endpoint/endpoint.go, or cmd/assistant/assistant.go. Add _ "github.com/golang-migrate/migrate/v4/database/sqlite3" to each file so migrate.New() can access the driver at runtime.

  2. Missing test coverage: sql_config_test.go does not test the new MigrationDSN() method for SQLiteConfig (only tests DriverName()). Add test cases to verify MigrationDSN() returns the correct DSN format for both PostgresConfig and SQLiteConfig.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/configs/sql_config.go` around lines 62 - 63, Add the sqlite3 database
driver import and tests: import the side-effect driver `_
"github.com/golang-migrate/migrate/v4/database/sqlite3"` into each command
entrypoint that constructs migrations (files using migrate.New():
cmd/web/web.go, cmd/integration/integration.go, cmd/endpoint/endpoint.go,
cmd/assistant/assistant.go) so the sqlite3 driver is registered at runtime; and
update sql_config_test.go to add test cases asserting
SQLiteConfig.MigrationDSN() returns "sqlite3://"+Path and that
PostgresConfig.MigrationDSN() still returns the expected Postgres DSN format
(use the existing PostgresConfig and SQLiteConfig constructors/fields in the
tests to validate their MigrationDSN() outputs).

Comment thread pkg/configs/sql_config.go
Comment on lines +97 to +105
func SelectedSQLConfig(postgres *PostgresConfig, sqlite *SQLiteConfig) SQLConfig {
if postgres != nil && sqlite != nil {
panic("SelectedSQLConfig requires exactly one SQL config; both postgres and sqlite were provided")
}
if sqlite != nil {
return sqlite
}
return postgres
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

SelectedSQLConfig can return a typed-nil SQLConfig and panics instead of erroring.

Two issues:

  1. When both postgres and sqlite are nil, this returns (*PostgresConfig)(nil) wrapped in an SQLConfig interface — a non-nil interface with a nil concrete value. Any caller doing if cfg != nil { cfg.DriverName() } will NPE rather than take the nil-guard branch.
  2. panic(...) is unfriendly for a config-selection helper that ultimately runs at startup; returning an error is more consistent with ResolveSQLConfig's style.
🛡️ Proposed fix
-func SelectedSQLConfig(postgres *PostgresConfig, sqlite *SQLiteConfig) SQLConfig {
-	if postgres != nil && sqlite != nil {
-		panic("SelectedSQLConfig requires exactly one SQL config; both postgres and sqlite were provided")
-	}
-	if sqlite != nil {
-		return sqlite
-	}
-	return postgres
-}
+func SelectedSQLConfig(postgres *PostgresConfig, sqlite *SQLiteConfig) (SQLConfig, error) {
+	switch {
+	case postgres != nil && sqlite != nil:
+		return nil, ErrMultipleSQLConfigsDetected
+	case sqlite != nil:
+		return sqlite, nil
+	case postgres != nil:
+		return postgres, nil
+	default:
+		return nil, ErrNoSQLConfigConfigured
+	}
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/configs/sql_config.go` around lines 97 - 105, SelectedSQLConfig currently
can return a non-nil interface holding a typed nil and panics when both configs
are provided; change its signature to SelectedSQLConfig(postgres
*PostgresConfig, sqlite *SQLiteConfig) (SQLConfig, error) and return explicit
errors instead of panicking: if both postgres and sqlite are non-nil return
(nil, errors.New("requires exactly one SQL config; both provided")), if both are
nil return (nil, nil) or better (nil, errors.New("no SQL config provided")) to
avoid a typed-nil SQLConfig, and when exactly one is set return that concrete
config and nil error (ensure you return the concrete sqlite or postgres value
directly, not a nil pointer wrapped in the interface); follow ResolveSQLConfig's
error-returning pattern and import errors as needed.

Comment thread pkg/configs/sql_config.go
Comment on lines +107 to +125
func detectSQLPrefixes(v *viper.Viper) (bool, bool) {
return hasConfigPrefix(v, "POSTGRES"), hasConfigPrefix(v, "SQLITE")
}

func hasConfigPrefix(v *viper.Viper, prefix string) bool {
prefix = strings.ToUpper(prefix) + "__"
for _, key := range v.AllKeys() {
normalizedKey := strings.ToUpper(strings.ReplaceAll(key, ".", "__"))
if strings.HasPrefix(normalizedKey, prefix) {
return true
}
}
for _, env := range os.Environ() {
name, _, found := strings.Cut(env, "=")
if found && strings.HasPrefix(strings.ToUpper(name), prefix) {
return true
}
}
return false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Prefix detection can produce false positives from unrelated process env vars.

hasConfigPrefix scans os.Environ() for any variable starting with POSTGRES__ / SQLITE__, independent of whether Viper is actually bound to those keys or whether this process' Viper uses an env prefix (e.g. RAPIDA_). In containerized environments where both a parent-provided POSTGRES__HOST and a configured SQLITE__PATH can legitimately coexist (e.g., sidecars, shared compose files), this will spuriously trip ErrMultipleSQLConfigsDetected, and configuration issues surface only at boot.

Consider relying on Viper alone (v.AllKeys() + v.IsSet) or checking only the prefix(es) explicitly bound via v.BindEnv/v.SetEnvPrefix.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/configs/sql_config.go` around lines 107 - 125, The prefix detection
currently inspects os.Environ() causing false positives; update hasConfigPrefix
(and thus detectSQLPrefixes) to stop scanning process env and instead rely on
Viper-only data: iterate v.AllKeys() (normalize keys as already done) and return
true only when a normalized key starts with the target prefix AND
v.IsSet(originalKey) (or otherwise confirmed by Viper), so only configuration
known to this Viper instance triggers detection; remove the os.Environ() loop
and any reliance on global environment variables in hasConfigPrefix.

Comment thread pkg/connectors/sql.go
Comment on lines +13 to +22
func NewSQLConnector(config configs.SQLConfig, logger commons.Logger) SQLConnector {
switch cfg := config.(type) {
case *configs.PostgresConfig:
return NewPostgresConnector(cfg, logger)
case *configs.SQLiteConfig:
return NewSQLiteConnector(cfg, logger)
default:
return nil
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Silent nil return will cause downstream nil-pointer panics.

When config is neither *PostgresConfig nor *SQLiteConfig (e.g. misconfiguration, or a value type accidentally passed instead of a pointer), NewSQLConnector returns nil with no error or log. Every caller in cmd/*/ passes the result straight into routers/services, so the first call to postgres.DB(ctx) / Connect(ctx) will panic at runtime with no actionable signal.

At minimum, log fatal/error on the default case; better, return (SQLConnector, error) so the startup path fails fast.

🔒 Suggested fix
-func NewSQLConnector(config configs.SQLConfig, logger commons.Logger) SQLConnector {
-	switch cfg := config.(type) {
-	case *configs.PostgresConfig:
-		return NewPostgresConnector(cfg, logger)
-	case *configs.SQLiteConfig:
-		return NewSQLiteConnector(cfg, logger)
-	default:
-		return nil
-	}
-}
+func NewSQLConnector(config configs.SQLConfig, logger commons.Logger) SQLConnector {
+	switch cfg := config.(type) {
+	case *configs.PostgresConfig:
+		return NewPostgresConnector(cfg, logger)
+	case *configs.SQLiteConfig:
+		return NewSQLiteConnector(cfg, logger)
+	default:
+		logger.Fatalf("unsupported SQL config type %T; expected *PostgresConfig or *SQLiteConfig", config)
+		return nil
+	}
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func NewSQLConnector(config configs.SQLConfig, logger commons.Logger) SQLConnector {
switch cfg := config.(type) {
case *configs.PostgresConfig:
return NewPostgresConnector(cfg, logger)
case *configs.SQLiteConfig:
return NewSQLiteConnector(cfg, logger)
default:
return nil
}
}
func NewSQLConnector(config configs.SQLConfig, logger commons.Logger) SQLConnector {
switch cfg := config.(type) {
case *configs.PostgresConfig:
return NewPostgresConnector(cfg, logger)
case *configs.SQLiteConfig:
return NewSQLiteConnector(cfg, logger)
default:
logger.Fatalf("unsupported SQL config type %T; expected *PostgresConfig or *SQLiteConfig", config)
return nil
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/connectors/sql.go` around lines 13 - 22, The NewSQLConnector function
currently returns nil on unknown config types which leads to silent nil-pointer
panics; change its signature to return (SQLConnector, error) (or at minimum
log.Fatal/error in the default branch) and update callers to handle the error.
Inside NewSQLConnector, switch on config types as before (case
*configs.PostgresConfig -> NewPostgresConnector, case *configs.SQLiteConfig ->
NewSQLiteConnector) but on the default path return a descriptive error (e.g.,
fmt.Errorf("unsupported SQL config type: %T", config)) instead of nil; ensure
all call sites that call NewSQLConnector are updated to check the returned error
and stop startup on failure.

Comment on lines +16 to +60
func TestSQLiteConnector_Lifecycle(t *testing.T) {
logger, _ := commons.NewApplicationLogger()
path := filepath.Join(t.TempDir(), "data", "rapida.db")
connector := NewSQLiteConnector(&configs.SQLiteConfig{
Path: path,
MaxIdealConnection: 1,
MaxOpenConnection: 1,
}, logger)

ctx := context.Background()
require.NoError(t, connector.Connect(ctx))
assert.True(t, connector.IsConnected(ctx))
assert.Equal(t, "SQLITE sqlite3://"+path, connector.Name())

db := connector.DB(ctx)
require.NoError(t, db.Exec("CREATE TABLE test_items (name TEXT NOT NULL)").Error)
require.NoError(t, db.Exec("INSERT INTO test_items(name) VALUES (?)", "sqlite").Error)

var rows []struct {
Name string
}
require.NoError(t, connector.Query(ctx, "SELECT name FROM test_items", &rows))
require.Len(t, rows, 1)
assert.Equal(t, "sqlite", rows[0].Name)
assert.FileExists(t, path)

require.NoError(t, connector.Disconnect(ctx))
assert.False(t, connector.IsConnected(ctx))
}

func TestNewSQLConnector_SQLite(t *testing.T) {
logger, _ := commons.NewApplicationLogger()
connector := NewSQLConnector(&configs.SQLiteConfig{
Path: filepath.Join(t.TempDir(), "rapida.db"),
MaxIdealConnection: 1,
MaxOpenConnection: 1,
}, logger)
require.NotNil(t, connector)
}

func TestEnsureSQLiteParentDir(t *testing.T) {
path := filepath.Join(t.TempDir(), "nested", "sqlite.db")
require.NoError(t, ensureSQLiteParentDir(path))
_, err := os.Stat(filepath.Dir(path))
require.NoError(t, err)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add an error/fallback path to round out coverage.

Per coding guidelines, backend tests should include at least a success path, fallback/error path, and factory/selection behavior assertion. Current coverage is success-only:

  • No negative test for NewSQLiteConnector (e.g. Path: "" or a path under a non-writable directory) to assert Connect returns an error.
  • No assertion that Disconnect is idempotent (calling twice, or calling when not connected).
  • TestNewSQLConnector_SQLite only asserts non-nil; consider exercising Connect+Name() to prove the factory actually dispatched to the SQLite implementation (selection behavior).

As per coding guidelines: "Include at least a success path, fallback/error path, and factory/selection behavior assertion in backend tests".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/connectors/sqlite_test.go` around lines 16 - 60, Add missing negative and
idempotency coverage: add a test that constructs NewSQLiteConnector (or via
NewSQLConnector) with an invalid config (e.g., Path: "" or a non-writable path)
and assert that connector.Connect(ctx) returns an error; add an assertion that
Disconnect is idempotent by calling connector.Disconnect(ctx) twice (or calling
Disconnect on a never-connected connector) and ensuring no panic and appropriate
error/no-op behavior; and extend TestNewSQLConnector_SQLite to call
connector.Connect(ctx) and assert connector.Name() (e.g., equals "SQLITE
sqlite3://...") to verify factory selection dispatched the SQLite
implementation. Reference NewSQLiteConnector, NewSQLConnector, Connect,
Disconnect, Name, and ensureSQLiteParentDir when adding these checks.

Comment thread pkg/connectors/sqlite.go
Comment on lines +33 to +35
func (sqlt *sqliteConnector) DB(ctx context.Context) *gorm.DB {
return sqlt.db.WithContext(ctx)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

DB(ctx) will panic if called before Connect (or after Disconnect).

sqlt.db is nil until Connect succeeds, and Disconnect explicitly sets it back to nil. Calling sqlt.db.WithContext(ctx) in that state dereferences nil. A nil guard (returning a *gorm.DB with an Error set, or a sentinel) would be safer and matches how callers treat the returned handle's .Error.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/connectors/sqlite.go` around lines 33 - 35, The DB(ctx) method on
sqliteConnector may dereference nil when sqlt.db is unset; add a nil guard in
sqliteConnector.DB that checks if sqlt.db == nil and, if so, returns a *gorm.DB
whose Error field is set to a descriptive error (e.g., using errors.New("sqlite
connector not connected")) instead of calling WithContext; otherwise return
sqlt.db.WithContext(ctx). Reference the sqliteConnector.DB method and set the
Error on the returned *gorm.DB so callers can check .Error safely.

Comment thread pkg/connectors/sqlite.go
Comment on lines +89 to +102
func (sqlt *sqliteConnector) Disconnect(ctx context.Context) error {
sqlt.logger.Debug("Disconnecting sqlite client.")
db, err := sqlt.db.DB()
sqlt.db = nil
if err != nil {
sqlt.logger.Errorf("Disconnecting sqlite client %s.", err)
return err
}
if err := db.Close(); err != nil {
sqlt.logger.Debug("Disconnecting sqlite client %s.", err)
return err
}
return nil
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Disconnect will panic if called without a prior successful Connect.

If sqlt.db is nil (e.g., Connect failed or was never called), sqlt.db.DB() on line 91 dereferences a nil *gorm.DB and panics. Add a nil-guard at the top:

🛡️ Proposed fix
 func (sqlt *sqliteConnector) Disconnect(ctx context.Context) error {
 	sqlt.logger.Debug("Disconnecting sqlite client.")
+	if sqlt.db == nil {
+		return nil
+	}
 	db, err := sqlt.db.DB()
 	sqlt.db = nil

Also note: the error-log message on line 98 reads "Disconnecting sqlite client %s." — it should describe the failure (e.g., "Failed to close sqlite client").

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (sqlt *sqliteConnector) Disconnect(ctx context.Context) error {
sqlt.logger.Debug("Disconnecting sqlite client.")
db, err := sqlt.db.DB()
sqlt.db = nil
if err != nil {
sqlt.logger.Errorf("Disconnecting sqlite client %s.", err)
return err
}
if err := db.Close(); err != nil {
sqlt.logger.Debug("Disconnecting sqlite client %s.", err)
return err
}
return nil
}
func (sqlt *sqliteConnector) Disconnect(ctx context.Context) error {
sqlt.logger.Debug("Disconnecting sqlite client.")
if sqlt.db == nil {
return nil
}
db, err := sqlt.db.DB()
sqlt.db = nil
if err != nil {
sqlt.logger.Errorf("Disconnecting sqlite client %s.", err)
return err
}
if err := db.Close(); err != nil {
sqlt.logger.Debug("Disconnecting sqlite client %s.", err)
return err
}
return nil
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/connectors/sqlite.go` around lines 89 - 102, Disconnect currently
dereferences sqlt.db without checking for nil and will panic if Connect never
succeeded; update sqliteConnector.Disconnect to first check if sqlt.db == nil
and return nil (or a clear error) before calling sqlt.db.DB(), and only then
call db.Close(); also fix the logger messages in Disconnect (replace ambiguous
"Disconnecting sqlite client %s." with clearer text like "Failed to get
underlying DB: %v" for the DB() error and "Failed to close sqlite client: %v"
for Close() error) so the logged messages accurately describe the failures.

Comment thread README.md
Comment on lines +189 to +190
SQLITE__MAX_OPEN_CONNECTION=1
SQLITE__MAX_IDEAL_CONNECTION=1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Typo: MAX_IDEAL_CONNECTION should be MAX_IDLE_CONNECTION.

"Ideal" is almost certainly meant to be "Idle" (as in sql.DB.SetMaxIdleConns). The same typo appears in pkg/configs/sqlite_config.go (MaxIdealConnection / mapstructure:"max_ideal_connection"), so fixing it requires a coordinated rename across the struct field, mapstructure tag, README, and any example env files. Shipping the typo will bake it into the public env-var contract.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 189 - 190, The README and config struct use a typo
"Ideal" instead of "Idle": rename the struct field MaxIdealConnection to
MaxIdleConnection and update its mapstructure tag from "max_ideal_connection" to
"max_idle_connection", then update all references/usages and example env vars
(change SQLITE__MAX_IDEAL_CONNECTION to SQLITE__MAX_IDLE_CONNECTION) to keep the
env-var contract consistent; ensure any code that reads the old tag/name
(parsing/config loading, tests, docs) is updated to use the new symbol and tag
so the change is applied project-wide.

@hetsaraiya

hetsaraiya commented Apr 17, 2026

Copy link
Copy Markdown
Author

@iamprashant, What do you should i do? think should i follow all the comments from coderabbit? i think some of them are pointless.

@iamprashant

Copy link
Copy Markdown
Member

Thank @hetsaraiya for creating PR. Will take a look at it in while.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class SQLite support across the Go services by introducing a shared SQL configuration/connector abstraction, allowing deployments to run on either Postgres or SQLite (but not both) and skipping bundled migrations when SQLite is selected (since migrations are currently Postgres-specific).

Changes:

  • Added SQLiteConfig, SQLConfig selection helpers, and a new sqlite GORM connector.
  • Updated service bootstrap/config to select exactly one SQL backend (Postgres or SQLite) and wire it through a unified SQLConnector.
  • Updated docs and tests to cover SQLite configuration and multi-SQL rejection behavior.

Reviewed changes

Copilot reviewed 91 out of 91 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
pkg/connectors/sqlite_test.go Adds lifecycle and helper tests for the new SQLite connector.
pkg/connectors/sqlite.go Implements SQLite GORM connector and connection setup helpers.
pkg/connectors/sql.go Adds NewSQLConnector factory to create Postgres/SQLite connectors from a SQLConfig.
pkg/connectors/postgres_test.go Renames tests to reflect SQLConnector naming.
pkg/connectors/postgres.go Renames exported connector interface to SQLConnector and updates constructor return type.
pkg/configs/sqlite_config.go Adds SQLite configuration struct for viper/mapstructure/validation.
pkg/configs/sql_config_test.go Adds tests for SQL config detection/selection and multi-config rejection.
pkg/configs/sql_config.go Adds SQL backend detection/selection logic + DSN/display helpers for migration wiring.
pkg/authenticators/service_authenticator.go Updates constructor signature to accept connectors.SQLConnector.
cmd/web/web.go Wires SQL connector selection and skips migrations when SQLite is selected.
cmd/integration/integration.go Wires SQL connector selection and skips migrations when SQLite is selected.
cmd/endpoint/endpoint.go Wires SQL connector selection and skips migrations when SQLite is selected.
cmd/assistant/assistant.go Wires SQL connector selection and skips migrations when SQLite is selected.
api/web-api/router/web.go Updates router signatures to accept connectors.SQLConnector.
api/web-api/router/health-check.go Updates health-check route wiring to accept connectors.SQLConnector.
api/web-api/internal/service/vault/service.go Updates service constructor/deps to accept connectors.SQLConnector.
api/web-api/internal/service/user/service.go Updates service constructor/deps to accept connectors.SQLConnector.
api/web-api/internal/service/project/service.go Updates service constructor/deps to accept connectors.SQLConnector.
api/web-api/internal/service/organization/service.go Updates service constructor/deps to accept connectors.SQLConnector.
api/web-api/internal/service/notification/service.go Updates service constructor/deps to accept connectors.SQLConnector.
api/web-api/internal/connect/slack.go Updates connect wiring to accept connectors.SQLConnector.
api/web-api/internal/connect/notion.go Updates connect wiring to accept connectors.SQLConnector.
api/web-api/internal/connect/microsoft.go Updates connect wiring to accept connectors.SQLConnector.
api/web-api/internal/connect/linkedin.go Updates connect wiring to accept connectors.SQLConnector.
api/web-api/internal/connect/hubspot.go Updates connect wiring to accept connectors.SQLConnector.
api/web-api/internal/connect/google.go Updates connect wiring to accept connectors.SQLConnector.
api/web-api/internal/connect/gitlab.go Updates connect wiring to accept connectors.SQLConnector.
api/web-api/internal/connect/github.go Updates connect wiring to accept connectors.SQLConnector.
api/web-api/internal/connect/external.go Updates shared external connect wiring to accept connectors.SQLConnector.
api/web-api/internal/connect/atlassian.go Updates connect wiring to accept connectors.SQLConnector.
api/web-api/config/config_test.go Adds SQLite + multi-SQL config validation tests for web-api config.
api/web-api/config/config.go Updates config struct to support Postgres/SQLite pointers + SQL selection helper.
api/web-api/authenticator/authenticator.go Updates authenticators wiring to accept connectors.SQLConnector.
api/web-api/api/web.go Updates API wiring to accept connectors.SQLConnector.
api/web-api/api/vault.go Updates vault API wiring to accept connectors.SQLConnector.
api/web-api/api/proxy/knowledge.go Updates proxy API wiring to accept connectors.SQLConnector.
api/web-api/api/proxy/invoke.go Updates proxy API wiring to accept connectors.SQLConnector.
api/web-api/api/proxy/endpoint.go Updates proxy API wiring to accept connectors.SQLConnector.
api/web-api/api/proxy/document.go Updates proxy API wiring to accept connectors.SQLConnector.
api/web-api/api/proxy/assistant_deployment.go Updates proxy API wiring to accept connectors.SQLConnector.
api/web-api/api/proxy/assistant.go Updates proxy API wiring to accept connectors.SQLConnector.
api/web-api/api/proxy/activity.go Updates proxy API wiring to accept connectors.SQLConnector.
api/web-api/api/project.go Updates project API wiring to accept connectors.SQLConnector.
api/web-api/api/organization.go Updates organization API wiring to accept connectors.SQLConnector.
api/web-api/api/notification.go Updates notification API wiring to accept connectors.SQLConnector.
api/web-api/api/connect.go Updates connect API wiring to accept connectors.SQLConnector.
api/web-api/api/auth.go Updates auth API wiring to accept connectors.SQLConnector.
api/integration-api/router/provider.go Updates router wiring to accept connectors.SQLConnector.
api/integration-api/router/health-check.go Updates health-check route wiring to accept connectors.SQLConnector.
api/integration-api/internal/service/audit/service.go Updates audit service deps to accept connectors.SQLConnector.
api/integration-api/config/config_test.go Adds SQLite + multi-SQL config validation tests for integration-api config.
api/integration-api/config/config.go Updates config struct to support Postgres/SQLite pointers + SQL selection helper.
api/integration-api/api/unified_provider.go Updates API wiring to accept connectors.SQLConnector.
api/integration-api/api/integration.go Updates API wiring to accept connectors.SQLConnector.
api/integration-api/api/audit_logging.go Updates API wiring to accept connectors.SQLConnector.
api/endpoint-api/router/health-check.go Updates health-check route wiring to accept connectors.SQLConnector.
api/endpoint-api/router/endpoint.go Updates router wiring to accept connectors.SQLConnector.
api/endpoint-api/internal/service/log/service.go Updates log service deps to accept connectors.SQLConnector.
api/endpoint-api/internal/service/endpoint/service.go Updates endpoint service deps to accept connectors.SQLConnector.
api/endpoint-api/config/config_test.go Adds SQLite + multi-SQL config validation tests for endpoint-api config.
api/endpoint-api/config/config.go Updates config struct to support Postgres/SQLite pointers + SQL selection helper.
api/endpoint-api/api/invoker-endpoint.go Updates invoker API wiring to accept connectors.SQLConnector.
api/endpoint-api/api/endpoint.go Updates endpoint API wiring to accept connectors.SQLConnector.
api/assistant-api/socket/socket.go Updates socket engine wiring to accept connectors.SQLConnector.
api/assistant-api/socket/pipeline.go Updates pipeline wiring to accept connectors.SQLConnector.
api/assistant-api/sip/sip.go Updates SIP engine wiring to accept connectors.SQLConnector.
api/assistant-api/router/knowledge.go Updates router wiring to accept connectors.SQLConnector.
api/assistant-api/router/health-check.go Updates health-check route wiring to accept connectors.SQLConnector.
api/assistant-api/router/assistant.go Updates router wiring to accept connectors.SQLConnector.
api/assistant-api/internal/services/knowledge/knowledge.impl.service.go Updates service deps to accept connectors.SQLConnector.
api/assistant-api/internal/services/knowledge/document.impl.service.go Updates service deps to accept connectors.SQLConnector.
api/assistant-api/internal/services/assistant/webhook.impl.service.go Updates service deps to accept connectors.SQLConnector.
api/assistant-api/internal/services/assistant/tool.impl.service.go Updates service deps to accept connectors.SQLConnector.
api/assistant-api/internal/services/assistant/telemetry.impl.service.go Updates service deps to accept connectors.SQLConnector.
api/assistant-api/internal/services/assistant/knowledge.impl.service.go Updates service deps to accept connectors.SQLConnector.
api/assistant-api/internal/services/assistant/conversaction.impl.service.go Updates service deps to accept connectors.SQLConnector.
api/assistant-api/internal/services/assistant/assistant.impl.service.go Updates service deps to accept connectors.SQLConnector.
api/assistant-api/internal/services/assistant/assistant.deployment.impl.service.go Updates service deps to accept connectors.SQLConnector.
api/assistant-api/internal/services/assistant/analysis.impl.service.go Updates service deps to accept connectors.SQLConnector.
api/assistant-api/internal/callcontext/store.go Updates store deps to accept connectors.SQLConnector.
api/assistant-api/internal/adapters/request_test.go Updates test documentation/signature expectations to connectors.SQLConnector.
api/assistant-api/internal/adapters/request.go Updates adapter wiring to accept connectors.SQLConnector.
api/assistant-api/internal/adapters/internal/requestor.go Updates requestor deps to accept connectors.SQLConnector.
api/assistant-api/config/config_test.go Adds SQLite + multi-SQL config validation tests for assistant-api config.
api/assistant-api/config/config.go Updates config struct to support Postgres/SQLite pointers + SQL selection helper.
api/assistant-api/api/talk/talk.go Updates conversation/talk API wiring to accept connectors.SQLConnector.
api/assistant-api/api/knowledge/knowledge.go Updates knowledge API wiring to accept connectors.SQLConnector.
api/assistant-api/api/knowledge/indexer.go Updates indexer API wiring to accept connectors.SQLConnector.
api/assistant-api/api/assistant/assistant.go Updates assistant API wiring to accept connectors.SQLConnector.
api/assistant-api/api/assistant-deployment/assistant_deployment.go Updates deployment API wiring to accept connectors.SQLConnector.
README.md Documents minimal SQLite setup and migration caveat.

Comment thread pkg/connectors/sqlite.go
Comment on lines +89 to +93
func (sqlt *sqliteConnector) Disconnect(ctx context.Context) error {
sqlt.logger.Debug("Disconnecting sqlite client.")
db, err := sqlt.db.DB()
sqlt.db = nil
if err != nil {

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disconnect() assumes sqlt.db is non-nil and calls sqlt.db.DB() unconditionally. If Disconnect() is called before Connect() succeeds, or called twice during shutdown, this will panic. Add a nil guard (and consider making Disconnect idempotent) before dereferencing sqlt.db.

Copilot uses AI. Check for mistakes.
Comment thread pkg/connectors/sqlite.go
Comment on lines +97 to +99
if err := db.Close(); err != nil {
sqlt.logger.Debug("Disconnecting sqlite client %s.", err)
return err

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On db.Close() error, this logs via logger.Debug with a printf-style format string, so the %s placeholder will not be expanded. Use the formatted logging method (e.g., Debugf/Errorf) and log close failures at an error level so they are visible in production.

Copilot uses AI. Check for mistakes.
Comment thread pkg/connectors/sql.go
Comment on lines +13 to +21
func NewSQLConnector(config configs.SQLConfig, logger commons.Logger) SQLConnector {
switch cfg := config.(type) {
case *configs.PostgresConfig:
return NewPostgresConnector(cfg, logger)
case *configs.SQLiteConfig:
return NewSQLiteConnector(cfg, logger)
default:
return nil
}

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NewSQLConnector returns nil for unknown SQLConfig implementations. That makes misconfiguration or future extension failures show up later as nil-pointer panics (e.g., when calling Connect/DB). Prefer failing fast (panic with a clear message) or changing the API to return (SQLConnector, error).

Copilot uses AI. Check for mistakes.
Comment thread pkg/configs/sql_config.go
Comment on lines +97 to +105
func SelectedSQLConfig(postgres *PostgresConfig, sqlite *SQLiteConfig) SQLConfig {
if postgres != nil && sqlite != nil {
panic("SelectedSQLConfig requires exactly one SQL config; both postgres and sqlite were provided")
}
if sqlite != nil {
return sqlite
}
return postgres
}

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SelectedSQLConfig panics when both configs are non-nil. Since this helper is exposed and used by service configs, a panic here will crash the process (and bypass normal config validation) if a caller constructs the config struct incorrectly. Prefer returning (SQLConfig, error) or reusing ResolveSQLConfig to produce a validated selection without panicking.

Copilot uses AI. Check for mistakes.
Comment thread pkg/configs/sql_config.go
Comment on lines +111 to +125
func hasConfigPrefix(v *viper.Viper, prefix string) bool {
prefix = strings.ToUpper(prefix) + "__"
for _, key := range v.AllKeys() {
normalizedKey := strings.ToUpper(strings.ReplaceAll(key, ".", "__"))
if strings.HasPrefix(normalizedKey, prefix) {
return true
}
}
for _, env := range os.Environ() {
name, _, found := strings.Cut(env, "=")
if found && strings.HasPrefix(strings.ToUpper(name), prefix) {
return true
}
}
return false

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ResolveSQLConfig/hasConfigPrefix inspects the full process environment (os.Environ) in addition to the provided viper instance. This can make behavior and unit tests non-deterministic (e.g., unrelated POSTGRES__/SQLITE__ vars in the environment can trigger ErrMultipleSQLConfigsDetected). Consider relying on viper’s env binding (AutomaticEnv + key replacer) and only checking viper keys, or make environment inspection injectable/opt-in for tests.

Copilot uses AI. Check for mistakes.
Comment on lines +130 to +142
func TestGetApplicationConfig_SQLite(t *testing.T) {
vConfig := viper.NewWithOptions(viper.KeyDelimiter("__"))
vConfig.Set("SERVICE_NAME", "endpoint-api")
vConfig.Set("HOST", "0.0.0.0")
vConfig.Set("PORT", 9005)
vConfig.Set("LOG_LEVEL", "debug")
vConfig.Set("SECRET", "rpd_pks")
vConfig.Set("ENV", "development")

vConfig.Set("SQLITE__PATH", filepath.Join(t.TempDir(), "integration.db"))
vConfig.Set("SQLITE__MAX_OPEN_CONNECTION", 1)
vConfig.Set("SQLITE__MAX_IDEAL_CONNECTION", 1)

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These new integration-api config tests set SERVICE_NAME to "endpoint-api" and use endpoint-oriented paths/names (e.g., assets/endpoint, integration.db). This looks like copy/paste from endpoint-api and makes the integration-api config tests misleading. Align SERVICE_NAME and path prefixes with integration-api to reflect the intended configuration.

Copilot uses AI. Check for mistakes.
Comment thread pkg/connectors/sqlite.go
Comment on lines +33 to +35
func (sqlt *sqliteConnector) DB(ctx context.Context) *gorm.DB {
return sqlt.db.WithContext(ctx)
}

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sqliteConnector.DB() calls sqlt.db.WithContext(ctx) without checking whether sqlt.db is nil. If DB() is called before Connect() or after Disconnect(), this will panic. Consider returning nil (and documenting it) or guarding with an explicit panic/message so failures are clearer and safer in shutdown/health-check paths.

Copilot uses AI. Check for mistakes.
Comment thread pkg/connectors/sqlite.go
Comment on lines +60 to +63
if err := db.Exec("PRAGMA foreign_keys = ON").Error; err != nil {
sqlt.logger.Errorf("Failed to enable sqlite foreign keys %s.", err)
return err
}

Copilot AI Apr 17, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SQLite foreign key enforcement is connection-specific. Executing PRAGMA foreign_keys = ON once may only affect the current connection, and pooled connections can still run with foreign keys disabled when MaxOpenConnection > 1. Prefer enabling it via the SQLite DSN options (e.g., _foreign_keys=1) or by ensuring the PRAGMA is applied for every new connection.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Enable SQLite for simpler deployment

4 participants