mahdahar 01bfb4e2f2 feat(clqms): restructure project documentation and add feedback modules
- Restructured 'clqms01' workspace with dedicated 'suggestion' and 'review' directories.
- Converted project landing page from Markdown to Nunjucks (index.njk) for an enhanced UI.
- Added new suggestion indices and initial technical templates (testdef, valueset).
- Updated core technical documents (001-006) for consistency and better formatting.
- Added site favicon and updated base layouts (base.njk, clqms-post.njk).
- Cleaned up .vscode settings and redundant project files.
2026-01-09 09:56:54 +07:00

3.1 KiB

layout, tags, title, description, date, order
layout tags title description date order
clqms-post.njk clqms Proposal: Valueset Replacement Remove magic numbers and enforce type safety using PHP Enums and Svelte stores 2026-01-09 2

🚀 Proposal: Valueset ("God Table") Replacement by Gemini 3

Target: valueset / valuesetdef Tables
Objective: Remove "Magic Numbers," enforce Type Safety, and optimize Frontend performance.


1. The Problem: "Magic Number Soup" 🥣

Current Status:
We store disparate system logic (Gender, Test Status, Colors, Payment Types) in a single massive table called valueset.

  • Code relies on IDs: if ($status == 1045) ...
  • Frontend Overload: Frontend makes frequent DB calls just to populate simple dropdowns.
  • No Type Safety: Nothing stops a developer from assigning a "Payment Status" ID to a "Gender" column.

2. The Solution: Enums & API Store 🛠️

Strategy: Split "System Logic" from the Database.
Use PHP 8.1 Native Enums for business rules and serve them via a cached API to Svelte.

Step A: The Backend (PHP Enums)

We delete the rows from the database and define them in code where they belong.

File: App/Enums/TestStatus.php

enum TestStatus: string {
    case PENDING = 'PENDING';
    case VERIFIED = 'VERIFIED';
    case REJECTED = 'REJECTED';

    // Helper for Frontend Labels
    public function label(): string {
        return match($this) {
            self::PENDING => 'Waiting for Results',
            self::VERIFIED => 'Verified & Signed',
            self::REJECTED => 'Sample Rejected',
        };
    }
}

Step B: The API Contract

GET /api/config/valueset
Instead of 20 small network requests for 20 dropdowns, the Frontend requests the entire dictionary once on load.

Response:

{
  "test_status": [
    { "value": "PENDING", "label": "Waiting for Results" },
    { "value": "VERIFIED", "label": "Verified & Signed" }
  ],
  "gender": [
    { "value": "M", "label": "Male" },
    { "value": "F", "label": "Female" }
  ]
}

Step C: The Frontend (Svelte Store)

We use a Svelte Store to cache this data globally. No more SQL queries for dropdowns.

Component Usage:

{% raw %}
<script>
  import { config } from '../stores/configStore';
</script>

<label>Status:</label>
<select bind:value={status}>
    {#each $config.test_status as option}
        <option value={option.value}>{option.label}</option>
    {/each}
</select>
{% endraw %}

3. The Benefits 🏆

Feature Old Way (valueset Table) New Way (Enums + Store)
Performance DB Query per dropdown Zero DB Hits (Cached)
Code Quality if ($id == 505) if ($s == Status::PENDING)
Reliability IDs can change/break Code is immutable
Network "Chatty" (Many requests) Efficient (One request)

Next Steps 🗒️

  • Define TestStatus and TestType Enums in PHP.
  • Create the /api/config/valueset endpoint.
  • Update one Svelte form to use the new Store instead of an API fetch.

Last updated: 2026-01-09 08:40:21