System Administration & Shared Services
Source libraries: homersys (application shell, navigation, logon, shared
search and maintenance windows — 152 objects), system (non-visual shared
services and base classes — 42 objects), base (a grab-bag of developer/ad-hoc
extract objects — 38 objects, mostly one-off DataWindows).
Security administration (users, classes, group-level data security, menu
security) lives in the app_sec library and is documented separately in
Security Model. This page covers everything
else that makes HOMER a single coherent application: the MDI shell and
data-driven navigation, the logon/connection sequence, reference-data (code
table) maintenance, and the shared behavioral framework — search/selection
windows, standard CRUD patterns, wizards, preferences, logging — that every
functional module inherits. These patterns are requirements: they define the
consistent behavior users experience across all ~550 screens, and a migration
that rebuilds modules one-by-one without them will produce an inconsistent
product.
Actors
- All HOMER users — everyone enters through the shell, logon, and navigator.
- System administrators / MIS staff — maintain code tables, batch report definitions, letter headers, release notes, and diagnose problems via error logs, trace, and the test log.
The navigation shell
MDI frame
w_sfpi_frame (homersys/w_sfpi_frame) is the MDI frame every functional
screen opens inside as a sheet. On post-open it:
- Shows the connected user and database/server in the MicroHelp bar and status bar, and halts if the database connection is not live.
- Applies Oracle roles for the user (
system/f_set_roles) and re-reads the user description once security tables are readable. - Sets the window title to indicate the environment —
(Production),(Test), or(Development)derived from the database name — plus the application version (homersys/w_sfpi_framepfc_postopen). - Verifies the client build against the database:
of_check_app_vercounts rows inhomer_versionsmatching the running version string and halts with "not currently running a valid version" if none match (homersys/n_cst_sfpiappmanager). - Initializes the security service, applies menu security via
n_system_menu_security.of_applymenusecurity(see Security Model), and builds the subscriber-protection list (below). - Opens the tree navigator automatically when the user's INI setting
SETTINGS/sys_menuisTrue(the default) (homersys/w_sfpi_frame).
The status bar shows user id, a clock (interval and format configurable from
the INI: timerinterval, timerformat), free-memory indicator, the active
sheet name, and a notes indicator that switches between "no notes", "notes
found", and "VIP notes found" bitmaps under module control
(w_sfpi_frame.wf_notes_found/wf_no_notes/wf_vip_notes_found).
- SYS-1 — All functional screens open as sheets of a single main window
that permanently displays: logged-on user, connected database and server, an
environment indicator (Production / Test / Development), application version,
and the active screen's identity. (
homersys/w_sfpi_frame) - SYS-2 — The client checks its own version against a database version
registry (
homer_versions) at startup and refuses to run when the version is not registered. (homersys/n_cst_sfpiappmanager.of_check_app_ver,w_sfpi_framepfc_postopen)
The function tree (w_system_tree_menu)
The primary navigator is homersys/w_system_tree_menu, opened as a sheet
titled "Menu". Mechanics:
-
The tree is built by walking the frame menu (
m_sys_frame'sm_functionsbranch): each visible menu item becomes a tree node, parents are folders, leaf items are launchable "programs" (w_system_tree_menu.wf_loadmenu).m_sys_frame(homersys/m_sys_frame, ~19,000 lines) is thus the master catalog of every function in the application, organized under top-level areas (Enrollment, Plan, COBRA, Funding, Accounting, Providers, Claims, UR/CM, Administrative, System, Security — per the picture-assignment code inwf_loadmenu). -
Items the user's security disables are shown non-bold and refuse to launch with "You do not have the proper security authorization to run this program." (
wf_launchprogram). The enable/disable state itself comes from menu security applied tom_sys_framebefore the tree is built (w_sfpi_framepfc_postopen →gnv_menu_security.of_applymenusecurity; see Security Model). -
Favorites: leaf items can be dragged onto a Favorites list; folders are rejected. Favorites launch on double-click/Enter and are removed with Delete. They persist per user as
user_inirows (section_name='MENU',key_name='FAVORITEnn') and are renumbered/compacted on load. (wf_setfavorite,wf_loadfavorites,lv_favoritesevents) -
Home item: Ctrl+Enter or right-double-click marks a node as "home"; the tree opens pre-selected there on next start (
user_iniMENU/HOME). (wf_sethome,tv_system_menu.ue_load) -
Expansion state: which folders are expanded is saved per user (
section_name='MENU_OPEN') on close and restored on load. (wf_expand_contract) -
Personal notepad: a free-text notepad on the navigator persists per user, chunked into 2,000-character
user_inirows (MENU/NOTEPADnn), saved on lose-focus/close. (wf_setnotes,wf_loadnotes) -
System notes banner: a banner DataWindow (
d_user_ini_sysnotes) shows broadcast rows (user_iniusernameSYSTEMor the current user, keySYSNOTE%), supporting[COLOR BOLD ITALIC]markup prefixes and substitution tokens&VERSION,&BUILD,&DATE,&USER,&NAME,&DB,&SERVER; when no rows exist it defaults to "Welcome (user). Running (version)". (w_system_tree_menu.dw_sysnotespfc_retrieve) -
SYS-3 — Navigation is presented as a security-filtered hierarchical tree of all application functions, mirroring a single master function catalog; unauthorized functions are visible but disabled and cannot be launched. (
homersys/w_system_tree_menu,homersys/m_sys_frame) -
SYS-4 — Per-user navigator personalization — ordered favorites, a home position, folder expansion state, and a free-text notepad — persists in the database (
user_inikeyed by username/section/key), not on the workstation. (homersys/w_system_tree_menu,homersys/d_user_ini) -
SYS-5 — Administrators can broadcast styled system notes (with runtime substitution of version, date, user, database) that display on every user's navigator. (
homersys/d_user_ini_sysnotes,w_system_tree_menu.dw_sysnotes)
The table-driven button menu (w_system_menu)
An older navigator, homersys/w_system_menu ("HOMER - System Menu"), renders
menu options as picture buttons from the system_menu table via
d_system_menu_datawindow: SELECT picture_path||picture_name, sys_menu_option, window_to_open, display_order, menu, parameter FROM system_menu WHERE menu = :menu_name ORDER BY display_order. Clicking a row either descends a level
(rows whose window_to_open is not a window name), returns a level (names
starting x, or Shift-click), or opens the target: names starting w open as
sheets (with parameter passed when present), names starting r are opened
as response windows after replacing the prefix with w. Every launch is
guarded by homersys/f_useraccess, which checks the user's security groups
against security_info/security_template for a 'Top Level Menu Object'
entry, and denies with "You do not currently have access to the requested
Application Function." A breadcrumb of the descent path is maintained in the
title text. The frame exposes ue_system_menu to open this navigator at a
given level (homersys/w_sfpi_frame).
- SYS-6 — The function catalog is data-driven: a database table
(
system_menu) defines menu captions, hierarchy, display order, target window and an optional launch parameter, so navigation can be re-arranged without code changes. (homersys/d_system_menu_datawindow,homersys/w_system_menu; the same table also drives menu security — see Security Model) - SYS-7 — Function launch is authorization-checked at the moment of launch
(not only at display), with a uniform denial message.
(
homersys/f_useraccess,w_system_menudoubleclicked,w_system_tree_menu.wf_launchprogram)
Functions not yet built open homersys/w_construct ("Under Construction");
f_useraccess exempts it from security.
The function catalog is organized by department
The user guide publishes the canonical department/function list, which is the business structure the frame menu's top-level areas mirror (User Guide ch. 22):
| Department | Functions |
|---|---|
| Enrollment | Enrollment; COBRA |
| Plan | Client Maintenance; Plan Design; Managed Care; Stoploss |
| Accounting | Billing A/R; Funding; Commissions |
| Providers | Provider Maintenance; Capitation |
| Claims | Claims Entry; Adjudication; Auditing |
| UR/CM | Utilization Review; Case Management |
| Administrative | Marketing (Sales Support); Forms Processing (Claims Output); Global (E-mail, Client Service Log, Printing) |
This matters beyond navigation: security is organized the same way. "Each Department has a defined role in the database", and the PFC security group level "for SFPI it is divided up into departments" (User Guide ch. 28; see Security Model). Department therefore simultaneously determines which menu branch a function sits under, which Oracle role grants its table access, and which security group controls its objects.
Standard window verbs
Every maintenance window exposes the same File and Edit vocabulary, defined once in the guide (User Guide ch. 22). File: Save ("Save current data"), Close ("Close current window and save current data"), New ("Enter Add mode and save any current data"), Open ("Open another window instance"), Menu ("Return to previous menu"), Exit ("Exit application (Save current data Y/N?)"). Edit: Find ("Enter Query mode and save current data"), Undo ("Reverse changes to current field only"), Cancel ("Reverse changes to all current data"), Clear ("Clear all data fields on current window"), Delete ("Delete selected data (Privilege will change window to window)"), plus the clipboard verbs. Note that Undo and Cancel are deliberately different scopes, and that Close saves while Exit prompts.
The guide also documents the mode state machine every function follows: a function opens in Query mode with a blank window; entering criteria and pressing Enter either populates the window and enters Update mode (unique match), presents a list to choose from (multiple matches), or shows an error (no match); File/New switches to Add mode. Saves occur "at: Exit (Save Y/N?), File Save, File Close (Save Y/N?), Change to new record, Add new record." (User Guide ch. 22)
- SYS-26 — Application windows share one command vocabulary and one
query/add/update mode model: a function opens in search mode, a unique match
goes straight to edit, multiple matches present a pick list, and save is
offered at every exit point. Field-level undo is distinct from
window-level cancel. (User Guide ch. 22; implemented across
homersys/w_maint_selection,w_edit_selection,system/u_homer_dw)
Result-set governors
Search screens must not return unbounded result sets. "Queries must be limited to reasonable amounts of returning data. If a query returns a number of rows greater than the specified allowable number, a message should appear requesting that the user refine the search criteria further." The documented limits are 100 rows each for Group, Member, SSN and Name searches (User Guide ch. 22).
This is the companion to SYS-17 (which refuses retrieval with no criteria): one rule guards the empty query, the other the over-broad one.
- SYS-27 — Searches enforce a maximum result-set size per search type
(documented as 100 rows for group, member, SSN and name lookups); exceeding it
returns a prompt to refine the criteria rather than a truncated or
unbounded list. (User Guide ch. 22) Whether the shipped code enforces these
caps could not be confirmed from the extract — verify against
homersys/n_member_search/n_group_searchbefore treating the numbers as current.
Logon and connection flow
The application manager homersys/n_cst_sfpiappmanager (a PFC application
manager subclass, global gnv_app) drives startup:
- INI resolution (constructor): the application INI is
homer.iniin the current directory if present, otherwise the path registered inwin.iniunder[SFPI]. The user INI is set to the same file. INI keys read at startup includeSETTINGS:microhelp,logo,help,debug,spy_file,activate_testlog,CREATEMEMBERID,pict_path,database,timerinterval,timerformat,sys_menu,test;ErrorLog:logfile,severity;Oracle Production:DbParm. It also writesSETTINGS/archive_dir = U:\mis\archiveback to the INI. - Services (pfc_open): error service with configurable log file and
severity; transaction registration; the security service; the application
preference service (
system/u_app_preference); the file service. - Connection:
SQLCA.of_Init(inifile, ProfileString(SETTINGS/database, default "Oracle")), then a modal logon loop —of_LogonDlgopenshomersys/w_homer_logonrepeatedly until logon succeeds or the user cancels (cancel halts the application). - Logon (pfc_logon): sets user/password on the transaction, connects,
captures the Oracle session id (
system/u_app_sql.uf_getoracleid), and writes an audit trail to the error log: database/server/logid, success or failure with SQL error text, and client environment (OS, CPU). - Password change: the logon window carries optional "New Password" /
"Verify New Password" fields; on match and confirmation it issues
ALTER USER ... IDENTIFIED BY ...(users are Oracle accounts), with failure guidance and a log entry. (homersys/w_homer_logonpfc_default) - Roles:
system/f_set_rolesissuesSET ROLE readsec, retrieves the user's role list (d_user_role_privs), and issues oneSET ROLE r1, r2,…for the session; distinct failure codes for "readsec not granted", "no roles", "set role failed". - Security service:
of_start_securityopens a second database connection (itr_security) with the same credentials for security lookups, runsof_InitSecurity, and maps failure codes −1…−5 to specific fatal messages (cannot connect / no app parameters / no user parameters / user has no granted functions / no default group), halting the application. - Subscriber protection:
of_subscriber_securityretrievesd_subscriber_protect(distinctmember_sys_keyfrommembers_includedwherename <> :userid) into an in-memory list of member keys the current user must not access — a member-level privacy screen used by search services. (homersys/n_cst_sfpiappmanager) - Frame: only after successful logon is the frame opened
(
ue_afteropen→Open(w_sfpi_frame)).
The user guide confirms the official provisioning sequence behind this logon design: before anything else, the Oracle DBA creates the user's Oracle id and password (from the user's full name and initials) — without it "the user would not be able to log on"; only then does the Homer administrator create the Homer user, associate the (unassigned) Oracle id with a name, and assign a role and a class in the Security User Maintenance window (User Guide ch. 28; see Security Model).
Diagnostics wired into the manager: a debug/SQL-spy mode (INI-driven)
logging all SQL to a file; a test log mode (activate_testlog=TRUE) that
adds a Tools menu item and routes unhandled system errors into a structured bug
report window (homersys/w_test_log) writing to the test_log table (version,
build, database, window, module, system message, user message, user details);
otherwise pfc_systemerror formats error number/text/object/script/line into
the standard error service and exits. A single-instance mutex check
(of_is_this_app_running via CreateMutexA) exists but its startup call is
commented out.
- SYS-8 — Startup is fail-closed: missing/invalid configuration, failed
connection, failed security initialization, an unregistered client version,
or a cancelled logon all terminate the application with a specific message.
(
homersys/n_cst_sfpiappmanagerpfc_open,of_start_security;w_sfpi_framepfc_postopen) - SYS-9 — Users authenticate with individual credentials; the session
identity drives role activation, security lookups, personalization, and audit
attribution. Logon attempts (success and failure), environment details, and
password-change attempts are logged. (
n_cst_sfpiappmanagerpfc_logon,w_homer_logon,system/f_set_roles; see Security Model) - SYS-10 — Users can change their own password at logon time with
verification and confirmation. (
homersys/w_homer_logon) - SYS-11 — A per-user member-exclusion list (
members_included) is loaded at startup and exposed application-wide so member-selection screens can hide protected members (e.g. fellow employees / VIPs) from users not authorized to see them. (n_cst_sfpiappmanager.of_subscriber_security,homersys/d_subscriber_protect; consumed e.g. byenroll/w_group_member_select) - SYS-12 — Behavior toggles are externalized configuration, not code:
environment/database selection, debug and SQL tracing, test-log capture,
microhelp, help file, image paths, member-ID generation mode
(
CREATEMEMBERID). (n_cst_sfpiappmanagerconstructor)
User-visible session info
homersys/w_homer_about (About box: application, version, copyright, logo) and
homersys/w_user_detail (popup showing the resolved system INI file, user INI
file, database username, and error-log path) expose session context for
support. (w_user_detail pfc_postopen)
Reference-data maintenance
Generic code tables (codes / code_keys)
homersys/w_code_maint is the system-wide code table editor. code_keys
defines the code sets (key + description, maintained in
homersys/w_code_key_maint); codes holds the values per set. The editor
lists all code sets, shows the values grid (d_codes_grid) for the selected
set, supports add/insert (pre-filling the selected code_key), prompts to save
when switching sets, and on delete warns: the system cannot verify whether a
code is in use — terminate the code by entering an expiration date rather than
deleting it. Code values carry effective/expiration dates: the shared
dropdown homersys/dddw_codes selects values for a key where
EFF_DT <= :date AND (EXP_DT IS NULL OR …), and helper functions
homersys/f_check_code_exp_date / f_check_category_exp_date validate dates.
The codes table is the lookup source for dozens of dropdowns across all
modules (relationship codes, action codes, reason codes, etc. — every
dddw_codes usage); which specific code sets exist is data, not code, so the
authoritative list must come from a code_keys export
(see Open questions).
The design rule for what belongs in codes (User Guide ch. 22): "All
generic codes will be defined in the codes/code_keys tables", where code_keys
holds the code types and codes the values, ordered by code_display_seq, and
"Dt_exp will be null when not used, dt_eff will be populated at all times."
Dating is mandatory behavior, not an option: "Codes will be date range
effective. The application must always check to see which codes are valid at the
current date."
The guide gives three tests for using the generic table rather than a dedicated
one — the codes are "internal/industry-standard codes generally not to be
modified by the non-developer users", they are mostly static, and there are
relatively few of them. "If they are codes that users (non-developers) will
maintain, then they should certainly be in their own table." The trade-off is
stated bluntly, and is a migration consideration: "you cannot do referential
integrity to the codes table… you cannot enforce that valid codes are entered
except at the application level. If there's a doubt, it's definitely safer to
err towards creating an extra table." Codes that need related-code relationships
already live outside codes (for example note_categories,
note_sub_categories, mbr_opt_xref).
- SYS-13 — A single generic code-set facility (
code_keys→codes) provides administrator-maintainable lookup values with display sequence, short/long descriptions, and effective/expiration dating; expired values drop out of selection lists but remain valid on historical data. (homersys/w_code_maint,w_code_key_maint,dddw_codes) - SYS-14 — Deleting a code value requires a double confirmation and the
system steers the user toward expiring instead of deleting, because
referential use cannot be checked. (
w_code_maint.dw_codespfc_deleterow)
Other reference screens in this domain
| Screen | Table(s) | What is maintained |
|---|---|---|
homersys/w_accident_type | accident_types | Accident type reference values (d_accident_types). |
homersys/w_general_member_cat_maintenance | general_cat | The catalog of member category options ("possible list of group options"). |
homersys/w_group_options_maintenance | group_options | Options assigned per employer group. |
homersys/w_header (+ w_group_validate) | letter_headers, groups | Per-group, per-letter-type letterheads: logo text and font, phone numbers, address lines. New entries validate the group id and uniqueness per (group, letter type); deletion is confirmed per group. system/n_letter_headers reads this table wherever letters are generated. |
homersys/w_batch_reports | batch_reports | The catalog of batch-runnable reports: auto-assigned report_cd, report name (required), report DataWindow (required), parameter window, type, allowed run events/times. Sortable grid with add/delete/print. |
homersys/w_examiner_select | user_info | Examiner list selection window (d_examiner_selection updates USER_INFO); user directory data (name, location, phones) lives in user_info (d_user_info). |
- SYS-15 — Letter headers (logo, fonts, phone/address lines) are
maintainable per employer group and letter type, and are resolved at letter
generation time by a shared service. (
homersys/w_header,homersys/d_letter_headers_maint,system/n_letter_headers) - SYS-16 — Batch reports are catalog-driven: a report becomes schedulable
by adding a row naming its DataWindow and parameter window; report codes are
system-assigned and names/DataWindows are mandatory.
(
homersys/w_batch_reports,homersys/d_batch_reports)
Shared services that carry business behavior
These live in system/homersys and are inherited or invoked by every
module. Each defines system-wide behavior a migration must reproduce (or
consciously replace) once, centrally — not per screen.
Selection → edit patterns
Two standard "find it, then work on it" window frameworks:
homersys/w_maint_selection— criteria fields at top, result grid below. Each criteria field's tag holds a SQL condition template with a&&placeholder; on Find, the window parses the result DataWindow's SQL, appends the filled-in templates to the WHERE clause (user*wildcards become%; entry is upper-cased), re-executes, and enables Open only when rows exist. Retrieval refuses to run with no criteria (no accidental full-table scans). New routes to add-row, Open/Enter routes to the edit window. (w_maint_selection.wf_get_selection_query,wf_criteria_found, dw_selection events)homersys/w_edit_selection— criteria DataWindow + result DataWindow with registered retrieval/key columns (up to 10). Search disables the criteria until Clear; any edit re-enables Search; leaving with unsaved changes prompts Save/Discard/Cancel; New pre-populates the result row's key columns from the criteria; commit/rollback is centralized in the window's end-transaction event. (w_edit_selection.of_register,of_saveprompt,of_setkeyvalues, pfc_endtran)
The edit service system/n_cst_edit_service links a selection window to
its edit window generically: it registers requestor DataWindow + key columns,
opens the named edit window in edit/new mode, passes parameters both ways,
supports next/previous record navigation from within the edit window, and
refresh-on-save of the parent. (n_cst_edit_service prototypes,
u_homer_dw.of_seteditservice)
- SYS-17 — Every maintenance area follows a uniform search-first pattern:
criteria-driven retrieval (wildcards supported, case-insensitive), no
retrieval without criteria, edit opens from a result row, unsaved-change
prompts on navigation, and add pre-keys new rows from the search context.
(
homersys/w_maint_selection,homersys/w_edit_selection,system/n_cst_edit_service)
Standard data grid (system/u_homer_dw)
The application-wide DataWindow class layers behavior on the PFC base: switches
for row add/delete permission; key-column edit protection; auto-add-row on
reaching the last row; "clear new rows" with minimum/maximum row counts;
Enter-as-Tab (a per-user preference — u_app_preference.of_set_useenterastab);
tab-page advance on tab-out; save-menu enablement when changes exist
(of_setsavemenu); update against an alternate table (of_update_table);
change tracking (of_ischangemade); size-to-columns. Windows enable the frame
Save item only when a grid reports modifications (w_edit_selection
ue_setsavemenu, homersys/w_batch_reports). system/n_homer_ds is the
matching datastore; system/u_dw_on_tabpage integrates grids with tab folders.
- SYS-18 — Grid behavior is uniform application-wide: controlled add/delete
rights per grid, protected key columns, optional auto-append row, Enter-key
navigation per user preference, and Save enabled only when unsaved changes
exist. (
system/u_homer_dw,system/u_app_preference)
Standard search components
Reusable, embeddable search objects with consistent behavior (criteria entry → explicit Search button, auto-search when a unique identifier like SSN or member id is completed, Clear resets):
-
Member search:
homersys/u_member_search(visual) overhomersys/n_member_search, criteriad_member_search_criteria(SSN, name, member id, group). (The member-exclusion list of SYS-11 is exposed asgnv_app.il_subscriber_protectand applied by member-selection screens, e.g.enroll/w_group_member_select.) -
Group search:
homersys/n_group_search,u_group_select(drag-drop multi-select of groups). -
Provider search:
homersys/n_provider_search,n_provider_search_quickfind,u_provider_search, windoww_provider_search. -
Claims examiner search:
homersys/n_claims_examiner_search,w_examiner_select. -
User pickers:
homersys/u_choose_user,u_choose_user_class. -
Multi-group member disambiguation:
homersys/w_homer_social_searchlets the user pick which enrollment of a member active in multiple groups is meant. -
SYS-19 — Member, group, provider, examiner, and user lookups are single shared components reused by all modules, so search semantics (fields, wildcards, auto-search on unique ids, exclusion of protected members) are identical everywhere. (
homersys/u_member_search,n_member_search,n_group_search,n_provider_search,n_claims_examiner_search)
Wizard framework
homersys/w_homer_wizard + u_homer_wizardobject: a base response window with
Cancel / Previous / Next / Finish buttons over an ordered set of registered
step objects; each step validates on leave (ue_leave) and can refuse entry
(ue_enter); Finish only enables on the last step. Module wizards (e.g. user
assignment in app_sec) inherit this. (w_homer_wizard.wf_nextprev,
of_register)
- SYS-20 — Multi-step guided flows share one wizard framework with
per-step validation and controlled navigation.
(
homersys/w_homer_wizard,homersys/u_homer_wizardobject)
User preferences & settings cloning
system/u_app_preference centralizes per-user behavior preferences persisted
in the user INI (APP PREFERENCES): display all groups, display expired
groups, default-to-last group, direct-to-member navigation, default member-ID
letter, Enter-as-Tab, client segment (default SFPI). The client segment is
the sixth level of the official security model — it partitions update rights
to commonly shared data by client, maintained via the "Client Segment User
Maintenance" screen (Application Functions / System / Client Segment User
Mapping) (User Guide ch. 28; see
Security Model). Database-backed
personalization goes to user_ini (SYS-4).
homersys/u_clonemanager clones one user's setup to a new user in a single
transaction: security group memberships (d_pfcsecurity_grouplookup),
database roles (d_user_roles), and user classes (d_user_classes), refusing
if the target already has settings and rolling back on any failure.
- SYS-21 — A new user can be provisioned by cloning an existing user's
function groups, roles, and classes atomically.
(
homersys/u_clonemanager; see Security Model)
Report archive (report_data / report_objects)
system/n_report_data persists generated report output into the database:
report content is stored as blobs in report_data with a description and
report_type_cd, related objects in report_objects; it handles 32K-chunk
blob/file conversion both directions, and multiple overloads accept
DataWindows/datastores. system/n_cst_reprint_print_reports and dropdown
homersys/d_dddw_report_type consume this archive; system/w_letter_on_cd
retrieves claim letters archived to CD. (No report_hist table appears in
these libraries — the archive mechanism here is report_data/report_objects.)
- SYS-22 — Generated reports/letters can be archived centrally (typed, with
description) and re-retrieved or reprinted later without regenerating them.
(
system/n_report_data,system/n_cst_reprint_print_reports)
Batch scheduler (system/n_batch_scheduler)
Drives unattended batch windows (claims processing etc.): a process registers
by name; the scheduler reads its run window (start/end time), mode (continuous
vs. once-daily), frequencies, and optional rollback segment; it verifies the DB
connection each cycle, never runs on Sundays, and in daily mode computes the
next wake-up and records LAST_RUN_DT in batch_schedules. Setting
batch_schedules.running = 'N' externally makes the process halt after its
current cycle — the operator kill switch. It also manages claim-lock
acquisition for competing batch workers (of_get_claim_lock overloads) and an
on-screen console log. (n_batch_scheduler.of_check_processing,
of_end_processing)
- SYS-23 — Batch processes are schedule-driven from a database table
(per-process run window, continuous/daily mode, last-run tracking, Sunday
blackout) and can be stopped externally via a database flag; concurrent
workers coordinate through lock acquisition.
(
system/n_batch_scheduler,batch_schedules)
Diagnostics & messaging
-
system/n_homer_messageextends the message object so structured parameters (istr_passparms— seesystem/str_passparms) travel between windows. -
homersys/n_homer_tracewrites timestamped, elapsed-time, free-memory-annotated trace entries for performance debugging, printable or saved to CSV (d_homer_trace). -
The error service logs to a configurable file with severity filtering (SYS-8/9);
system/w_dwdebuggeris the PFC DataWindow debugging utility. -
Address handling:
homersys/u_homer_address(standard address entry object) andhomersys/u_mailers(address standardization via the "Mailers" interface) withw_addr_search/w_addr_linkto apply a corrected address to the linked persons/groups; commented-out startup hooks for the Mailers+4 verification software remain in the app manager (n_cst_sfpiappmanagerpfc_open). See the dedicated section below. -
Utility functions used as business rules:
system/n_functions.of_dwrangesvalid(validates from/thru date ranges do not overlap per key — used by dated reference data),system/f_init_cap,f_fixedlength,f_fund_money_to_word/f_fund_digit_to_word(check-amount wording),f_next_letter,f_lookupdisplay, and resize helpers (f_set_resize,f_set_tab_resize,f_set_uo_resize). -
SYS-24 — Date-ranged records (rates, codes, eligibility-like rows) share one overlap-validation routine ensuring from/thru ranges for the same key do not overlap. (
system/n_functions.of_dwrangesvalid)
Address standardization
Addresses are held in two tables by type — Standard and Provider — keyed by an internally assigned address system key, and standardization plus de-duplication are performed by Mailers, "a distributed PowerBuilder application" reached over WinSock, using the Mailers+4 DLL and MelissaData reference data (User Guide ch. 22).
Operator-visible rules, quoted:
- "All addresses in the system will be entered on the window with the second address line containing the suite or apartment information, and the first address line containing a street address or PO box. If the user only enters information in the second address line, the application should move that information to the first address line."
- "If the user needs to enter both a PO Box and a street address, they must enter two separate addresses. The Mailers application cannot standardize addresses that contain both a PO Box and a street address."
- "The system must display addresses which are not standardized with a red background. This is the only distinction made between standardized and non-standardized addresses."
- Standardization failure is non-blocking: "The application must inform the user that the address could not be standardized and ask them if they want to save the address anyway… the address as originally entered by the user will be re-displayed."
- A silently changed state is the caller's problem: "If the address standardization process changes the state that the user entered… the Mailers application does not consider this an error. It is up to the calling application to detect this."
- Duplicate checking runs "within address type and, for PROVIDER, within client segment".
std_addr_flg carries three values — U unchecked, N non-standardized,
Y standardized.
- SYS-28 — Postal addresses are validated and normalized through a shared
standardization service, with a persistent per-address standardized state,
non-blocking failure (the user may save an unstandardized address), a visual
indicator for unstandardized addresses, and duplicate detection scoped by
address type and client segment. (
homersys/u_mailers,w_addr_search,w_addr_link; User Guide ch. 22)
Vendor-data risk, recorded in the guide itself (User Guide ch. 22): "Mailers
data was provided by MelissaData. As of Dec. 2002, we have chosen not to renew
receiving this data due to a 3+-times increase in expected cost. The last data
set available is from Nov 2002, and will expire in 1 year, and become unusable."
Combined with the commented-out startup hooks in n_cst_sfpiappmanager, this
strongly suggests standardization has been dormant for two decades — see Open
questions.
Audit trail and database-implemented behavior
A substantial amount of system-wide behavior lives in Oracle rather than in PowerBuilder, and will not be found by reading these libraries (User Guide ch. 22):
-
Audit columns — "Many tables have
updt_dtandupdt_user_idcolumns… These columns will have triggers that automatically update their values… with the system date and Oracle database login." -
Effective-date integrity — "a trigger will be built to ensure that when an
eff_dtis created or updated, it is no earlier than the latestexp_dtfor a row that otherwise has the same key." -
Audit trail — after-triggers named
TUA/TDAwrite group changes toAUD_TRAIL_GRPand member changes toAUD_TRAIL_MBR, each row recording the key, timestamp, table changed, U or D, the user, and a change description holding "the changed column name and its before/after values". The scope is deliberate: triggers fire on update and delete only — "We consciously chose not to record inserts of data (new data) to limit the amount of information held in the audit trail" — and "Only tables that are directly related to enrollment or group information have audit trail requirements." -
Audit control package —
PKG_AUDIT_CONFIGexposesAUDIT_FLG,WANG_FLGandCHG_COMMprocedures so a session can suspend auditing or attach a comment to the changes it is about to make. -
Mutating-trigger workaround — cascading parent/child date triggers would raise ORA-04091, so the
SP_MUTATION_PREVENTpackage holds session-level flags (group_fire_trigger,grpcov_fire_trigger,mbrelig_fire_trigger,coverage_fire_trigger,rider_fire_trigger,grpcatval_fire_triggerand others) that the first trigger clears and restores around its cascade. -
Parentless groups — the only way to create a group with no parent in any hierarchy is with a privileged role, and "the database will enforce the rule within a trigger using the role as a prerequisite".
-
SYS-29 — Changes to enrollment and group data are audited automatically at the data layer: every update and delete on an audited table records the key, the table, the action, the user, the timestamp and the before/after values of each changed column. Inserts are intentionally not audited. A privileged session can suspend auditing or attach an explanatory comment to a batch of changes. (
AUD_TRAIL_GRP,AUD_TRAIL_MBR,PKG_AUDIT_CONFIG,TUA/TDAtriggers; User Guide ch. 22)
Member deletion
homersys/w_member_delete + n_delete_member remove a member and dependent
data from the application — an administrative repair function (duplicated in
base/w_member_delete).
The user guide documents both the entry point and the cascade (User Guide ch. 22). Purpose: "Occasionally, a member is added error and needs to be completely deleted from the system." Access is restricted — "The delete function is only accessible from the Application Functions, Enrollment drop down menu bar. For security purposes, the Delete Member function is not available to all users." Subscriber versus dependent is inferred from the keys: "if the two sys keys are equal, the member is a subscriber; if not, the member is a dependent."
The blocking precondition, which is the most important business rule on this function: "The delete member function must not be allowed for any member that has appeared on a bill. This modification will be crucial once the Billing part of HOMER has been installed."
Documented deletion order — dependents must go first "due to data constraints":
| Scope | Tables, in order |
|---|---|
| Dependent | election_coverages, member_cat_val, member_eligibilities, member_waiting_periods, drug_mbr_exts, family, coord_of_bens, students |
| Subscriber | election_coverages, elections, member_cat_val, member_eligibilities, member_waiting_periods, notes, id_card_req, drug_mbr_exts, family |
Finally: "If the member sys key is not found in the family table as a dependent
sys key, then the member record is deleted from the members table along with
the corresponding address record. Otherwise, the member record and address is
not deleted."
- SYS-30 — Administrative member deletion is a restricted function that
removes a member and every dependent record in a fixed order (dependents
before subscribers), refuses outright for any member that has appeared on a
bill, and retains the member row itself whenever the member is still
referenced as someone's dependent. (
homersys/w_member_delete,n_delete_member; User Guide ch. 22)
A related function documented alongside it is member move
(f_member_division_move), which relocates a member's eligibility between
divisions, is reachable only from the enrollment screen, and performs its
deletes through the stored procedure pkg_del.del_mbr_elig (User Guide
ch. 22).
Release notes & help
-
homersys/w_release_notesdisplays a printable release-notes grid. The content is hard-coded in the window's open event (38 entries covering versions 1.1.5–1.2.0);d_release_notesis an external (non-database) DataWindow. Later practice moved user-facing announcements to the navigator system notes (SYS-5). -
Context help: F1 help is wired to a
homer.hlpWinHelp file whose path comes from the INI (n_cst_sfpiappmanagerconstructor,w_sfpi_framepfc_postopen). -
MicroHelp: menu/tag-based hints in the frame's status line, toggled by INI (
SETTINGS/microhelp; tag conventionmhseparator —n_cst_sfpiappmanagerinstance variables). -
SYS-25 — The system provides in-app release/announcement visibility (currently: static release-notes screen + database-driven system notes) and screen-level help; a migration should consolidate on a data-driven mechanism. (
homersys/w_release_notes,d_user_ini_sysnotes)
Data touched
| Table | Used by |
|---|---|
system_menu | Navigation catalog (d_system_menu_datawindow); menu security (see Security Model) |
user_ini | Favorites, home, expansion, notepad, system notes (d_user_ini, d_user_ini_sysnotes) |
homer_versions | Client-version gate (n_cst_sfpiappmanager.of_check_app_ver) |
codes, code_keys | Generic code sets (w_code_maint, dddw_codes) |
accident_types, general_cat, group_options, state | Reference screens (w_accident_type, w_general_member_cat_maintenance, w_group_options_maintenance, d_states) |
letter_headers | Letterheads (w_header, n_letter_headers) |
batch_reports, batch_schedules | Batch report catalog and scheduler (w_batch_reports, n_batch_scheduler) |
report_data, report_objects | Report archive (n_report_data) |
test_log | In-app bug reports (w_test_log) |
members_included | Per-user member exclusion (d_subscriber_protect) |
user_info, user_dept_group, security_groupings | User directory, department groupings (d_user_info, n_user_dept_groups) |
security_* | Logon/roles/access checks (see Security Model) |
aud_trail_grp, aud_trail_mbr | Database-side audit trail for group and member changes (TUA/TDA triggers — SYS-29) |
bnotice | CP2100 / IRS B-notice tracking for 1099 TIN mismatches (legacy; see the 1099 screens) |
Migration notes
- The shell patterns are the product's UX. SYS-17/18/19 (search-first screens, uniform grid behavior, shared lookup components) should be rebuilt as shared components/framework in the target platform before module migration begins, or every migrated screen will re-implement them inconsistently.
- Navigation should stay data-driven (SYS-3/6): the
system_menutable + per-user/role filtering maps naturally to a dynamic menu service; favorites, home, and broadcast notes (SYS-4/5) map to per-user settings and an announcements feature. - Oracle-coupled mechanics need redesign: logon as Oracle accounts,
SET ROLE,ALTER USERpassword change, dual security connection, and theDisableBindINI workarounds (f_set_roles) are implementation details — the requirement is individual identity + role activation + self-service password change (SYS-9/10). - Workstation INI files split personalization between file (preferences,
u_app_preference) and database (user_ini); consolidate on server-side per-user settings. - The client-version gate (SYS-2) becomes trivially unnecessary in a server-delivered UI but the compatibility check concept may survive for any installed components.
baselibrary: aside fromw_member_delete,w_open_windowname(developer window launcher),w_provider_consolidate_vendors(vendor merge utility) andn_check_copy(check-copy/EOB print), it is dominated by one-off extract DataWindows (Burns enrollment dumps, MagellanRx files, test objects) that look like developer ad-hoc work products — candidates to not migrate; the extracts that are real recurring feeds belong to the EDI domain.- Test-log / trace facilities (SYS diag) can be replaced by standard
logging/APM; the requirement worth keeping is that unhandled errors are
captured with context and, in test mode, routed into a triage queue
(
test_log). - A large share of system behavior is in the database, not these libraries
(SYS-29). Audit triggers, effective-date integrity triggers, the
SP_MUTATION_PREVENTcascade-control package,PKG_AUDIT_CONFIG, thepkg_del.del_mbr_eligprocedure, and role-gated parentless-group creation are all Oracle-side. None of them appear in the PowerBuilder extract, so a migration scoped from the client code alone will silently drop them. The Oracle DDL, trigger and package source is a prerequisite deliverable. - Background processes run as a separate Oracle identity. The guide's
claim-rollback procedure identifies extra claim lines created by the
background process by
create_user_id = SFPIBACK(User Guide ch. 22) — the background account whose code is a known recovery gap. Anything attributing data toSFPIBACKwas written by an unattended process, not a user. - Scheduled work is spread across three mechanisms: the in-application
n_batch_scheduler(SYS-23), Oracle-side jobs and triggers, and Unix crontab entries on the database hosts. The guide documents the data warehouse refresh running from crontab (weekday claim sync in the evening and a fuller morning pass, plus a Saturday run, with a separate snapshot refresh Monday–Saturday), a once-daily claims-delete process that removes claims marked for deletion and 60 days or older from ~34 tables, and a daily reset of claim-ID starting numbers that "will be implemented later either during the nightly cycle or independently by a Cron job on the Unix box" (User Guide ch. 22). A migration inventory of scheduled work must cover all three mechanisms. - Three master groups are hard-coded. "Currently three Master groups exist in
the groups table: SFPI, M/III, and IBA. Master groups can be identified as
having a null
parent_group_idcolumn." Adding a fourth requires code changes in three named places —w_census_rpt_args_sheet,d_annlstmt_group_selectandn_cst_sales_report_wizard— and the guide notes the intent to "find the masters logically instead of having them hardcoded" (User Guide ch. 22). This is a concrete, cheap fix to carry into the target system.
Open questions
- Which code sets live in
code_keys? The editor is generic; the authoritative inventory of code sets (and which modules read each) requires a data export ofcode_keys/codes. (homersys/w_code_maint) - Is
w_system_menu(button navigator) still in use, or fully superseded byw_system_tree_menu? Both are wired to the frame (w_sfpi_frame.ue_system_menuvs. the INI-driven tree auto-open). The user guide (ch. 28, 1999) directs administrators to a screen "found under the menu application functions/system/client segment user mapping" — a hierarchical menu-path phrasing consistent with the table-driven navigator being the official navigation at the time the guide was written; still confirm current production usage. - Member deletion cascade — largely answered by the user guide (ch. 22):
the child tables and their order are documented above (SYS-30), as is the
"must not be allowed for any member that has appeared on a bill"
precondition. What still needs SME confirmation is whether
n_delete_memberin the shipped code matches that documented list — the guide predates several tables — and whether the billing precondition was ever implemented (the guide frames it as a future "modification… crucial once the Billing part of HOMER has been installed"). (homersys/n_delete_member,w_member_delete) members_includedsemantics — the protection list retrieves members wherename <> :userid, implying the table lists member↔user pairs that are allowed; confirm intended population and coverage (VIPs? employees?). (homersys/d_subscriber_protect)- Mailers address standardization — the Mailers+4 integration hooks are
commented out in
n_cst_sfpiappmanager, and the user guide records that the MelissaData reference data was deliberately not renewed after November 2002 and would "expire in 1 year, and become unusable" (ch. 22). Treat standardization as presumed dormant since roughly 2003 and confirm: isstd_addr_flgstill maintained, and are unstandardized addresses still shown with the red background? (u_mailers,w_addr_search,w_addr_link) - Pridecare screens (
w_pridecare,w_pridecare_bill_data,n_ds_pridecare_coverages) — a client-specific monthly billing extract living in the shared library; is this client still active, and should it migrate as a billing-domain feed? report_datagrowth/retention — no purge mechanics were found in these libraries; confirm retention policy for the report archive.SETTINGS/archive_diris force-written toU:\mis\archiveat every startup (n_cst_sfpiappmanagerconstructor) — confirm what consumes it (report/letter archival paths) for infrastructure planning.