Skip to content

Commit 3374e03

Browse files
committed
Merge branch 'main' of github.com:CS3219-AY2425S1/cs3219-ay2425s1-project-g16 into PEER-230-Login-Registration-UI
Signed-off-by: SeeuSim <[email protected]>
2 parents 96efc1b + 2e89e6f commit 3374e03

23 files changed

+8743
-8453
lines changed

backend/user/.dockerignore

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

backend/user/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+
```

backend/user/docker-compose.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
services:
2+
postgres:
3+
hostname: postgres
4+
image: "user-db"
5+
container_name: "user_db"
6+
build:
7+
context: ./src/lib/db
8+
dockerfile: ./postgres.Dockerfile
9+
environment:
10+
POSTGRES_DB: "User"
11+
POSTGRES_USER: "user"
12+
POSTGRES_PASSWORD: "user"
13+
PGDATA: "/data/user-db"
14+
volumes:
15+
- "user-db-docker:/data/user-db"
16+
# - ./init.sql:/docker-entrypoint-initdb.d/init.sql
17+
ports:
18+
- "5431:5432"
19+
restart: unless-stopped
20+
21+
express:
22+
image: "user-express"
23+
container_name: "user-express"
24+
build:
25+
context: ./
26+
dockerfile: ./express.Dockerfile
27+
target: build
28+
ports:
29+
- "8001:8001"
30+
command: node dist/index.js
31+
depends_on:
32+
postgres:
33+
condition: service_started
34+
restart: true
35+
36+
volumes:
37+
user-db-docker:

backend/user/drizzle.config.ts

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: 5431,
10+
database: 'User',
11+
user: 'user',
12+
password: 'user',
13+
},
14+
});

backend/user/drizzle.migrate.mts

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 = 'User';
9+
const port = 5431;
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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CREATE TABLE IF NOT EXISTS "users" (
2+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3+
"email" varchar(255) NOT NULL,
4+
"username" varchar(255) NOT NULL,
5+
"first_name" varchar(255) NOT NULL,
6+
"last_name" varchar(255) NOT NULL,
7+
"password" varchar(255) NOT NULL,
8+
CONSTRAINT "users_email_unique" UNIQUE("email"),
9+
CONSTRAINT "users_username_unique" UNIQUE("username")
10+
);
11+
--> statement-breakpoint
12+
DROP TABLE "tableName";
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: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"id": "ecf4404b-9642-42c5-b6d6-deeaeaca7a77",
3+
"prevId": "bfb0f47d-1ebe-47d4-b979-8fe9d6305cd4",
4+
"version": "7",
5+
"dialect": "postgresql",
6+
"tables": {
7+
"public.users": {
8+
"name": "users",
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+
"email": {
19+
"name": "email",
20+
"type": "varchar(255)",
21+
"primaryKey": false,
22+
"notNull": true
23+
},
24+
"username": {
25+
"name": "username",
26+
"type": "varchar(255)",
27+
"primaryKey": false,
28+
"notNull": true
29+
},
30+
"first_name": {
31+
"name": "first_name",
32+
"type": "varchar(255)",
33+
"primaryKey": false,
34+
"notNull": true
35+
},
36+
"last_name": {
37+
"name": "last_name",
38+
"type": "varchar(255)",
39+
"primaryKey": false,
40+
"notNull": true
41+
},
42+
"password": {
43+
"name": "password",
44+
"type": "varchar(255)",
45+
"primaryKey": false,
46+
"notNull": true
47+
}
48+
},
49+
"indexes": {},
50+
"foreignKeys": {},
51+
"compositePrimaryKeys": {},
52+
"uniqueConstraints": {
53+
"users_email_unique": {
54+
"name": "users_email_unique",
55+
"nullsNotDistinct": false,
56+
"columns": [
57+
"email"
58+
]
59+
},
60+
"users_username_unique": {
61+
"name": "users_username_unique",
62+
"nullsNotDistinct": false,
63+
"columns": [
64+
"username"
65+
]
66+
}
67+
}
68+
}
69+
},
70+
"enums": {},
71+
"schemas": {},
72+
"sequences": {},
73+
"_meta": {
74+
"columns": {},
75+
"schemas": {},
76+
"tables": {}
77+
}
78+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
"idx": 1,
14+
"version": "7",
15+
"when": 1726678203279,
16+
"tag": "0001_clammy_grandmaster",
17+
"breakpoints": true
18+
}
19+
]
20+
}

0 commit comments

Comments
 (0)