Skip to content

Commit 298cad8

Browse files
authored
Merge pull request #106 from DefiFundr-Labs/feat/db_goose_migration
feat: add database migration scripts and create DB Diagram
2 parents 5de246c + c3c3250 commit 298cad8

23 files changed

+830
-4
lines changed

.github/workflows/defifundr-ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- name: Set up Go
1818
uses: actions/setup-go@v3
1919
with:
20-
go-version: 1.19
20+
go-version: 1.23
2121
cache: true
2222

2323
- name: Install golangci-lint
@@ -53,7 +53,7 @@ jobs:
5353
- name: Set up Go
5454
uses: actions/setup-go@v3
5555
with:
56-
go-version: 1.19
56+
go-version: 1.23
5757
cache: true
5858

5959
- name: "Create env file"
@@ -96,7 +96,7 @@ jobs:
9696
- name: Set up Go
9797
uses: actions/setup-go@v3
9898
with:
99-
go-version: 1.19
99+
go-version: 1.23
100100
cache: true
101101

102102
- name: Build application

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
- name: Set up Go
3030
uses: actions/setup-go@v3
3131
with:
32-
go-version: 1.19
32+
go-version: 1.23
3333
id: go
3434
- name: "Create env file"
3535
run: |

Readme.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,94 @@ go test ./...
5454
```bash
5555
go test -v -cover ./...
5656
```
57+
58+
```markdown
59+
# Database Migrations
60+
61+
The DefiFundr backend uses [goose](https://github.com/pressly/goose) for managing database migrations. Migrations are stored in the `migrations` directory and are written in SQL.
62+
63+
## Setting Up Migrations
64+
65+
1. Install goose:
66+
```bash
67+
go install github.com/pressly/goose/v3/cmd/goose@latest
68+
```
69+
70+
2. Make sure you have PostgreSQL running and accessible with the connection details specified in your environment variables or `.env` file.
71+
72+
## Migration Commands
73+
74+
We provide helper scripts to manage migrations:
75+
76+
* `./scripts/migrate.sh` - Apply all pending migrations
77+
* `./scripts/migrate_create.sh <migration_name>` - Create a new migration file
78+
* `./scripts/migrate_down.sh` - Roll back the last migration
79+
* `./scripts/migrate_status.sh` - Check the status of all migrations
80+
* `./scripts/migrate_reset.sh` - Roll back all migrations and apply them again (use with caution!)
81+
82+
### Creating a New Migration
83+
84+
To create a new migration:
85+
86+
```bash
87+
./scripts/migrate_create.sh add_new_feature
88+
```
89+
90+
This will create a new file in the `migrations` directory with a timestamp prefix, like `20230809123456_add_new_feature.sql`.
91+
92+
Edit this file to add your SQL commands. Each migration file should have two sections:
93+
94+
```sql
95+
-- +goose Up
96+
-- SQL in this section is executed when the migration is applied
97+
CREATE TABLE example (
98+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
99+
name VARCHAR(255) NOT NULL
100+
);
101+
102+
-- +goose Down
103+
-- SQL in this section is executed when the migration is rolled back
104+
DROP TABLE example;
105+
```
106+
107+
### Running Migrations
108+
109+
To apply all pending migrations:
110+
111+
```bash
112+
./scripts/migrate.sh
113+
```
114+
115+
### Database Connection
116+
117+
By default, the migration scripts will use the `DATABASE_URL` environment variable. If this is not set, they will fall back to `postgres://postgres:postgres@localhost:5432/defifundr?sslmode=disable`.
118+
119+
You can set the environment variable before running the script:
120+
121+
```bash
122+
DATABASE_URL="postgres://user:password@localhost:5432/dbname?sslmode=disable" ./scripts/migrate.sh
123+
```
124+
125+
Or you can update the default value in the scripts.
126+
127+
## Migration Best Practices
128+
129+
1. **Always include a Down migration**: This ensures you can roll back if something goes wrong.
130+
2. **Keep migrations small and focused**: It's better to have multiple small migrations than one large one.
131+
3. **Test migrations before deploying**: Run migrations on a test database to ensure they work correctly.
132+
4. **Version control migrations**: All migrations should be committed to the repository.
133+
5. **Never modify an existing migration file**: Once a migration has been applied to any environment, create a new migration instead of modifying the existing one.
134+
135+
## Troubleshooting
136+
137+
If you encounter issues with migrations:
138+
139+
1. Check the migration status with `./scripts/migrate_status.sh`
140+
2. Ensure your database connection details are correct
141+
3. Look for syntax errors in your SQL statements
142+
4. Check if you have the necessary permissions on the database
143+
144+
For more complex issues, you might need to manually fix the goose migration table (`goose_db_version`).
145+
```
146+
147+
These scripts and documentation provide a comprehensive system for managing your database migrations using goose. Make sure to make the scripts executable after creating them (`chmod +x scripts/*.sh`).

docs/db_diagram/db.dbml

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
Project DefiFundr {
2+
database_type: 'PostgreSQL'
3+
Note: '''
4+
**DefiFundr is a revolutionary decentralized payroll and invoice management system that bridges
5+
the gap between traditional financial systems and blockchain technology.
6+
The platform provides a seamless, secure, and transparent solution for businesses to manage employee payments,
7+
handle freelancer invoices, and automate salary disbursements across both fiat and cryptocurrency channels.**
8+
'''
9+
}
10+
11+
Table users {
12+
id UUID [pk, default: `uuid_generate_v4()`]
13+
email VARCHAR(255) [not null, unique]
14+
password_hash VARCHAR(255) [not null]
15+
account_type VARCHAR(50) [not null, note: 'business, personal']
16+
personal_account_type VARCHAR(50) [not null, note: 'contractor, business']
17+
first_name VARCHAR(255) [not null]
18+
last_name VARCHAR(255) [not null]
19+
nationality VARCHAR(255) [not null]
20+
residencial_country VARCHAR(255) [null]
21+
job_role VARCHAR(255) [null]
22+
company_website VARCHAR(255) [null]
23+
employment_type VARCHAR(255) [null]
24+
created_at timestamptz [not null, default: `now()`]
25+
updated_at timestamptz [not null, default: `now()`]
26+
27+
indexes {
28+
email [unique]
29+
}
30+
}
31+
32+
Table kyc {
33+
id uuid [pk]
34+
user_id UUID [not null, ref: > users.id]
35+
face_verification bool [not null]
36+
identity_verification bool [not null]
37+
updated_at timestamptz [not null, default: '0001-01-01']
38+
created_at timestamptz [not null, default: `now()`]
39+
}
40+
41+
42+
Table sessions {
43+
id uuid [pk]
44+
user_id UUID [not null, ref: > users.id]
45+
refresh_token varchar [not null]
46+
user_agent varchar [not null]
47+
client_ip varchar [not null]
48+
is_blocked boolean [not null, default: false]
49+
expires_at timestamptz [not null]
50+
created_at timestamptz [not null, default: `now()`]
51+
}
52+
53+
54+
Table wallets {
55+
id UUID [pk, default: `uuid_generate_v4()`]
56+
user_id UUID [not null, ref: > users.id]
57+
wallet_address VARCHAR(255) [not null, unique]
58+
chain VARCHAR(50) [not null, note: 'ethereum, solana']
59+
is_primary BOOLEAN [not null, default: false]
60+
created_at timestamptz [not null, default: '0001-01-01']
61+
pin_hash VARCHAR(255) [not null]
62+
63+
indexes {
64+
user_id
65+
wallet_address [unique]
66+
}
67+
}
68+
69+
Table organizations {
70+
id UUID [pk, default: `uuid_generate_v4()`]
71+
name VARCHAR(255) [not null]
72+
employer_id UUID [not null, ref: > users.id]
73+
created_at timestamptz [not null, default: '0001-01-01']
74+
updated_at timestamptz [not null, default: '0001-01-01']
75+
76+
indexes {
77+
name [unique]
78+
employer_id
79+
}
80+
}
81+
82+
Table organization_members {
83+
id UUID [pk, default: `uuid_generate_v4()`]
84+
organization_id UUID [not null, ref: > organizations.id]
85+
employee_id UUID [not null, ref: > users.id]
86+
role VARCHAR(50) [not null, note: 'employee, manager, etc.']
87+
created_at timestamptz [not null, default: '0001-01-01']
88+
89+
indexes {
90+
organization_id
91+
employee_id
92+
(organization_id, employee_id) [unique]
93+
}
94+
}
95+
96+
Table payrolls {
97+
id UUID [pk, default: `uuid_generate_v4()`]
98+
employer_id UUID [not null, ref: > users.id]
99+
organization_id UUID [null, ref: > organizations.id]
100+
payment_frequency VARCHAR(50) [not null, note: 'weekly, bi-weekly, monthly']
101+
salary_amount NUMERIC(18, 2) [not null]
102+
currency VARCHAR(10) [not null, note: 'USDC, SOL, ETH']
103+
contract_address VARCHAR(255) [null]
104+
status VARCHAR(50) [not null, note: 'pending, active, completed']
105+
created_at timestamptz [not null, default: '0001-01-01']
106+
updated_at timestamptz [not null, default: '0001-01-01']
107+
108+
indexes {
109+
employer_id
110+
organization_id
111+
}
112+
}
113+
114+
Table payroll_employees {
115+
id UUID [pk, default: `uuid_generate_v4()`]
116+
payroll_id UUID [not null, ref: > payrolls.id]
117+
employee_id UUID [not null, ref: > users.id]
118+
created_at timestamptz [not null, default: '0001-01-01']
119+
120+
indexes {
121+
payroll_id
122+
employee_id
123+
(payroll_id, employee_id) [unique]
124+
}
125+
}
126+
127+
Table invoices {
128+
id UUID [pk, default: `uuid_generate_v4()`]
129+
freelancer_id UUID [not null, ref: > users.id]
130+
employer_id UUID [not null, ref: > users.id]
131+
amount NUMERIC(18, 2) [not null]
132+
currency VARCHAR(10) [not null, note: 'USDC, SOL, ETH']
133+
status VARCHAR(50) [not null, note: 'pending, approved, rejected, paid']
134+
contract_address VARCHAR(255) [null]
135+
created_at timestamptz [not null, default: '0001-01-01']
136+
updated_at timestamptz [not null, default: '0001-01-01']
137+
138+
indexes {
139+
freelancer_id
140+
employer_id
141+
}
142+
}
143+
144+
Table transactions {
145+
id UUID [pk, default: `uuid_generate_v4()`]
146+
user_id UUID [not null, ref: > users.id]
147+
tx_hash VARCHAR(255) [not null, unique]
148+
amount NUMERIC(18, 2) [not null]
149+
currency VARCHAR(10) [not null, note: 'USDC, SOL, ETH']
150+
type VARCHAR(50) [not null, note: 'payroll, invoice']
151+
status VARCHAR(50) [not null, note: 'pending, success, failed']
152+
created_at timestamptz [not null, default: '0001-01-01']
153+
154+
indexes {
155+
user_id
156+
tx_hash [unique]
157+
}
158+
}
159+
160+
Table notifications {
161+
id UUID [pk, default: `uuid_generate_v4()`]
162+
user_id UUID [not null, ref: > users.id]
163+
message TEXT [not null]
164+
type VARCHAR(50) [not null, note: 'payroll, invoice, transaction']
165+
is_read BOOLEAN [not null, default: false]
166+
created_at timestamptz [not null, default: '0001-01-01']
167+
168+
indexes {
169+
user_id
170+
is_read
171+
}
172+
}

0 commit comments

Comments
 (0)