Skip to main content

COBRA Administration

Source libraries: cobra (windows, admin DataWindows), cobradw (letter/notice DataWindows and letter functions), cobrarpt (reports). 13 windows, 89 DataWindows. Screen-by-screen detail is in the Screen catalog.

Purpose​

Administers continuation-of-coverage (COBRA) for members of self-funded plans: it captures qualifying events against a member's eligibility record, determines who is entitled to an election letter and who the qualified beneficiaries (QBs) are, generates and prints the statutory letter set (first notice, election letter and form, conversion, unavailability, early-termination, etc.), records election responses, maintains group-specific COBRA premium rates, receives premium check payments, and terminates member eligibility when COBRA coverage ends (cobra/w_cobra_administration, cobra/w_cobra_printqueue, cobra/w_cobra_rate_maint, cobra/w_cobra_receive_premium).

Letter content is rendered by a separate "COBRA background process" that writes the finished letter blobs into cobra_letter_data; the windows in these libraries queue letter requests and print the finished blobs (comments in cobra/n_cst_cobra_notification_gen, cobra/w_cobra_printqueue — "the actual letter is generated in the COBRA background process").

The user guide confirms this split: the background process is a server-side application that continuously checks whether any letters need to be created or any terminations need to be performed; at guide time it created election, termination and notification letters (User Guide ch. 3).

Actors​

Grounded in the system frame menu (homersys/m_sys_frame, m_cobra submenu: COBRA Administration, Receive Premium, COBRA Reports, Delete COBRA, Letter Error Maintenance, Letter Print Queue, COBRA Rates, Mailing Labels, Request Notification/Conversion/Unavailability Letter):

  • COBRA administrator — works events, creates letters, records responses, terminates coverage (cobra/w_cobra_administration).
  • Premium clerk — logs received premium checks (cobra/w_cobra_receive_premium).
  • Print/mailroom operator — prints letter batches and certificates of mailing (cobra/w_cobra_printqueue, cobrarpt/w_cobra_printlabel_select).
  • Rate/billing maintainer — maintains group COBRA rates (cobra/w_cobra_rate_select, cobra/w_cobra_rate_maint).
  • Enrollment staff — fix relationship-code data that blocks letter generation; auto-termination hands off to the enrollment screen (cobra/w_cobra_administration pfc_save opens w_enrollment_maintenance).
  • The COBRA background process (external) — renders letter blobs into cobra_letter_data and logs failures to cobra_errors (cobra/w_cobra_printqueue, cobra/w_cobra_letter_errors); a server-side application that runs continuously, creates election/termination/notification letters, and performs deadline-driven terminations — see CBR-60..CBR-63 (User Guide ch. 3).

Key workflows​

Evidenced end-to-end flow (each edge cited below):

  • A→B: the qualifying-event code shown on the event header is member_eligibilities.dep_exp_cd (cobra/d_cobra_event, cobra/w_cobra_administration ue_create_letters); event selection lists events with status (PENDING)/INCOMPLETE (cobra/d_cobra_event_select).
  • C→D: entering a QE date flips status from INCOMPLETE to (PENDING) and fires ue_create_letters (cobra/w_cobra_administration dw_header.itemchanged).
  • D: recipients/QBs and 18/36-month maximums per QE code (cobra/w_cobra_administration wf_create_letters).
  • E→F: print queue reads blobs from cobra_letter_data keyed by letter_sys_key (cobra/w_cobra_printqueue pfc_print).
  • F→G: on print, UPDATE cobra_letters SET sent_dt=…, print_flg='Y', response_cd='Pending', deadline_dt = greatest(sent+60, coverage_end+60) (cobra/w_cobra_printqueue pfc_print, ELECTION case).
  • H→I/J: response-code side effects (cobra/w_cobra_administration dw_detail4.itemchanged).
  • K: cobra/w_cobra_receive_premium inserts cobra_stub.
  • L→M: expiration-date edits trigger the auto-terminate prompt and member_eligibilities update (cobra/w_cobra_administration pfc_save, cobra/w_cobra_autoterm_response); audits reported from cobra_terms (cobrarpt/d_cobra_termed_members_rpt).

Documented procedure: adding a dependent after the qualifying event​

(User Guide ch. 3 — operational practice, not enforced by code.) When a dependent must be added to a subscriber's COBRA coverage after the qualifying event (e.g. a child born just before normal coverage ends):

  • No claims processed under COBRA yet: print both screens for reference; delete the COBRA record; in enrollment, blank the subscriber eligibility expiration date, add the dependent on the Dependents tab and under each coverage election, then restore the expiration date and termination reason — restoring the reason regenerates the COBRA record automatically; finally re-enter the QE Notify and QE dates in COBRA Administration to regenerate the letter requests.
  • Claims already processed (MIS-assisted): add the dependent in enrollment, then manually insert a cobra_qb row (via TOAD) carrying the new dependent's member_sys_key as qb_member_sys_key and the electing spouse's key as elect_member_sys_key; back in COBRA Administration the dependent appears under Qualified Beneficiaries On Letter — checking Coverage Elected with coverage level Single automatically creates their own subscriber record in enrollment.

Business rules​

Every statement below is testable and cited to the object that implements it.

Event capture and status​

  • CBR-1 A COBRA event is uniquely identified by subscriber key, dependent key, and the effective date of the eligibility period in which the qualifying event occurred (qe_elig_eff_dt); the event header joins cobra_event to member_eligibilities on exactly those columns (cobra/d_cobra_event).
  • CBR-2 Event status codes come from code table key COBRSTAT (cobra/dddw_cobra_status, cobra/d_event_cd_select). Values used by code: (PENDING), ACTIVE, INACTIVE, INCOMPLETE (cobra/d_cobra_event_select retrieval SQL; cobrarpt/d_cobra_term_rpt; cobrarpt/d_cobrarpt_arra). The user guide documents two further selectable statuses — ERNOCOBRA (employer has opted for no COBRA on this individual) and VOID (record marked as bad) — and glosses the others: (PENDING) = waiting for a response, ACTIVE = currently under COBRA, INACTIVE = terminated or old record, INCOMPLETE = missing necessary information such as the QE date (User Guide ch. 3).
  • CBR-3 If the QE date is cleared/blank the event status is set to INCOMPLETE; when a QE date is entered the status is set to (PENDING) and letter generation is triggered immediately (cobra/w_cobra_administration dw_header.itemchanged).
  • CBR-4 The qualifying-event code is the eligibility record's dependent expiration code (member_eligibilities.dep_exp_cd), maintained in enrollment from code table key MBREXP (cobra/w_cobra_administration ue_create_letters; enroll/dddw_enroll_eligibility_exp_codes).
  • CBR-5 Only one event header row may exist per event; adding a header row is blocked when one already exists (cobra/w_cobra_administration dw_header.ue_preaddrow). Deletes are disabled on the header (dw_header.constructor, ib_Delete = FALSE).
  • CBR-6 The event-work queue lists all (PENDING)/INCOMPLETE events, plus events of any other status that already have election persons and QBs (cobra/d_cobra_event_select); users may filter by SSN, Member ID, Group ID and one or more status codes, and at least one status code must be selected (cobra/w_cobra_event_select pfc_finddlg).
  • CBR-58 COBRA event/QB records are created automatically by the system when the termination reason entered in enrollment amounts to a qualifying event; users take no other action. Criteria by member class: subscribers — every termination reason except Divorce, Family Separation and Re-Enrollment; spouses — Family Separation, Subscriber Deceased and Divorce only; other dependents — Loss of Student Status, Loss of Dependent Status, Dependent Disabled and Medicare only (User Guide ch. 3). No INSERT INTO cobra_event exists in the PB source, so this automation is server-side (see open question 1, resolved).

Letter-recipient and qualified-beneficiary derivation​

  • CBR-7 Recipient candidates are the family members holding coverage under a COBRA-eligible benefit (coverages.cobra_elig_flg = 'Y') whose eligibility ends with the event period, with their current RELATIONS category value (subscriber rows are forced to Sub; missing values become Unknown) (cobra/w_cobra_administration wf_create_letters cursor cur_deps).

  • CBR-8 Relationship values Common Law and Ex-Spouse are treated as Spouse (cobra/w_cobra_administration wf_create_letters).

  • CBR-9 Letter generation is blocked with an "Enrollment must fix" message when the family has more than one Sub relationship or any Unknown relationship (cobra/w_cobra_administration wf_create_letters).

  • CBR-10 Recipients and QBs per qualifying-event code (cobra/w_cobra_administration wf_create_letters CHOOSE CASE):

    QE codesElection letter toQBs on letterMaximum period
    Divorce, FamilySepSpouse onlySpouse and Step Child only36 months
    SubDecease, SubMedicarSpouse; each other dependent only if its address number differs from the spouse'sSpouse letter: all non-Sub family; separate-address dependent letter: that dependent36 months
    TermEmp, ReduceHrs, Layoff, Retired, SubDisable, LeaveMed, LeaveFam, LeaveMil, LeaveOther, Strike, RIF, EndFMLA, EndSickLv, InvTermEmp, VolTermEmpSubscriber; SpouseSubscriber letter: all family; Spouse letter: all non-Sub family18 months
    LossStud, LossDep, DepDisable, AdultDepStThe affected dependent onlyThat dependent only36 months
    any other codeerror: "Qualifying Event … could not be correctly determined"——
  • CBR-11 QB continuation start date (cobra_qb.eff_dt) = eligibility expiration date + 1 day (wf_create_letters: ldt_elig_exp_dt = RelativeDate(member_eligibilities.exp_dt, 1)).

  • CBR-12 QB maximum expiration date (cobra_qb.max_exp_dt) = QE date plus 18 or 36 months (per CBR-10) minus one day (wf_create_letters: of_RelativeMonth(qe_dt, 18|36) then of_RelativeDateTime(…, -86400); same formula exposed to letters via cobradw/f_calc_period).

  • CBR-13 New QB rows default disability_notice_ind = 'N' and disability_ind = 'N' (wf_create_letters; dw_detail2.ue_set_new_row).

  • CBR-14 Disability extension: when a QB's disability_ind is set to Y and disability_notice_ind is already Y, max_exp_dt is extended by 11 months (18 → 29 months) minus one day (cobra/w_cobra_administration dw_detail2.itemchanged, case cobra_qb_disability_ind). The user guide (ch. 3) states the two disability checkboxes expand the maximum to "29 or 36 months" and that the feature was "not complete" when the guide was written; code implements only the 18 → 29 extension — discrepancy for SME confirmation (the guide likely predates the final implementation).

  • CBR-15 If SSN is missing for a recipient the letter row carries the literal Not available (wf_create_letters).

  • CBR-16 A member may not be added twice as a QB on the same letter; a duplicate pick from the family window deletes the pending row with "already a qualified beneficiary on this letter" (cobra/w_cobra_administration ue_add_qb).

  • CBR-17 The family-member picker refuses to add the subscriber to a letter addressed to someone else ("Cannot add Subscriber to letter") (cobra/w_select_family_members cb_1.clicked).

  • CBR-18 Family membership and relationships for the picker come from family + latest member_cat_val (RELATIONS) rows (cobra/d_select_family_members).

Election window, responses and deadlines​

  • CBR-19 Election letter deadline: on printing an ELECTION letter, cobra_letters.deadline_dt is set verbatim to greatest((sent_dt + 60), (coverage_end_dt + 60)) — i.e. 60 days from the later of the sent date and the member's coverage end date (cobra/w_cobra_printqueue pfc_print ELECTION update SQL; equivalently the letter form computes relativedate(if(sent_dt > exp_dt, sent_dt, exp_dt), 60) (cobradw election-letter computed field)).
  • CBR-20 First premium payment deadline = election response date + 45 days. The administration screen displays it ("First Premium Payment Deadline") whenever an ELECTION letter's response date is present (cobra/w_cobra_administration dw_detail4.itemchanged case response_dt, dw_detail4.retrieveend: relativedate(response_dt, 45)).
  • CBR-21 Letter response codes come from code table key COBRRESP (cobra/dddw_cobra_letter_responses, cobra/dddw_cobra_response_cds). Recording a response drives event status (cobra/w_cobra_administration dw_detail4.itemchanged case response_cd): NoResponse → INACTIVE; Waived → INACTIVE; Pending → (PENDING); Elected → ACTIVE; IndivElect → ACTIVE (individual set manually).
  • CBR-22 On Elected, every QB row on the letter is marked elect_ind = 'Y' and its coverage level is set to Family when the letter has more than one QB, else Single (dw_detail4.itemchanged). Operationally, Elected (and Waived) also require the response date to be recorded, and marking Elected adds a new eligibility period for a subscriber or builds a new subscriber when the electing member is a dependent (User Guide ch. 3; server-side build per CBR-59).
  • CBR-59 Before a dependent's election letter is marked Elected, the dependent must have a social security number on file — the new subscriber record is built server-side by database trigger TU_COBRA_QB, which clones the prior member row located by soc_sec_no and then attaches a waiting period; the insert is not guarded (no sql%rowcount check), so a missing SSN means no member row is created yet the trigger continues, leaving the waiting period with no member to attach to (User Guide ch. 3, incl. its future-enhancements defect note).
  • CBR-23 Entering a rescind date on a letter copies that date into cobra_qb.eff_dt for all QB rows on the letter (dw_detail4.itemchanged case rescind_dt).
  • CBR-24 QB coverage-level values come from code table key ELECTLEVEL (cobra/dddw_cobra_coverage_levels).
  • CBR-25 New letters get letter_sys_key from sequence cobra_letters_seq and default print_flg = 'N'; an ELECTION letter also defaults response_cd = 'NotPrinted' (dw_detail4.ue_set_new_row, dw_detail4.itemchanged case letter_type_cd).

Letter/notice generation mechanics (cobra_letters and friends)​

Letter types offered on the administration screen come from code table key COBRLETTER (cobra/dddw_cobra_letter_codes); the print-queue filter list is hard-coded (cobra/dddw_letter_types): NOTIFY, ELECTION, CONVERSION, BADPREM, INSIG, COUPONS, UNAVAIL, EARLYTERM, plus % (all). The admin screen additionally recognizes TERM when typing a letter row (dw_detail4.itemchanged writes "Termination Letter Generated by …").

LetterTriggerStorageTiming rules found in code
ELECTIONAutomatic when QE date is entered (CBR-3, CBR-10); rows in cobra_letters + recipients in cobra_elect_persons + QBs in cobra_qbBlob rendered by background process into cobra_letter_data (format_type = 'PSR', chained via related_letter_sys_key for the election form); older letters stored as delimited text imported into d_cobradw_election_letter_18/36_prior + d_cobradw_election_frm_comp_prior layouts (cobra/w_cobra_printqueue pfc_print)60-day election window (CBR-19); 45-day first premium (CBR-20); letter text: 30-day grace for subsequent premiums, disability extension to 29 months if SSA-determined within first 60 days of coverage and notified within 60 days, second-event notification within 60 days (cobradw/d_cobradw_election_18_body_* text/computed fields)
NOTIFY (first notice of COBRA rights)Manual request via member search; inserts cobra_notification_requests (one per member; duplicates refused, return −10) (cobra/n_cst_cobra_notification_gen)Blob in cobra_letter_data keyed by letter_sys_key from cobra_letters_seqOn print, stamps member_eligibilities.cobra_rights_sent_dt on the member's latest eligibility row; after printing, the operator chooses whether to delete the requests or leave them queued (cobra/w_cobra_printqueue pfc_print NOTIFY case)
CONVERSION (medical conversion)Manual request; allowed only if the member elected COBRA under their own ID and the member's group has active enrollment option Conversion; duplicates refused (cobra/n_cst_cobra_conversion_gen)Row inserted directly into cobra_letters (letter_type_cd='CONVERSION', response_cd='NotPrinted', format_type='PSR')Issued only for QBs whose max_exp_dt > eff_dt and whose coverage has not expired (exp_dt IS NULL and exp_cd null/(none))
UNAVAIL (unavailability of continuation coverage)Manual request for a termed member who is not COBRA-qualified: requires an eligibility row expiring on the entered date (or termed COBRA-typed election coverages under a CobraADM group); upserts cobra_non_qual (cobra/n_cst_cobra_unavailability_letter_gen); also offered from enrollment termination (enroll/w_enrollment_maintenance wf_non_qual_event)Blob in report_objects keyed by report_data_sys_keySuppressed from the print queue while the family has an outstanding ELECTION letter with deadline_dt >= sysdate (cobra/d_cobra_printqueue_letters UNAVAIL branch); printing clears unprinted_flg and stamps print_dt
EARLYTERM (early termination letter)Created outside these libraries into cobra_early_term_letters (PB CRUD shows only R/U — see open questions)Blob in report_objectsPrinting clears unprinted_flg, stamps print_dt, and prints a companion termed-members report (cobra/w_cobra_printqueue pfc_print EARLYTERM case; cobra/d_cobra_termed_rpt)
BADPREM ("Incorrect Premium"), NOTINSIG ("Not Insignificant"), COUPONS, TERMManually addable letter rows on the admin screen with generated descriptions (dw_detail4.itemchanged)cobra_lettersPrint queue explicitly refuses INSIG and COUPONS ("cannot be currently printed"); no print handler exists for TERM/BADPREM (cobra/w_cobra_printqueue pfc_print). Per the user guide, termination letters are created by the background process, and the QB expiration-date flow anticipated an automatically generated termination letter (User Guide ch. 3) — see open question 3

Supporting mechanics:

  • CBR-26 Letters render to print only if their blob exists; rows whose letter generation failed are excluded from the queue while a matching cobra_errors row exists (cobra/d_cobra_printqueue_all, cobra/d_cobra_printqueue_letters, cobra/d_cobra_printqueue_notify — not exists (select * from cobra_errors …)).
  • CBR-27 The letter-error queue lists errors joined to members and events; marking a row corrected = 'Y' deletes it on save (cobra/w_cobra_letter_errors pfc_preupdate, cobra/d_cobradw_letter_errors).
  • CBR-28 The background feed of letters to render is: cobra_letters rows with response_cd = 'NotPrinted', sent_dt null, print_flg = 'N', no error and no existing blob, unioned with notification requests (cobradw/d_cobradw_letters_to_print).
  • CBR-29 Printing any queue row marks it print_flg = 'Y' and stamps the operator-entered sent date; for ELECTION/CONVERSION an existing sent_dt is only overwritten when the operator checks "UPDATE SENT DATE?" (cobra/w_cobra_printqueue pfc_print).
  • CBR-30 A USPS certificate of mailing is printed for mailed election/conversion letters: no certificate below 3 addressees, pages padded to 15 rows, batches over 15 split across pages; postage and certificate fee amounts are table-driven from code table key POSTAGE (values Postage, MailCert) (cobra/w_cobra_printqueue wf_certificatemailing, pfc_print; cobradw/d_cobradw_cert_mailing).
  • CBR-31 Election letters print duplex; the operator is prompted once per session to set duplex/left-binding (cobra/w_cobra_printqueue pfc_print).
  • CBR-32 Election form signature lines (subscriber / spouse / dependent) are shown only for the member classes present on the form's line items (ids A/B/other) (cobra/w_cobra_printqueue pfc_print and ue_certificate_reprint).
  • CBR-33 Deleting queue rows removes cobra_notification_requests and cobra_letter_data for the selected letter keys after confirmation (cobra/w_cobra_printqueue pfc_deleterow).
  • CBR-34 The election letter's premium-periods block lists monthly payment periods starting the day after existing benefits end and running through the end of the month 105 days later (60-day election + 45-day first payment) (cobradw/f_premium_periods, used by cobradw/d_cobradw_elctionperiods).

Background process (automatic letter creation and termination)​

The user guide documents the server-side component whose outputs the windows consume (only its outputs — cobra_letter_data, cobra_errors, cobra_early_term_letters — are visible in the PB source):

  • CBR-60 The background process runs continuously, checking whether any letters need to be created or any terminations need to be performed; at guide time it created election letters, termination letters and notification letters (User Guide ch. 3). Conversion-letter creation in the background process, partial-payment notices and billing/termination logic were listed as future enhancements in the same chapter.
  • CBR-61 The background process performs terminations when (a) 63 days have passed beyond the payment deadline, (b) the maximum deadline is reached, or (c) a response deadline is reached (User Guide ch. 3).
  • CBR-62 The background process tracks the secondary 30-day billing cycle specified for the insignificant-amount rule (User Guide ch. 3).
  • CBR-63 Background letter-generation failures fall into four documented categories — address errors, rate errors, group errors and missing-coverage errors. After an error is cleared (CBR-27) the background process acknowledges the clearing and re-tries the letter on its next run; if the error was cleared without an actual correction, the same error is recreated (User Guide ch. 3).

COBRA premium computation (rates + amounts)​

  • CBR-35 COBRA premium rates are kept per group in cobra_rates_master (rate key, group, coverage level, effective/expiration dates, rate_amt, rate code, display description) with the covered benefit list in cobra_rate_coverages (rate key → benefit coverage type/code) (cobra/d_cobra_rates_hdr, cobra/d_cobra_rates_dtl).
  • CBR-36 A rate's group cannot be changed after it is set ("create a new rate for the desired group") (cobra/w_cobra_rate_maint dw_header.itemchanged).
  • CBR-37 A rate must have a display description and at least one coverage row to save; new/empty coverage rows are stripped first (cobra/w_cobra_rate_maint dw_header.ue_validate).
  • CBR-38 "Generate display text" builds the description as the slash-joined list of the rate's coverage type codes (e.g. Medical/Drugs/Dental) (cobra/w_cobra_rate_maint cb_4.clicked).
  • CBR-39 The election form offers each rate whose covered benefits match the family's elected COBRA-eligible coverages for the member's group, effective at the eligibility end date, showing coverage level, rate_amt and rate period (cobradw/d_cobradw_election_frm_b; per-coverage lookup in cobradw/d_cobra_rates_display).
  • CBR-40 No administrative-percentage arithmetic exists in this code: the charged amount is the stored rate_amt. The 102 % statutory cap (and higher cap during a disability extension, with months 19–29 premiums possibly increased) appears only as letter text (cobradw election letter body: "may not exceed 102 percent…", "Premiums for months 19-29 may be increased…"). Loaded rates are therefore presumed to be gross (rate + admin allowance) — see open questions.
  • CBR-41 ARRA premium subsidy is documented in letter text and reporting only: qualifying individuals (involuntary termination 9/1/2008–5/31/2010) pay 35 % of the premium for up to 15 months; subsidized members are identified by member category ARRASUBSID (cobradw/d_cobradw_election_frm_c_arra text; cobrarpt/d_cobrarpt_arra; cobrarpt/w_cobrarpt_select_criteria wf_cobraarrareport).
  • CBR-42 Rates can be copied to another group (skipping rows already present with identical description, effective date, level and amount) (cobra/w_cobra_rate_select wf_copy_rates).
  • CBR-43 Rates can be rolled forward: for every division under a group (hierarchical CONNECT BY), each rate effective on the original start date is duplicated with the new start date and an expiration of new start + 1 year − 1 day (cobra/w_cobra_rate_select wf_copy_rates_forward).

Premium receipt​

  • CBR-44 A premium receipt records received date (defaults to today), paid- through date, check number and amount, with Partial Payment and Insignificant Amt. flags, into cobra_stub (key from sequence all_purpose_seq) (cobra/w_cobra_receive_premium cb_save.clicked).
  • CBR-45 The payer is located by SSN or Member ID against members re-enrolled from COBRA (cobra_qb.new_qb_member_sys_key = members.member_sys_key). The paid-through date must fall inside the QB coverage window (eff_dt..exp_dt), or — when no such row matches — the receipt is accepted if it is on/before the first-payment deadline nvl(response_dt + 45, deadline_dt) of an elected ELECTION letter (cobra/w_cobra_receive_premium em_ssn.modified, em_member_id.modified).
  • CBR-46 When the identifier matches more than one elected COBRA the entry is refused: "Member has elected COBRA more than once. Look under spouse also." (cobra/w_cobra_receive_premium). The user guide (ch. 3) states that when more than one COBRA event exists for the member "a screen will appear allowing the user to choose which event to apply payment" — discrepancy for SME confirmation (code refuses rather than offering a chooser). The guide also directs that payment adjustments be made only in the participant's detail window.
  • CBR-47 All receipt fields are mandatory (identifier, paid-through date, check number, non-zero amount) (cb_save.clicked validations).
  • CBR-48 On the administration payments grid, checking the significant-amount flag (sig_ind = 'Y') stamps insig_dt with the current date/time (cobra/w_cobra_administration dw_detail3.itemchanged). Adding a payment row there opens the Receive Premium window pre-keyed to the selected QB (or the recipient's SSN) and re-retrieves on return (dw_detail3.pfc_addrow).

Coverage termination​

  • CBR-49 QB expiration-reason codes come from code table key COBRA, with a synthetic (None) first entry; clearing the expiration date resets the reason to (none) (cobra/dddw_cobra_termcodes; cobra/w_cobra_administration dw_detail2.itemchanged, dw_detail2.pfc_retrievedddw).
  • CBR-50 Editing a QB expiration date flags the row (exp_mod_flg = 'Y'). On save: if the expiration equals the coverage start − 1 day (coverage never used) the user is offered the enrollment screen; otherwise a three-way prompt is shown — Auto Terminate / Open Enrollment / Ignore (cobra/w_cobra_administration pfc_save; cobra/w_cobra_autoterm_response).
  • CBR-51 Auto-terminate sets member_eligibilities.exp_dt to the COBRA expiration date for the QB's family record (dependent coverages are expired by a database trigger — comment in code); it is skipped when blocking election rows exist for the eligibility period, and the whole batch rolls back on any error ("AutoTermination not successful") (pfc_save).
  • CBR-52 Termination candidates are reported when (a) an election letter is 7+ days past deadline_dt with no response ("Election Forms Not Recieved"), (b) an active event's QB passed max_exp_dt ("End of COBRA Eligibility") (cobrarpt/d_cobra_term_rpt).
  • CBR-53 A COBRA event can be deleted by SSN + QE eligibility effective date; deleting cobra_event cascades to all child tables (comment: "all other tables are cascade delete"); the SSN must pass user security and resolve to a single member (cobra/w_cobra_member_delete). The user guide frames this as a data-correction utility — for terminations that were reversed or incorrectly input — and notes the functionality "will be moved into the background as soon as possible" (User Guide ch. 3).
  • CBR-54 Auto-terminations are audited in cobra_terms (old/new expiration date and code, user, date) and reported by date range (cobrarpt/d_cobra_termed_members_rpt).

Interplay with enrollment (members on COBRA)​

  • CBR-55 An elected QB is re-enrolled as their own subscriber: cobra_qb carries new_qb_member_sys_key, and payment/reporting joins treat that key as the member on COBRA (cobra/w_cobra_receive_premium; cobrarpt/d_cobrarpt_active_list; cobrarpt/d_cobra_term_rpt).
  • CBR-56 Enrollment termination offers to create a COBRA unavailability letter when the termed member has COBRA-typed coverages under a group with the CobraADM enrollment option (enroll/w_enrollment_maintenance wf_non_qual_event, using cobradw/d_cobra_non_qual_events).
  • CBR-57 Only groups holding the CobraADM enrollment option (or under hard-coded master groups SFPI / M/III) participate in COBRA reporting and the ARRA group pick-list (cobrarpt/w_cobrarpt_select_criteria dddw case d_cobrarpt_arra; cobra/n_cst_cobra_unavailability_letter_gen).

Data + CRUD​

COBRA-owned tables (columns as extracted; _re/analysis/schema.json):

TablePurposecobracobradwcobrarpt
cobra_eventQualifying event header (sub/dep keys, qe_elig_eff_dt, qe_dt, qe_notify_dt, status_cd)CRUDRR
cobra_elect_personsElection-letter recipients per eventCRUDRR
cobra_qbQualified beneficiaries (eff/exp/max dates, elect + disability flags, coverage level, new_qb_member_sys_key)CRUDRR
cobra_lettersLetter register (type, sent/deadline/response/rescind dates, response code, print flag, dw_object, format_type, batch)CRUDRR
cobra_letter_dataRendered letter blobs (+ related_letter_sys_key chain)R (blob read; delete of rows in print queue)RR
cobra_notification_requestsFirst-notice queue per memberCRUDRR
cobra_errorsLetter-generation error queueCRUDRR
cobra_non_qualUnavailability letters (elig-exp date, print state)CRUCRUD—
cobra_early_term_lettersEarly-termination letters (term date, print state)RUR—
cobra_stubPremium check receiptsCRUD—R
cobra_rates_master / cobra_rate_coveragesGroup premium rates and covered benefitsCRUD / CUDRR
cobra_ratesLegacy rates table, report-only——R
cobra_termsAuto-termination audit——R

Shared tables read: members, family, member_eligibilities (also updated by cobra: exp_dt on auto-term, cobra_rights_sent_dt on NOTIFY print), member_cat_val (RELATIONS, ARRASUBSID), elections, election_coverages, coverages (cobra_elig_flg), group_coverages (cobra_type_cd: NOCOBRA/BOTH/COBRAONLY), group_enroll_opts (CobraADM, Conversion), groups, addresses, codes, report_objects, batch_reports (report catalog rows, report_type = 'COBRA').

Sequences: cobra_letters_seq, cobra_rates_master_seq, cobra_stub_seq (legacy, commented out), all_purpose_seq (cobra/w_cobra_administration, cobra/w_cobra_rate_maint, cobra/w_cobra_receive_premium).

Code tables (key → use): COBRSTAT event status; MBREXP qualifying-event codes; COBRLETTER letter types; COBRRESP letter responses; COBRA QB termination reasons; ELECTLEVEL coverage levels; POSTAGE postage/certificate fees (cobra/dddw_*, cobra/w_cobra_printqueue).

Reports (cobrarpt catalog)​

The report list is data-driven from batch_reports where report_type = 'COBRA' (cobrarpt/dddw_cobrarpt_types, cobrarpt/d_cobrarpt_report_types); the criteria window special-cases these DataWindows (cobrarpt/w_cobrarpt_select_criteria, cobrarpt/w_cobrarpt_display):

Report DataWindowContentCriteria
d_cobra_ee_statusPer-group COBRA employee status: event status, letter sent/response, QB dates, paid-through, per-benefit coverage levelsGroup multi-select
d_cobra_rates_bygroupRate book for selected groups (rates not expired as of date)Groups + "Not Expired as of" date
d_cobra_rates_missingCOBRA-eligible group coverages (cobra_type_cd BOTH/COBRAONLY) with no current rateGroups + date
d_cobra_termed_members_rptAuto-terminated members from cobra_terms (old/new exp date+code, user)From/thru dates
d_cobrarpt_payment_checklistPremium checks received on a date (cobra_stub by recv_dt)Mail-received date
d_cobrarpt_elect_printedElection letters sent on a date, with deadlinesSent date
d_cobrarpt_elect_to_printElection letters not yet printed (print_flg = 'N', no errors)none
d_cobrarpt_arraARRA premium-subsidy activity for ARRASUBSID members (rates vs paid amounts, subscriber/dependent counts); can be run for all groups with active subsidized membersGroups + from/thru dates
d_cobrarpt_active_listActive COBRA participants with most recent paid-through datenone
d_cobra_term_rptTermination candidates: no election response 7 days past deadline; QBs past max_exp_dt; expired eligibilitynone
d_cobra_events_wo_qe_dtEvents missing a QE date, scoped to the user's group securityuser id (implicit)
d_cobra_first_notification_requestsOutstanding first-notice requests with subscriber/member namesnone
d_cobra_rates_rptLegacy cobra_rates table listinggroup list
d_cobra_labels (via cobradw/n_cobra_functions.of_printlabels)Mailing labels for active QBs (elected Single dependents, or the electing member) with an election letter; label offset and page-break-per-division optionsGroup multi-select (cobrarpt/w_cobra_printlabel_select)
d_cobra_notification_rpt, d_cobra_unavailability_rpt, d_cobra_termed_rptCompanion audit reports auto-printed after NOTIFY / UNAVAIL / EARLYTERM print batchesprinted member keys (cobra/w_cobra_printqueue pfc_print)

Migration notes​

COBRA is a deadline-regulated domain. All date-window logic found in code, verbatim:

  • Election deadline: deadline_dt = to_date( greatest((:ldt_today+60), (:ldt_coverage_end_dt+60)) ) (cobra/w_cobra_printqueue pfc_print); letter-side equivalent relativedate( if( cobra_letters_sent_dt > member_eligibilities_exp_dt, cobra_letters_sent_dt, member_eligibilities_exp_dt ), 60 ) (cobradw election letter computed field).
  • First payment: st_45.Text = string(relativedate(ldt_date,45),'mm/dd/yyyy') (cobra/w_cobra_administration); acceptance check :idt_received_through_date <= NVL( ( cobra_letters.response_dt + 45 ), cobra_letters.deadline_dt ) (cobra/w_cobra_receive_premium).
  • Maximum period: date(gnv_app.inv_datetime.of_RelativeDateTime( datetime(gnv_app.inv_datetime.of_RelativeMonth(date(ldt_qe_dt),36)), -86400)) (and 18) (cobra/w_cobra_administration wf_create_letters); disability extension of_RelativeMonth(date(ldt_max_cur),11) − 1 day (dw_detail2.itemchanged).
  • Premium-period horizon: ld_105_after_dt = lnv_datetime.of_lastdayofmonth(RelativeDate(ld_initial_dt,105)) (cobradw/f_premium_periods).
  • Termination report trigger: sysdate >= cobra_letters.deadline_dt + 7 (cobrarpt/d_cobra_term_rpt).
  • Letter-text-only rules (not enforced in code, must become system rules in the target): 30-day grace for subsequent premiums; 60-day windows for reporting divorce/separation/dependent-loss events, SSA disability determinations and second qualifying events; 30-day notice when SSA finds the QB no longer disabled; special-enrollment 30-day windows (cobradw/d_cobradw_election_18_body_*).

Other migration-relevant observations:

  • Event status is read/written by positional index into the status dropdown (code_value[1]=(PENDING), [2]=ACTIVE, [3]=INACTIVE, [4]=INCOMPLETE), so behavior silently depends on codes.code_display_seq ordering (cobra/w_cobra_administration dw_header.itemchanged, dw_detail4.itemchanged). Replace with value-based logic.
  • Letter rendering is split between this app and an external background process communicating via cobra_letters/cobra_letter_data/cobra_errors; printing parses letter blobs (PSR files written to c:\temp.psr) and, for legacy rows, splits a delimited text blob on markers HEDHEDHEDHED, BODBODBODBOD, PERPERPERPER, DY1DY1DY1DY1, EFAEFAEFAEFA, EFBEFBEFBEFB (cobra/w_cobra_printqueue pfc_print). None of this should survive migration; letters need a template service.
  • pfc_save uses if ll_foundrow > 1 after Find(...), so a modified QB found at row 1 does not trigger the auto-term prompt — likely a defect to confirm, not to re-implement (cobra/w_cobra_administration pfc_save).
  • Hard-coded values: master groups SFPI/M/III (reports, labels), placeholder date 12/07/1941 used as a null-date sentinel in queue unions, far-future sentinels 01/01/2500, 12/31/2049, 12/31/2050, TPA address text in letter bodies (cobrarpt/w_cobrarpt_select_criteria, cobra/d_cobra_printqueue_all, cobradw letter DWs).
  • Eligibility auto-termination relies on a database trigger to expire coverages ("coverages will be termed by trigger") — that trigger is outside the PB source and must be re-specified (cobra/w_cobra_administration pfc_save).
  • A second server-side trigger, TU_COBRA_QB, builds the new subscriber when a QB elects: it clones the previous member row located by soc_sec_no, then adds a waiting period. Known defect documented in the guide: the insert into members is not checked (sql%rowcount), so an electing member with no SSN yields no member row while the trigger continues, orphaning the waiting-period insert; the recommended fix was front-end SSN enforcement plus a guard in the trigger (User Guide ch. 3, future enhancements). Both triggers must be recovered from the Oracle DDL.
  • The guide's future-enhancements list (priority-ordered 4-13-2000) explains several half-built features visible in code: rates on election letters (since implemented — CBR-39), insignificant-amount logic and coupons/billing (INSIG and COUPONS letter types are still refused by the print queue), partial-payment notices and background termination logic (billing), conversion-letter creation in the background process, print-queue mods (request/delete notifications from the queue), generating a QE event from the COBRA windows, exit-without-save options, report corrections, and a view-only participant address on the admin screen (User Guide ch. 3).
  • ARRA subsidy handling is reporting/letter-text only; if it is truly dead (post-2010) it can be dropped with SME sign-off.

Open questions​

  1. Who creates cobra_event rows? — RESOLVED (mechanism); trigger DDL pending. The user guide confirms creation is fully automatic: when the termination reason entered in enrollment meets the qualifying-event criteria (CBR-58), "the system will automatically generate a 'QB' record" with no further user action, and the documented dependent-add workaround regenerates the record simply by re-entering the termination reason in enrollment (User Guide ch. 3). Since no PB code inserts the row, the mechanism is a database trigger on eligibility maintenance (the guide names the companion trigger TU_COBRA_QB for the election side). The exact trigger source still needs Oracle DDL recovery.
  2. The COBRA background process — RESOLVED (role and rules); source pending. A server-side application that runs continuously, creating election, termination and notification letters and performing deadline-driven terminations, including the 63-days-past-payment-deadline rule and the secondary 30-day insignificant-amount cycle (CBR-60..CBR-62) (User Guide ch. 3); it renders the blobs the print queue consumes and writes cobra_errors in the four categories of CBR-63. Its source is not in the PB extraction — how it selects the 18- vs 36-month election layout, sets format_type, and creates cobra_early_term_letters must be confirmed from the recovered server-side code.
  3. TERM and BADPREM letters — PARTIALLY RESOLVED. The guide states the background process creates termination letters, and the QB expiration flow anticipated an automatically generated termination letter; partial-payment notices (the likely BADPREM output) and full background termination/billing logic were still listed as future enhancements (User Guide ch. 3). Whether TERM printing was ever wired end-to-end needs SME confirmation — pfc_print has no CHOOSE branch for either type (INSIG and COUPONS are explicitly refused).
  4. Admin percentage: rates are charged exactly as stored (rate_amt); is the 2 % administration fee expected to be baked into loaded rates, and is the 150 % disability-extension premium (months 19–29) handled manually?
  5. cobra_stub vs billing — PARTIALLY RESOLVED. The background process, not the client, was responsible for non-payment terminations (63 days past the payment deadline) and for tracking the secondary 30-day insignificant-amount cycle (CBR-61/CBR-62); coupons/billing, payment reports and partial-payment notices were future enhancements (User Guide ch. 3). No amount-due computation existed client-side; how much of the billing roadmap was ever built must come from the recovered background process source.
  6. d_cobra_stub DataWindow (cobra/d_cobra_stub.srd) appears unused by any window read (payments grid uses d_cobra_payments); confirm dead.
  7. exp_mod_flg find starting at row 2 (if ll_foundrow > 1 in pfc_save) — defect or intentional?
  8. Positional status-code indexing (COBRSTAT display order) — confirm the production codes ordering matches the assumed (PENDING)/ACTIVE/INACTIVE/ INCOMPLETE sequence before writing migration mappings.
  9. cobra_rates (legacy) vs cobra_rates_master — is the old table still populated, or is d_cobra_rates_rpt dead?
  10. Retroactive-termination enforcement — PARTIALLY RESOLVED. Non-payment termination is automated: the background process terminates 63 days past the payment deadline (CBR-61) (User Guide ch. 3) — a hold-back beyond the letter's 30-day grace. The effective date the termination is applied with (retroactive to the last paid day, per the letter text, or the processing date) still needs SME confirmation.