summaryrefslogtreecommitdiff
path: root/server/NOTES
blob: 01fefd68c7cf7b86a32b06b7cc08c0ae98701482 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
-*- auto-fill -*-
################
# XML struktur #
################
Templates skal indeholde strukturer, men ingen makroer. En template
indeholder et course (forløb), som refererer til makroer, vha. navn.
I makroreferencerne står dependencies og optional/required.

Makronerne findes seperat i egne filer, så de kan genbruges i flere
forløb uden duplikering. Makroerne indeholder queries og maps til de
widgets de indeholder.

Specielle include makroer skal stilles til rådighed for makroerne som
betsår af klumper af widgets som kan indsættes i en makro. Disse skal
ligeledes lagres i seperate filer.
Include makroerne skal være self contained, dvs. de skal selv
indeholde de queries og maps de skal bruge.

Kan include makroerne undværes hvis man blot lader includes inkludere
andre makroer?

Hvad er den egentlige forskel på en includemacro og en macro?

Hvis include blot er en anden makro, hvor det eventuelle ydre vindue
ignoreres, kan deciderede include makroer helt undværes.

Makroer kan skrives med det formål at de skal inkluderes, hvormed
deres ydre vindue helt undlades. For at det skla kunne lade sig gøre
skal det ydre vindue ikke være påkrævet i specifikationen

Hvordan skal klienten reagere hvis den modtager en makro uden ydre
vindue?
En løsning kan være blot at bruge den yderste widget som vindue.
En anden løsning kan være at ignorere makroen (Der er alligevel
forksel hvad der accepteres på serverens xml og klientens xml).

Et tag includeable kan overvejes, så det kun er makroer der er
designede til det som kan inkluderes.

#############################
# Pracro database interface #
#############################
Databasen skal dybest set kunne 2 ting: skrive commits og genindlæse
gamle værdier til preudfyldning af makroer.

Database modulet skal kunne oprettes uden at det connectes, og
disconnectes explicit, med henblik på genbrug af connection, for at
spare tid i udførslen af en request.

Skal database objektet lave en connection pr. transaktion? Eller skal
der laves et system med en connection pool?
Det afhænger naturligvis af om det er hurtigt nok med en connection
pr. transaktion.

Alle opslag skal laves initielt, og så skal queries efterfølgende
laves 'lokalt', i et result set (std::map eller lign.).

###################
# Svar fra server #
###################
Svaret fra pracro serveren til klienten skal udover svar på eventuelle
makro queries indeholde en liste af errorcodes tilhørende de atomare
elementer i transaktionne, specielt commits.

Det er vigtigt at man på klienten kan få at vide hvis der gik noget
galt i en commit.

############
# Ordliste #
############
 forløb:   course
 makro:    macro
 skabelon: template

#######################################
# Navngivning af markoerne i requests #
#######################################
En makro er nested indeni en template paa serversiden.
Makroen er logisk nested indeni en macrosequence.
Templatesne er navngivet efter den macro sequence den indeholder.
Man skal referere til baade macrosequencen og macroen for at faa fat i den.

Eksempel:
<request macrosequence="forundersoegelse" macro="stamdata"/>

##################
# Makro editoren #
##################
Den skal kunne uploade makroer/templates til serveren, som validerer
 dem inden de lagres. Under lagringen skal versioneringen samtidig
 foregaa.

Editoren skal laese makroerne/templatesne direkte fra serveren, saa en
 servernaer editering bliver bibeholdt, blandt andet med henblik paa
 versionering.

###################
# Makro templates #
###################
En makro template består af fire dele:
 1: Header
 2: Queries
 3: Maps
 4: Widgets

Headeren indeholder alle overordnede info, såsom cpr nummer og makro
 version.

Queries udføres af serveren een gang og resultaterne mappes til nogle
 symboler som kan bruges i value felterne i widgets sektionen.

Der skal være mulighed for simpel aritmetik i mapningsfunktionerne.

Widgets sektionen er som beskrevet andetsteds.

###########
# Queries #
###########
For hver makro er der defineret en raekke queries.

For at en query skal give mening, skal der være en stor mængde klasser
 man kan lave requests på.
 Disse klasser skal tilsammen beskrive al apparatur på afdelingen,
 hiraktisk, så man f.eks kan bede om "lensmeter" eller en konkret
 model.

En nedarvningsmodel kan bruges som inspirationskilde.

Der skal være mulighed for at hæfte flere klasser på det samme
 apparat, idet nogle apparater måler mere end een ting. (ala multipel
 nedarvning.)

En attribute "automap" soerger for at lave en default 1:1 mapning
 mellem vaerdier i resultatet og value namespacet.
 Disse vil blive overskrevet af maps ved eventuelle overlap i navnene.

Eksempel paa en query til pentominos:
<query ttl="86400" class="lensmeter" automap="true"/>

Queries til pracro serveren selv bliver automatisk udfoert vha. tag
 navnet i wigdets sektionen.

Alle queries sker til pentominos. Hvis der bliver behov for at traekke
 data andre steder fra, skal dette ske via pentominos, istedet for
 direkte (Det er hele tanken bag pentominos, at den skal vaere
 samlingspunkt for alle taenkelige dataudtraek).

Sproget i en query som laver mapningen.
 -> class, cpr, timestamp (oldest)
 <- xml formateret

<?xml version="1.0" encoding="UTF-8"?>
<results>
  <result timestamp="1234567890">
    <group name="fisk">
      <value name="dims" value="42"/>
      <value name="fnuller" value="blah"/>
    </group>
    <group name="ostemad">
      <value name="dims" value="42"/>
      <group name="olm">
        <value name="fnuller" value="blah"/>
      </group>
    </group>
  </result>
</results>

Mapningerne kan således laves 1:1 fisk.dims, fisk.fnuller,
ostemad.dims og ostemad.olm.fnuller.

Eksempler på mapninger:
<map name="myvalue">
     return 2 * fisk.dims
</map>
<map name="anothervalue">
     return math.sin(fisk.dims / math.pi) + 42
</map>

Mapningssproget: LUA

En simpel map kan overvejes at bruges til enkelte expressions (det er
 muligvis de simple som skal hedde map og de avancerede som skal hedde
 complexmap).

De simple kan i koden pakkes ind i en return statement:
 <map name="myvalue" value="2 * dimmer"/>
 bliver til "return 2 * dimmer" som LUA kode.

De komplekse bliver ikke pakket ind i noget:
 <complexmap name="myvalue">
   function recurser( var )
     recurser( tail(var) )
     return head( var )
   end
   return recurser( [1, 2, 3, 4] )
 </complexmap>

En endnu simplere map kan bruges ved 1:1 mapninger:
 <simplemap name="myvalue" value="dimmer"/>
 Denne map type skal ikke engang koeres igennem LUA, men kan blot
 udfyldes direkte.

Hvis der performance maessigt ikke er nogen forskel paa map og
 simplemap kan simplemap helt undlades, for at bibeholde simpliciteten
 i serverkoden.

######################################
# Preudfyldning af felter i en makro #
######################################

Preudfyldningen skal ske serverside.

Det skal indikeres i feltet at det er preudfyldt og den information
 skal lagres sammen med dataene naar de senere bliver gemt paa serveren
 efter en commit.

Hvis preudfyldte felter aendres paa klienten, skal dette indikeres i
 de lagrede data.

Skal den preudfyldte vaerdi lagres, saa man altid kan se hvad det
 foreslaaede var?

Data som allerede eksisterer paa serveren:
 Hvis et felt allerede findes paa serveren fra en tidligere
  indtastning og dens ttl ikke er overskredet, skal feltet preudfyldes
  med denne vaerdi.

 TTLerne?
 Hvem skal saette dem?
 Hvor skal de saettes?

 Hvis de saettes paa feltet paa kontruktionstidspunktet, uafhangig af
  kilden, betyder det at feltet har samme udloebstid uanset om det er
  manuelt indtastet, eller indlaest fra en ekstern kilde.

 Et felts ttl vil nok vaere defineret uafhaengigt af kilden, saa
  ovenstaeende loesning kan sikkert vaere fin nok.

Data som kommer fra eksterne kilder (Pentominos):
 Et flest skal have en eller flere properties som indikerer at feltet
  skal udfyldes fra en ekstern datakilde.

 Disse properties skal beskrive hvilken kilde dataene skal hentes fra,
  samt hvor gamle dataene maksimalt maa vaere.

%%
%% Flg. er slettet
%%
% En maade at goere det paa kunne vaere at kalde en ekstern applikation
%  (via. popen eller lign.) som spytter data ud paa stdout i et af
%  pracro velkendt format.
%  Parametrene til dette eksterne program kan saa styres vha. af en
%  lignende mekanisme som i formatet til journal resumeet ($$, ${cpr},
%  ${firstname}, etc).
%
% En anden maade at goere det paa kunne vaere at lave et indbygget
%  kommandosaet som kan tage en raa streng som parameter, som derved
%  fungerer som kald til et eksternt program, bortset fra at der kaldes
%  en intern rutine istedet.
%
% En tredie maade, som er en afart af den anden maade, vil vaere at
%  lave kommandsaet baseret udelukkende paa kilde. [kilde]/[apparat]/[parameter]
%  ex. pentominos/lensmeter/axis
%  Problem: Hvordan skelnes mellem flere ensnavngivne parametre?
%  I lensmeter findes axis parameteren principielt to gange, een gang
%  for hoejre og een gang for venstre linse.

Hvis der baade eksisterer data paa serveren og findes ekstern data.
 Dataene paa serveren har precedens over data fra eksterne kilder,
 hvis:
  a) Dataene paa serveren er nyere end dem fra den eksterne kilde.
  b) Dataene paa serveren er indtastet af en bruger og stadig gyldige.

 Hvis der hverken findes gyldig data (ikke eksisterende eller
  udloebet) paa serveren eller fra den eksterne kilde (igen ikke
  eksisterende eller udloebet) benyttes value feltets indhold.

%%
%% Flg. er slettet
%%
%Pentominos data eksempel:
%  Serveren laeser:
%  <lineedit name="dioptri_odex"
%            source="pentominos/lensmeter"
%            command="cliclient --cpr=${cpr} query --filter=latest --deviceid=lensmeter --devicetype=lensmeter --format=xml"
%            ttl="86400"
%            value=""/>
%
%  Serveren oversaetter dette til:
%  <lineedit name="dioptri_odex"
%            value="4"
%	    source="pentominos/lensmeter"/>
%
%Taenkt eksempel med et fundus billede:
%  Serveren laeser:
%  <image name="dioptri_odex"
%         source="pentominos/fundus"
%         command="cliclient --cpr=${cpr} query --filter=latest --devicetype=fundus --format=raw"
%         ttl="86400"
%         value="SOMERAWJPEGCODEINBASE64-9823fasd73487234fas7asd8732487asd8fc7sd8f76328732"/>
%
%  Serveren oversaetter dette til:
%  <image name="dioptri_odex"
%         value="SOMERAWJPEGCODEINBASE64-9823fasd73487234fas7asd8732487asd8fc7sd8f76328732"
%         source="pentominos/lensmeter"/>


###################################
# Avanceret validering af widgets #
###################################

LUA Ide:
  LUA som validering, sat i serie med en regexp validering. Begge kan
   vaere tomme, eller udeladt (svarende til tomme).

  Hver widget optraeder automatisk som preloaded variabel i lua
   programmet.

  Programmet indeholder en funktion validate som returnerer true eller
   false afhaengigt af om den er valid eller ej.

  Hvad med reserverede karaterer i hhv. LUA og XML? skal lua koden base64 enkodes?
   Eller maaske bare XML kodes (i.e. &quot; osv.)

  Hvornaar skal koden udfoeres? Naar feltet aendres? Naar feltet forlades (lost
   focus) eller inden makroen comittes?

  Flere funktioner kan introduceres for at kunne udfoere lua kode paa forskellige
   tidspunkter (onfocus(), onfocusleave(), onchange(), beforecommit(), etc...)

  Istedet for at bruge direkte mapninger mellem variable og widgets kan man bruge
   et array (eller hvad der nu svarer til map< std::string, std::string > i c++),
   saa man slipper for at overskrive nogen af LUAs interne variable og funktioner.
   Hvis der ikke findes en saadan type i LUA kan man lave et funktionkald ind i c
   koden som goer det, altsaa field('varname')

  Injicering af data i makroen paa runtime.
   Et funktionskald fra lua programmet saetter vaerdien af et felt.

  En serie af funktioner kan introduceres til at kontrollere GUI igennem LUA.
   Funktioner som disable('button1'), uncheck('checkbox2'), osv.
   Disse funktioner skal bruges til at lave selve makroindholdet dynamisk, saa man
   f.eks vaelger en radiobutton som aktiverer en hel undersektion af lineedits.
   Alt dette kan muligvis implementeres vha. checkbox/radiobutton grupper istedte,
   saa man slipper for denne forholdsvis dybe kontrol paa LUA niveau (laes, der er
   mange muligheder for fejl!)

Eksempel:
<lineedit name="dioptri_odex"
          regexp="[1-9][0-9]{0,2}"
          lua="function validate() return math.abs(fields['dioptri_odex'] - fields['dioptri_osin']) < 3 end"
          value=""
          help="Dioptrien på venstre øje skal være max 2 dioptri fra højre."/>
<lineedit name="diotri_osin"
          regexp="[1-9][0-9]{0,2}"
          lua="function validate() return math.abs(fields['dioptri_odex'] - fields['dioptri_osin']) < 3 end"
          value=""
          help="Dioptrien på højre øje skal være max 2 dioptri fra venstre."/>

##################################
# Forløb og deres struktur i xml #
##################################

Makro er en del af et forløb

Forløb skal sammensætte makroer i logiske sekvenser.
 - Backward dependancy
 - Forward dependancy
 - Optional
 - Required

Et forløb beskrevet som et komplet xmldokument?
 - Alle makroer er indeholdt i et større dokument, forløbet.
 - Når data postes, lagres forløbs id sammen med makro id'et.
 - Der er indbygget i xml strukturen en logisk sammenhæng mellem makroerne
   (dependencies o. lign.).
 
Eksempel:
<forløb>
  <makro navn="makro1" completed="true" optional>
    ...
  </makro>
  <makro navn="makro2" depencies="makro1" required>
    ...
  </makro>
  <makro navn="makro3" depencies="makro2" optional>
    ...
  </makro>
  <makro navn="makro4" optional>
    ...
  </makro>
  <makro navn="makro5" optional>
    ...
  </makro>
  <makro navn="makro6" depencies="makro1,makro5" required>
    ...
  </makro>
</forløb>

Eksempel med B2 forloebet i pseudokode:
B2 req

B21 dep=B2 opt

B22 - B26, B28 dep=B2,B21 opt

B27 dep=B2,B21 req

B29 dep=B27 req

#############################################
# CPR indtastning, hvordan? hvor? hvornaar? #
#############################################

 1) - CPR nummeret hentes fra sygesikringsbevis eller RFID eller lign.
    - Det sendes til cpr server (ligesom paa barcode)
    - Naar et apparat skal sende data henter det foerst cpr nummeret vha.
      sit lokationnummer.

 2) - CPR nummeret hentes fra sygesikringsbevis eller RFID eller lign.
    - Det sendes til pentominos med lokationsnummer som raa data som alle
      andre apparater.
    - Naar der sendes data fra et andet apparat vedhaeftes kun lokationkoden,
      og det er pentominos serverens ansvar at vide hvilket cpr nummer der
      skal bruges.
 
 3) - CPR nummeret hentes fra sygesikringsbevis eller RFID eller lign.
    - Nummeret lagres lokalt paa den Soekris kassen.
    - Naar der sendes apparatdata vedhaeftes det lagrede cpr nummer.

 4) - CPR nummeret hentes fra sygesikringsbevis eller RFID eller lign.
    - Nummeret sendes til en server sammen med et lokationsnummer.
    - Serveren har registreret hvilkemaskiner der findes paa den lokation
      og broadcatser cpr nummeret til disse.

 5) - CPR nummeret hentes fra sygesikringsbevis eller RFID eller lign.
    - Det sendes til cpr server (ligesom paa barcode)
    - Naar der sendes data fra et andet apparat vedhaeftes kun lokationkoden.
    - Pentominos serveren henter cpr nummeret fra cpr serveren vha. den
      vedhaeftede lokationskode.

Overvejelser:
 a - Data og kilde (cpr nummer) boer holdes samlet.
 b - Hvem har ansvaret for at cpr nummer og data haenger sammen.
 c - Hvem har ansvaret for at cpr nummer og data er rigtige?
 d - Fordele/ulemper ved at have een cpr indtastningsmekaniske pr. Soekris
     boks.
 e - Hvilken vej koerer forbindelserne? Kan de fungere igennem en firewall?
 f - Hvor mange forbindelser er der?
 g - Boer forbindelserne holdes i live fremfor at lave nye hver gang der
     skal kommunikeres?
 h - Hvilke muligheder vil vi have for central logning af hvor patienter
     bliver 'logget ind'?
 i - Hvor og hvordan skal cpr numrenes ttl implementeres?