Project

General

Profile

Actions

Bug #12

open

Fax Tone/Send Module - Modernization: Dual-Family Consolidation, Redis Caching & Security Hardening

Added by Redmine Admin about 2 months ago.

Status:
New
Priority:
Normal
Assignee:
-
Start date:
08/19/2026
Due date:
% Done:

0%

Estimated time:

Description

Fax Tone/Send Module — Modernization

Project: klearcom-in/kc-web · Branch global-logic
Module scope: Fax Tone/Send (test_type=6) — Plain Fax and Verify+ Fax families only.

⚠️ All field names, file paths, and validation rules are inferred from module documentation. Actual PHP source files must be read before any code generation begins.


User Story

As a platform engineering team member,
I want the Fax Tone/Send module refactored to eliminate its dual-family duplication, add a Redis caching layer for dashboard queries, harden the fax_test_type entitlement check, and introduce a formal REST API deprecation lifecycle,
so that the module is maintainable by a single code path, dashboards perform reliably at scale, Verify+ Fax access is properly gated by subscription, and external API consumers have a clear migration path from v1/v2 to v3.


Background

The Fax Tone/Send module (fax_test_type 1 and 2; TEST_TYPE_FAX=6) is a Laravel/PHP vertical spanning 14 MySQL tables, 20 Eloquent models, 14 service classes, 4 web + 9 REST API controllers (3 versions), 9 Form Request validators, 2 partial repositories, and one Artisan cron command (monitor:fax) that also writes audit records to MongoDB.

The dominant structural problem is horizontal duplication: a "Plain Fax" family and an almost identical "Verify+ Fax" family exist in parallel, controlled by a single request field (fax_test_type). This switch propagates through every layer — controllers, services, models, and tables — meaning every bug fix must be applied twice. Three simultaneous live REST API versions (v1/v2/v3) add maintenance overhead without a formal deprecation plan.

Performance is at risk: dashboard aggregation services query unbounded history tables per request with no caching layer. Two security gaps were identified: fax_test_type=2 (Verify+) may not be gated by a client subscription entitlement check, and scheduler_id route parameters may not validate client ownership (IDOR risk).


Scope

In Scope

  • Dual-family table consolidation (~13 tables → ~7 with discriminator column)
  • Strategy/Factory pattern for fax_test_type routing across all layers
  • Redis caching layer for dashboard aggregation services
  • Entitlement guard for fax_test_type=2 (Verify+ subscription gate)
  • scheduler_id ownership validation (IDOR fix)
  • REST API v1/v2 deprecation lifecycle with X-Api-Deprecation-Notice headers
  • Non-billable as a flag column (remove separate table)
  • Queue-based monitor + abstract MongoDB audit write

Out of Scope

  • Cross-module consumers: KcDashboardController, KcBillingControllers, KcCronPdfReports, KcNumberPerformanceTracker
  • Test Engine
  • Outbound Fax Monitoring vertical

Acceptance Criteria

  1. AC1 — Dual-family consolidation: Plain Fax and Verify+ Fax share a single set of ~7 tables with a fax_test_type discriminator; no parallel table pairs remain.
  2. AC2 — Strategy/Factory routing: All fax_test_type branching is handled by a Strategy or Factory pattern; no inline if fax_test_type == 1 / 2 scattered across controllers and services.
  3. AC3 — Redis caching: Dashboard aggregation service results are cached in Redis with a configurable TTL; unbounded history table queries per request are eliminated.
  4. AC4 — Entitlement guard: Requests with fax_test_type=2 are rejected with HTTP 403 if the client's subscription does not include Verify+ Fax.
  5. AC5 — IDOR fix: All scheduler_id route parameters are validated for client ownership before processing; unauthorized access returns HTTP 403.
  6. AC6 — API deprecation: v1 and v2 REST endpoints return X-Api-Deprecation-Notice headers with sunset dates; a migration guide to v3 is documented.
  7. AC7 — Non-billable flag: Non-billable state is stored as a flag column on the unified fax table; the separate non-billable table is removed.
  8. AC8 — Async monitor: monitor:fax Artisan command dispatches to a queue; MongoDB audit writes are abstracted behind a repository interface.

Technical Notes

Stack

  • PHP/Laravel (version from repo), MySQL/MariaDB, MongoDB (monitor audit), Redis (new caching layer)
  • REST API: v1, v2, v3 controllers
  • Eloquent ORM, Artisan cron, Form Request validators

Key Files (inferred — verify before editing)

  • StoreFaxRequest.php, UpdateFaxRequest.php — Form Request validators
  • FaxServices.php, KcFaxSchedulerService.php — primary service classes
  • Dashboard aggregation services — candidates for Redis caching

Modernization Items (ranked)

Priority Item Description Effort
P1 M9 Entitlement guard for fax_test_type=2 Low
P1 M3 Redis caching for dashboard aggregations Medium
P1 M1 Consolidate 13 near-identical Plain/Verify+ tables High
P2 M2 Strategy/Factory for fax_test_type routing High
P2 M4 Non-billable as flag column Medium
P2 M6/M7 Queue-based monitor + abstract MongoDB audit Medium/Low
P2 M8 REST v1/v2 deprecation lifecycle Medium

Dependencies

  • Redis must be provisioned in the environment before AC3 can be tested
  • DB migrations for table consolidation (AC1) require a maintenance window
  • API deprecation headers (AC6) must be coordinated with external API consumers

Labels: ai-created · modernization · fax-module · php-laravel · p1-security · p1-performance

Labels: ai-created, modernization, fax-module, php-laravel, p1-security, p1-performance

No data to display

Actions

Also available in: Atom PDF