This document outlines the changes made to remove TypeORM and rewrite the API with pure SQL queries.
- Removed:
@nestjs/typeormandtypeorm - Kept:
pg(Node.js PostgreSQL client)
-
Created:
src/database/database.service.ts- Manages PostgreSQL connection pool
- Provides query execution methods
- Handles transactions
- Automatically initializes database schema on module load
-
Created:
src/database/database.module.ts- Exports DatabaseService for dependency injection
- Updated:
src/app.module.ts- Removed
TypeOrmModule.forRoot() - Added
DatabaseModuleimport - Configuration is now handled by DatabaseService
- Removed
- Updated:
src/users/users.service.ts- Removed
@InjectRepositorydecorator - Injected
DatabaseServiceinstead - Replaced TypeORM methods with raw SQL queries:
create(): INSERT query with UUID generationfindByEmail(): SELECT query with email parameterfindById(): SELECT query with ID parameter
- Added
Userinterface definition - Added
mapRowToUser()helper method for type mapping
- Removed
- Updated:
src/users/entities/user.entity.ts- Removed all TypeORM decorators (
@Entity,@Column,@PrimaryGeneratedColumn, etc.) - Kept only GraphQL decorators (
@ObjectType,@Field) - Removed password field from GraphQL type (security best practice)
- Removed all TypeORM decorators (
- Updated:
src/users/users.module.ts- Removed
TypeOrmModule.forFeature([User]) - Added
DatabaseModuleimport - Now uses DatabaseService via UsersService
- Removed
- Updated:
src/config/database.config.ts- Changed from TypeOrmModuleOptions to simple pg pool config
- Returns connection pool configuration (host, port, user, password, database, pool options)
-
Created:
scripts/init-db.ts- Standalone script to initialize database schema
- Creates
userstable with proper structure - Creates indexes for performance
- Run with:
npm run db:init
-
Updated:
package.json- Added
db:initscript
- Added
The users table is automatically created with the following structure:
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
"firstName" VARCHAR(255) NOT NULL,
"lastName" VARCHAR(255) NOT NULL,
"isVerified" BOOLEAN DEFAULT false,
"createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_users_email ON users(email);- create() - INSERT with UUID and password hashing
- findByEmail() - SELECT by email parameter
- findById() - SELECT by UUID parameter
- validatePassword() - Bcrypt password comparison
-
Install dependencies:
npm install
-
Initialize database (creates schema):
npm run db:init
-
Start development server:
npm run start:dev
Make sure your .env file contains:
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5432
DATABASE_USER=postgres
DATABASE_PASSWORD=admin
DATABASE_NAME=task_api_db
JWT_SECRET=your_secret_key
NODE_ENV=development
- No ORM overhead: Direct SQL queries are faster and more efficient
- Better control: Full control over query execution and optimization
- Reduced dependencies: Fewer dependencies to maintain
- Type safety: Interface-based types with TypeScript
- Simplified migrations: SQL scripts are easier to understand and maintain
- Connection pooling: pg library handles efficient connection management
- All GraphQL resolvers remain unchanged
- Auth mutations (signUp, signIn) work the same
- User queries remain the same
- JWT authentication is still in place