= openKonsequenz - How to run the module "Statement Public Affairs"
:Date: 2020-06-09
:Revision: 0.3.0
:icons:
:source-highlighter: highlightjs
:highlightjs-theme: solarized_dark

<<<

IMPORTANT: Please be sure that you have installed and configured the following openKonsequenz modules!

* Portal (AuthNAuth)
* Contact Base Data

== Requirements
* Browser (Chrome or Firefox)
* For Linux based installation
** `statemtent-public-affairsBE.war` file after a successfully maven build located in `<back-end project root>/target`.
** `statemtent-public-affairsFE.war` file after a successfully npm build located in `<front-end project root>/dist`.

* For Docker based installation
** `statemtent-public-affairsBE.jar` file after a successfully maven build located in `<back-end project root>/target`.
** already configured and successful npm build results located in `<front-end project root>/dist`.


See *howToBuild* documentation.

== Prerequisites
* Configured Portal Available modules configuration - add statement module
* Contact Base Data module
* Configured AuthNAuth module

== Configure Keycloak
* AuthNAuth service users
* AuthNAuth SPA_Roles

Required Roles are:

[%header,cols=3*]
.User roles
|===
| Role | Assign to users | Description
| ROLE_SPA_ACCESS | all service users | General service access
| ROLE_SPA_OFFICIAL_IN_CHARGE | Official in charge users | Create and manage statements 
| ROLE_SPA_APPROVER | approvers | Approve statement responses
| ROLE_SPA_DIVISION_MEMBER | only division members | Enrich statement
| ROLE_ADMIN | admin users | Access administrator interfaces
|===

== Installation overview
The openK module Statement Public Affairs consists of a front end web application that communicates with a back end application via a RESTful interface. Both are independent of each other what allows different deployment options that should fit for common environments. Besides a properly configured authNAuth module and Contact Base Data module, the Statement Public Affairs module relies on a database for storing statement process data and a workflow engine that supports the statement specific workflow states and variables for the workflow gateway transition.
Described below are two common installation types, the installation on a Linux based host environment as well as a docker based version.  

== Linux based installation
The Linux based installation that follows the original guidelines of most openK modules uses an Apache Tomcat that runs both, the front-end web application and the back-end web application of the statement module. For storing the statement process data, a PostgreSQL database is used. The statement workflow process is supported by a Camunda workflow engine. In this installation guide, all services are deployed on the same host. You can adapt this according to your own environment if necessary.

=== Install and configure Apache Tomcat
The back-end and front-end web applications are deployed on a Apache Tomcat application sever. To run the Apache Tomcat application server a Java runtime has to be installed first.
For compatibility reasons with other modules, an openjdk-8 environment is required. This can be done via your application repository such as apt of the Linux distribution of your choice.

To install the Apache Tomcat application server, just download the respective version and follow the general installation guides on the Apache documentation.
https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.24/bin/apache-tomcat-8.5.24.tar.gz

Later, after successful configuration of the keycloak server, the Contact Base Data module, the statement database and the Camunda workflow engine, the statement module back-end and front-end web application can be deployed by copying the artifacts to the webapps folder of the extracted Apache Tomcat installation.

=== Install and deploy the database
All statement specific process data is is saved to in a relational database. Following already existing openK modules the PostgreSQL database was chosen as a default. 
At the time of the module implementation, the PostgreSQL database in version 9.5 was used.

First create a new user and database for the statement module (named spa_service in the example). The user and password should match the back-end module configuration.
[source, command]
----
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
	CREATE USER spa_service;
	CREATE DATABASE spa_service;
    ALTER USER spa_service with encrypted password 'service password';
	GRANT ALL PRIVILEGES ON DATABASE spa_service TO spa_service;
----

Then initialize the database with the init script 'createDB.sql' that can be found in the back-end source deploy/db folder.

The following database parameters are required for the statement module back-end configuration:

* Database URI and port
* Service username and password

=== Install and configure the Camunda workflow engine
The statement workflow process is supported by a Camunda workflow engine.
At the time of the module implementation, the Camunda worklflow engine in version 7.8.0 was used.
It can be downloaded from the following location:
https://downloads.camunda.cloud/release/camunda-bpm/tomcat/7.8/camunda-bpm-tomcat-7.8.0.tar.gz

To install the Camunda workflow engine, just download the respective version and follow the general installation guides in the Camunda documentation. In addition to that the authentication configuration has to be adapted to enable Basic-Auth for the engine REST interface.

Therefore add the following lines to the webapps/engine-rest/WEB-INF/web.xml of your Camunda tomcat installation:
[source, xml]
----
<filter>
  <filter-name>camunda-auth</filter-name>
  <filter-class>
    org.camunda.bpm.engine.rest.security.auth.ProcessEngineAuthenticationFilter
  </filter-class>
  <init-param>
    <param-name>authentication-provider</param-name>
    <param-value>org.camunda.bpm.engine.rest.security.auth.impl.HttpBasicAuthenticationProvider</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>camunda-auth</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
----

Then finish the installation and create a new service admin and service user and a tenant with id "spa" via the Camunda web-interface. The service user requires access to Deployment, Tasks, Process Definition and Process Instance.

The service user and password should match the back-end module configuration.

Then use the service user with the Camunda modeler to upload the statmenent.bpmn workflow model to the Camunda instance.
An alternate way to upload the statement.bpmn is via the following curl command:
[source, command]
----
curl --user username:password http://localhost:8480/engine-rest/deployment/create -F "data=@Stellungnahme.bpmn" -F "deployment-source=process-application" -F "deployment-name=Stellungnahme" -F "tenant-id=spa" -v
----


The following workflow engine parameters are required for the statement module back-end configuration:

* engine URI and port
* service username and password
* workflow identifier
* tenantId

=== Run the back-end
To run the module back-end, just deploy the artifact with a proper configuration to the Apache Tomcat instance.
For configuration details, please see section Configuration below.

=== Run the front-end
To run the module front-end, just deploy the artifact with a proper configuration to the Apache Tomcat instance.
For configuration details, please see section Configuration below.

== Docker based installation
Based on the Docker container philosopy, the docker container structure of the statement module is splitted up into multiple docker containers. The module front-end is implemented as a nginx based container that provides the module webapp. The module back-end is implemented as a Java runtime environment based container that runs the back-end as a spring application.

Please ensure that you have alreaady configured the front-end and that you have already build the front-end and back-end according to the howToBuild documentation. The front-end and back-end repositories contain buildDocker scripts that may help you with the build process by creating a closed build environment for reproducible builds.

=== Front-end
Building the front-end docker image requires already configured build artifacts.

The front-end docker image can be build from the project root folder (contains the package.json file).

=== Back-end
Building the back-end docker image requires build artifacts with the package-format 'jar'.

The back-end docker has the following folder structure:

* /app
* /app/bin
* /app/config
* /app/archive
* /app/logs

That folder structure can be found in the repository /docker/runenv folder.
The config folder contains all configuration files. They are baked into the docker image. For security reasons it might make sense to mount the configuration files when starting the back-end docker container.

To build the back-end docker image please see section 'Docker Compose - Blueprint'

=== Dependency Services - Blueprint
The back-end project /docker folder also contains docker recipes for dependencies. They can be used as a blueprint how to configure the dependency services in a production environment.

The folder /docker/postgresenv contains a docker recipe to create a postgreSQL based database instance that is initialized properly for the statement module.

The folder /docker/camundaenv contains a docker recipe to create a camunda workflow engine instance. It is automatically initialized with a statement module user, access rules and a deployed workflow by the start-scripts.

The folder /docker/openkmain contains a nginx based docker recipe that can be used as a reverse proxy to be able to access all configured openKONSEQUENZ modules at one host (like in the QA-Environment).

To run the other dependency openKONSEQUENZ services like the authNAuth module and the Contact Base Data module please see the module specific installation documentation.

=== Docker Compose - Blueprint
Docker compose is a tool to orchestrate multi-container Docker applications. There you can specify build options, run options and dependencies between configured docker containers.

The root folder of the module back-end repository contains a docker-compose.yml configuration that can be used as a blueprint to manage a openKONSEQUENZ service environment.
Please alter the configuration according to your environment.

To build the docker containers specified in the configuration use the following command:
[source, command]
----
$ docker-compose build
----

To start the docker containers specified in the configuration use the following command:
[source, command]
----
$ docker-compose up
----

== Configuration

=== Configuration of the Statement Public Affairs module back-end

The back-end service is configured with the `application.yml` file.

==== Configuration Settings
The back end configuration is separated into multiple configuration files.

The basic configuration values are located in the application.yml and are loaded when starting the back end service (see section Application YML).
Some of the configuration parameters refer to specific configurations that are described in the sections below.

===== Application YML
The back-end service is configured with the application.yml file.

* *spring*:
** *datasource*: Section for the database connection
*** url: jdbc:postgresql://serverdomain:port (default: 5432)/NameOfDatabase (Example: spa_service)
*** username: spa_service
*** password: <password of spa_service> see "Install and deploy the Database"


* *application*:
** name: \^project.artifactId^ extract name from the pom.xml at build time
* *build*:
** version: \^project.version^ extract version from pom.xml at build time

* *server*:
** port: 9156 port of the server when running as stand alone spring application

* *jwt*:
** tokenHeader: Authorization HTTP header key of the token
** useStaticJwt: false (enable only for testing)
** staticJwt: x (set static jwt token value when enabling useStaticJwt setting)

* *services*: Define service specific config root section
** *authNAuth*:
*** name: authNAuthService
** *camunda*:
*** name: camundaService
** *contactdatabase*:
*** name: contactDatabaseService
 

* *authNAuthService*: Section for the AuthNAuth service
** *ribbon*: 
*** listOfServers: http://localhost:8080 base URL of the AuthNAuth service
    
* *camundaService*: Section for the Camunda service
** *ribbon*: 
*** listOfServers: http://localhost:8280 base URL of the Camunda service

* *contactDatabaseService*: Section for the contact database service
** *ribbon*: 
*** listOfServers: http://localhost:9155 base URL of the contact database service

* *camunda*: User credentials for the service to authenticate against the Camunda service
** user: spa_service
** pw: password


* *authnauth*: User credentials for the service to authenticate against the AuthNAuth service
** technical-username: spa_service
** technical-userpassword: password


* *contactDatabase*: User credentials for the service to access the contact database
** technical-username: spa_service
** technical-userpassword: password


* *workflow*: Workflow specific configuration parameters
**  processDefinitionKey: statement_p key of the workflow process to use for the statement workflow
**  tenantId: spa tenant Id, the workflow is assigned to

* *feign*:
** *client*:
*** *config*:
**** *default*:
***** *connectTimeout*: (Default: 60000) Connection timeout for the REST-Calls (in ms).
***** *readTimeout*: (Default: 60000) Read timeout for the REST-Calls (in ms).

* *cors*:
** *corsEnabled*: (Default: false) (true or false) Cross-Origin Resource Sharing on/off

* *statement*:  
** *compile*:
*** dateFormatPattern: dd.MM.yyyy date format string in response texts (e.g. PDF response)
*** statementFileName: Statement.pdf file name of a generated response PDF
*** templatePdf: classpath:template.pdf path of the template.pdf file to user for generating the response PDF (see section Template PDF)
*** templateJson: classpath:template.json path of the template.json file for generating the response PDF texts (see section Template JSON)
** *authorization*:
*** path: classpath:authorization.csv path of the authorization configuration containing the authorization rules (see section Authorization CSV)
*** csv-delimiter: ; delimiter char of the authorization configuration CSV file entries

* *archive*:
** basefolder: /opt/statement/archive base folder path for the statement archive
** statementArchiveFolderName: <t:finishedDate>_<t:id>_statement name of the statement archive folder <t:finishedDate> and <t:id> are place holder keys

* *mail*:
** *account*:
*** *statement*:
**** properties: /opt/statement/config/mail-statement.properties path of the mail properties file for the statement mail box (see section Mailbox Config properties)
*** *notification*:
**** properties: /opt/statement/config/mail-notification.properties path of the mail properties file for the notification mail box
** newmailcheck: true check for new mails in statement inbox every minute and send notification mail to users with role SPA_STATEMENT_OIC
** configurationPath: /opt/statement/config/mailConfig.json path of the mailConfig json configuration (see section MailConfig)

===== Mailbox Config properties
There are two required mail box properties files. Both are properties are described in the sections below.
The configuration parameters have to be altered fit your mail server configuration.

====== Mailbox Config properties - statement

* mail.imap.host = imap.host.tld IMAP host address
* mail.imap.user = username username of the mail account
* mail.imap.password = password password of the mail account
* mail.imap.port = 993 port of the IMAP server
* mail.imap.auth = true enable authentication
* mail.imap.socketFactory.class = javax.net.ssl.SSLSocketFactory set SSL connections


* mail.smtp.host = smtp.host.tld SMTP host address
* mail.smtp.auth = true enable authentication
* mail.smtp.from = statements@company.tld email address of the sender
* mail.smtp.port = 465 port
* mail.smtp.socketFactory.port = 465
* mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
* mail.smtp.socketFactory.fallback = false

====== Mailbox Config properties - notification

* mail.imap.user = username username of the mail account
* mail.imap.password = password password of the mail account

* mail.smtp.host = smtp.host.tld SMTP host address
* mail.smtp.auth = true enable authentication
* mail.smtp.from = statements@company.tld email address of the sender
* mail.smtp.port = 465 port
* mail.smtp.socketFactory.port = 465
* mail.smtp.socketFactory.class = javax.net.ssl.SSLSocketFactory
* mail.smtp.socketFactory.fallback = false

===== Mail Config JSON
The mail configuration specifies the response email content values. It contains an entry for each notification type and the response email. There one can set the email subject and text body values. Notifications that reference a statement can contain a placeholder value for the statement identifier to allow linking to the specific statement (e.g. via an URL containing the statement identifier).

[source, json]
----
{
	"notificationInboxNewMail": {
		"subject": "[Statement] New statement request",
		"body": "Notification email body\n\nStatement module: https://url-to-the-statement service\n",
		"bccEmailAddresses": []
	},
	"notificationEnrichDraft": {
		"subject": "[Statement] Division contributions required",
		"body": "Notification email body can directly reference the statement with an <id> place holder value https://url../statementpaFE/details?id=<id>",
		"bccEmailAddresses": []
	},
	"notificationApprovalRequired": {
		"subject": "[Statement] Approval required",
		"body": "Notification email body ...",
		"bccEmailAddresses": []
	},
	"notificationNotApproved": {
		"subject": "[Statement] Not approved, rework required",
		"body": "Notification email body ...",
		"bccEmailAddresses": []
	},
	"notificationApprovedAndNotSent": {
		"subject": "[Statement] Approved, manual send required",
		"body": "Notification email body ..."
		"bccEmailAddresses": []
	},
	"notificationApprovedAndSent": {
		"subject": "[Statement] Approved and sent",
		"body": "Notification email body ..."
		"bccEmailAddresses": []
	},
	"notificationAllMandatoryContributions": {
		"subject": "[Statement] All mandatory departments contributed",
		"body": "Notification email body ..."
		"bccEmailAddresses": []
	},
	"statementResponse": {
		"subject": "[Statement] Response for your request - our sign <t:id>",
		"body": "Statement response email body ..."
		"bccEmailAddresses": []
	}
	
}
----

===== Template PDF

To generate a response letter in form of a PDF document the following procedure is used.

The PDF documents are generated by using a letter paper template PDF and a definition of the position and size of text blocks that are placed on the letter paper. The content structure of a response letter is as follows:

image::pdf-concept.png[]

As shown in the diagram above, the first page has a similar structure as a business letter. It contains of the three text blocks
 address-block, infodata-block and content-block. The address-block shows the recipient address with values like company address and and recipient name that are part of the statement-info-data-set. The infodata-block contains predefined text as well as information from the statement-infodata-set.

The text-block compilation that is created by the statement contributors is then printed as left-aligned text in the content-block. If the content exceeds the size of the content block of a page, an additional page that uses a different letter paper template and contains only a content-block is added. The letter ends with a predefined closing and a signature part.

The template can be configured according to a specific letter format and consists of a two page PDF document and a configuration file with the text-block positions and text-block sizes. Page one of the template PDF is the first page. Page two is used for all following pages.

===== Template JSON
Each text- block is referenced as follows:

* type [address | info | content-p1 | content-p2]
* top-left (x,y) position in cm (float) from the top-left document corner
* width, height in cm (float)
* text lines that can contain statement placeholders
* fontsize

The closing has special configuration including the salutation and up to two signature fields. The position is relative to the current text position.

Example configuration:
[source, json]
----
{
	"address": {
		"x": 2.5,
		"y": 5.8,
		"width": 10,
		"height": 5.0,
		"fontSize": 10
	},
	"info": {
		"x": 14.7,
		"y": 5.3,
		"width": 5.5,
		"height": 5.0,
		"fontSize": 6,
		"text": ["Dornheimer Weg 24", "64293 Darmstadt", "Telefon  06151 701-xxxx", "Telefax  06151 701-xxxx", "vorname.nachname@e-netz-suedhessen.de", "Ihr Zeichen: <t:customerReference>", "Unser Zeichen: <t:id>", "", "" ,"Datum <t:b-currentDate>" ]
	},
	"contentP1": {
		"x": 2.5,
		"y": 11.4,
		"width": 13.0,
		"height": 14.0,
		"fontSize": 10,
		"text": ["Sehr geehrte(r) <t:c-salutation> <t:c-title> <t:c-firstName> <t:c-lastName>,\n\n vielen Dank für Ihre Anfrage.\n\n\n"]
	},
	"contentP2": {
		"x": 2.5,
		"y": 5.3,
		"width": 13.0,
		"height": 20.0,
		"fontSize": 10
	},
	"closing": {
		"salutation": [
			"",
			"",
			"",
			"Mit freundlichen Grüßen",
			"Ihre e-netz Südhessen AG"
		],
		"signatures": [
			{
				"xoffset": 0,
				"yoffset": 2,
				"width": 5,
				"lines": [
					"Hans Huber",
					"Geschäftsführer"
				]
			},
			{
				"xoffset": 7.8,
				"yoffset": 2,
				"width": 5,
				"lines": [
					"i.A. Sepp Meier",
					"Netzbetrieb"
				]
			}
			
		]
	}
}
----

===== Authorization CSV
The authorization configuration is specific to the statement workflow definition. In general it should not be altered.
In case the statement workflow definition has changed and additional tasks are added, the configuration can be altered accordingly.

Each line contains a single authorization rule. It consists of the four columns:

* taskDefinitionKey
* required ROLE
* action
* special constraint

The default csv delimiter is ';'. It can be configured in the appliction.yml configuration (see section Application YML)

Default configuration:
[source, csv]
----
ANY; ROLE_SPA_OFFICIAL_IN_CHARGE; CREATE_STATEMENT; ANY
ANY; ROLE_SPA_OFFICIAL_IN_CHARGE; MANIPULATE_ATTACHMENTS; ANY
ANY; ROLE_SPA_OFFICIAL_IN_CHARGE; SEARCH_CONTACTS; ANY
ANY; ROLE_SPA_OFFICIAL_IN_CHARGE; MOVE_MAIL; ANY
ANY; ROLE_SPA_OFFICIAL_IN_CHARGE; FINISH_STATEMENT; ANY
ANY; ROLE_SPA_APPROVER; FINISH_STATEMENT; ANY

ANY; ROLE_SPA_ACCESS; READ_BASE_DATA; ANY
ANY; ROLE_SPA_ACCESS; READ_STATEMENT; ANY
ANY; ROLE_SPA_ACCESS; READ_MAIL; ANY
ANY; ROLE_SPA_ACCESS; READ_WORKFLOW_TASK; ANY
ANY; ROLE_SPA_ACCESS; UNCLAIM_TASK; ANY
ANY; ROLE_SPA_ACCESS; CREATE_COMMENT; ANY
ANY; ROLE_SPA_ACCESS; READ_STATEMENT_PROCESS_HISTORY; ANY
ANY; ROLE_SPA_ACCESS; DELETE_COMMENT; IS_OWN_COMMENT
ANY; ROLE_SPA_ACCESS; READ_DASHBOARD_STATEMENTS; ANY

addBasicInfoData; ROLE_SPA_OFFICIAL_IN_CHARGE; READ_WORKFLOW_TASK; ANY
addBasicInfoData; ROLE_SPA_OFFICIAL_IN_CHARGE; CLAIM_TASK; ANY
addBasicInfoData; ROLE_SPA_OFFICIAL_IN_CHARGE; MANIPULATE_ATTACHMENTS; IS_CLAIMED_BY_USER
addBasicInfoData; ROLE_SPA_OFFICIAL_IN_CHARGE; MANIPULATE_STATEMENT; IS_CLAIMED_BY_USER


addWorkflowData; ROLE_SPA_OFFICIAL_IN_CHARGE; READ_WORKFLOW_TASK; ANY
addWorkflowData; ROLE_SPA_OFFICIAL_IN_CHARGE; CLAIM_TASK; ANY
addWorkflowData; ROLE_SPA_OFFICIAL_IN_CHARGE; SET_PARENT_STATEMENTS; ANY
addWorkflowData; ROLE_SPA_OFFICIAL_IN_CHARGE; SET_REQ_DEPARTMENTS; ANY
addWorkflowData; ROLE_SPA_OFFICIAL_IN_CHARGE; SET_WORKFLOW_DATA; ANY


createDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; READ_WORKFLOW_TASK; ANY
createDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; CLAIM_TASK; ANY
createDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; SET_TEXTARRANGEMENT; IS_CLAIMED_BY_USER
createDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; MANIPULATE_ATTACHMENTS; IS_CLAIMED_BY_USER
createDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; SET_DEPARTMENT_CONTRIBUTIONS; ANY


enrichDraft; ROLE_SPA_DIVISION_MEMBER; READ_WORKFLOW_TASK; ANY
enrichDraft; ROLE_SPA_DIVISION_MEMBER; CLAIM_TASK; IS_REQ_DIVISION_MEMBER
enrichDraft; ROLE_SPA_DIVISION_MEMBER; SET_TEXTARRANGEMENT; IS_REQ_DIVISION_MEMBER
enrichDraft; ROLE_SPA_DIVISION_MEMBER; MANIPULATE_ATTACHMENTS; IS_REQ_DIVISION_MEMBER
enrichDraft; ROLE_SPA_DIVISION_MEMBER; MANIPULATE_ATTACHMENTS; IS_CLAIMED_BY_USER
enrichDraft; ROLE_SPA_DIVISION_MEMBER; SET_USER_CONTRIBUTED; ANY

enrichDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; READ_WORKFLOW_TASK; ANY
enrichDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; CLAIM_TASK; ANY
enrichDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; SET_TEXTARRANGEMENT; IS_CLAIMED_BY_USER
enrichDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; MANIPULATE_ATTACHMENTS; ANY
enrichDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; MANIPULATE_ATTACHMENTS; IS_CLAIMED_BY_USER
enrichDraft; ROLE_SPA_OFFICIAL_IN_CHARGE; SET_USER_CONTRIBUTED; ANY


checkAndFormulateResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; READ_WORKFLOW_TASK; ANY
checkAndFormulateResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; CLAIM_TASK; ANY
checkAndFormulateResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; SET_TEXTARRANGEMENT; IS_CLAIMED_BY_USER
checkAndFormulateResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; MANIPULATE_ATTACHMENTS; IS_CLAIMED_BY_USER
checkAndFormulateResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; REPLACE_STATEMENT_RESPONSE; IS_CLAIMED_BY_USER
checkAndFormulateResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; SET_DEPARTMENT_CONTRIBUTIONS; ANY

createNegativeResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; READ_WORKFLOW_TASK; ANY
createNegativeResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; CLAIM_TASK; ANY
createNegativeResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; SET_TEXTARRANGEMENT; IS_CLAIMED_BY_USER
createNegativeResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; MANIPULATE_ATTACHMENTS; IS_CLAIMED_BY_USER
createNegativeResponse; ROLE_SPA_OFFICIAL_IN_CHARGE; REPLACE_STATEMENT_RESPONSE; IS_CLAIMED_BY_USER


approveStatement; ROLE_SPA_APPROVER; CLAIM_TASK; ANY
approveStatement; ROLE_SPA_APPROVER; READ_WORKFLOW_TASK; ANY

sendStatement; ROLE_SPA_OFFICIAL_IN_CHARGE; READ_WORKFLOW_TASK; ANY
sendStatement; ROLE_SPA_OFFICIAL_IN_CHARGE; CLAIM_TASK; ANY
sendStatement; ROLE_SPA_OFFICIAL_IN_CHARGE; DISPATCH_STATEMENT_RESPONSE; IS_CLAIMED_BY_USER
----

=== Configuration of the Statement Public Affairs module front-end
The front-end application requires a configured web server and a configuration file with certain
properties for its general settings as described below.

==== Web server
The front-end web server requires a fall back configuration for all deep links to the application that returns
its main index.html file.

Configuration files for an Apache Tomcat server are already deployed to the `assets/WEB-INF` and `assets/META-INF`
folders as build artefacts, but other server types may require a different configuration
(see https://angular.io/guide/deployment#server-configuration[Angular docs] for more information).

==== General settings
The whole front-end application can be configured by certain properties in the `app.config.json` file in the source
directory prior to building. Thus, all changes to this configuration file only take effect after (re-)building the
front-end application.

===== Routes
* `routes.spaBackend`: Route on which the website's back-end is served
* `routes.portal`: Route on which the main portal is served
* `routes.contactDataBase`: Route on which the Contact Data Base front-end is served
* `routes.userDocu`: Route on which the user documentation is served

===== Leaflet
* `leaflet.urlTemplate`: URL template to the map tile server required by https://leafletjs.com[Leaflet]
* `leaflet.attribution`: Attribution which is added to all Leaflet map views
* `leaflet.lat`/`leaflet.lng`/`leaflet.zoom`: Default coordinates and zoom level to which all leaflet maps are
                                              initially configured

===== Nominatim
* `nominatim.url`: URL to a https://nominatim.org[Nominatim] geocoding service
* `nominatim.searchQueryPrefix`: Prefix which is added automatically to every https://nominatim.org[Nominatim]
                                 search query

===== Geographic Information System (GIS)
* `gis.urlTemplate`: URL template to a geographic information system (GIS)
* `gis.projectionFrom`: Coordinate projection used by the configured tile server
* `gis.projectionTo`: Coordinate projection used in the configured GIS

The following key words are replaced in the given GIS URL template for each map view:

* `{centerX}`, `{centerY}`: Center coordinates
* `{northEastX}`, `{northEastY}`: North east boundary coordinates
* `{northWestX}`, `{northWestY}`: North west boundary coordinates
* `{southEastX}`, `{southEastY}`: South east boundary coordinates
* `{southWestX}`, `{southWestY}`: South west boundary coordinates
* `{user}`: User name

All coordinates are transformed via a HTTP call to the back end before opening the GIS.
Please visit https://trac.osgeo.org/proj4j/[Proj4j] for all available projections.

===== Example configuration
[source, json]
----
{
  "gis": {
    "urlTemplate": "http://localhost/gis?pCX={centerX}&pCY={centerY}&pOSUser={user}",
    "projectionFrom": "EPSG:4326",
    "projectionTo": "EPSG:25832"
  },
  "leaflet": {
    "urlTemplate": "https://{s}.openk-tile-server.org/{z}/{x}/{y}.png",
    "attribution": "&copy; <a href=\"https://www.openk-tile-server.org\">TileServer</a> contributors",
    "lat": 49.87282103349044,
    "lng": 8.651196956634523,
    "zoom": 12
  },
  "nominatim": {
    "url": "https://nominatim.openk.org",
    "searchQueryPrefix": "Germany"
  },
  "routes": {
    "spaBackend": "/statementpaBE",
    "portal": "/portalFE",
    "contactDataBase": "/contactdatabase",
    "userDocu": "./assets/docu/userDocumentation.pdf"
  }
}
----
