<?xml version='1.0' ?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
               "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
<!ENTITY % myvars SYSTEM "../variables.ent">
%myvars;
]>
<sect1 id="groups-requirements" xreflabel="OpenACS 4 Groups Requirements">
  <title>Groups Requirements</title>

  <authorblurb>
    <para>By <ulink url="http://planitia.org">Rafael H. Schloming</ulink>, Mark Thomas</para>
  </authorblurb>


  <sect2 id="groups-requirements-intro">
    <title>Introduction</title>


    <para>Almost all database-backed websites have users, and need to model the
      grouping of users. The OpenACS 4 Parties and Groups system is intended to provide
      the flexibility needed to model complex real-world organizational structures,
      particularly to support powerful subsite services; that is, where one OpenACS
      installation can support what appears to the user as distinct web services
      for different user communities.</para>

  </sect2>

  <sect2 id="groups-requirements-vision">
    <title>Vision Statement</title>


    <para>A powerful web service that can meet the needs of large enterprises must
      be able to model the the real world&#39;s very rich organizational structures
      and many ways of decomposing the same organization. For example, a
      corporation can be broken into structures (the corporation, its divisions,
      and their departments) or regions (the Boston office, the LA office); a
      person who is employed by (is a member of) a specific department is also a
      member of the division and the corporation, and works at (is a member of, but
      in a different sense) a particular office. OpenACS&#39;s Parties and Groups
      system will support such complex relations faithfully.</para>

    <para><emphasis role="strong">Historical Motivations</emphasis></para>

    <para>The primary limitation of the OpenACS 3.x user group system is that it
      restricts the application developer to representing a &quot;flat group&quot;
      that contains only users: The <computeroutput>user_groups</computeroutput> table may contain the
      <computeroutput>group_id</computeroutput> of a parent group, but parent-child relationship
      support is limited because it only allows one kind of relationship between
      groups to be represented. Moreover, the Oracle database&#39;s limited support
      for tree-like structures makes the queries over these relationships
      expensive.</para>

    <para>In addition, the Module Scoping design in OpenACS 3.0 introduced a
      <emphasis>party</emphasis> abstraction - a thing that is a person or a group of people -
      though not in the form of an explicit table. Rather, the triple of
      <computeroutput>scope</computeroutput>, <computeroutput>user_id</computeroutput>, and <computeroutput>group_id</computeroutput> columns
      was used to identify the party. One disadvantage of this design convention is
      that it increases a data model&#39;s complexity by requiring the programmer
      to:</para>

    <itemizedlist>
      <listitem><para>add these three columns to each &quot;scoped&quot; table</para></listitem>

      <listitem><para>define a multi-column check constraint to protect against data corruption
          (e.g., a row with a <computeroutput>scope</computeroutput> value of &quot;group&quot; but a null
          <computeroutput>group_id</computeroutput>)</para></listitem>

      <listitem><para>perform extra checks in <computeroutput>Tcl</computeroutput> and <computeroutput>PL/SQL</computeroutput>
          functions and procedures to check both the <computeroutput>user_id</computeroutput> and
          <computeroutput>group_id</computeroutput> values</para></listitem>
    </itemizedlist>

    <para>In sum, the goal of the <emphasis role="strong">Parties and Groups</emphasis> system is to
      provide OpenACS programmers and site administrators with simple tools that fully
      describe the complex relationships that exist among groups in the real
      world.</para>

  </sect2>

  <sect2 id="groups-requirements-user-scenarios">
    <title>User Scenarios</title>


    <para>Pat Developer has a client project and wants to model the company, its
      offices, its divisions, and its departments as groups and the employees as
      users.</para>

  </sect2>

  <sect2 id="groups-requirements-system-overview">
    <title>System Overview</title>


    <para>We start with <emphasis role="strong">Groups</emphasis>, which contain members; the
      <emphasis role="strong">member can be either a person or another group</emphasis> (i.e. a
      member is a party).</para>

    <para>In addition to membership, the party and groups system defines a
      <emphasis role="strong">composition</emphasis> relationship that may exist between groups: A
      group can be a <emphasis role="strong">component</emphasis> of another group. The child group
      is called a <emphasis>component group</emphasis>; the parent group is called a
      <emphasis>composite group</emphasis>.</para>

    <para>A group <emphasis role="strong">G<subscript>c</subscript></emphasis> can be a member and/or a component
      of another group <emphasis role="strong">G<subscript>p</subscript></emphasis>; the difference is in the way
      the members of <emphasis role="strong">G<subscript>c</subscript></emphasis> are related to
      <emphasis role="strong">G<subscript>p</subscript></emphasis>:</para>

    <itemizedlist>
      <listitem><para>If a party <emphasis role="strong">P</emphasis> is a member (or a component) of
          <emphasis role="strong">G<subscript>c</subscript></emphasis> and if <emphasis role="strong">G<subscript>c</subscript></emphasis> is a
          component of <emphasis role="strong">G<subscript>p</subscript></emphasis>, then <emphasis role="strong">P</emphasis> is also
          a member (or a component) of <emphasis role="strong">G<subscript>p</subscript></emphasis></para></listitem>

      <listitem><para>If a party <emphasis role="strong">P</emphasis> is a member (or a component) of
          <emphasis role="strong">G<subscript>c</subscript></emphasis> and if <emphasis role="strong">G<subscript>c</subscript></emphasis> is a
          member of <emphasis role="strong">G<subscript>p</subscript></emphasis>, then <emphasis role="strong">no
            relationship</emphasis> between <emphasis role="strong">P</emphasis> and
          <emphasis role="strong">G<subscript>p</subscript></emphasis> exists as a result of the relationship between
          <emphasis role="strong">G<subscript>p</subscript></emphasis> and <emphasis role="strong">G<subscript>p</subscript></emphasis>.</para></listitem>
    </itemizedlist>

    <para>Consider an example to make this less abstract: Pretend that the Sierra
      Club is a <emphasis>member</emphasis> of Greenpeace. The Sierra Club has chapters; each
      chapter is a <emphasis>component</emphasis> of the Sierra Club. If Eddie Environmentalist
      is a member of the Massachusetts Chapter of the Sierra Club, Eddie is
      automatically a member of the Sierra Club, but being a Sierra Club member
      does not make Eddie a member of Greenpeace.</para>

    <para>In the OpenACS, Greenpeace, Sierra Club, and the Sierra Club chapters would be
      modeled as groups, and Eddie would be a user. There would be a composition
      relationship between each Sierra Club chapter and the Sierra Club. Membership
      relationships would exist between Eddie and the Massachusetts Chapter,
      between Eddie and the Sierra Club (due to Eddie&#39;s membership in the
      Massachusetts chapter), and between the Sierra Club and Greenpeace.</para>

    <para>Membership requirements can vary from group to group. The parties and
      groups system must provide a base type that specifies the bare minimum
      necessary to join a group.</para>

    <para>The parties and groups system must support constraints between a composite
      group <emphasis role="strong">G<subscript>P</subscript></emphasis> and any of its component groups,
      <emphasis role="strong">G<subscript>C</subscript></emphasis>. For example, the system should be able to
      enforce a rule like: Do not allow a party <emphasis role="strong">P</emphasis> to become a
      member of <emphasis role="strong">G<subscript>C</subscript></emphasis> unless <emphasis role="strong">P</emphasis> is already
      a member of <emphasis role="strong">G<subscript>P</subscript></emphasis>.</para>

  </sect2>

  <sect2 id="groups-requirements-links">
    <title>Related Links</title>


    <itemizedlist>
      <listitem><para><xref linkend="groups-design"/></para></listitem>
    </itemizedlist>

  </sect2>

  <sect2 id="groups-requirements-data-model">
    <title>Requirements: Data Model</title>


    <para>The data model for the parties and groups system must provide support for
      the following types of entities:</para>

    <variablelist>
      <varlistentry>
        <term><emphasis role="strong">10.0 Parties</emphasis>

        </term>
        
        <listitem>
          <para>A <emphasis role="strong">party</emphasis> is an entity used to represent either a
            <emphasis>group</emphasis> or a <emphasis>person</emphasis>.</para>

          <para>The data model should enforce these constraints:</para>

          <para><emphasis role="strong">10.10</emphasis> A party has an email address, which can be
            empty.</para>

          <para><emphasis role="strong">10.20</emphasis> A party may have multiple email addresses
            associated with it.</para>

          <para><emphasis role="strong">10.30</emphasis> The email address of a party must be unique within
            an OpenACS system.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">20.0 Groups</emphasis>

        </term>
        
        <listitem>
          <para>A <emphasis role="strong">group</emphasis> is a collection of zero or more parties.</para>

          <para><emphasis role="strong">20.10</emphasis> The data model should support the subclassing of
            groups via OpenACS Objects.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">30.0 Persons</emphasis>

        </term>
        
        <listitem>
          <para>A <emphasis role="strong">person</emphasis> represents an actual human being, past or
            present.</para>

          <para><anchor id="groups-requirements-30-10"/><emphasis role="strong">30.10.</emphasis> A person must have
            an associated name.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">40.0 Users</emphasis>

        </term>
        
        <listitem>
          <para>A <emphasis role="strong">user</emphasis> is a person who has registered with an OpenACS site. A
            user may have additional attributes, such as a screen name.</para>

          <para>The data model should enforce these constraints:</para>

          <para><emphasis role="strong">40.10</emphasis> A user must have a non-empty email address.</para>

          <para><emphasis role="strong">40.20</emphasis> Two different users may not have the same email
            address on a single OpenACS installation; i.e., an email address identifies a
            single user on the system.</para>

          <para><emphasis role="strong">40.30</emphasis> A user may have multiple email addresses; for
            example, two or more email addresses may identify a single user.</para>

          <para><emphasis role="strong">40.40</emphasis> A user must have password field which can be
            empty.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <para>The data model for the parties and groups system must provide support for
      the following types of relationships between entities:</para>

    <variablelist>
      <varlistentry>
        <term><emphasis role="strong">50.0 Membership</emphasis>

        </term>
        
        <listitem><para>
            A party <emphasis role="strong">P</emphasis> is considered a <emphasis role="strong">member</emphasis> of a
            group <emphasis role="strong">G</emphasis></para>

          <itemizedlist>
            <listitem><para>when a direct membership relationship exists between <emphasis role="strong">P</emphasis>
                and <emphasis role="strong">G</emphasis></para></listitem>

            <listitem><para>or when there exists a direct membership relationship between
                <emphasis role="strong">P</emphasis> and some group <emphasis role="strong">G<subscript>C</subscript></emphasis> and
                <emphasis role="strong">G<subscript>C</subscript></emphasis> has a composition relationship (c.f., <link linkend="groups-requirements-60-0">60.0</link>) with <emphasis role="strong">G</emphasis>.</para></listitem>
          </itemizedlist>
          

          <para><emphasis role="strong">50.10</emphasis> A party may be a member of multiple groups.</para>

          <para><emphasis role="strong">50.20</emphasis> A party may be a member of the same group multiple
            times only when all the memberships have different types; for example, Jane
            may be a member of The Company by being both an Employee and an
            Executive.</para>

          <para><emphasis role="strong">50.30</emphasis> A party as a member of itself is not supported.</para>

          <para><emphasis role="strong">50.40</emphasis> The data model must support membership
            constraints.</para>

          <para><emphasis role="strong">50.50</emphasis>The data model should support the subclassing of
            membership via OpenACS Relationships.</para>
        </listitem>
      </varlistentry>
    </variablelist>

    <variablelist>
      <varlistentry>
        <term>
          <anchor id="groups-requirements-60-0"/>
          <emphasis role="strong">60.0 Composition</emphasis>
        </term>
        
        <listitem>
          <para>A group <emphasis role="strong">G<subscript>C</subscript></emphasis> is considered a
            <emphasis role="strong">component</emphasis> of a second group
            <emphasis role="strong">G<subscript>P</subscript></emphasis></para>

          <itemizedlist>
            <listitem><para>when a direct composition relationship exists between
                <emphasis role="strong">G<subscript>C</subscript></emphasis> and <emphasis role="strong">G<subscript>P</subscript></emphasis></para></listitem>

            <listitem><para>or when there exists a direct composition relationship between
                <emphasis role="strong">G<subscript>C</subscript></emphasis> and some group <emphasis role="strong">G<subscript>i</subscript></emphasis>
                and <emphasis role="strong">G<subscript>i</subscript></emphasis> has a composition relationship with
                <emphasis role="strong">G<subscript>P</subscript></emphasis>.</para></listitem>
          </itemizedlist>

          

          <para><emphasis role="strong">60.10</emphasis>A group may be a component of multiple groups.</para>

          <para><emphasis role="strong">60.20</emphasis>A group as a component of itself is not
            supported.</para>

          <para><emphasis role="strong">60.30</emphasis>The data model must support component
            constraints.</para>

          <para><emphasis role="strong">60.40</emphasis>The data model should support the subclassing of
            composition via OpenACS Relationships.</para>
        </listitem>
      </varlistentry>
    </variablelist>

  </sect2>

  <sect2 id="groups-requirements-api">
    <title>Requirements: API</title>


    <para>The API should let programmers accomplish the following tasks:</para>

    <variablelist>
      <varlistentry>
        <term><emphasis role="strong">70.10 Create a group</emphasis>

        </term>
        
        <listitem>
          <para>The parties and groups system provides a well defined API call that
            creates a new group by running the appropriate transactions on the parties
            and groups system data model. This API is subject to the constraints laid out
            in the data model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">70.20 Create a person</emphasis>

        </term>
        
        <listitem>
          <para>The parties and groups system provides a well defined API call that
            creates a new person by running the appropriate transactions on the parties
            and groups system data model. This API is subject to the constraints laid out
            in the data model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">70.30 Create a user</emphasis>

        </term>
        
        <listitem>
          <para>The parties and groups system provides a well defined API call that
            creates a new user by running the appropriate transactions on the parties and
            groups system data model. This API is subject to the constraints laid out in
            the data model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">80.10 Refine a person to a user</emphasis>

        </term>
        
        <listitem>
          <para>The parties and groups system provides a well defined API call that
            creates a new user by running the appropriate transactions on an existing
            person entity. This API is subject to the constraints laid out in the data
            model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">80.30 Demote a user to a person</emphasis>

        </term>
        
        <listitem>
          <para>The parties and groups system provides a well defined API call that
            demotes an existing user entity to a person entity by running the appropriate
            transactions on the existing user. This API is subject to the constraints
            laid out in the data model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">90.10 Update a party</emphasis>

        </term>
        
        <listitem>
          <para>The programmer should be able to modify, add, and delete attributes on any
            party. This API is subject to the constraints laid out in the data model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">95.10 Get the attributes of a party</emphasis>

        </term>
        
        <listitem>
          <para>The programmer should be able to view the attributes on any party. This
            API is subject to the constraints laid out in the data model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">100.10 Delete a party</emphasis>


        </term>
        
        <listitem>
          <para>The system provides an API for deleting a party. This API is subject to
            the constraints laid out in the data model.</para>

          <para><emphasis role="strong">100.30</emphasis> The system may provide a single API call to remove
            the party from all groups and then delete the party.</para>

          <para><emphasis role="strong">100.40</emphasis> In the case of a group, the system may provide a
            single API call to remove all parties from a group and then delete the
            group.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">110.0 Add a party as a member of a group</emphasis>

        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for adding a party as a
            member of a group. This API is subject to the constraints laid out in the
            data model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">115.0 Add a group as a component of a second group</emphasis>

        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for adding a group as a
            component of a second group. This API is subject to the constraints laid out
            in the data model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">120.0 Remove a party as a member of a group</emphasis>

        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for deleting a party&#39;s
            membership in a group. This API is subject to the constraints laid out in the
            data model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">125.0 Remove a group as a component of a second
            group</emphasis>

        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for deleting a group&#39;s
            composition in a second group. This API is subject to the constraints laid
            out in the data model.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">130.0 Membership check</emphasis>


        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for answering the question:
            &quot;Is party <emphasis role="strong">P</emphasis> a member of group
            <emphasis role="strong">G</emphasis>?&quot;</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">135.0 Composition check</emphasis>


        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for answering the question:
            &quot;Is group <emphasis role="strong">G<subscript>C</subscript></emphasis> a component of group
            <emphasis role="strong">G<subscript>P</subscript></emphasis>?&quot;</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">140.0 Get members query</emphasis>


        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for answering the question:
            &quot;Which parties are members of group <emphasis role="strong">G</emphasis>?&quot;</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">145.0 Get components query</emphasis>


        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for answering the question:
            &quot;Which groups are components of group <emphasis role="strong">G</emphasis>?&quot;</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">150.0 Member-of-groups query</emphasis>


        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for answering the question:
            &quot;Of which groups is party <emphasis role="strong">P</emphasis> a member?&quot;</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">155.0 Component-of-groups query</emphasis>


        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for answering the question:
            &quot;Of which groups is group <emphasis role="strong">G</emphasis> a component?&quot;</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">160.0 Allowed membership check</emphasis>


        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for answering the question:
            &quot;Is party <emphasis role="strong">P</emphasis> allowed to become a member of group
            <emphasis role="strong">G</emphasis>?&quot;</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">165.0 Allowed composition check</emphasis>


        </term>
        
        <listitem>
          <para>The parties and groups system provides an API for answering the question:
            &quot;Is group <emphasis role="strong">G<subscript>C</subscript></emphasis> allowed to become a component
            of group <emphasis role="strong">G<subscript>P</subscript></emphasis>?&quot;</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">170.0 Efficiency</emphasis>


        </term>
        
        <listitem>
          <para>Since many pages at a site may check membership in a group before serving
            a page (e.g., as part of a general permissions check), the data model must
            support the efficient storage and retrieval of party attributes and
            membership.</para>
        </listitem>
      </varlistentry>

      <varlistentry>
        <term><emphasis role="strong">180.0 Ease of Use</emphasis>


        </term>
        
        <listitem>
          <para>Since many SQL queries will check membership in a group as part of the
            <computeroutput>where</computeroutput> clause, whatever mechanism is used to check membership in SQL
            should be fairly small and simple.</para>
        </listitem>
      </varlistentry>
    </variablelist>

  </sect2>

  <sect2 id="groups-requirements-ui">
    <title>Requirements: User Interface</title>


    <para>The user interface is a set of HTML pages that are used to drive the
      underlying API. The user interface may provide the following functions:</para>

    <itemizedlist>
      <listitem><para><emphasis role="strong">200.0</emphasis> Create a party</para></listitem>

      <listitem><para><emphasis role="strong">210.0</emphasis> View the attributes of a party</para></listitem>

      <listitem><para><emphasis role="strong">220.0</emphasis> Update the attributes of a party</para></listitem>

      <listitem><para><emphasis role="strong">240.0</emphasis> Delete a party</para></listitem>

      <listitem><para><emphasis role="strong">250.0</emphasis> Add a party to a group</para></listitem>

      <listitem><para><emphasis role="strong">260.0</emphasis> Remove a party from a group</para></listitem>

      <listitem><para><emphasis role="strong">270.0</emphasis> Perform the membership and composition checks
          outlined in 130.x to 165.x</para></listitem>
    </itemizedlist>

  </sect2>

  <sect2 id="groups-requirements-rev-history">
    <title>Revision History</title>


    
    <informaltable>
      <tgroup cols="4">
        <tbody>
          <row>
            <entry><emphasis role="strong">Document Revision #</emphasis></entry>
            <entry><emphasis role="strong">Action Taken, Notes</emphasis></entry>
            <entry><emphasis role="strong">When?</emphasis></entry>
            <entry><emphasis role="strong">By Whom?</emphasis></entry>
          </row>

          <row>
            <entry>0.1</entry>
            <entry>Creation</entry>
            <entry>08/16/2000</entry>
            <entry>Rafael Schloming</entry>
          </row>

          <row>
            <entry>0.2</entry>
            <entry>Initial revision</entry>
            <entry>08/19/2000</entry>
            <entry>Mark Thomas</entry>
          </row>

          <row>
            <entry>0.3</entry>
            <entry>Edited and reviewed, conforms to requirements template</entry>
            <entry>08/23/2000</entry>
            <entry>Kai Wu</entry>
          </row>

          <row>
            <entry>0.4</entry>
            <entry>Further revised, added UI requirements</entry>
            <entry>08/24/2000</entry>
            <entry>Mark Thomas</entry>
          </row>

          <row>
            <entry>0.5</entry>
            <entry>Final edits, pending freeze</entry>
            <entry>08/24/2000</entry>
            <entry>Kai Wu</entry>
          </row>

          <row>
            <entry>0.6</entry>
            <entry>More revisions, added composition requirements</entry>
            <entry>08/30/2000</entry>
            <entry>Mark Thomas</entry>
          </row>

          <row>
            <entry>0.7</entry>
            <entry>More revisions, added composition requirements</entry>
            <entry>09/08/2000</entry>
            <entry>Mark Thomas</entry>
          </row>
        </tbody></tgroup></informaltable>

  </sect2>

</sect1>
