[open-ils-commits] r848 - servres/branches/2010-02-campus-integration-reorg/conifer/integration (gfawcett)
svn at svn.open-ils.org
svn at svn.open-ils.org
Thu Mar 25 21:12:20 EDT 2010
Author: gfawcett
Date: 2010-03-25 21:12:18 -0400 (Thu, 25 Mar 2010)
New Revision: 848
Added:
servres/branches/2010-02-campus-integration-reorg/conifer/integration/campus-interface.md
Log:
initial draft of OpenSRF campus-information service interface spec.
Added: servres/branches/2010-02-campus-integration-reorg/conifer/integration/campus-interface.md
===================================================================
--- servres/branches/2010-02-campus-integration-reorg/conifer/integration/campus-interface.md (rev 0)
+++ servres/branches/2010-02-campus-integration-reorg/conifer/integration/campus-interface.md 2010-03-26 01:12:18 UTC (rev 848)
@@ -0,0 +1,243 @@
+<!-- -*- mode: markdown; indent-tabs-mode: nil; -*- -->
+
+# Course Information Service Interface
+
+This is an early, early draft.
+
+## Introduction
+
+This document specifies the interface for an OpenSRF service which
+gives access to course-related information, such as the names of
+courses taught at a given university, who is teaching them, and which
+students are enrolled in them.
+
+This service is designed to meet the needs of a certain reserves
+application (Syrup). More broadly, we hope to design a service that
+will be useful in a wide range of applications that need to integrate
+library information with course-related information.
+
+We will specify the OpenSRF interface of the course-information
+service, without constraining how the service is implemented. Each
+institution will need to implement the service in a way that makes
+local sense.
+
+## Design considerations
+
+### Partial implementations
+
+*write me.* Explain why partial implementations might be all you
+get. How to test the interface to see what it implements. See
+[Static informational methods].
+
+
+### Caching
+
+*write me.* Explain that caching should be done in OpenSRF
+fashion. Applications should avoid caching themselves, and let the
+course-info service decide on how quickly course-info gets stale.
+
+## Data types
+
+We specify all of the data types that should appear in a complete
+implementation of the interface. Since you are free to implement only
+parts of the interface (see [Partial implementations]), all of these
+data types might not apply in your case.
+
+### Identifier types
+
+ COURSE-ID = string (matching a local COURSE-ID-FORMAT)
+ TERM-ID = string (matching a local TERM-ID-FORMAT)
+ OFFERING-ID = string (matching a local OFFERING-ID-FORMAT)
+ PERSON-ID = string (matching a local PERSON-ID-FORMAT)
+
+These four identifier types are used respectively as unique keys for
+courses, terms, course offerings, and people. (`String` is the
+primitive type of strings of Unicode characers.)
+
+People may have several unique identifiers (student numbers, SINs,
+etc.). Since the PERSON-ID may be exposed in reports and user
+interfaces, it should be a common public identifier (such as a
+'single-sign-on ID', 'email prefix', or 'campus username') that can be
+displayed beside the person's name without violating privacy
+regulations.
+
+**Section numbers:** Note that while we have an OFFERING-ID, we don't
+mention 'section numbers' at all, even though you might use them at
+your institution (to differentiate multiple instances of a course in
+the same term). Your offering ID `ENG100-2010W-03` might represent
+Section 3 of English 100 being taught in Winter 2010: here, the
+section number is embedded in the offering ID. There is no requirement
+that your offering ID is so structured, and nowhere in the interface
+do we use section numbers. But if you use section numbers at your
+school, consider embedding them in your offering ID (in case your
+end-users have to decode them).
+
+**Formats:** Each identifier type adheres to a respective,
+locally-defined format. You should define a (private, internal)
+function for each format, that verifies whether a given string matches
+the format. For example, a Java implementation might define a
+function, `boolean isValidCourseID(String)`. Consider using regular
+expressions to define your formats, but it's not a requirement. At the
+very least your local formats should reject empty strings as IDs.
+
+### Record types
+
+We model the record types as associative arrays (lists of key/value
+pairs).
+
+ COURSE = { id: COURSE-ID,
+ title: string }
+
+A COURSE record describes a course in the abstract sense, as it would
+appear in an academic calendar. It must have at least a unique course
+ID and a descriptive (possibly non-unique) title. It may include other
+attributes if you wish, but we specify `id` and `title` as required
+attributes.
+
+ TERM = { id: TERM-ID,
+ name: string,
+ start-date: date,
+ end-date: date }
+
+A TERM record describes a typical period in which a course is offered
+(a 'term' or 'semester'). It must have a unique term-ID, a
+probably-unique name, and start and end dates. (`Date` is a primitive
+type, representing a year-month-day date.)
+
+ PERSON = { id: PERSON-ID,
+ surname: string,
+ given-name: string,
+ email: (string)? }
+
+A PERSON record describes a person! It must include a unique
+person-ID, a surname and given name. A value for `email` is optional
+(the `(string)?` notation indicates a value that may be omitted,
+i.e. it may be `null`). You may also add other attributes as you see
+fit.
+
+ OFFERING = { id: OFFERING-ID,
+ course: COURSE-ID,
+ starting-term: TERM-ID,
+ ending-term: TERM-ID,
+ students: [PERSON-ID]*,
+ assistants: [PERSON-ID]*,
+ instructors: [PERSON-ID]* }
+
+A OFFERING record describes an instance of a course being offered:
+your institution might call this a 'class' or a 'section'. It has
+specific start and and end dates (derived from its starting and ending
+terms: note that some institutions may have courses that span multiple
+terms). It refers to a single course, of which it is an instance (our
+specification punts on the issue of cross-listed offerings). It has
+sets of zero-or-more students, teaching assistants and instructors.
+
+A given OFFERING record is a snapshot of a course offering at a given
+time. It is expected that people may join and leave the actual course
+offering at any point during the offering's duration.
+
+ OFFERING-FLESHED = { id: OFFERING-ID,
+ course: COURSE,
+ starting-term: TERM,
+ ending-term: TERM,
+ students: [PERSON]*,
+ assistants: [PERSON]*,
+ instructors: [PERSON]* }
+
+A OFFERING-FLESHED record is like a OFFERING record, except that the
+course, term, and people-set attributes have been 'fleshed out', so
+that they contain not codes, but actual copies of the COURSE, TERM and
+PERSON records.
+
+## Method signatures
+
+### Static informational methods
+
+ methods-supported: void -> [string]*
+
+*write me.* This should tell the client which of the other methods are
+actually implemented (see [Partial implementations]). This one should
+be mandatory.
+
+### Format-matching methods
+
+ resembles-course-id: string -> boolean
+ resembles-offering-id: string -> boolean
+ resembles-term-id: string -> boolean
+ resembles-person-id: string -> boolean
+
+These can be used to implement data-input validation tests in user
+interfaces, primarily where lookups are not possible. Applications
+can use them to determine whether a given string falls within the
+general guidelines of what your IDs are supposed to look like. At some
+institutions, this might be the best you can offer: you might not have
+access to databases in which you can look records up (see
+[Partial implementations]), but at least you can offer a means to
+avoid basic typographic errors.
+
+You could implement these methods by exposing the functions you
+defined for your COURSE-ID-FORMAT, TERM-ID-FORMAT, OFFERING-ID-FORMAT
+and PERSON-ID-FORMAT tests (see [Identifier types]).
+
+You might choose to use implement these as lookup functions, returning
+`True` only if a matching record was found. For example, if your
+school offers only two courses (say `ENG100` and `ENG200`), you could
+choose to implement a `resembles-course-id` method that only returned
+a `true` value if the argument was exactly one of those two course
+codes. But keep in mind that the intent of the `resembles` methods is
+to offer some general guidance, not to restrict vocabularies.
+
+### Course methods
+
+ course-lookup: COURSE-ID -> (COURSE)?
+ course-id-list: void -> [COURSE-ID]*
+ course-list: void -> [COURSE]*
+ course-id-example: void -> COURSE-ID
+
+*write me.*
+
+### Term methods
+
+ term-lookup: TERM-ID -> (TERM)?
+ terms-at-date: date -> [TERM]*
+ term-list: void -> [TERM]*
+
+*write me.*
+
+### Person methods
+
+ person-lookup: PERSON-ID -> (PERSON)?
+
+*write me.*
+
+### Offering methods
+
+ course-term-offerings: (COURSE-ID, TERM-ID) -> [OFFERING]*
+ course-term-offerings-fleshed: (COURSE-ID, TERM-ID) -> [OFFERING-FLESHED]*
+
+ # fixme, move to Data Types. A triple of lists:
+ MBR(TYPE) = ([TYPE]*, # memberships as a teacher,
+ [TYPE]*, # as an assistant,
+ [TYPE]*) # as a student.
+
+ memberships: PERSON-ID -> MBR(OFFERING)
+ membership-ids: PERSON-ID -> MBR(OFFERING-ID)
+ memberships-fleshed: PERSON-ID -> MBR(OFFERING-FLESHED)
+
+ member-ids: OFFERING-ID -> MBR(PERSON-ID)
+ members: OFFERING-ID -> MBR(PERSON)
+
+ teacher-ids: OFFERING-ID -> MBR(PERSON-ID)
+ teachers: OFFERING-ID -> MBR(PERSON)
+
+*write me.*
+
+`teachers` is like `members` -- they both return a MBR triple of
+(teachers, assistants, students)) -- but in the `teachers` triple, the
+student list may be empty (even if there are students). It is an
+optimized version of `members`: if an application just needs the
+teaching team for an offering (typically a very small list), don't
+calculate the student list as well (typically 50-100 times larger).
+
+[Partial implementations]: #partial-implementations
+[Static informational methods]: #static-informational-methods
+[Identifier types]: #identifier-types
More information about the open-ils-commits
mailing list