Skip to content

Commit 5046753

Browse files
authored
Merge pull request #776 from topcoder-platform/migration-setup
Umzug Migration setup
2 parents 77ef8b4 + 082b71a commit 5046753

File tree

13 files changed

+448
-7
lines changed

13 files changed

+448
-7
lines changed

.circleci/config.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: 2.1
22
python_env: &python_env
33
docker:
4-
- image: cimg/python:3.11.7-browsers
4+
- image: cimg/python:3.11.11-browsers
55
install_awscli: &install_awscli
66
name: "Install awscli"
77
command: |
@@ -32,13 +32,13 @@ deploy_steps: &deploy_steps
3232
source awsenvconf
3333
./buildenv.sh -e $DEPLOY_ENV -b ${LOGICAL_ENV}-${APPNAME}-deployvar
3434
source buildenvvar
35-
./master_deploy.sh -d ECS -e $DEPLOY_ENV -t latest -s ${LOGICAL_ENV}-global-appvar,${LOGICAL_ENV}-${APPNAME}-appvar -i ${APPNAME}
35+
./master_deploy.sh -d ECS -e $DEPLOY_ENV -t latest -s ${LOGICAL_ENV}-global-appvar,${LOGICAL_ENV}-${APPNAME}-appvar -i ${APPNAME} -p FARGATE
3636
3737
echo "======= Running Masterscript - deploy projects-api-consumers ==========="
3838
if [ -e ${LOGICAL_ENV}-${APPNAME}-appvar.json ]; then sudo rm -vf ${LOGICAL_ENV}-${APPNAME}-appvar.json; fi
3939
./buildenv.sh -e $DEPLOY_ENV -b ${LOGICAL_ENV}-${APPNAME}-consumers-deployvar
4040
source buildenvvar
41-
./master_deploy.sh -d ECS -e $DEPLOY_ENV -t latest -s ${LOGICAL_ENV}-global-appvar,${LOGICAL_ENV}-${APPNAME}-appvar -i ${APPNAME}
41+
./master_deploy.sh -d ECS -e $DEPLOY_ENV -t latest -s ${LOGICAL_ENV}-global-appvar,${LOGICAL_ENV}-${APPNAME}-appvar -i ${APPNAME} -p FARGATE
4242
4343
jobs:
4444
UnitTests:
@@ -149,7 +149,7 @@ workflows:
149149
context : org-global
150150
filters:
151151
branches:
152-
only: ['develop', 'connect-performance-testing', 'feature/new-milestone-concept', 'permission_fixes']
152+
only: ['develop', 'migration-setup']
153153
- deployProd:
154154
context : org-global
155155
filters:

docs/swagger.yaml

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ securityDefinitions:
2424
type: apiKey
2525
name: Authorization
2626
in: header
27-
paths:
27+
paths:
2828
"/projects":
2929
get:
3030
tags:
@@ -244,6 +244,38 @@ paths:
244244
description: Internal Server Error
245245
schema:
246246
$ref: "#/definitions/ErrorModel"
247+
"/projects/{projectId}/copilots/request":
248+
post:
249+
tags:
250+
- projects copilot request
251+
operationId: createCopilotRequest
252+
security:
253+
- Bearer: []
254+
description: "create copilot request"
255+
responses:
256+
"200":
257+
description: Created copilot request
258+
schema:
259+
$ref: "#/definitions/Copilot"
260+
"401":
261+
description: Unauthorized
262+
schema:
263+
$ref: "#/definitions/ErrorModel"
264+
"400":
265+
description: Bad request
266+
schema:
267+
$ref: "#/definitions/ErrorModel"
268+
"500":
269+
description: Internal Server Error
270+
schema:
271+
$ref: "#/definitions/ErrorModel"
272+
parameters:
273+
- $ref: "#/parameters/projectIdParam"
274+
- name: body
275+
in: body
276+
required: true
277+
schema:
278+
$ref: "#/definitions/NewCopilotRequest"
247279
"/projects/{projectId}/attachments":
248280
get:
249281
tags:
@@ -5459,6 +5491,14 @@ definitions:
54595491
type: string
54605492
address:
54615493
type: string
5494+
NewCopilotRequest:
5495+
type: object
5496+
required:
5497+
- data
5498+
properties:
5499+
data:
5500+
type: object
5501+
description: copilot request data
54625502
NewProject:
54635503
type: object
54645504
required:
@@ -5581,6 +5621,37 @@ definitions:
55815621
type: integer
55825622
format: int64
55835623

5624+
Copilot:
5625+
type: object
5626+
properties:
5627+
id:
5628+
description: unique identifier
5629+
type: integer
5630+
format: int64
5631+
data:
5632+
description: copilot data
5633+
type: object
5634+
status:
5635+
description: status of the copilot request
5636+
type: string
5637+
createdAt:
5638+
type: string
5639+
description: Datetime (GMT) when task was created
5640+
readOnly: true
5641+
createdBy:
5642+
type: integer
5643+
format: int64
5644+
description: READ-ONLY. User who created this task
5645+
readOnly: true
5646+
updatedAt:
5647+
type: string
5648+
description: READ-ONLY. Datetime (GMT) when task was updated
5649+
readOnly: true
5650+
updatedBy:
5651+
type: integer
5652+
format: int64
5653+
description: READ-ONLY. User that last updated this task
5654+
readOnly: true
55845655
Project:
55855656
type: object
55865657
properties:
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--
2+
-- CREATE NEW TABLE:
3+
-- copilot_requests
4+
--
5+
CREATE TABLE copilot_requests (
6+
id bigint NOT NULL,
7+
"data" json NOT NULL,
8+
"status" character varying(16) NOT NULL,
9+
"projectId" bigint NOT NULL,
10+
"deletedAt" timestamp with time zone,
11+
"createdAt" timestamp with time zone,
12+
"updatedAt" timestamp with time zone,
13+
"deletedBy" bigint,
14+
"createdBy" bigint NOT NULL,
15+
"updatedBy" bigint NOT NULL
16+
);
17+
18+
CREATE SEQUENCE copilot_requests_id_seq
19+
START WITH 1
20+
INCREMENT BY 1
21+
NO MINVALUE
22+
NO MAXVALUE
23+
CACHE 1;
24+
25+
ALTER SEQUENCE copilot_requests_id_seq OWNED BY copilot_requests.id;
26+
27+
ALTER TABLE copilot_requests
28+
ALTER COLUMN id SET DEFAULT nextval('copilot_requests_id_seq');
29+
30+
ALTER TABLE ONLY copilot_requests
31+
ADD CONSTRAINT "copilot_requests_pkey" PRIMARY KEY (id);
32+
33+
ALTER TABLE ONLY copilot_requests
34+
ADD CONSTRAINT "copilot_requests_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES projects(id) ON UPDATE CASCADE ON DELETE SET NULL;

migrations/umzug/README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Migration Guide
2+
3+
This project uses **Sequelize** with **Umzug** for managing database migrations.
4+
5+
## **📌 How to Add a New Migration**
6+
7+
1. **Generate a new migration file**
8+
9+
cd into `migrations/umzug/` directory and run:
10+
11+
```sh
12+
npx sequelize-cli migration:generate --name your_migration_name
13+
```
14+
15+
This will create a new migration file inside `umzug/migrations/`.
16+
17+
2. **Modify the generated migration file**
18+
19+
- Open the file inside `umzug/migrations/`.
20+
- Define the required table changes inside the `up` method.
21+
- Define how to revert the changes in the `down` method.
22+
23+
**Example:** Creating a `users` table
24+
25+
```javascript
26+
module.exports = {
27+
up: async (queryInterface, Sequelize) => {
28+
await queryInterface.createTable("users", {
29+
id: {
30+
type: Sequelize.BIGINT,
31+
allowNull: false,
32+
primaryKey: true,
33+
autoIncrement: true,
34+
},
35+
name: {
36+
type: Sequelize.STRING,
37+
allowNull: false,
38+
},
39+
createdAt: {
40+
type: Sequelize.DATE,
41+
allowNull: true,
42+
},
43+
updatedAt: {
44+
type: Sequelize.DATE,
45+
allowNull: true,
46+
}
47+
});
48+
},
49+
down: async (queryInterface, Sequelize) => {
50+
await queryInterface.dropTable("users");
51+
}
52+
};
53+
```
54+
55+
3. **Test Migrations**
56+
57+
```sh
58+
npm run migrate
59+
```
60+
61+
This will apply all pending migrations.
62+
63+
4. **Rollback Migrations (If Needed)**
64+
65+
```sh
66+
npm run migrate:down
67+
```
68+
69+
This will revert the last applied migration.
70+
71+
5. **Revert All Migrations (If Needed)**
72+
73+
If you need to revert all applied migrations, run:
74+
75+
```sh
76+
npm run migrate:reset
77+
```
78+
79+
This will undo all migrations in reverse order.
80+
81+
---
82+
83+
## **📌 How Migrations Work in This Project**
84+
85+
- All migration files are stored in `umzug/migrations/`.
86+
- The migration runner is inside `umzug/index.js`.
87+
- After installing dependencies (`npm install`), migrations will **automatically run** via `postinstall`.
88+
89+
---

migrations/umzug/index.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const config = require('config');
2+
const { Sequelize } = require('sequelize');
3+
const { Umzug, SequelizeStorage } = require('umzug');
4+
5+
// Initialize Sequelize
6+
const sequelize = new Sequelize(config.get('dbConfig.masterUrl'), {
7+
dialect: 'postgres',
8+
});
9+
10+
console.log('Umzug migration script:', __dirname);
11+
12+
// Initialize Umzug
13+
const umzug = new Umzug({
14+
migrations: {
15+
glob: 'migrations/umzug/migrations/*.js',
16+
resolve: ({ name, path, context }) => {
17+
console.log('Loading migration:', name, path);
18+
const migration = require(path);
19+
return {
20+
name,
21+
up: async () => migration.up(context, Sequelize),
22+
down: async () => migration.down(context, Sequelize),
23+
};
24+
},
25+
},
26+
context: sequelize.getQueryInterface(),
27+
storage: new SequelizeStorage({ sequelize }),
28+
logger: console,
29+
});
30+
31+
// Run migrations
32+
if (require.main === module) {
33+
umzug
34+
.up()
35+
.then(() => {
36+
console.log('Migrations executed successfully');
37+
process.exit(0);
38+
})
39+
.catch((err) => {
40+
console.error('Migration failed', err);
41+
process.exit(1);
42+
});
43+
}
44+
45+
module.exports = umzug;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'use strict';
2+
3+
module.exports = {
4+
up: async (queryInterface, Sequelize) => {
5+
await queryInterface.createTable("copilot_requests", {
6+
id: {
7+
type: Sequelize.BIGINT,
8+
allowNull: false,
9+
primaryKey: true,
10+
autoIncrement: true,
11+
},
12+
data: {
13+
type: Sequelize.JSON,
14+
allowNull: false,
15+
},
16+
status: {
17+
type: Sequelize.STRING(16),
18+
allowNull: false,
19+
},
20+
projectId: {
21+
type: Sequelize.BIGINT,
22+
allowNull: false,
23+
references: {
24+
model: "projects",
25+
key: "id",
26+
},
27+
onUpdate: "CASCADE",
28+
onDelete: "SET NULL",
29+
},
30+
deletedAt: {
31+
type: Sequelize.DATE,
32+
allowNull: true,
33+
},
34+
createdAt: {
35+
type: Sequelize.DATE,
36+
allowNull: true,
37+
},
38+
updatedAt: {
39+
type: Sequelize.DATE,
40+
allowNull: true,
41+
},
42+
deletedBy: {
43+
type: Sequelize.BIGINT,
44+
allowNull: true,
45+
},
46+
createdBy: {
47+
type: Sequelize.BIGINT,
48+
allowNull: false,
49+
},
50+
updatedBy: {
51+
type: Sequelize.BIGINT,
52+
allowNull: false,
53+
},
54+
});
55+
},
56+
57+
down: async (queryInterface, Sequelize) => {
58+
await queryInterface.dropTable("copilot_requests");
59+
}
60+
};

0 commit comments

Comments
 (0)