SSP 2.6 MAP Plan/Template Hard Delete

Overview

Primarily because of usage scenarios which generate a large number of Templates each year, end users would like the ability to permanently delete Template records such that they never show up in any Template search/load result. These same users would also like to permanently delete Plans.

Alternatives to true hard deletion, i.e. physical removal from the database, as the specific means by which Templates and Plans are "permanently deleted" have been proposed and rejected. Thus "hard" and "permanent" are used interchangeably throughout this document. Since hard deletion has such potentially disastrous consequences, though, Plans/Templates will be explicitly archived prior to hard deletion.

Note that the Template load dialog already filters out inactive (soft-deleted) Templates by default.

Error rendering macro 'jira' : Unable to locate Jira server for this macro. It may be due to Application Link configuration.

Permissions and Business Rules

In general, users should only be able to hard delete Plans and Templates for which they are the current owner. Template hard deletion should be further restricted such that deletion of a non-private Template is only allowed to certain highly permissed users ("template admins").

Not all Plan/Template deletions will be hard deletions. I.e. users will still be able to switch Plans/Templates between "active" and "inactive" statuses as they always have. Users will need to explicitly indicate when they wish to hard delete a Plan/Template. (See UI section below.)

SSP does not currently distinguish between create, edit, and soft delete permissions for MAP Plans/Templates. PERSON_MAP_WRITE controls all three of those operations. Following this convention, we will extend the semantics of that permission rather than introduce a new permission.

Deployers will control users' ability to hard-delete Plans and Templates via global configuration. The new configuration will be map_hard_delete. It will default to false (hard deletions not supported). (Config naming is based on the convention established by map_edit_past_terms.)

Thus either all Plan/Template authors and Template admins can hard delete their Plans/Templates, or none can. More fine-grained control can be implemented in the future, but would require a new permission.

Rules for PERSON_MAP_WRITE as extended to support hard deletes are as follows:

Plans

  1. If map_hard_delete=false, error
  2. If user not granted PERSON_MAP_WRITE, error (i.e. you cannot delete a Plan you own if you've been demoted out of the writing permission)
  3. If user ID is not Plan owner_id, error
  4. Else archive the Plan, its planned courses, and its term notes, and permanently delete the operational copies of those records

Templates

  1. If map_hard_delete=false, error
  2. If user not granted PERSON_MAP_WRITE, error
  3. If user ID is not Template owner_id and user not granted MAP_PUBLIC_TEMPLATE_WRITE, error
  4. If user ID is Template owner_id and Template is non-private and user not granted MAP_PUBLIC_TEMPLATE_WRITE, error  (i.e. you cannot delete a non-private Template you own if you've been demoted out of the MAP_PUBLIC_TEMPLATE_WRITE permission)
  5. Else archive the Template, its planned courses, and its term notes, and permanently delete the operational copies of those records

 

See "API and Implementation" below for more detail on Plan/Template archiving.

UI

If a Plan/Template is eligible for hard-deletion by the current user, as defined above, the MAP "button" panel will include a new icon for triggering hard deletion. The user should be prompted for confirmation before completing the operation.

Sourcing the button icon is TBD.

API and Implementation

The DELETE methods on /ssp/api/1/reference/map/template/<id> and /ssp/api/1/person/<id>/map/plan/<id> will accept a new query parameter: deleteMode. This will map to an enum with two values: HARD and SOFT. The default is SOFT to preserve historical behavior.

Following conventions throughout the rest of the app and in MAP API controllers in particular (esp TemplateController), the enforcement of the business rules above when deleteMode=HARD will be factored into TemplateController and PlanController.

The Plan and Template Hibernate entities will likely need to re-map their associations to PlanCourseTemplateCourse, and TermNote to cascade deletions.

Note that while map_plan has a based_on_template_id column, which is a FK to map_template.id, the application does not use that field and should not need to delete dependent FK values prior to hard-deleting a template.

However, the map_status_report.plan_id to map_plan.id FK will require that map_status_report records be deleted should any corresponding map_plan be deleted.

Plan/Template archiving will be implemented by creating shadow tables into which to take copies of Plans/Templates and associated data prior to deletion. There will be one shadow/archive table per live MAP table, excluding status reporting tables:

  1. map_plan -> map_plan_archive
  2. map_plan_course -> map_plan_course_archive
  3. map_template -> map_template_archive
  4. map_template_course -> map_template_course_archive
  5. map_term_note -> map_term_note_archive

Using an _archive suffix rather than archive_ prefix follows the convention established for similar "backup" tables, e.g. map_term_note_ssp_2303_bak.

Not collapsing map_template_archive and map_plan_archive into a single able keeps the mapping very straightforward and ensures minimal refactoring in the future should one or the other "live" model start to evolve independently of the other (which was part of the original design motivation for separating Plan and Template tables in the first place).

The map_*_archive tables should have the same foreign key structure as their live counterparts, but needn't have the same indexing scheme. These should be primarily write-only tables, so indexes needless slow down those operations.

The copy to map_*_archive and deletion of the live records should occur in a single transaction. I.e. either the backup and the deletion fail, or it all fails.

Estimate

Development: 3d

Testing: 1d