Setting up a development environment
Some steps described here overlap the ones described in the installation instructions.
Using Docker
Inside the docker
folder you can find all the Dockerfile and docker-compose
files for several enviroments. To run the development setup, copy the
.env.example
to .env
and update it to the values of your environment.
In the root .env
, use these values
DB_HOST=db
...
API_BASE_URL="http://phpreport-api:8555"
In the frontend/.env
, use the following:
VITE_OIDC_REDIRECT_URL='http://0.0.0.0:5173/web/v2/'
VITE_API_BASE='http://0.0.0.0:8555'
You need docker and docker-compose running and you can run it from the root folder of the project with:
docker-compose -f docker/docker-compose.dev.yml up
During the first time running the app, the API will fail because it needs to access the database tables that still don't exist, so run the migrations to create the tables with:
docker exec -ti phpreport-api alembic upgrade head
Kill the containers and run them again, so the API can connect to the database correctly.
[Optional] When running the project for the first time, you can add some basic data for the development environment:
docker exec -dti phpreport-db psql phpreport -U phpreport < sql/initialData.sql
If you make changes to the models and want to create migrations:
docker exec -ti phpreport-api alembic revision --autogenerate -m "Migrations description"
All the services are setup to reload when the files are updated without the need of rebuild the containers.
If you are using an external OAuth provider, you will also need to add a user to the database with the same username as your OAuth user because PhpReport will match on the username. To do this, you will want to run the following commands once your db container is up and running:
docker exec -ti phpreport-db bash
psql -U phpreport
INSERT INTO usr (id, password, login) VALUES (DEFAULT, md5('myusername'), 'myusername') RETURNING id;
This will echo the id of the user you just created. Keep this terminal open. Now
you will need to also add some permissions to your user. To do this you'll need
to insert the user id into the belongs
table along with the proper group id.
The default group ids added are as follows:
id | name |
---|---|
1 | staff |
2 | admin |
3 | manager |
If you want your user to have the highest permission level, then run the
following and replace {your user id}
with the value returned when you inserted
your user: INSERT into belongs VALUES(1, {your user id}), (2, {your user id}), (3, {your user id});
If you want your user to have lower permissions, then remove whichever groups from your INSERT statement you don't want your user in.
If you've given your user the highest permissions, then you'll be able to use the interface to create clients and projects to use for creating tasks.
Dependencies
Follow the corresponding section from the installation instructions. Make sure to also install composer as specified there.
Additionally, a development environment may need the following dependencies to generate minified versions of the JS code and the documentation pages:
- Fedora: package
uglify-js
. - Debian/Ubuntu: package
uglifyjs
.
NOTICE: UglifyJS version must be 3.15 or above.
For the React frontend, you will need to run npm install
inside the frontend
folder. Make sure that you have Node.js version 20 or higher.
For the Python API, make sure you have Python version 3.11 or higher.
Setting up the database
From the api
folder, run the migrations with
alembic upgrade head
Create a new migration with
alembic revision --autogenerate -m "Migrations description"
For more details check the alembic documentation.
History tracking in database
As part of the migrations, an archive
table is added to the database along with a function to log to this table and a trigger to captures changes on the project
table. A trigger using this function can be added to track the history of any table. To do so, create a migration with the following (with the customer
table used as an example):
customer_trigger = PGTrigger(
schema="public",
signature="trg_make_archive_of_changes_for_customers",
on_entity="public.customer",
definition="""
after insert or delete or update on
public.customer for each row execute function make_archive_of_changes('Customer')
"""
)
op.create_entity(customer_trigger)
Setting up the files
Clone the PhpReport repository https://github.com/Igalia/phpreport
in
a location available to the web server. The usual default location for
the Apache web server is: /var/www/html/
Alternatively, clone it elsewhere and create a link from the web server directory.
You must also run composer dump-autoload -o
inside PhpReport root
directory, so it can generate the autoload files. Then, run
composer install
to install the project dependencies.
Creating the schema and initial data of the database
The configuration file with the default values already exists in the repository, so you don't have to touch it unless you changed any data in the first step.
Then, you can follow the step three in the installation instructions (either the manual or the wizard setup) to create the schema and initial data.
Setup autogenerated files
You can optionally minify the JS source with make minify
. You should
be able to debug it because there are source map files in place, but
take into account you would have to re-generate them with make minify
every time you modify a .js
file. In a development environment, it's
probably better not to minify the sources.
Create necessary .env files in your project
Using the .env.example as a template, create an .env at the root and one inside frontend
and set the values to fit your environment.
Running the API
Before you try the application, you'll want to get the API server running. To do so, follow the instructions in the api documentation section
Running the frontend (React)
If you only want to want the React portion of the frontend and not the PHP portion, you can run npm run dev
in the frontend
folder. This will spin up a server at `http://localhost:5173/web/v2'
If you want to run everything together (exisiting PHP app, new API, and new frontend), it is easiest to run npm run build
in the frontend
folder. This will compile your JS to the web/v2
folder.
Try the application
Use a browser to open the correct URL of your web server (very likely,
http://localhost/phpreport
), then use the user name admin
and the
password admin
to try a user with full privileges, or user
with
password user
to try a login with restricted permissions. You will
also be able to create users with any permission level once you are
logged in as admin
.
Running automated tests
There 2 types of tests in the project: unit and integration tests.
The unit tests will work locally without issues, but the integration tests will only work if there is a service running on the port 8000 with the data from the [sql/initialData.sql]{.title-ref} file. In that case it's easier to run it with docker, as it has everything setup.
In one terminal build and run the application and the database:
docker-compose -f docker/docker-compose.test.yml up --build --renew-anon-volumes
In a second terminal run the test
container to run the tests:
docker-compose -f docker/docker-compose.test.yml run -T test
If you don't want to setup docker, it's possible to run only the unit
tests. Make sure you have composer and the projects dependencies
installed. To install the dependencies run composer install
in the
project root directory.
All the automated tests should be placed inside the tests
directory.
From the project root, run ./vendor/bin/phpunit --testdox tests/unit
to execute the automated tests.
Documentation
The application documentation is published using mdBook. To preview the output of mdBook locally, ensure you have mdBook installed, then run mdbook serve
at the root of the project.
API documentation is autogenerated using the OpenAPI standard. When running locally, you can view those docs at http://localhost:8555/docs
. The FastAPI framework also provides docs at http://localhost:8555/redoc
if you prefer ReDoc to Swagger.
Linting and Formatting
The API uses Flake8 for linting and Black for formatting.
The frontend uses ESLint and Prettier.