Connector in opbouw.
Inleiding
FOCUS is de softwareapplicatie die lokale politiezones gebruiken om evenementen te beheren. De FOCUS-connector legt een link met deze applicatie om enerzijds evenementgegevens door te spelen (een happening) en anderzijds advies van de politie over dat evenement op te vragen en op te volgen (een adviesaanvraag).
Use case
De FOCUS-connector wordt ingezet in evenementgerelateerde dossiers waarbij een advies van de lokale politie nodig is vooraleer een evenement (sportmanifestatie, festival, rommelmarkt, enzovoort) kan doorgaan of vergund wordt.
Typisch verloop binnen een Skryv-toepassing:
-
Een burger of organisator dient een evenementaanvraag in via het digitale loket.
-
De workflow maakt een happening aan in FOCUS (
addHappening) met de evenementgegevens uit het dossier. -
De workflow voegt een adviesaanvraag toe voor de bevoegde politiezone (
addAdviceRequest). -
Zolang er nog geen advies is, pollt de workflow periodiek (bijvoorbeeld via een timer-event) of het advies al beschikbaar is (
getUnconfirmedAdvice). -
Zodra een advies beschikbaar is, haalt de workflow het advies en eventuele bijlagen op (
getAdvice,saveAdviceAttachment) en bevestigt de ontvangst (confirmAdvice). -
Het advies dient als input voor de verdere afhandeling van het dossier, bijvoorbeeld bij de beslissing of de motivering ervan.
-
Wordt de aanvraag ingetrokken of geannuleerd vóór het advies binnen is, dan trekt de workflow de adviesaanvraag in (
repealAdviceRequest).
Setup
Onboarding bij FOCUS
Neem via de lokale politiezone contact op met het FOCUS-team om de onboardingprocedure te doorlopen. Tijdens dit proces verkrijg je de informatie die je via de applicatie eigenschappen moet toevoegen. Je krijgt ook toegang tot de FOCUS OpenAPI-specificatie. Die heb je nodig om specifieke calls op te bouwen.
Dependency toevoegen in het pom.xml bestand
Voeg onderstaande dependency toe aan het pom.xml bestand van je applicatie. Dit zorgt ervoor dat de connector code ingeladen wordt bij de build van de applicatie.
<dependency>
<groupId>com.skryv.connectors</groupId>
<artifactId>focus</artifactId>
</dependency>
Applicatie eigenschappen
|
Eigenschap |
Default |
Beschrijving |
|---|---|---|
|
FocusProperties |
||
|
|
- |
FOCUS base URL |
|
|
|
Timeout (ms) |
|
|
- |
Token URL |
|
|
- |
Client ID |
|
|
- |
Client secret |
|
FocusBusinessConnector |
||
|
|
|
FOCUS provider name |
Services en functies
Overzicht
|
Functie |
Retourtype |
Info |
|---|---|---|
|
Object (ongetypeerd) |
Evenement aanmaken bij FOCUS. |
|
|
Object (ongetypeerd) |
Bestaand evenement opvragen. |
|
|
Object (ongetypeerd) |
Bestaand evenement wijzigen. |
|
|
Object (ongetypeerd) |
Adviesaanvraag koppelen aan een evenement, met zelf gegenereerde |
|
|
|
Nagaan of er een onbevestigd advies is voor een evenement (pollingstap). |
|
|
Advies-response (met bijlagenlijst en confirmationToken) |
Volledig advies opvragen voor een adviesaanvraag. |
|
|
|
Bijlage bij een advies ophalen en als dossierbijlage opslaan. |
|
|
(geen) |
Adviesaanvraag intrekken. |
|
|
Object (ongetypeerd) |
Ontvangst van een advies bevestigen (haalt intern zelf de confirmationToken op). |
Er zijn op dit moment geen kant-en-klare workflow expressies voorzien voor de FOCUS-functies. Elke aanroep verloopt via een workflow script task: de developer stelt daarin zelf de JSON-payload samen volgens de FOCUS OpenAPI-spec en roept de gewenste functie aan op de geïnjecteerde focus-bean. Dit is een bewuste, tijdelijke aanpak in afwachting van een uitgewerkte procesopzet met eigen businesslogica in de backend. Deze pagina is daarom momenteel enkel relevant voor developers, niet voor pure Studio-configuratoren.
Elke functie hieronder is, naast de workflow, ook rechtstreeks aanroepbaar vanuit Java-code door FocusConnector (bean focus) te injecteren in je klasse.
@RequiredArgsConstructor
public class MyOwnService {
private final FocusConnector focus;
}
addHappening
Java-code
Object response = focus.addHappening(request);
Input
|
Parameter |
Data type |
Uitleg |
|---|---|---|
|
|
JSON-object conform FOCUS OpenAPI-spec |
De evenementgegevens, samengesteld volgens de FOCUS OpenAPI-specificatie voor deze operatie. De connector legt geen eigen Skryv-modelstructuur op. Je bouwt het object zelf op, conform de FOCUS-specs, en geeft het ongewijzigd door. |
Top-level structuur van request (beide verplicht):
-
happening: de kerngegevens van het evenement:startTime,endTime,name(max 255),happeningTypeKey(enum:escort,filmShoot,localSoccer,manifestation,publicDomainIntake,studentActivity),externalId,externalReference, enlocation(één van vier varianten:fixedLocation,multipleFixedLocations,trailofspecialLocation). -
providerData: bijkomende context zoals contactpersonen, locatie-intakes, hindermuziek, activiteiten (bv. drones met piloten) en beveiliging/diensten.
Voor de volledige, gedetailleerde structuur (verplichte velden, enums, varianten) verwijzen we naar de FOCUS OpenAPI-documentatie zelf.
Output
Geen response body.
Error-handling
|
Statuscode |
Betekenis |
|---|---|
|
|
Succesvol aangemaakt. |
|
|
Onverwerkbaar (bv. verplicht veld ontbreekt of ongeldige waarde). |
getHappening
Java-code
Object response = focus.getHappening(externalId);
Input
|
Parameter |
Data type |
Uitleg |
|---|---|---|
|
|
String |
External ID van de happening die je wil ophalen. |
Output
Object, ongetypeerd. De spec definieert voor dit endpoint geen response-schema (enkel de statuscodes).
Error-handling
|
Statuscode |
Betekenis |
|---|---|
|
|
Happening bestaat niet. |
updateHappening
Java-code
Object response = focus.updateHappening(externalId, request);
Input
|
Parameter |
Data type |
Uitleg |
|---|---|---|
|
|
String |
External ID van de happening die je wil wijzigen. |
|
|
JSON-object conform FOCUS OpenAPI-spec |
Partiële update: je geeft enkel de top-level sleutel(s) mee die je wil wijzigen — |
Output
Object, ongetypeerd. Geen response-schema gedefinieerd (net als bij getHappening/addHappening).
Error-handling
|
Statuscode |
Betekenis |
|---|---|
|
|
Happening bestaat niet. |
|
|
Onverwerkbaar. |
addAdviceRequest
Java-code
Object response = focus.addAdviceRequest(externalId, adviceRequestId, request);
Input
|
Parameter |
Data type |
Voorbeeld |
Uitleg |
|---|---|---|---|
|
|
String |
- |
De external ID van de happening waarvoor advies gevraagd wordt. |
|
|
String |
- |
Zelf gegenereerde identifier voor deze adviesaanvraag (pad-parameter, vandaar PUT). |
|
|
JSON-object conform FOCUS OpenAPI-spec |
Zie onder |
De configuratie van de adviesaanvraag. |
Structuur van request (verplicht: type):
-
type(string, max 50): bv."Technisch advies". -
options(array, min. 2 items): de mogelijke adviesuitkomsten, elk metlabel,value(patroon^[a-zA-Z0-9_]*$) en optioneelfields(extra invulvelden metkey,label,required,maxLength). -
attachments(optioneel):allowedTypes(array, bv."IMAGE") enmaxAmount(1 tot 10).
Output
Geen output, anders dan statuscodes.
Error-handling
|
Statuscode |
Betekenis |
|---|---|
|
|
Happening aangemaakt. |
|
|
Happening bestaat niet. |
|
|
|
|
|
Onverwerkbaar |
getUnconfirmedAdvice
Deze functie is een pollingstap: ze haalt de volledige lijst van onbevestigde adviezen op voor de eigen provider (GET /happenings/{provider}/advices/unconfirmed) en filtert die client-side op externalId. Er is geen server-side filterparameter. Bij elke aanroep wordt dus de volledige lijst opgehaald en pas daarna doorzocht.
Java-code
UnconfirmedAdvice advice = focus.getUnconfirmedAdvice(externalId);
Input
|
Parameter |
Data type |
Uitleg |
|---|---|---|
|
|
String |
External ID van de happening waarvoor je wil weten of er een onbevestigd advies is. Bij |
Output
|
Situatie |
Resultaat |
|---|---|
|
Er is een onbevestigd advies voor deze |
Een |
|
Er is geen match, of de lijst is leeg |
|
De FOCUS OpenAPI-spec beschrijft dit endpoint met een andere responsvorm dan wat UnconfirmedAdvice verwacht:
-
Spec:
{ "references": [ { "id": "...", "adviceRequestKey": "..." } ] } -
Code verwacht: rechtstreeks een lijst van objecten met
externalId,externalAdviceId,status.
Error-handling
|
Situatie |
Gedrag |
|---|---|
|
|
Geen call naar FOCUS. Waarschuwing gelogd, functie geeft |
|
Geen match in de lijst |
|
getAdvice
Java-code
HappeningsProviderExternalIdAdviceRequestsAdviceRequestIdAdviceGet200Response response =
focus.getAdvice(externalId, adviceRequestId);
Input
|
Parameter |
Data type |
Uitleg |
|---|---|---|
|
|
String |
External ID van de happening. |
|
|
String |
ID van de adviesaanvraag. |
Output
|
Veld |
Uitleg |
|---|---|
|
|
Token nodig om het advies te bevestigen via |
|
|
Auteur van het advies. |
|
|
Tijdstip van het advies. |
|
|
De adviestekst zelf. |
|
|
Bijkomende, vrij ingevulde velden (structuur niet vast gedefinieerd in de spec). |
|
|
Lijst van bijlagen ( |
Error-handling
|
Statuscode |
Betekenis |
|---|---|
|
|
Happening bestaat niet, of er is nog geen advies voor deze adviesaanvraag. |
saveAdviceAttachment
Java-code
Attachment attachment = focus.saveAdviceAttachment(dossierId, externalId, adviceRequestId, attachmentId);
Input
|
Parameter |
Data type |
Uitleg |
|---|---|---|
|
|
String |
ID van het Skryv-dossier waaraan de bijlage toegevoegd moet worden. |
|
|
String |
External ID van de happening. |
|
|
String |
ID van de adviesaanvraag. |
|
|
String (uuid) |
ID van de specifieke bijlage, zoals opgelijst in |
Output
Een Attachment, opgeslagen bij het opgegeven dossier. Bestandsnaam en content-type worden niet uit het JSON-antwoord gehaald, maar rechtstreeks uit de HTTP-headers van FOCUS: de bestandsnaam komt uit Content-Disposition, het content-type uit Content-Type. De connector saniteert de bestandsnaam (verwijdert niet-toegelaten tekens) en garandeert dat er een extensie aanwezig is.
Error-handling
|
Situatie |
Gedrag |
|---|---|
|
Lege of ontbrekende bijlage-inhoud |
|
|
Geen bestandsnaam in |
|
|
Bestandsnaam zonder extensie na sanitisatie |
|
|
FOCUS geeft |
(niet apart afgevangen — zie algemeen openstaand punt over |
repealAdviceRequest
Java-code
focus.repealAdviceRequest(externalId, adviceRequestId);
Input
|
Parameter |
Data type |
Uitleg |
|---|---|---|
|
|
String |
External ID van de happening. |
|
|
String |
ID van de adviesaanvraag die ingetrokken wordt. |
De connector verstuurt hierbij zelf een leeg JSON-object als request body. Er is geen inhoudelijke input mee te geven.
Output
Geen output, anders dan statuscodes.
Error-handling
|
Statuscode |
Betekenis |
|---|---|
|
|
Ingetrokken. |
|
|
Happening of adviesaanvraag niet gevonden |
confirmAdvice
Java-code
Object response = focus.confirmAdvice(advice); // advice: UnconfirmedAdvice
Input
|
Parameter |
Data type |
Uitleg |
|---|---|---|
|
|
|
Het onbevestigde advies dat je wil bevestigen (bv. het resultaat van |
De connector haalt intern zelf eerst getAdvice() op om de confirmationToken te vinden, en stuurt die dan door naar FOCUS — je geeft die token dus niet zelf mee.
Output
Geen inhoud, anders dan statuscodes.
Error-handling
|
Statuscode |
Betekenis |
|---|---|
|
|
Bevestigd |
|
|
Ongeldige of ontbrekende |
|
|
Happening of adviesaanvraag niet gevonden |
|
|
Advies kan gewijzigd zijn sinds ophalen |