Development of 'Lender Group' support in OpenDb
-----------------------------------------------

1) Introduction

So what is a group?  We might have a 'Game' lending
club, where the only s_item_type allowed is 'GAME',
we might have a 'BOOK' club.  Or we might have a 
group at Work and one for Friends and Family.

This document is an outline of a potential solution
to allow the OpenDb software _and_ a single database
instance (without prefixing!) to be used for multiple
OpenDb lending groups.

* Each group would have a defined set of users.

* Each group would define a set of s_item_type's
  that are valid for that particular group.

* As long as an item_instance has an owner in the current
  group AND the item.s_item_type is in the
  group_item_type table, that item will be visible.

* The configuration file for OpenDb will be the same
  across all groups.

* The current language (for the time being) will be the
  same across all groups.

* The choice of themes and languages will be the same
  across all groups.

* Various $lang_var variables will be updated to support
  a {group_cd} variable, so that the display of titles
  and such will include this.

  The definition of some of the config variables will
  be mutated based on the current group.

  For instance $CONFIG_VARS['site.title'], if it includes the
  {group_cd} will be updated to include it at runtime.

  	So titles such as:
		OpenDb 'Gamers' v0.51 

	will have resulted from a $opendb['title'] variable of:
		$CONFIG_VARS['site.title'] = 'OpenDb \'{group_cd}\''

	The v0.51 is a result of the particular theme adding
	the version number of OpenDb to the end.

2) Database Changed

2.1) New tables

	groups
	------

	group_id
	description
	...
 s_status_type

	group_user
	----------
	group_id
	user_id
	user_type
	...
 s_status_type

	group_item_type
	---------------
	group_cd
	s_item_type


3)	Login process

A user can ONLY log into one group at a time.  When they login,
they will choose from a 'group' list, which could be as simple as
a SELECT field, populated from the groups table where s_status_type = 'Y'

A users password is the same across ALL groups.  They will be allowed
to login if their password is correct (as usual) and they have an
active (s_status_type='Y') record in the group_user table.

Once they have satisfied this step, their 'user_id', 'theme', 'user_type',
'group_cd', 'login_time', etc will all be registered in the environment.

The session registered group code will then be used throughout to restrict
the users view of the OpenDb system to only those records that correspond.

4)	Record Restrictions

4.1)	Users

For group administrators, they should only be able to see users who belong
to the group they are logged in to.

The basic select statement against the user table would be:

	SELECT
	FROM	user u,
			group_user gu
	WHERE	u.user_id = gu.user_id

4.2)	Items

The restriction of items is the most complicated part of the whole process.

4.2.1)	Rules
	
4.2.1.1)	We only want to see items owned by users in this group.

4.2.1.2)	Groups may restrict type support.  For example one group
			may allow only CD's, while another will have VCD & DVD's.

			In this situation we only want to see items which are
			owned by users in the group and have a s_item_type that
			is allowed for this group.

4.2.2)	Assumptions

As a result of 4.2.1.2 we have two ways to proceed.

4.2.2.1)	We add a 'group_cd' to the item_instance table.  This would 
			mean that items created in the current group would _not_ be 
			accessible to another group even if the original owner was 
			also in that group, and	the item_type's matched.

4.2.2.2)	Add a join between item.s_item_type, item_instance and 
			group_s_item_type.  This is the most flexible solution.  The
			only concern is performance issues for such a join.  
			
			A possible workaround would be to select all s_item_type's from
			the group_item_type table at login time and store in a 
			session_variable.  This way we could build a s_item_type IN(...) 
			clause for all item listings and validations.

4.2.3) SQL Logic

4.2.3.1) Listings

The item listing logic for including a link to group_user and group_item_type	

	SELECT	
	FROM	item i,
		item_instance ii,
		group_user gu,
		group_item_type git
	WHERE	i.id = ii.item_id AND
		i.s_item_type = gsit.s_item_type AND
		ii.owner_id = gu.user_id AND
		git.group_cd = $CURRENT_GROUP_CD AND
		gu.group_id = $CURRENT_GROUP_CD

4.2.3.2) Restrictions

To make sure that users cannot circumvent the listings logic, we
would have to modify the is_item_instance_exists(...) functions 
to include the group code.

The test 'is_item_owned_by_user' would still work, because the
item_instance table is a global table.  

It is the combination of 'group_user.user_id' against 
'item_instance.owner_id' and 'group_item_type.s_item_type' against
the 'item.s_item_type' table, that give us our group item restrictions.

So a user in two groups can see their items in both groups
only if the item types are applicable.


	








