Table of Contents
Pracro - Praxis Macro system
New concepts
Upgrade from old to new database structure
Remove duplicate entries from fieldnames table:
delete from fieldnames where ctid not in (select max(dup.ctid) from fieldnames as dup group by dup.name);
Remove duplicates from fields:
delete from fields where ctid not in (select max(dup.ctid) from fields as dup group by dup.transaction, dup.name, dup.value);
ALTER TABLE transactions RENAME TO transactions_old;
CREATE TYPE session_status AS ENUM ('active', 'idle', 'committed');
Roadmap
See the roadmap page for details on how and when releases are made.
Widgets
See the widgets page for design details on new widgets.
Database
See the database page for database layout notes.
Random Stuff
Open/Close logic
GOALS:
- Only one open macro at any point of time.
- Not possible to close an unchanged macro by saving it.
- Warn the user if an unsaved macro is about to be collapsed.
When clicking on the expand/collapse button (the one with the ± on it) or on the title/line on top of the macro resume, the macro will be expanded.
Initially the 'Commit' button will be disabled, and stay that way until the user changes something in the macro.
The only exception to this is if the macro is loaded, prefilled with commit-able data, ie. data from Pentominos or other external sources, that simply needs to be committed to the database without further actions of the user.
When the commit button (or optionally abort button) is clicked, the macro will be collapsed, and its data either committed to the server, or thrown away.
If the expand/collapse button, or the title/line on the top of the macro is clicked, the macro will enter an 'about to collapse' mode:
If the macro contains no changes, it will simply be collapsed.
If the macro contains unsaved data, the user will be prompted to save these data and collapse, ignore the changes and collapse or stay open and do nothing.
If another macro is already open when the expansion is about to be initiated, the already open macro will enter 'about to collapse' mode. If the stay open option is selected, the new about to expand macro will stay collapsed.
Types
There are two types in the pracro database.
A simple
type, which is simply a text string, and a complex
type, which is a compound string containing nested key/value pairs encapsulated in ${key|value}
blocks.
The type is used when it is about to be inserted into a resume. If it is a simple type it is copied verbatim into the the resume. If it is
Resume text
If the resume text is stored with each transaction, the resume can be recreated at any point in time without consulting the XML files. Furthermore the recreated resume text can highlight all fields, thereby pointing out that they are values and not just surrounding text.
How to handle editing of prefilled macros
If a macro has already been committed t the journal and is opened for editing in the editor, is it then correct to assume that the user is about to correct a mistake made in the previous transaction? and if so, does it make sence to ask the user to fill in a reason for the editing, for later prepend at commit time?
Scenario:
A macro is already filled out.
A user clicks the open-for-edit button.
A pop-up box declares that “You are about to fix an error. Please specify your reason for this.”
The user fills in the lineedit, with the text “Correcting a spelling error”, and clicks OK.
he pop-up dialog closes and the macro expands for editing with all fields prefilled with the previous values.
The user corrects the error and clicks “Store”.
The new journal entry is committed with the reason-text prepended on a separate line.
Open Questions
- What to do in journal, when committing a result that is already there (for instance an error correction).
- What are the core functionality of Pracro??
Field database
In order to not flood the database with new fields every time a new macro is being inserted (where many of the fields are duplicates from other macroes with new names), a field table with uids, aliases and description should be created.
Every time a new field is created in a macro the existence of the field in this table must be verified.
The names (aliases) of these fields define which field values in a macro can be stored in the database, thus requiring the client to send all fields (with name attributes) and their values to the server.
Naming of the fields:
[context].[descriptor]
ex. henvisning.diagnose
ex. lensmeter.axis
or in some unique instances:
ex. cave
ex. cpr
Multilist format string and resume embedded language
'Raw' value from multilist (which is also the one stored in the database):
Patienten er overfølsom overfor ${cave.prep|anabolske steroider} med reaktionen ${cave.reak|udslæt}.
The journal format string:
Patienten er overfølsom overfor $[outputfield(cave.prep)] med reaktionen $[outputfield(cave.reak)].
This goes into the journal:
Patienten er overfølsom overfor anabolske steroider med reaktionen udslæt.
Block delimiter characters ''${...}'', ''$[...]''
The reason for using two different block delimiters are for the programmer to be able to distinguish the two very different types of block content. One containing a special blockname/blockvalue pair (the ${…}
block), and the other containing LUA code (the $[…]
block).
The reason for choosing ${}
and $[]
for delimiters are that they do not interfere with the XML, since neither of the constructs contain XML special characters, but still the contained values/source code must still be XML escaped. Furthermore none of the characters a used very often in what one might call natural written language, compared to for example, ()
, and they are also used less frequently in LUA code compared to ()
, thus making the job of escaping easier, and the final code easier to read, as-it-is.
The $
characters will simply render as a $
if not followed by a {
or a [
, and need nnever to be escaped.
The {
, }
, [
and ]
characters can be escaped by putting two next to each other, i.e. {
{
to render a single {
.
If the $
is put just before a {
{
or [
[
, the $
will be rendered as a $
.
Lib docs
Procedure
Request
Initially the server receives a request from the client.
The request contains a course and a macro.
The template containing the course is loaded, and the macros in it are verified.
The requested macro are loaded.
All macro fields are looked up in the db, and prefilled.
All queries to pentominos are performed.
Maps between fields and pentominos values are performed.
The final xml are generated accordingly and sent back to the client.
Commit
The server receives a commit from the client, containing all fields and their values.
The server puts all field/value pairs in the db, all connected to a transaction id.
The corresponding macro is loaded and its resume generated according to the resume format string.
The resume is sent to the upload server.
Error handling
All server output is cached prior to sending. Upon error a special error macro window is generated and sent to the client, containing a description of the error, and a close button.
All errors should be prevented/worked around if possible.
All actions already taken, should be rolled back. In order to do this, all external transmissions must be made last, bacause they are not necessarily possible to roll back.
Connection lifespan
A connection is made to the server at first request. It is kept alive for the entire session, i.e. during commit and possible following requests (due to continue action buttons).
The connection may be terminated at any key point (after a request or a commit), since the server is stateless, but it may be saving resources to keep the connection alive, thus only creating one connection per session.