diff --git a/config/authorization/config.lisp b/config/authorization/config.lisp
index 4d234aa..947f44e 100644
--- a/config/authorization/config.lisp
+++ b/config/authorization/config.lisp
@@ -56,6 +56,9 @@
:reporting "http://lblod.data.gift/vocabularies/reporting/"
:oslc "http://open-services.net/ns/core#"
:cogs "http://vocab.deri.ie/cogs#"
+ :sioc "http://rdfs.org/sioc/ns#"
+ :sioct "http://rdfs.org/sioc/types#"
+ :as "https://www.w3.org/ns/activitystreams#"
)
(type-cache::add-type-for-prefix "http://mu.semte.ch/sessions/" "http://mu.semte.ch/vocabularies/session/Session")
@@ -220,7 +223,8 @@
("code:EredienstBeroepen" -> _)
("code:Rechtsvormtype" -> _)
("prov:Location" -> _)
- ("code:BijkomendeKwalificatieCode" -> _))
+ ("code:BijkomendeKwalificatieCode" -> _)
+ ("prov:SoftwareAgent" -> _))
(define-graph shared ("http://mu.semte.ch/graphs/shared")
("foaf:Image" -> _)
@@ -266,6 +270,22 @@
("nfo:DataContainer" -> _)
("nfo:FileDataObject" -> _))
+;; Chat: one graph per account, only its owner reads or writes it.
+;; The four chat types appear in no other group: a graph-less insert lands
+;; in every graph whose group allows the type.
+(define-graph chat ("http://mu.semte.ch/graphs/users/")
+ ("reporting:Report" -> _)
+ ("oslc:Error" -> _)
+ ("nfo:DataContainer" -> _)
+ ("nfo:FileDataObject" -> _)
+ ("cogs:Job" -> _)
+ ("nfo:DataContainer" -> _)
+ ("nfo:FileDataObject" -> _)
+ ("sioc:Thread" -> _)
+ ("sioc:Post" -> _)
+ ("sioct:InstantMessage" -> _)
+ ("as:Document" -> _))
+
(supply-allowed-group "public")
(supply-allowed-group "o-admin-rwf"
@@ -336,12 +356,20 @@
FILTER( ?session_role = \"ABBOrganisatiePortaalErediensten-beheerder\" )
}")
+(supply-allowed-group "chat-owner"
+ :parameters ("session_account")
+ :query "PREFIX session:
+ PREFIX mu:
+ SELECT DISTINCT ?session_account WHERE {
+ session:account/mu:uuid ?session_account.
+ }")
+
(grant (read)
:to-graph (acmidm-lezer acmidm-vendor)
:for-allowed-group "ABBOrganisatiePortaalGebruiker-lezer")
(grant (read write)
- :to-graph (acmidm-editeerder acmidm-vendor)
+ :to-graph (acmidm-editeerder acmidm-vendor chat)
:for-allowed-group "ABBOrganisatiePortaalGebruiker-editeerder")
(grant (read write)
@@ -366,4 +394,8 @@
(grant (read write)
:to-graph (reports jobs system-jobs)
- :for-allowed-group "o-admin-rwf")
\ No newline at end of file
+ :for-allowed-group "o-admin-rwf")
+
+(grant (read write)
+ :to-graph (chat)
+ :for-allowed-group "chat-owner")
diff --git a/config/delta/rules.js b/config/delta/rules.js
index 33289e8..1cc784b 100644
--- a/config/delta/rules.js
+++ b/config/delta/rules.js
@@ -199,6 +199,27 @@ export default [
gracePeriod: 1000,
ignoreFromSelf: true
}
+ },
+ // The chat's data (per-user graphs) is written straight to the store by
+ // the natural-language-report service, so mu-cl-resources only sees it
+ // fresh when a delta clears its caches.
+ {
+ match: {
+ subject: {}
+ },
+ callback: {
+ url: 'http://resource/.mu/delta',
+ method: 'POST'
+ },
+ options: {
+ resourceFormat: 'v0.0.1',
+ gracePeriod: 250,
+ ignoreFromSelf: true,
+ optOutMuScopeIds: [
+ "http://redpencil.data.gift/id/concept/muScope/deltas/initialSync",
+ "http://redpencil.data.gift/id/concept/muScope/deltas/vendor-data"
+ ]
+ }
}
/*
Commenting ldes rules until ready to go to qa/prod. In the meantime, we override the configuration on dev.
diff --git a/config/dispatcher/dispatcher.ex b/config/dispatcher/dispatcher.ex
index 1fcc85b..35c5e2a 100644
--- a/config/dispatcher/dispatcher.ex
+++ b/config/dispatcher/dispatcher.ex
@@ -248,6 +248,47 @@ defmodule Dispatcher do
Proxy.forward(conn, path, "http://resource/kbo-organizations/")
end
+ ###############################################################
+ # CHAT
+ # To the resource service, not the cache: the data is per user and
+ # changes every few seconds.
+ ###############################################################
+
+ match "/chat-conversations/*path", %{accept: [:json], layer: :api} do
+ Proxy.forward(conn, path, "http://resource/chat-conversations/")
+ end
+
+ match "/chat-messages/*path", %{accept: [:json], layer: :api} do
+ Proxy.forward(conn, path, "http://resource/chat-messages/")
+ end
+
+ match "/chat-instant-messages/*path", %{accept: [:json], layer: :api} do
+ Proxy.forward(conn, path, "http://resource/chat-instant-messages/")
+ end
+
+ match "/chat-documents/*path", %{accept: [:json], layer: :api} do
+ Proxy.forward(conn, path, "http://resource/chat-documents/")
+ end
+
+ match "/chat-agents/*path", %{accept: [:json], layer: :api} do
+ Proxy.forward(conn, path, "http://resource/chat-agents/")
+ end
+
+ # The chat frontend's login screens speak the gebruiker/bestuurseenheid
+ # resource names (frontend-lblod-chat, used verbatim). The same data as
+ # /users and /groups, seen through the loket naming.
+ match "/gebruikers/*path", %{accept: [:json], layer: :api} do
+ Proxy.forward(conn, path, "http://cache/gebruikers/")
+ end
+
+ match "/bestuurseenheden/*path", %{accept: [:json], layer: :api} do
+ Proxy.forward(conn, path, "http://cache/bestuurseenheden/")
+ end
+
+ match "/bestuurseenheid-classificatie-codes/*path", %{accept: [:json], layer: :api} do
+ Proxy.forward(conn, path, "http://cache/bestuurseenheid-classificatie-codes/")
+ end
+
# Dashboard
match "/jobs/*path", %{accept: [:json], layer: :api} do
Proxy.forward(conn, path, "http://cache/jobs/")
@@ -417,6 +458,15 @@ defmodule Dispatcher do
forward(conn, path, "http://error-report-service/error-reports/")
end
+ #################################################################
+ # CHAT ASSISTANT
+ # The chat's turn endpoint: POST /assistant/conversations/:id/turns
+ #################################################################
+
+ match "/assistant/*path" do
+ forward(conn, path, "http://natural-language-report/assistant/")
+ end
+
#################################################################
# FILES
#################################################################
@@ -491,6 +541,20 @@ defmodule Dispatcher do
forward conn, [], "http://frontend-dashboard/index.html"
end
+ # The chat frontend (frontend-lblod-chat). Hosted on the "chat"
+ # subdomain (reverse_host), so the SPA stays a separate app.
+ get "/assets/*path", %{ reverse_host: ["chat" | _rest], layer: :api } do
+ forward conn, path, "http://chat/assets/"
+ end
+
+ get "/@appuniversum/*path", %{ reverse_host: ["chat" | _rest], layer: :api } do
+ forward conn, path, "http://chat/@appuniversum/"
+ end
+
+ match "/*_path", %{ reverse_host: ["chat" | _rest], layer: :api, accept: [:html] } do
+ forward conn, [], "http://chat/index.html"
+ end
+
match "/assets/*path", %{layer: :api} do
Proxy.forward(conn, path, "http://frontend/assets/")
end
diff --git a/config/resources/auth.json b/config/resources/auth.json
index 2046ef1..89d7781 100644
--- a/config/resources/auth.json
+++ b/config/resources/auth.json
@@ -53,6 +53,12 @@
"target": "user",
"cardinality": "one",
"inverse": true
+ },
+ "gebruiker": {
+ "predicate": "foaf:account",
+ "target": "gebruikers",
+ "cardinality": "one",
+ "inverse": true
}
},
"new-resource-base": "http://data.lblod.info/id/account/"
diff --git a/config/resources/domain.lisp b/config/resources/domain.lisp
index f2d2fd4..2e93235 100644
--- a/config/resources/domain.lisp
+++ b/config/resources/domain.lisp
@@ -16,6 +16,7 @@
(read-domain-file "domain.json")
(read-domain-file "auth.json")
+(read-domain-file "chat-domain.json")
(read-domain-file "change-events.json")
(read-domain-file "file.json")
(read-domain-file "dcat.json")
diff --git a/docker-compose.yml b/docker-compose.yml
index 71d640a..b589ddd 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -684,6 +684,43 @@ services:
restart: always
logging: *default-logging
+ ################################################################################
+ # CHAT / NATURAL LANGUAGE REPORTS
+ ################################################################################
+ natural-language-report:
+ image: lblod/natural-language-report-service:0.1.0
+ build: ../natural-language-report-service/
+ volumes:
+ - ./data/files:/share
+ - ./config/report-profiles/:/config/profiles/
+ environment:
+ MU_SPARQL_ENDPOINT: "http://db:8890/sparql"
+ CSV_SEPARATOR: ";"
+ SUBJECT_CHUNK_SIZE: "100"
+ ROW_LIMIT: "200000"
+ MAX_PATH_DEPTH: "8"
+ # The chat's turn answers in the background; full-organisation runs
+ # easily outgrow a minute.
+ RUN_TIMEOUT: "300"
+ INLINE_VALUES_MAX: "50"
+ VALUES_TTL: "3600"
+ labels:
+ - "logging=true"
+ restart: always
+ logging: *default-logging
+ chat:
+ image: lblod/frontend-lblod-chat:0.1.0
+ build: ../frontend-lblod-chat/
+ links:
+ - identifier:backend
+ environment:
+ EMBER_ASSISTANT_PATH: "/assistant"
+ EMBER_APP_NAME: "Rapportassistent"
+ labels:
+ - "logging=true"
+ restart: always
+ logging: *default-logging
+
###################################################################################
# MU SCRIPTS
# #################################################################################