-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
new version of handling besluit information #45
base: master
Are you sure you want to change the base?
Conversation
593dfca
to
993f177
Compare
6d2472c
to
a233d4b
Compare
d6638e7
to
873ac7a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just went over the code, mostly some things about variables or doing the same in a different way.
graph: string, | ||
) { | ||
const id = uuidv4(); | ||
const intervalUri = `http://data.lblod.info/id/tijdsintervallen//${id}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it need to be //
?
if (sparqlresult?.artikel) { | ||
return sparqlresult.artikel; | ||
return { | ||
besluit: sparqlresult.artikel.value, | ||
link: sparqlresult.link.value, | ||
}; | ||
} | ||
|
||
return null; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you prefer that the returning value of this function is of a different format?
Would remove the if and just add a ? after sparqlResult.artikel?.value
. Than you do have to change the logic where this method is called to check if (findDecisionForMandataris(URI).besluit)
instead of just the return value
} | ||
|
||
return null; | ||
} | ||
|
||
export async function updatePublicationStatusOfMandataris( | ||
mandataris: Term, | ||
mandataris: string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we create a URI type so we work with these and errors can be thrown when it is not a URI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
afaik a uri is just a string
mandataris: sparqlEscapeUri(mandataris), | ||
status: sparqlEscapeUri(status), | ||
mandatarisType: sparqlEscapeTermValue(TERM_MANDATARIS_TYPE), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we change mandataris to escapeUri we should also do it for the type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is a separate story to remove all uses of term from the mandataris service.
// keep these mandataris instances in the database instead of memory | ||
// so if we crash we know they should still be processed | ||
// wait BUFFER_TIME to process the mandataris so we are reasonably sure that we have all the info |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏻
); | ||
console.log( | ||
`|> Found ${incomingTriples.length} triples in the staging graph for mandataris.`, | ||
async function isValidMandataris(mandataris: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*mandatarisUri
? ('ontslag' as const) | ||
: ('aanstelling' as const), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or do we use an enum
for this?
} LIMIT ${BESLUIT_BATCH_SIZE}`; | ||
|
||
const result = await querySudo(query); | ||
return result.results.bindings.map((binding) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getSparqlResults.map(...
*
const safeMandatarisUri = sparqlEscapeUri(mandatarisUri); | ||
const safeGraph = sparqlEscapeUri(graph); | ||
const safeIntervalUri = sparqlEscapeUri(intervalUri); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uniform: do we want to do separate escapes or use the const escaped = { ... }
as did before?
mandataris: Term, | ||
): Promise<Term | null> { | ||
const mandatarisSubject = sparqlEscapeTermValue(mandataris); | ||
mandataris: string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mandatarisUri*
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried out the mock routes
-
Karel's: besluiten processing
- First mock route looks to be working correctly ✅
- second ✅
- third a notification is created for the unknown fractie ✅
- fourth: unknown mandaat error => checkIfMinimalMandatarisInfoAvailable returned and not throwing an error.. ❌
- incomplete person, error message => checkIfMinimalMandatarisInfoAvailable returned and not throwing an error.. ❌
- different fraction name => checkIfMinimalMandatarisInfoAvailable returned and not throwing an error.. ❌
- new beleidsdomein, info message => checkIfMinimalMandatarisInfoAvailable returned and not throwing an error.. ❌
It seems that the minimal info is often not valid because of the graph and after that the publication status is still changed to bekrachtigt?
Im open to check these last mock calls togheter!
(quad) => | ||
quad.graph.value.startsWith(BESLUIT_STAGING_GRAPH) && | ||
quad.predicate.value.startsWith( | ||
'http://data.vlaanderen.be/ns/mandaat#bekrachtigt', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the docs it just says to process mandaat:bekrachtigtAanstellingVan
(first point). A mandataris should only be set to bekrachtigd when it is an aanstelling?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it makes sense to handle both, even if it not mentioned in the docs, but I think the outcome should be different, but now they seem to be handled the exact same way?
for (const match of batch) { | ||
await safeProcessMandatarisForDecisions(match); | ||
} | ||
await cleanInstancesFromQueue(batch); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we also need to remove the batch from the staging graph?
873ac7a
to
f93e979
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The besluiten logic seems pretty solid, few remarks here and there. The code is not always as readable, a few more descriptive function names would help.
Few issues however with older logic, a method disappeared which is still used and a method seems to mix ids and uris, but this might just be the name that is misleading.
@@ -49,3 +50,4 @@ const errorHandler: ErrorRequestHandler = function (err, _req, res, _next) { | |||
app.use(errorHandler); | |||
|
|||
notificationBekrachtigdMandataris.start(); | |||
setTimeout(() => cronjob.start(), 10000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably remove this when actually merging this I guess?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit confused about these http vs https prefixes, both seem to be in use in our application.
async function findDecision(mandatarisUri: string): Promise<string | null> { | ||
const isMandataris = await mandataris.isValidId(mandatarisUri); | ||
if (!isMandataris) { | ||
throw new HttpError( | ||
`Mandataris with id ${mandatarisId} not found.`, | ||
`Mandataris with id ${mandatarisUri} not found.`, | ||
STATUS_CODE.BAD_REQUEST, | ||
); | ||
} | ||
const decision = await findDecisionForMandataris({ | ||
type: 'uri', | ||
value: mandatarisId, | ||
} as Term); | ||
const decision = await findDecisionForMandataris(mandatarisUri); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit confused about this, what is it? a uri or an id, because some statements seem to imply the first, other the second.
@@ -11,15 +11,15 @@ PREFIX euro: <http://data.europa.eu/m8g/> | |||
PREFIX euvoc: <http://publications.europa.eu/ontology/euvoc#> | |||
PREFIX ext: <http://mu.semte.ch/vocabularies/ext/> | |||
PREFIX foaf: <http://xmlns.com/foaf/0.1/> | |||
PREFIX generiek: <https://data.vlaanderen.be/ns/generiek#> | |||
PREFIX generiek: <http://data.vlaanderen.be/ns/generiek#> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this generiek prefix, if I look in the app, sometimes we seem to use http
and sometimes https
.
export function getIdentifierFromPersonUri(uri: string) { | ||
const personBaseUri = 'http://data.lblod.info/id/personen/'; | ||
if (!uri.includes(personBaseUri)) { | ||
return uuidv4(); | ||
} | ||
|
||
return uri.replace(personBaseUri, '').trim(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not used anymore.
); | ||
console.log( | ||
`|> Found ${incomingTriples.length} triples in the staging graph for mandataris.`, | ||
async function isValidMandataris(mandataris: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function name is not really descriptive. It does more than it says. It checks whether the madataris is valid and whether it has a besluit. Maybe you could call it isValidMandatarisWithBesluit
?
|
||
export const BESLUIT_STAGING_GRAPH = | ||
process.env.BESLUIT_STAGING_GRAPH || | ||
'http://mu.semte.ch/graphs/besluiten-consumed'; | ||
|
||
export const TERM_STAGING_GRAPH = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't used anymore.
GRAPH ?bestuurseenheidGraph { | ||
?mandaat a mandaat:Mandaat . | ||
} | ||
?bestuurseenheidGraph ext:ownedBy ?bestuurseenheid. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used so you don't have to exclude all special graphs?
PREFIX ext: <http://mu.semte.ch/vocabularies/ext/> | ||
PREFIX person: <http://www.w3.org/ns/person#> | ||
|
||
SELECT * { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The *
seems a bit inefficient if you only need the bestuurseenheidGraph.
OPTIONAL { | ||
?graph ext:ownedBy ?bestuurseenheid. | ||
} | ||
FILTER(?graph = <http://mu.semte.ch/graphs/public> || BOUND(?bestuurseenheid)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think public now also has the ext:ownedBy?
We need to do a second pass over the code to check we always exclude the besluiten staging graph. Now it is often implicit and sometimes the |
Testing:
|
Noticed two more things.
|
Description
Besluiten are now handled as described on the gitbook: https://app.gitbook.com/o/-MP9Yduzf5xu7wIebqPG/s/UYHyp4MV7ApSjjQn2DUx/algemene-informatie/besluit-harvesting
How to test
Use the mock route to receive besluit instances in the consumer graph. Verify that indeed they are processed as per the gitbook.
After each mock route check, run the clear decisions endpoint: localhost:8082/mock/clear-decisions
The mock routes are configured for use in provincie vlaams brabant as an example bestuurseenheid. Because of a delay of delta message processing you need to wait 10s before you see the notifications.
mock routes exist for:
Links to other PR's