Intranet Module
part of the
ArsDigita Community System
by a lot of people at ArsDigita and maintained by
Michael Bryzek.
The Big Picture
The faster the pace of change in an industry or business, the more time
and effort workers have to spend on coordination. Consider Adam Smith's
pin factory. The boss has to stand up in front of the workers once per
year and say "Thank you for your fine work last year. This year, I want
you to make lots of pins. They should be really straight, blunt on one
end, and pointy on the other. See you next year." In a university
literature department, you need to have a meeting once per semester.
Perhaps some of the curriculum should be revised? In a business facing
innovative competitors, you need to have a meeting once every month to
think about required responses. In a complex organization that is
try to change and adapt, meetings and other forms of coordination may
consume 20-30 hours per week.
Why is this a problem? People still have to work 40 hours per week to
get anything done. The result is that people will have to spend 60-70
hours per week at the office in order to coordinate and work.
What's the solution to this social problem? A computer program of
course! (You didn't expect anything better from three MIT graduates did
you?)
A modern organization exhibits the classical problem at which Web-based
applications excel: people separated in time and space. We can thus use
the same toolkit that we developed for helping people work together and
teach each other over the Internet to work together within an
organization.
For What Kinds of Organizations Is This Best?
What kinds of organizations can get the most out of this toolkit? Ones
just like ArsDigita, of course! We built this for ourselves. ArsDigita
currently (May 2000) has approximately ten offices, 140 busy
highly-paid people, and rapid growth (revenue doubling every
six months). Coincidentally, it also works great for groups within
larger companies. Consider Jane Manager at Hewlett-Packard who is
forming a team to build a new product. Within a couple of weeks, she
might be managing 100 people spread out among four physical locations in
Japan, California, the Pacific Northwest, and Spain. That's much faster
organizational growth and change than any startup company will ever
experience. It would be awfully nice if Jane could go up to a Web
browser and ask "Who works for me today? What are their names? What do
they look like? How do I get in touch with them?"
The Medium-Size Picture
We assume that all the employees are users in a standard ArsDigita
Community System. We keep track of employees, customers, project,
salaries, and deadlines. This enables us to ask questions like
- How many people work in this organization and how much money are we
spending each month on salaries?
- Who works for whom? (fun with Oracle tree extensions)
- What are our upcoming deadlines?
- What is John Smith working on?
- Which people are on the CNN project?
- How much time did that project take?
- What current issues and problems we are facing?
- What has this project involved so far?
For companies that operate an Internet service based on our toolkit, a
side benefit of using our intranet module is that employees who develop
skills in maintaining the intranet can then apply those skills to the
public Web services. Novices have to start out somewhere and they might
as well start in a place where an error isn't observed by customers.
One of the key components to any intranet is keeping members of the company up-to-date.
The intranet makes it easy to spam the entire company, a specific office, or employees
working on a given project.
Daily Status Report
The intranet supports a daily status report that is sent to every employee
in the company, on a nightly basis. Any module in the acs can add something
to this status report by:
- Creating a procedure that generates the content to include in the
status report. This procedure takes 4 arguments: database handle (db),
number of days the report covers (coverage, defaults to 1),
the date of the report (report_date, defaults to sysdate), and
the purpose of the report (purpose, generally defaults to email,
but can be either web_display or email_display.
Example:
proc im_news_status {db {coverage ""} {report_date ""} {purpose ""} } {
if { [empty_string_p $coverage] } {
set coverage 1
}
if { [empty_string_p $report_date] } {
set report_date sysdate
} else {
set report_date "'$report_date'"
}
set since_when [db_string unused "select to_date($report_date, 'YYYY-MM-DD') - $coverage from dual"]
return [news_new_stuff $since_when "f" $purpose]
}
- Use
im_add_to_status_report
to register the
name of the procedure and caching information with the intranet status
report:
proc_doc im_add_to_status_report { title proc_name { cache_p "f" } } {
Adds proc_name to the list of procs needed to generete the
status_report. If cache_p is t, then we cache the result to reuse
later (like when we're sending the status report to all employees).
You want to cache all information that does not depend on the
current user id.
} {
ns_share im_status_report_section_list
if { ![info exists im_status_report_section_list] || \
[lsearch -glob $im_status_report_section_list $proc_name] == -1 } {
lappend im_status_report_section_list [list $title $proc_name $cache_p]
}
}
# Register the procedure im_news_status with the intranet status report. We can cache
# this information because it does not change based on the user id
im_add_to_status_report "News" im_news_status t
Under the Hood
The parameters/ad.ini file
[ns/server/yourservername/acs/intranet]
; Log email sent to groups as correspondance and enable auto-emailing of
; these correspondance to members of the group
LogEmailToGroupsP=1
; Use the intranet filters to restrict access to all bboard topic with a group_id
EnableIntranetBBoardSecurityFiltersP=1
; Set to 1 if you want to automatically redirect users to enter project reports
ForceUsersToEnterProjectReportsP=0
; If you want users to automatically be redirected to log their hours
; if they haven't, set this flag to 1
ForceUsersToLogHoursP=1
; How many results/rows do we show on a page before splitting up into
; previous/next links?
NumberResultsPerPage=50
; On pages with dimensional sliders, having too many categories leads to
; messy navigation. How many text characters do we allow before switching
; from text links to a select bar?
LengthBeforeSelectBar=50
; If you want to include a default graphic in your
; intranet header, put the path to that graphic here
DefaultGraphic=
; If you would like to track projects with a
; survey in the survey module, put the project
; type and its paired survey
ProjectReportTypeSurveyNamePair=Client - full service,project_report
;You may send email notifications of payment
; changes to members of a specified group
BillingGroupShortName=receivable
IntranetName=aD Intranet
IntranetEnabledP=1
; If you want to restrict access to the /shared/community-member
; page to users of the intranet only, set KeepSharedInfoPrivate to 1
KeepSharedInfoPrivate=1
; Should we enable bboard with the intranet pages? The BBoard
; module must be scoped or be altered to have a groud_id column first
BBoardEnabledP=1
; do we serve the generated /intranet/index page or something
; else from the file system?
SpecialIndexPage=
DisplayVacationsOnCalendar=1
; the unit of measurement for entering salaries (month or year)
SalaryPeriodInput=year
; used to display salary
SalaryPeriodDisplay=year
; list of fee types
FeeTypes="setup" "monthly development" "monthly hosting" "hourly" "stock"
; Do we want to track hours?
TrackHours=1
; what's the url stub? i.e. http://www.yourdomain.com
IntranetUrlStub=/intranet
; Group Types
IntranetGroupType=intranet
ProjectGroupShortName=project
OfficeGroupShortName=office
CustomerGroupShortName=customer
PartnerGroupShortName=partner
ProcedureGroupShortName=procedure
EmployeeGroupShortName=employee
TeamGroupShortName=team
AuthorizedUsersGroupShortName=authorized_users
CustomerPortalName=Customer Portals
; What color do we put in the header row of tables?
TableColorHeader=#e6e6e6
; What color do we put in the odd numbered rows of tables?
TableColorOdd=#f4f4f4
; What color do we put in the even numbered rows of tables?
TableColorEven=#ffffff
CommentApprovalPolicy=open
; If we want to include people who are delinquent with project
; reports in our status-report, what user_class_id do we use?
; Leave blank to skip this part of the status report
UserClassStatusReportID=
Categories of users
There are several different categories of users in intranet-enabled
acs installations:
- Normal users: Those who register on the site but are not
authorized for intranet access
- Customers: Users who belong to customers are given access to
certain parts of the intranet, including the list of employees
working with them and status reports posted for their projects.
- Employees: Employees gain full access to all intranet pages
and information (except for pages reserved for administrators)
- Authorized users: These users have the same level of access
as Employees, but are simply categorized differently. This allows us
to give employee-level access to any user and still maintain a
consistent view of all the employees in the company.
- Intranet administrators: Intranet uber-users who can
see/change anything in the intranet. Note that site-wide
administrators can also access anything that an Intranet
administrator can.
User Groups
The intranet module defines several standard user groups which can be
used to model your organization. The intranet is a group_type, and
each category of users is its own user_group of type intranet. Within
each group, you can have subgroups if there is a need. One example is
offices. There is a user group named Offices, and each office is a
subgroup of the Office group. This way, we can keep the large number
of objects organized in a hierarchical way.
Intranet administrators belong to the "Intranet Administrators"
subgroup of the standard ACS Administration group. All other intranet
groups have a group_type of intranet. The following groups are
automatically created:
- Projects: Every project in the intranet is a subgroup of the
projects groups
- Customers: Every customer in the intranet is a subgroup of the
projects groups. Users who work for a customer belong to one
subgroup.
- Partners: Every partner in the intranet is a subgroup of this group.
- Employees: Users become employees by joining this group.
- Offices: Each office is a subgroup of this group.
- Procedures: Each procedure that employees create is a subgroup
of the procedures user_group.
Top-level pages /intranet
Top-level files include the employee's workspace and pages that are commonly reused by intranet submodules. This includes:
- Adding users to intranet groups
- Searching for users using intranet permissions
The following parameters can be used to modify the general behavior of the intranet module:
- SpecialIndexPage: Changes the default intranet workspace page from
/intranet/index to whatever file you would like.
- IntranetEnabledP: Global parameter thats tells us that the
intranet is enabled. Currently, this changes the default user
workspace for authorized users of the intranet to /intranet/, adds
intranet-specific information to the community-member page, and
displays vacations on the calendar. Non authorized users can still
see public information about all other users in the system.
Categories in the intranet
The intranet module uses the categories table, originally created for
user profiling, to categorize attributes
of the various intranet objects. For instance, the list of possible
job titles that an employee may have will vary between different
organizations. Each job title is an entry in the categories table
with category_type='Intranet Job Title'. The /admin/intranet page
lists each of the intranet categories, and allows maintenance of their
possible values. This flexibility allows the intranet data model to
adapt to your company's standard practices and workflow.
Employees /intranet/employees
The employees section of the intranet is used to manage the employees
in the company. Employees can search for others in the company, can
spam all company employees, can download AIM lists to load into
instant messenger, and can view a dynamically generated company org
chart. Employees can also be categorized/seen by office or team.
Every employee is a member of the employees user_group. Detailed
contact information is stored for users in order to provide a company
directory. The im_employee_info table holds information like
the employee's salary and Social Security number. When a new person
is hired, you can add them to the employees group by choosing "Add an
employee" from the intranet admin screen. This gives them access to
the intranet portal.
Making the recruiting process visible
The im_employee_pipeline
table allows recruiters to keep
track of applicants, interviews, and hiring status. From the employee
administration page, summaries of current candidates as well as
employee referrals are available.
Work absences /intranet/absences
Users record their work absences (e.g. vacations, travel, personal
time-off) providing a central resource to see where all employees
are. Users can describe why they are taking time off and list
emergency contact information.
Employee administration /intranet/employees/admin
Employee administration consists of:
- Adding new employees
- Adding new intranet administrators
- Assigning users to various groups (e.g. offices, teams, projects, etc.)
- Entering HR information (e.g. start date, salary, experience, etc.)
- Managing the employee pipeline
- Managing employee referrals
- Managing termination by recording termination dates and removing terminated employees from all intranet groups.
Customers /intranet/customers
Customers in the intranet maintain basic information, such as the type
of customer, and are associated with address books and projects. From
the customers page, you can also see everyone who works with that
customer. We also store all correspondance with the customer through
the
general comments module. Like
projects, customers can be categorized into types or states, stored in
the
categories
table.
The intranet module also provides easy integration with the bboard
module to create and link bboard topics to each customer. Note that
you should probably enable the EnableIntranetBBoardSecurityFiltersP=1
parameter to register a filter that prevents unauthorized access to
the intranet bboards.
Employees who work for a given customer can be automatically
redirected to a Customer Portal (identified by the CustomerPortalName
parameter)
Projects /intranet/projects
The projects module is probably the most useful place for
employees. Typical projects include
- A client project (iMedix.com)
- A module (Project Tracker Module)
- An initiative (convert company structure from LLC to SCorp)
Each project maintains basic information about the project (a
description, the project lead, the supervisor, etc.), tracks project
reports (in the form of
general comments
and/or
surveys), and basic categorization to
help you organize the lists of projects. We also track project
payments and allocations over time. Projects can also be categorized
by type (e.g. client/internal) or state (e.g. open/closed).
We currently support one level of subprojects allowing users to break
up a large project if needed. Each intranet project can be associated
with a ticket tracker project. The idea here is to use projects in the
intranet as a way of managing information about the projects -
employee allocations, payments, people involved, etc. - and use the
ticket tracker to actually manage work on the project.
Project reports
The intranet module currently supports two types of reports:
- General comments - the default report that simple associated
general comments with each project. Each project maintains a flag
telling us whether or not a project report is required for that
project.
- Surveys - Surveys can be created as an enhanced project
report. You can associate a type of project with a survey by adding
a parameter similar to this one (you can have as many as you like!):
- ProjectReportTypeSurveyNamePair=Client - full service,project_report
This associates the survey named "project_report" as the report to
use for all projects of type "Client - full service"
If set, the ForceUsersToEnterProjectReportsP parameter will
automatically redirects users who are late with a project report to
the forms they need to fill in. If desired, this feature can be
enabled to intrusively remind employees to fill out late reports.
Tracking Hours
All hours logged on any project are records in the im_hours table
using the generic on_which_table and on_what_id structure. This allows
us to extend hour tracking in the future to the ticket
tracker or other tools that employees use throughout the work day,
recording hours in the same table and thus simplifying hour
reporting. Note that the TrackHours parameter should be enabled to
prompt users to log their hours.
If set, the ForceUsersToLogHoursP parameter will automatically
redirect users to the log hours screen for yesterday if they have not
logged their hours in the past day.
Facilities
Facilities represent physical locations including offices and company
homes, such as extravigant Cape Cod beach houses. Each facility stores
basic information, including its location, directions, and primary
contact.
An office is fundamentally a business unit to which employees are assigned.
The main difference between an office and any other user group is that an
office is associated with a particular facility.
Company houses are another special type of facility, containing rooms
and beds that can be reserved. Most company house serves a particular
office location, providing temporary accomodations for visiting
ArsDigitans. Some company houses, such as special retreat facilities,
however, aren't associated with any particular office.
Partners /intranet/partners
Company partners, such as strategic consultants, graphics design
firms, etc., are each subgroups of the Partners user group. Partners
are similar to customers in that they have their own address books,
correspondance history, and list of employees engaged with the partner.
Partners can also be categorized through the categories table.
Allocations /intranet/allocations
You can use allocations to assign a percentage of an employee's time
to a specific project. This helps you to keep track of what each
employee is working on and to ensure that all employees are properly
allocated.
Email
You can set up qmail on your box to receive emails sent to your server
and automatically log them with a corresponding project, customer,
partner, or random user group. The idea is to send mail to the
user_groups.short_name@somedomain, and associate the emails with the
user_groups. This works because the short_name is unique. Here's how
it works (very briefly):
- Point a domain (like intranet.arsdigita.com) to the box running your intranet
- Install qmail and pipe all mail to intranet.arsdigita.com to a perl script that stuffs the mail into your database. The perl scripts to do this come with acs.
- Use these "aliases": (the actual processing is handled through email-handler-sweeper-procs)
Assume the short_name for our user_group is toolkit
- toolkit@intranet.arsdigita.com to simply log the email as a correspondance
- toolkit-employees@intranet.arsdigita.com to log the email as a correspondance and to forward it to all employees associated with the user group
- toolkit-customers@intranet.arsdigita.com to log the email as a correspondance and to forward it to all customers associated with the user group
- toolkit-all@intranet.arsdigita.com to log the email as a correspondance and to forward it to everyone associated with the user group
- Finally, be sure to set the LogEmailToGroupsP parameter to tell the email-handler to process the group-based email!
In the future, we'd like to create mailing lists for the groups and
aliases rather than use ns_sendmail for all members of the group.
Procedures
The
im_procedures
table can be used to record
company procedures and the people certified to do them. Anyone can
add a procedure, and they're allowed to pick the first person
certified for that procedure. Anyone certified in procedure X can
certify anyone else to do that procedure. (That person can also add
restrictions like
only certified on HPUX) Certified users
should record times they supervised a non-certified user doing a
procedure, so we can use rules like
A user can be certified after
completing the procedure 5 times under the supervision of a certified
user. Each procedure is a subgroup of the Procedures user group.
Processes
Process and process tracking is vital to make sure that
a company runs well-oiled. For each process, we need
to record the process details, which department is involved,
and the primary owner. The primary owner is in charge
of auditing the process periodically to make sure the description
is correct and that the process is happening as planned.
create table im_processes (
im_process_id integer primary key,
-- name of the basic process
process_name varchar(100) not null,
-- department that runs this process
department_id integer references categories(category_id),
description clob,
primary_owner_id integer references users(user_id)
-- processes should be audited by the primary owner
-- we record when this process was last audited
last_audit date,
-- when will we check on the health of this process?
next_audit date
);
Simple processes might only involved the owners.
For those that involved more people, we keep track of this users involved in
this process and their role using the standard user group
tables.
For example, take a process "hiring pipeline".
Roles would be
- Supervisor
- Scheduling and administration
- Phone Interviews
- Technical Interviews
- Reference Checks
Reports /intranet/reports
General reports about the intranet broken down by office, team, data quality, employee information, etc.
mbryzek@arsdigita.com