Skip to content

Support alternative data stores with SQLite implementation#73

Merged
teekay merged 10 commits into
masterfrom
add-alternative-datastore
Feb 1, 2026
Merged

Support alternative data stores with SQLite implementation#73
teekay merged 10 commits into
masterfrom
add-alternative-datastore

Conversation

@teekay
Copy link
Copy Markdown
Owner

@teekay teekay commented Jan 30, 2026

This implements a repository pattern to abstract database-specific operations and adds SQLite as an alternative to PostgreSQL for lower-cost deployments.

Key changes:

  • Add PasswordService with bcrypt for application-layer password hashing
  • Create repository interfaces for Account, Token, Auth, and Comment
  • Implement PostgreSQL repositories wrapping existing pgtyped queries
  • Implement SQLite repositories using better-sqlite3
  • Add DatabaseModule with factory pattern for selecting database provider
  • Add in-memory queue for SQLite mode (pg-boss requires PostgreSQL)
  • Update services to use repository interfaces instead of direct DB access
  • Support automatic migration of legacy SHA256 passwords to bcrypt on login
  • Add session store factory supporting both PostgreSQL and SQLite

Configuration:

  • DB_PROVIDER=sqlite|postgres (default: postgres)
  • SQLITE_PATH=./data/jcomments.db (default path)
  • QUEUE_PROVIDER=pgboss|memory (auto-detected from DB_PROVIDER)

teekay and others added 6 commits January 30, 2026 11:24
This implements a repository pattern to abstract database-specific operations
and adds SQLite as an alternative to PostgreSQL for lower-cost deployments.

Key changes:
- Add PasswordService with bcrypt for application-layer password hashing
- Create repository interfaces for Account, Token, Auth, and Comment
- Implement PostgreSQL repositories wrapping existing pgtyped queries
- Implement SQLite repositories using better-sqlite3
- Add DatabaseModule with factory pattern for selecting database provider
- Add in-memory queue for SQLite mode (pg-boss requires PostgreSQL)
- Update services to use repository interfaces instead of direct DB access
- Support automatic migration of legacy SHA256 passwords to bcrypt on login
- Add session store factory supporting both PostgreSQL and SQLite

Configuration:
- DB_PROVIDER=sqlite|postgres (default: postgres)
- SQLITE_PATH=./data/jcomments.db (default path)
- QUEUE_PROVIDER=pgboss|memory (auto-detected from DB_PROVIDER)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a repository pattern to abstract database operations and adds SQLite as an alternative to PostgreSQL for lower-cost deployments. The key architectural change is moving from direct database access to repository interfaces, enabling support for multiple database backends.

Changes:

  • Introduces bcrypt-based password hashing to replace legacy SHA256, with automatic migration on user login
  • Implements repository pattern with interfaces for Account, Token, Auth, and Comment operations
  • Adds SQLite support with better-sqlite3 and in-memory queue for single-process deployments
  • Provides database and queue provider factories with environment-based selection
  • Updates all services to use repository interfaces instead of direct database queries

Reviewed changes

Copilot reviewed 56 out of 57 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
package.json Adds bcrypt, better-sqlite3, and better-sqlite3-session-store dependencies
src/shared/crypto/password.service.ts New service for bcrypt password hashing with legacy SHA256 verification support
src/shared/crypto/password.service.spec.ts Comprehensive test coverage for password service
src/shared/repositories/*.ts Repository interface definitions for Account, Token, Auth, and Comment
src/shared/repositories/postgres/*.ts PostgreSQL repository implementations wrapping pgtyped queries
src/shared/repositories/sqlite/*.ts SQLite repository implementations using better-sqlite3
src/shared/database/database.module.ts Factory module for selecting and configuring database providers
src/shared/database/session-store.factory.ts Factory for creating session stores based on database provider
src/shared/queue/queue.module.ts Factory module for selecting queue providers (pgboss or memory)
src/shared/queue/memory/*.ts In-memory queue implementation for SQLite mode
src/shared/accounts/account.service.ts Updated to use repository interfaces with password migration logic
src/shared/auth/auth.service.ts Updated to use repository interfaces and PasswordService
src/shared/comments/comment.service.ts Updated to use CommentRepository interface
src/console/console.service.ts Added SQLite migration support and bootstrap command
scripts/migrate-pg-to-sqlite.ts Migration script to export PostgreSQL data to SQLite
sql/sqlite/schema.sql SQLite schema definition equivalent to PostgreSQL migrations
docker-compose.yml Updated environment variable names for PostgreSQL
Dockerfile Updated to Node.js 22 (from 20-alpine)
.env.example Added configuration options for database and queue providers

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/shared/database/session-store.factory.ts
Comment thread src/shared/repositories/sqlite/sqlite-comment.repository.ts
Comment thread src/shared/repositories/sqlite/sqlite-comment.repository.ts
Comment thread src/shared/repositories/sqlite/sqlite-account.repository.ts
Comment thread package.json Outdated
Comment thread scripts/migrate-pg-to-sqlite.ts
Comment on lines +24 to +29
async send(queueName: string, data: unknown): Promise<string | null> {
const handler = this.handlers.get(queueName)
if (handler) {
// Process immediately
await handler({ data })
}
Copy link

Copilot AI Feb 1, 2026

Choose a reason for hiding this comment

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

Missing error handling: If the handler throws an error during execution, it will propagate to the caller. This differs from pg-boss behavior which would typically handle errors within the job queue system. Consider wrapping the handler call in a try-catch block and logging errors appropriately.

Copilot uses AI. Check for mistakes.

@Module({
imports: [forwardRef(() => CommentsModule), AccountsModuleCore, PgBossQueueModule],
imports: [forwardRef(() => CommentsModule), AccountsModuleCore, QueueModule.forRoot()],
Copy link

Copilot AI Feb 1, 2026

Choose a reason for hiding this comment

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

Redundant QueueModule.forRoot() import: The QueueModule is already imported globally at the root WebModule level (line 23 in web.module.ts). This redundant import in the AccountsModule could lead to multiple instances of the queue being created. Since QueueModule is marked as @global(), it should be automatically available to all modules without re-importing.

Copilot uses AI. Check for mistakes.
Comment thread Dockerfile
# Stage 1: Build the application
# Use a Node.js image
FROM node:20-alpine as builder
FROM node:22 as builder
Copy link

Copilot AI Feb 1, 2026

Choose a reason for hiding this comment

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

Breaking change in Node.js version: The Dockerfile changes from node:20-alpine to node:22, which is a major version upgrade. This could introduce compatibility issues with existing deployments and dependencies. Consider documenting this change in the PR description and ensuring all dependencies are compatible with Node.js 22.

Copilot uses AI. Check for mistakes.
Comment thread src/shared/accounts/account.service.ts
@teekay teekay marked this pull request as ready for review February 1, 2026 12:57
@teekay teekay merged commit 469ffd6 into master Feb 1, 2026
6 checks passed
@teekay teekay deleted the add-alternative-datastore branch February 1, 2026 12:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants