Open-source blockchain-based track and trace system for an agricultural commodities (such as coffee) supply chain run. It provides transparency and creation of trust through digitalization of supply chains, connects every actor along the supply chain, assures quality and fair pricing.
Project is composed of 3 parts:
This new major release includes new functionalities, refactorings, optimizations and bugfixes. The most important additions and changes are:
11
or higher3
8.0.33
Clone the repository
Import as maven project to your preferred IDE
Prepare environment
Run INATraceBackendApplication.java
Spin up a container:
docker run --name inatrace-mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=inatrace -e MYSQL_USER=inatrace -e MYSQL_PASSWORD=inatrace -p 3306:3306 -d mysql:8.0.33
Tables will be created and prefilled with starter data on application startup.
MailHog is an email testing tool for developers. It runs a SMTP server on port 1025
which intercepts messages and displays them in a GUI.
Spin up a container:
docker run --name inatrace-mailhog -p 1025:1025 -p 8025:8025 -d mailhog/mailhog:v1.0.1
The GUI is available at localhost:8025
.
Spring uses application.properties
file stored in src/main/resources
for configuration. A template is provided, see instructions below.
application.properties.template
and save it as application.properties
NOTE: The values defined below are applicable for a local development environment. For other environments, change the values accordingly.
INATrace.database.name
: inatrace
spring.datasource.username
: inatrace
spring.datasource.password
: inatrace
spring.mail.protocol
: smtp
spring.mail.host
: localhost
spring.mail.port
: 1025
spring.mail.username
spring.mail.password
spring.mail.properties.mail.smtp.ssl.checkserveridentity
: false
spring.mail.properties.mail.smtps.auth
: false
INAtrace.mail.template.from
: info@inatrace.com
INAtrace.mail.redirect
INAtrace.mail.sendingEnabled
: true
(false
by default) INATrace.loginManager.mail
: registrations@inatrace.com
(Email address to receive notifications for new registrations)INAtrace.info.mail
: info@inatrace.com
(Contact email)INATrace.auth.jwtSigningKey
: sign
(Key for signing JWT tokens)INATrace.requestLog.token
: token
(Key for authorizing log requests)INATrace.fileStorage.root
: Path on local filesystem for saving images, documents, etc. (e.g. C:\\Users\\Name\\inatrace-backend
or /home/name/inatrace-backend
) INAtrace.exchangerate.apiKey
: API key for exchange rate service. Create a free account at https://exchangeratesapi.io to get an API key.INATrace supports integration with Beyco platform. This allows users to create Beyco offers automatically from INATrace stock orders. For more info about Beyco, please go to: https://beyco.nl
. This integration is optional. Integration properties are following:
beyco.oauth2.clientId
: clientId
beyco.oauth2.clientSecret
: clientSecret
beyco.oauth2.url
: url
The values of these properties are provided by Beyco. If integration with Byeco is not needed, the values of these properties should be empty.
Resources are annotated with Swagger annotations version 1.5.13
. After the application is started, the Swagger service definition JSON is served at http://localhost:8080/v2/api-docs
.
Using Postman, you can create a collection from the Swagger definition.
Import > Link
Continue
Import
Variables
baseUrl
to contain localhost:8080
as current valueAll requests are populated with sample requests, but the content is random. Fill in data to accomodate your test case.
Clients authenticate against POST /api/user/login
endpoint and receive a JWT token in the Set-Cookie
response header. The token is valid for 1 hour. See section Common requests below for a sample login request.
Response header | Value |
---|---|
Set-Cookie | inatrace-accessToken=JWT ; Path=/; Max-Age=3600; Expires=Thu, 24 Mar 2022 13:33:34 GMT; HttpOnly |
When accessing secured endpoints, the token has to be provided in the Cookie
request header.
Request header | Value |
---|---|
Cookie | inatrace-accessToken=JWT |
A complete list of endpoints is available here.
POST /api/user/register
{
"email": "test@user.com",
"password": "password",
"name": "Test",
"surname": "User"
}
POST /api/user/confirm_email
Insert token from the activation email message
{
"token": "2b7875bc-13ec-4cc3-bf75-21e9a5847d44"
}
POST /api/user/login
{
"username": "",
"password": ""
}
POST /api/user/admin/execute/ACTIVATE_USER
Find the user ID in the database.
{
"id": "2"
}
POST /api/common/image
Body: form-data
Key: file
Value: select file
Response:
{
"status": "OK",
"data": {
"id": 1,
"storageKey": "b822e079-7584-4489-ac78-81292d0c2c8c",
"name": "roasted_coffee_beans.jpg",
"contentType": "image/jpeg",
"size": 599153
}
}
POST /api/company/create
or PUT /api/company/profile
{
"name": "Coffe company",
"abbreviation": "CCC",
"headquarters": {
"address": "Coffee street",
"city": "Java",
"state": "Java",
"zip": "1000",
"country": {
"id": "104"
}
},
"about": "Making great coffee",
"manager": "Mana Ger",
"webPage": "inatrace.org",
"email": "info@inatrace.org",
"logo": {
"storageKey": "b822e079-7584-4489-ac78-81292d0c2c8c"
}
}
Response:
{
"status": "OK",
"data": {
"id": 1
}
}
POST /api/product/create
or PUT /api/product
{
"id":"integer",
"name":"string",
"photo":"ApiDocument",
"description":"string",
"origin": ApiProductOrigin,
"process": ApiProcess,
"responsibility": ApiResponsibility,
"sustainability": ApiSustainability,
"associatedCompanies": ApiProductCompany,
"company": ApiCompany,
"labels": ApiProductLabelValues,
"settings": ApiProductSettings,
"knowledgeBlog":"boolean"
}
Response is structured in following way:
It always contains attribute status
.
If response is successful, then status
is equal to 'OK' and appropriate response can be found under data
attribute.
If response is unsuccessful (see above link for other statuses), then errorMessage
attribute is returned.
Example of successful and unsuccessful response
{
"status": "OK",
"data": {
"id": 4,
"email": "example@example.com",
"name": "Example",
"surname": "Example",
"status": "ACTIVE",
"role": "SYSTEM_ADMIN",
"actions": [
"VIEW_USER_PROFILE",
"UPDATE_USER_PROFILE"
],
"companyIds": [
1
]
}
}
{
"status": "AUTH_ERROR",
"errorMessage": "Invalid credentials"
}
Currency service manages exchange rate data retrieval and currency conversion.
The service uses exchangeratesapi.io API for fetching currency conversion rates. It runs daily at 00:01 system time. The API is limited to 250 requests per day.
The service exposes methods convert
and convertAtDate
to convert between any two supported currencies. convert
uses the latest localy stored rate. convertAtDate
uses the rate at the specified date. If the exchange rate for the specified date is not stored locally it fetches it from the API.
MySQL 8.0.33
If you are using a database management tool, use the following parameters to create a connection:
localhost
3306
inatrace
root
root
true
allowPublicKeyRetrieval
: true
A complete list of entities is available here.
Below is the entity graph for an initialized INATrace database. The full-sized vector image can be found here.
There are two types of users:
System users are used for logging in. Based on their role, they have different permissions inside the system. Available roles are:
Company users are essentially role mappings for system users within a company. Based on their role, they have different permissions in the context of the company. A system user with role User can have the role Admin in a company. Available company roles are:
Some items have names, descriptions and other data in multiple languages. To enable extensible adding of translations, these entities have a one-to-many mapping to corresponding Translation entities (e.g. Company and CompanyTranslation).
Flyway is used to update the database when adding, changing or removing rows or columns. Here's how to configure a migration:
com.abelium.inatrace.db.migrations
package and implement JpaMigration
V<yyyy>_<MM>_<dd>_<hh>_<mm>__<Descriptive_Operation_Name>
@Override
the migrate
methodThe migrations run automatically at application startup. Once completed a record is created in table schema_version
. A migration does not run again if a record already exists.
To build an executable jar
run the following command in the project root directory:
mvn clean install
openjdk:11-jre-slim
Since only the major version is specified, the build process will always pull the latest minor and patch versions automatically.
To build and tag a Docker image run docker-build.sh
in the project root directory. The script runs mvn clean package
then builds and tags a Docker image with the resulting jar
.
./docker-build.sh <repo name (local or remote)> <tag> [push]
./docker-build.sh inatrace-be 2.4.0 push
Project INATrace welcomes contribution from everyone. See CONTRIBUTING.md for help getting started.
Copyright (c) 2023 Anteja ECG d.o.o., GIZ - Deutsche Gesellschaft für Internationale Zusammenarbeit GmbH, Sunesis ltd.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see http://www.gnu.org/licenses/.