-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feat(envited.ascs.digital): add db connection (#15)
- Loading branch information
Showing
26 changed files
with
1,841 additions
and
429 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,8 +43,9 @@ Thumbs.db | |
# Next.js | ||
.next | ||
.env | ||
.env.dev | ||
.env.development | ||
.env.staging | ||
.env.prod | ||
.env.production | ||
|
||
.nx | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,32 @@ | ||
# ENVITED Marketplace | ||
|
||
## Resources | ||
* [Miro Board](https://miro.com/app/board/uXjVNeZRbEw=/) | ||
|
||
- [Miro Board](https://miro.com/app/board/uXjVNeZRbEw=/) | ||
|
||
### Prerequisites | ||
|
||
- Node.js >= 18.18, [Installation instructions](https://github.com/nvm-sh/nvm) | ||
- Postgres DB, for example using [Docker](https://hub.docker.com/_/postgres) automatically downloaded later | ||
|
||
#### Installing dependencies | ||
|
||
### Installation | ||
|
||
#### Clone the repository | ||
|
||
```bash | ||
git clone [email protected]:ASCS-eV/envited-marketplace | ||
``` | ||
|
||
#### Update repository | ||
|
||
```bash | ||
git fetch origin # get new branches | ||
git status # check branch | ||
git pull # update current branch | ||
``` | ||
|
||
From the root directory run: | ||
|
||
```bash | ||
|
@@ -14,6 +36,45 @@ node --version | |
npm install | ||
``` | ||
|
||
#### Database Connection | ||
|
||
> The local database schema may change so you have to make sure to clean up by removing existing container and images just to be sure: | ||
```bash | ||
docker container ls --all | ||
docker container remove envited | ||
docker image ls | ||
docker image remove postgres | ||
``` | ||
|
||
At first you need to create a docker container. The only thing we need is the individual connection string of a running postgres db. | ||
For example by using Docker, when running the Docker instance with the following example values: | ||
|
||
```bash | ||
docker run --name envited -p 5436:5432 \ | ||
-e POSTGRES_DB=envited \ | ||
-e POSTGRES_USER=admin \ | ||
-e POSTGRES_PASSWORD=123456 \ | ||
postgres | ||
``` | ||
|
||
The connection string will in this case look like this: | ||
|
||
```text | ||
postgres://admin:123456@localhost:5436/envited | ||
``` | ||
|
||
If you have completed the setup of the docker container before you can start it and check if the envited container is running: | ||
|
||
```bash | ||
docker start envited | ||
docker container ls | ||
``` | ||
|
||
#### Setting up the environment | ||
|
||
In `apps/envited.ascs.digital` rename `.env.example` to `.env.development` and fill out the required values. | ||
|
||
## Start the app | ||
|
||
To start the development server run `npx nx serve envited.ascs.digital`. Open your browser and navigate to http://localhost:4200/. Happy coding! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,12 @@ | ||
PLATFORM='' # Database platform thats being used. Choices are 'node', 'RDS' or 'vercel' | ||
ROLE_TO_ASSUME='' | ||
ENV='local' | ||
REGION='eu-central-1' | ||
|
||
# .env.development only | ||
POSTGRES_HOST='localhost' | ||
POSTGRES_PORT='5436' | ||
POSTGRES_DATABASE_NAME='envited' | ||
POSTGRES_DATABASE_USER='postgres' | ||
POSTGRES_DATABASE_PASSWORD='' | ||
|
||
# AWS deployments only | ||
RDS_SECRET_ARN='' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const ERRORS = { | ||
CANNOT_CONNECT_TO_DATABASE: 'Cannot connect to database', | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { ERRORS } from './errors' |
67 changes: 67 additions & 0 deletions
67
apps/envited.ascs.digital/common/database/database.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { initDb } from './database' | ||
|
||
describe('common/database', () => { | ||
describe('database', () => { | ||
it('should should setup a connection with a local database', async () => { | ||
// when ... we want to make a connection with a local db | ||
// then ... we should get a connection as expected | ||
process.env.ENV = 'local' | ||
process.env.POSTGRES_DATABASE_NAME = 'DB_NAME' | ||
process.env.POSTGRES_DATABASE_USER = 'DB_USER' | ||
process.env.POSTGRES_DATABASE_PASSWORD = 'DB_PASSWORD' | ||
|
||
const drizzle = jest.fn().mockReturnValue('DB_CONNECTION') | ||
const postgres = jest.fn().mockReturnValue(jest.fn()) | ||
const getSecret = jest.fn().mockResolvedValue({}) | ||
|
||
const config = { | ||
host: 'localhost', | ||
port: 5432, | ||
database: 'DB_NAME', | ||
username: 'DB_USER', | ||
password: 'DB_PASSWORD', | ||
max: 1, | ||
} | ||
|
||
const db = await initDb({ drizzle, postgres, getSecret })() | ||
|
||
expect(postgres).toHaveBeenCalledWith(config) | ||
expect(drizzle).toHaveBeenCalledWith(postgres(config)) | ||
expect(getSecret).not.toHaveBeenCalled() | ||
expect(db).toEqual('DB_CONNECTION') | ||
}) | ||
|
||
it('should should setup a connection with a local remote database', async () => { | ||
// when ... we want to make a connection with a remote db | ||
// then ... we should get a connection as expected while using the secrets manager to get the credentials | ||
process.env.ENV = 'staging' | ||
|
||
const drizzle = jest.fn().mockReturnValue('DB_CONNECTION') | ||
const postgres = jest.fn().mockReturnValue(jest.fn()) | ||
const getSecret = jest.fn().mockResolvedValue({ | ||
host: 'localhost', | ||
port: 5432, | ||
dbname: 'DB_NAME', | ||
username: 'DB_USER', | ||
password: 'DB_PASSWORD', | ||
max: 1, | ||
}) | ||
|
||
const config = { | ||
host: 'localhost', | ||
port: 5432, | ||
database: 'DB_NAME', | ||
username: 'DB_USER', | ||
password: 'DB_PASSWORD', | ||
max: 1, | ||
} | ||
|
||
const db = await initDb({ drizzle, postgres, getSecret })() | ||
|
||
expect(postgres).toHaveBeenCalledWith(config) | ||
expect(drizzle).toHaveBeenCalledWith(postgres(config)) | ||
expect(getSecret).toHaveBeenCalled() | ||
expect(db).toEqual('DB_CONNECTION') | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { PostgresJsDatabase, drizzle } from 'drizzle-orm/postgres-js' | ||
import postgres from 'postgres' | ||
import { equals } from 'ramda' | ||
|
||
import { ERRORS } from '../constants' | ||
import { getSecret } from '../secretsManager' | ||
|
||
export const initDb = | ||
({ | ||
drizzle, | ||
postgres, | ||
getSecret, | ||
}: { | ||
drizzle: (client: postgres.Sql) => PostgresJsDatabase | ||
postgres: (options: postgres.Options<any>) => postgres.Sql | ||
getSecret: (secretId: string) => Promise<Record<string, any>> | ||
}): (() => Promise<PostgresJsDatabase>) => | ||
async () => { | ||
let config = { | ||
host: process.env.POSTGRES_HOST || 'localhost', // Postgres ip address[s] or domain name[s] | ||
port: parseInt(process.env.POSTGRES_PORT || '5432', 10), // Postgres server port[s] | ||
database: process.env.POSTGRES_DATABASE_NAME!, // Name of database to connect to | ||
username: process.env.POSTGRES_DATABASE_USER!, // Username of database user | ||
password: process.env.POSTGRES_DATABASE_PASSWORD!, // Password of database user | ||
max: 1, | ||
} | ||
|
||
if (!equals(process.env.ENV, 'local')) { | ||
try { | ||
const { password, dbname, port, host, username } = await getSecret(process.env.RDS_SECRET_ARN!) | ||
config = { | ||
host, | ||
port, | ||
database: dbname, | ||
username, | ||
password, | ||
max: 1, | ||
} | ||
} catch (error) { | ||
console.log(ERRORS.CANNOT_CONNECT_TO_DATABASE, error) | ||
} | ||
} | ||
|
||
return drizzle(postgres(config)) | ||
} | ||
|
||
export const connectDb = initDb({ drizzle, postgres, getSecret }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { connectDb } from './database' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { PostgresJsDatabase } from 'drizzle-orm/postgres-js' | ||
import { migrate as PGMigrate } from 'drizzle-orm/postgres-js/migrator' | ||
|
||
import { connectDb } from './database' | ||
|
||
const runMigration = async () => { | ||
const db = await connectDb() | ||
try { | ||
await PGMigrate(db as PostgresJsDatabase, { migrationsFolder: `../../drizzle/${process.env.ENV}` }) | ||
} catch (error) { | ||
console.error(error) | ||
} finally { | ||
process.exit(0) | ||
} | ||
} | ||
|
||
runMigration() |
5 changes: 5 additions & 0 deletions
5
apps/envited.ascs.digital/common/database/queries/common/common.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { sql } from 'drizzle-orm' | ||
import { PostgresJsDatabase } from 'drizzle-orm/postgres-js' | ||
|
||
export const fetchTables = (db: PostgresJsDatabase) => async () => | ||
db.execute(sql`select * from information_schema.tables;`) |
1 change: 1 addition & 0 deletions
1
apps/envited.ascs.digital/common/database/queries/common/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { fetchTables } from './common' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { db } from './queries' |
18 changes: 18 additions & 0 deletions
18
apps/envited.ascs.digital/common/database/queries/queries.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { init } from './queries' | ||
|
||
describe('common/database/queries', () => { | ||
describe('queries', () => { | ||
it('should load the queries with an active db connection', async () => { | ||
// when ... we want to load the queries | ||
// then ... we should get the queries as expected | ||
const connectDb = jest.fn().mockResolvedValue('DB_CONNECTION') | ||
const testQuery = jest.fn().mockReturnValue('TEST_QUERY') | ||
|
||
const db = await init(connectDb)({ testQuery: testQuery })() | ||
|
||
expect(connectDb).toHaveBeenCalled() | ||
expect(testQuery).toHaveBeenCalledWith('DB_CONNECTION') | ||
expect(db).toEqual({ testQuery: 'TEST_QUERY' }) | ||
}) | ||
}) | ||
}) |
28 changes: 28 additions & 0 deletions
28
apps/envited.ascs.digital/common/database/queries/queries.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { PostgresJsDatabase } from 'drizzle-orm/postgres-js' | ||
import postgres from 'postgres' | ||
import { fromPairs, map, pipe, toPairs } from 'ramda' | ||
|
||
import { connectDb } from '../database' | ||
import { fetchTables } from './common' | ||
|
||
const queries = { | ||
fetchTables, | ||
} | ||
|
||
export const init = | ||
(connectDb: () => Promise<PostgresJsDatabase>) => | ||
(queries: Record<string, (db: PostgresJsDatabase) => () => Promise<postgres.RowList<Record<string, unknown>[]>>>) => | ||
async () => { | ||
const connection = await connectDb() | ||
|
||
return pipe( | ||
toPairs, | ||
map(([key, value]: [key: string, value: (connection: PostgresJsDatabase) => any]): [any, any] => [ | ||
key, | ||
value(connection), | ||
]), | ||
fromPairs, | ||
)(queries) | ||
} | ||
|
||
export const db = init(connectDb)(queries) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const seed = async () => { | ||
try { | ||
// Insert seeding requirements here | ||
} catch (error) { | ||
console.error(error) | ||
} finally { | ||
process.exit(0) | ||
} | ||
} | ||
|
||
seed() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { getSecret } from './secretsManager' |
7 changes: 7 additions & 0 deletions
7
apps/envited.ascs.digital/common/secretsManager/secretsManager.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { GetSecretValueCommand, SecretsManagerClient } from '@aws-sdk/client-secrets-manager' | ||
|
||
export const getSecret = (secretId: string) => | ||
new SecretsManagerClient() | ||
.send(new GetSecretValueCommand({ SecretId: secretId })) | ||
.then(({ SecretString }) => (SecretString ? JSON.parse(SecretString) : {})) | ||
.catch(error => console.log('error', error)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import type { Config } from 'drizzle-kit' | ||
|
||
export default { | ||
schema: './common/database/schema.ts', | ||
out: `./drizzle/${process.env.ENV}`, | ||
} satisfies Config |
Oops, something went wrong.