GDX Agreements Tracker API
What the API does
- handles all CRUD operations for the application
- handles all authentication and authorization for the application
- handles all routing for the application
Testing the API
To run tests:
npm test
To Write tests:
Many of the codebase's functions are asynchronous. In order to test them, you'll need to pass an "async" function as the second argument to it()
. Within that function, you'll need to "await" the function you're testing. For example:
it("tests an asynchronous function", async () => {
const result = await functionToTest();
});
To debug tests:
npm run test:debug
To get test coverage:
npm run test:coverage
References:
- Test Runner: Jest
- Test Utilities: light-my-request
Database
Connecting
To connect to a database GUI tool during development, use the following parameters:
- Server host:
localhost
- Server port:
15432
- Username:
postgres
- Password:
postgres
If using the docker-compose.yml file to develop locally, you'll need to populate your database once the containers are up and running. Make sure to run these migrate and seed commands from within the /backend directory so that the knex command can find /backend/knexfile.js.
Migrations
Create a new migration:
docker compose exec backend npx knex migrate:make <name_of_migration>
Migrate new Schema into the Database:
docker compose exec backend npx knex migrate:latest
Reverse a migration:
docker compose exec backend npx knex migrate:rollback
Seeds
Create new Seeds:
npx knex seed:make <name_of_seed>
Execute all seeds
npx knex seed:run
Database migrations that target tables inside the
data
Schema may fail under some conditions:
- if they require table structures to already exist before they can be run
- example:
Schema.data.projects
migrations are run before thedata.projects
table has been createdWe need to guarantee that migrations on the
Schemas.data
schema run in this order:
- Migration of new Schema into database
- Migrations of new tables into the existing Schema
- Seeding those tables with data
Environment Variables for the backend API
- The .env file is not committed to the repo.
- There is an up to date sample.env file here: /backend/sample.env
- you will need to create your own .env file in the backend directory: (/backend/.env)
- For the values you will need, look here: OpenShift config maps for acd38d-dev
note: The JSON Web Key Set (keycloak ) endpoint is: https://mykeycloak.com/realms/my-realm/protocol/openid-connect/certs
Create a New API Endpoints for existing Database Tables
Run this script in the /backend directory:
npm run createAPI
- The cli will prompt you for the {API Name}
- The cli generates the bare minimum files needed to create a new API endpoint:
backend/src/controllers/{API Name}
backend/src/models/{API Name}
backend/src/routes/{API Name}
backend/src/validators/{API Name}
- Once these files are created, you should have a (locally) working API at: http://localhost:8080/{API NAME}
Note: if you run
createAPI
inside a remote docker container, your API URL may be different.
Using of CDOGS and CHES APIs inside the GDX Agreements Tracker API:
The GDX Agreements Tracker API uses the Common Components with this syntax:
const cdogs = useCommonComponents("{cdogs|ches}");
const result = cdogs.api.get('/{uri}', config={});
const result = cdogs.api.post('/{uri}', body={}, config={});
How Routes use Roles to control user Edit/Read Capabilities:
The globally default Role for all Routes is PMO-Manager-Edit-Capability
:
see verifyRole() in ./src/facilities/fastify.js
// This sets the DEFAULT Role for ALL Routes globally
const routeRoleRequired = request.routeConfig?.role ?? "PMO-Manager-Edit-Capability";
if (!roles.includes(routeRoleRequired)) {
const message = `User doesn't have required role ${routeRoleRequired}`;
request.log.warn(message);
request.log.debug(roles);
reply.code(401).send({ message });
}
Set a different Role for a Route
How to set a different Role for a Route:
Set config.role in the fastify.route({ config.role })
see example route at ./src/routes/reports/genericRoute.js
fastify.route({
method: "GET",
url: `/report/:type`,
schema: getReport,
preHandler: controller.reportHandler,
handler: controller.getReport,
config: {
role: "PMO-Reports-Capability",
},
});
The following Roles are available for use in Routes:
Composite roles - each composite role contains one or more individual Roles
- PMO-Admin-Role
- PMO-Manager-Role
- PMO-User-Role
- pmo-sys-admin (deprecated - do not use)
Individual Roles: they determine what a user can do:
- PMO-Admin-Edit-Capability
- PMO-Manager-Edit-Capability
- PMO-Manager-Read-Capability
- PMO-Reports-Capability
Troubleshooting
- coming soon!
Folder structure
- coming soon!