Skip to content

Commit 4b37739

Browse files
committed
PEER-118: Set up collaboration service
1 parent 218d776 commit 4b37739

18 files changed

+473
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
dist/

backend/collaboration/README.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# Template Service
2+
3+
This directory contains the code for the Template
4+
Service.
5+
6+
## Database
7+
8+
We use:
9+
10+
- PostgreSQL 16 for the database. To run it, we use:
11+
- Docker to run the database, as well as inject any user-defined
12+
configurations or SQL files into the Docker image.
13+
- Docker-Compose to run the database, as well as any other
14+
services this API microservice may depend on.
15+
- [**Drizzle**](https://orm.drizzle.team/) for the ORM.
16+
17+
Follow the instructions below for the setup, as well as to learn how to work with the database.
18+
19+
### Setup
20+
21+
1. Install Docker Desktop on your device. Launch it.
22+
23+
2. To verify that it is launched and installed correctly, run the
24+
following in your terminal:
25+
26+
```bash
27+
docker --version
28+
```
29+
30+
If the command does not error, and outputs a version, proceed to
31+
the next step.
32+
33+
3. Inspect the `docker-compose.yml` file. It
34+
should look like this:
35+
36+
```yml
37+
services:
38+
# ...
39+
postgres:
40+
# ...
41+
volumes:
42+
- "template-db-docker:/data/template-db"
43+
# - ./init.sql:/docker-entrypoint-initdb.d/init.sql
44+
ports:
45+
- "5431:5432"
46+
restart: unless-stopped
47+
48+
volumes:
49+
template-db-docker:
50+
external: true
51+
```
52+
53+
We observe that this Database relies on a
54+
Docker Volume. Replace all instances of
55+
`template-db-docker` with your desired
56+
volume name.
57+
58+
4. Then, create the Docker Volume with
59+
the following command:
60+
61+
```bash
62+
# in this case, the command is
63+
# docker volume create template-db-docker
64+
docker volume create <volume-name>
65+
```
66+
5. Finally, create the Database Container:
67+
68+
```bash
69+
docker-compose up -d
70+
```
71+
72+
6. To bring it down, run this command:
73+
74+
```bash
75+
docker-compose down
76+
```
77+
78+
### Schema
79+
80+
We maintain the schema in the `src/lib/db/schema.ts` file.
81+
82+
Refer to the Drizzle documentation to learn how
83+
to properly define schemas. Then, insert your
84+
schemas into the file.
85+
86+
### Migration
87+
88+
After you have created/updated your schemas in
89+
the file, persist them to the Database with
90+
Migrations.
91+
92+
1. Configure your credentials (port,
93+
password, ...) in:
94+
95+
- `drizzle.config.ts`
96+
- `drizzle.migrate.mts`.
97+
- `src/lib/db/index.ts`.
98+
99+
In the future, we may wish to migrate these
100+
credentials to environment variables.
101+
102+
2. Run the `npm run db:generate` command to
103+
generate your `.sql` Migration Files under the
104+
`drizzle` folder.
105+
106+
3. Rename your
107+
`<migration_num>_<random_name>.sql` file
108+
to `<migration_num>_<meaningful_name>.sql`.
109+
110+
For example:
111+
- Generated: `0000_dazzling_squirrel.sql`
112+
- Renamed: `0000_initial_schema.sql`.
113+
114+
Then, rename the
115+
`meta/_journal.json` tag from
116+
`0000_dazzling_squirrel` to
117+
`0000_initial_schema` as well. Replace the
118+
migration number and name with the one you
119+
used.
120+
121+
4. Finally, run the migration with this:
122+
123+
```bash
124+
npm run db:migrate
125+
```
126+
127+
### Connecting with the DB
128+
129+
1. Import the `db` instance from `lib/db`.
130+
2. Use the Drizzle APIs and the tables defined in
131+
`src/lib/schema.ts` to interact with the
132+
tables.
133+
134+
```ts
135+
import { db, tableName } from '../lib/db';
136+
137+
const route = async (req, res) => {
138+
await db.select().from(tableName); //...
139+
}
140+
```
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
services:
2+
postgres:
3+
hostname: postgres
4+
image: 'collaboration-db'
5+
container_name: 'collaboration_db'
6+
build:
7+
context: ./src/lib/db
8+
dockerfile: ./postgres.Dockerfile
9+
environment:
10+
POSTGRES_DB: 'Collaboration'
11+
POSTGRES_USER: 'user'
12+
POSTGRES_PASSWORD: 'user'
13+
PGDATA: '/data/collaboration-db'
14+
volumes:
15+
- 'collaboration-db-docker:/data/collaboration-db'
16+
# - ./init.sql:/docker-entrypoint-initdb.d/init.sql
17+
ports:
18+
- '5434:5432'
19+
restart: unless-stopped
20+
21+
express:
22+
image: 'collaboration-express'
23+
container_name: 'collaboration-express'
24+
build:
25+
context: ./
26+
dockerfile: ./express.Dockerfile
27+
target: build
28+
ports:
29+
- '8002:8001'
30+
command: node dist/index.js
31+
depends_on:
32+
postgres:
33+
condition: service_started
34+
restart: true
35+
volumes:
36+
collaboration-db-docker:
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { defineConfig } from 'drizzle-kit';
2+
3+
export default defineConfig({
4+
schema: './src/lib/db/schema.ts',
5+
out: './drizzle',
6+
dialect: 'postgresql',
7+
dbCredentials: {
8+
host: 'localhost',
9+
port: 5434,
10+
database: 'Collaboration',
11+
user: 'user',
12+
password: 'user',
13+
},
14+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import postgres from 'postgres';
2+
import { drizzle } from 'drizzle-orm/postgres-js';
3+
import { migrate } from 'drizzle-orm/postgres-js/migrator';
4+
5+
const user = 'user';
6+
const password = 'user';
7+
const url = 'localhost';
8+
const database = 'Collaboration';
9+
const port = 5434;
10+
11+
const CONNECTION_STRING = `postgresql://${user}:${password}@${url}:${port}/${database}`;
12+
13+
const sql = postgres(CONNECTION_STRING, { max: 1 });
14+
15+
const db = drizzle(sql);
16+
17+
await migrate(db, { migrationsFolder: 'drizzle' });
18+
await sql.end();
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CREATE TABLE IF NOT EXISTS "tableName" (
2+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3+
CONSTRAINT "tableName_id_unique" UNIQUE("id")
4+
);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"id": "bfb0f47d-1ebe-47d4-b979-8fe9d6305cd4",
3+
"prevId": "00000000-0000-0000-0000-000000000000",
4+
"version": "7",
5+
"dialect": "postgresql",
6+
"tables": {
7+
"public.tableName": {
8+
"name": "tableName",
9+
"schema": "",
10+
"columns": {
11+
"id": {
12+
"name": "id",
13+
"type": "uuid",
14+
"primaryKey": true,
15+
"notNull": true,
16+
"default": "gen_random_uuid()"
17+
}
18+
},
19+
"indexes": {},
20+
"foreignKeys": {},
21+
"compositePrimaryKeys": {},
22+
"uniqueConstraints": {
23+
"tableName_id_unique": {
24+
"name": "tableName_id_unique",
25+
"nullsNotDistinct": false,
26+
"columns": [
27+
"id"
28+
]
29+
}
30+
}
31+
}
32+
},
33+
"enums": {},
34+
"schemas": {},
35+
"sequences": {},
36+
"_meta": {
37+
"columns": {},
38+
"schemas": {},
39+
"tables": {}
40+
}
41+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"version": "7",
3+
"dialect": "postgresql",
4+
"entries": [
5+
{
6+
"idx": 0,
7+
"version": "7",
8+
"when": 1726382290778,
9+
"tag": "0000_initial_schema",
10+
"breakpoints": true
11+
}
12+
]
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM node:lts-alpine AS build
2+
WORKDIR /data/user-express
3+
COPY package*.json ./
4+
RUN npm install
5+
COPY . .
6+
RUN npm run build
7+
8+
FROM node:lts-alpine AS production
9+
WORKDIR /data/user-express
10+
COPY --from=build /data/user-express/package*.json ./
11+
RUN npm ci --omit=dev
12+
COPY --from=build --chown=node:node /data/user-express/dist ./dist
13+
EXPOSE 8001
14+
ENTRYPOINT ["node", "dist/index.js"]

backend/collaboration/package.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "collaboration",
3+
"version": "1.0.0",
4+
"main": "dist/index.js",
5+
"scripts": {
6+
"dev": "nodemon src/index.ts | pino-pretty",
7+
"build": "tsc",
8+
"start": "node dist/index.js",
9+
"fmt": "prettier --config .prettierrc src --write",
10+
"db:generate": "drizzle-kit generate",
11+
"db:migrate": "tsx drizzle.migrate.mts",
12+
"test": "echo \"Error: no test specified\" && exit 1"
13+
},
14+
"keywords": [],
15+
"author": "",
16+
"license": "ISC",
17+
"description": "",
18+
"dependencies": {
19+
"drizzle-orm": "^0.33.0",
20+
"express": "^4.21.0",
21+
"pino": "^9.4.0",
22+
"pino-http": "^10.3.0",
23+
"postgres": "^3.4.4"
24+
},
25+
"devDependencies": {
26+
"@types/express": "^4.17.21",
27+
"@types/node": "^22.5.5",
28+
"drizzle-kit": "^0.24.2",
29+
"nodemon": "^3.1.4",
30+
"pino-pretty": "^11.2.2",
31+
"ts-node": "^10.9.2"
32+
}
33+
}

0 commit comments

Comments
 (0)