From beb0233106658cff482ab41f0d979fb7c8395ce7 Mon Sep 17 00:00:00 2001 From: gfawcett Date: Fri, 26 Mar 2010 01:12:18 +0000 Subject: [PATCH] initial draft of OpenSRF campus-information service interface spec. git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/branches/2010-02-campus-integration-reorg@848 6d9bc8c9-1ec2-4278-b937-99fde70a366f --- conifer/integration/campus-interface.md | 243 ++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 conifer/integration/campus-interface.md diff --git a/conifer/integration/campus-interface.md b/conifer/integration/campus-interface.md new file mode 100644 index 0000000..fe82dec --- /dev/null +++ b/conifer/integration/campus-interface.md @@ -0,0 +1,243 @@ + + +# 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 -- 2.11.0