User Tools

Site Tools


stats:schema:stats

The Whole Stat System

The stats element represents the whole system, i.e. its XCend Schema is not repeated here. The main parts of the system are

The procedures to create and manage these major parts are among the most important ones of the system.

Procedures

System Creation

This is not real atomic operation, more like a constructor for the whole type. It is useful to think about what the smallest valid document is, however.

createEmptyStats() {
  remove /stats; # procedures only operate on valid documents, so we have to get rid of "whatever was there" before
  insert / 
    <stats revision="0">
      <account username="admin" lastName="admin" firstName="admin" email="admin@stats.system" password="some hash of 'admin'">
        <admin />
      </account>
    </stats>;
}

Account Management

Three of the most important procedures, as they create and delete elements of a major part of the system, namely User Accounts and Roles.

Naturally, a lot of things depend on accounts and their associated roles. Especially the student role restricts the deletion of accounts.

The third procedure is a compound procedure, which combines account and student role creation and therefore also combines their preconditions. This is the procedure which should be offered for everyone, especially guests.

Finally, there are more procedures which can be called by anyone, as they are concerned about users who lost their password.

# This doesn't take account validation into consideration at all. It probably has to be allowed to replace an unvalidated account.
createAccount(ident uid, ident username, string lastName, string firstName, string email, string password) {
  assume exists /account[uid]/admin;
 
  assume not exists /account[username];
 
  insert / <account username=[username] lastName=[lastName] firstName=[firstName] email=[email] password=[password] />
}
deleteAccount(ident uid, ident username) {
  assume exists /account[uid]/admin;
  assume uid != username; # or do we want to allow an admin to delete himself?
 
  assume exists /account[username];
 
  assume size(/account[username]/examiner) = 0;
  assume size(/account[username]/assistant) = 0;
  assume size(/account[username]/tutor) = 0;
 
  # not yet a constraint of the implementation, but is seems practically relevant :-)
  if exists /account[username]/admin then
    assume size(/account/admin) > 1;
  fi
 
  if exists /account[username]/student then
    assume size(/exercise/student[/account[username]/student/id]) = 0;
    assume size(/exam/participant[/account[username]/student/id]) = 0;
  fi
 
  remove /account[username];
}
createStudentAccount(ident username, ident studentId, string lastName, string firstName, string email, string password, string code) {
  assume not exists /account[username];
  assume count(studentId, /account/student/id) = 0;
 
  insert /
    <account username=[username] lastName=[lastName] firstName=[firstName] email=[email] password=[password] code=[code]>
      <student id=[studentId] />
    </account>
}
requestReset(ident username, string reset) {
  assume exists /account[username];
 
  assume not exists /account[username]/code; # account is already validated
 
  if not exists /account[username]/reset then
    insert /account[username]/reset;
  fi
  update /account[username]/reset reset;
}
resetPassword(ident username, string reset, string password) {
  assume exists /account[username]/reset; # reset code was requested before, implies account exists
  assume /account[username]/reset = reset; 
 
  remove /account[username]/reset;
  update /account[username]/password password;
}

Validation and Authentication

The free procedures to create a student account comes with the obligation to validate the email address. Its only then that the user can authenticate. The latter is not a real procedure, as nothing even gets modified in the system. It is there to illustrate who the Roles system works.

validateAccount(ident username, string code) {
  assume exists /account[username]/code; # implies existence of the account
 
  assume /account[username]/code = code;
 
  remove /account[username]/code;
}
authenticate(ident username, string password) {
  assume exists /account[username];
 
  assume /account[username]/password = password;
}

Exercise Management

Also two of the most important procedures, as they create and delete elements of a major part of the system, namely Exercise Management and Sheets.

A few roles, like tutor and assistant, depend on the existence of an exercise. Students sign-up status, on the other hand, just gets removed as well.

createExercise(ident uid, ident id, string lecture, string term) {
  assume exists /account[uid]/admin;
 
  assume not exists /exercise[id];
 
  insert / <exercise id=[id] lecture=[lecture] term=[term] open=[false] />
}
deleteExercise(ident uid, ident id) {
  assume exists /account[uid]/admin;
 
  assume exists /exercise[id];
 
  assume size(/exercise[id]/assistant) = 0;
  assume size(/exercise[id]/group/tutor) = 0;
 
  assume size(/exercise[id]/student) = 0; # don't allow to delete if students are there
 
  remove /exercise[id];
}

Exam Management

Finally, the last two of the most important procedures, which create and delete elements of a major part of the system, namely Exam Management and Grades.

The examiner role depends on the existence of an exam.

createExam(ident uid, ident id, ident eid, string title, string date, string time, string location) {
  assume exists /account[uid]/admin;
 
  assume not exists /exam[id];
  assume exists /exercise[eid];
 
  insert /
    <exam id=[id] title=[title] date=[date] time=[time] location=[location] free=[false] published=[false] exercise=[eid] />
}
deleteExam(ident uid, ident id) {
  assume exists /account[uid]/admin;
 
  assume exists /exam[id];
 
  assume size(/exam[id]/examiner) = 0;
 
  assume size(/exam[id]/participant) = 0; # don't allow to delete if participants are there
 
  remove /exam[id];
}

Admin Management

The admin role procedures from User Accounts and Roles can be offered here, too.

grantAdminRights(ident uid, ident username) {
  assume exists /account[uid]/admin;
 
  assume exists /account[username]; # implicitly true in OO implementations
  assume not exists /account[username]/admin;
 
  insert /account[username] <admin />;
}
revokeAdminRights(ident uid, ident username) {
  assume exists /account[uid]/admin;
 
  assume exists /account[username]/admin; # implies the account exists, which is implicitly true anyway
 
  assume size(/account/admin) > 1; # kind of a practical constraint
 
  remove /account[username]/admin;
}
stats/schema/stats.txt · Last modified: 2012/01/11 14:53 by Patrick Michel