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
dataSchema may fail under some conditions:
- if they require table structures to already exist before they can be run
- example:
Schema.data.projectsmigrations are run before thedata.projectstable has been createdWe need to guarantee that migrations on the
Schemas.dataschema 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
createAPIinside 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!