Aman-Mittal opened a new issue, #281:
URL: https://github.com/apache/fineract-backoffice-ui/issues/281

   ## Business value
   
   A data table is how an institution adds its own fields to clients, loans and 
savings accounts — a national ID, a branch-specific reference, a survey answer. 
Two properties decide whether those fields are usable at scale, and neither can 
be set from the UI.
   
   `src/app/features/system/data-tables/datatables-form.component.ts` binds 
four column properties — `name`, `type`, `length`/`code`, and `mandatory` 
(`:183-190`). The request model supports six. From 
`src/app/api/model/postColumnHeaderData.ts`:
   
   ```ts
   export interface PostColumnHeaderData {
       code?: string;
       indexed?: boolean;     // ← not bound
       length?: number;
       mandatory?: boolean;
       name: string;
       type: string;
       unique?: boolean;      // ← not bound
   }
   ```
   
   The read side is equally ready — `ResultsetColumnHeaderData` returns 
`isColumnIndexed` and `isColumnUnique`, and `loadDatatableData()` (`:330-336`) 
currently drops both on the floor.
   
   What that costs:
   
   - **No index.** Fineract indexes the foreign key automatically, but a custom 
column gets nothing. A "find the client with this national ID" query becomes a 
full scan of the data table. On a few hundred rows nobody notices; on a few 
hundred thousand, the screen that uses it becomes unusable, and the only remedy 
is a hand-written `ALTER TABLE` against production by someone with database 
access.
   - **No unique constraint.** Nothing stops two clients being registered 
against the same national ID. Duplicate-identity prevention is exactly what a 
field like that exists for, and the constraint has to be declared when the 
column is created — the platform will not add it retroactively once duplicates 
are already in the table.
   
   Both are one checkbox each. The gap is only in the form.
   
   ## Reproducing it
   
   ```
   grep -n "unique\|indexed" 
src/app/features/system/data-tables/datatables-form.component.ts   # nothing
   grep -n "unique\|indexed" src/app/api/model/postColumnHeaderData.ts          
                # both present
   ```
   
   ## Describing the change
   
   Two checkboxes in the column row next to the existing `mandatory` one 
(`:181-190`), bound to `column.unique` and `column.indexed`. The form's signal 
is already typed `PostDataTablesRequest` (`:303`), so the properties are there 
and type-check without any model change.
   
   Three small pieces:
   
   1. **The template** — add to the `.column-checkboxes` block. Note the grid 
at `:256` is `grid-template-columns: 2fr 1.5fr 1.5fr 1fr auto`; two more 
checkboxes in the existing cell will need the widths looking at, which is the 
only fiddly part of this issue.
   2. **`addColumn()` (`:341`)** — seed `unique: false, indexed: false` so a 
new row starts defined rather than `undefined`.
   3. **`loadDatatableData()` (`:330`)** — read them back:
      ```ts
      unique: col.isColumnUnique,
      indexed: col.isColumnIndexed,
      ```
      Without this the edit screen shows every existing column as neither 
unique nor indexed, which is worse than not showing it at all.
   
   Two i18n keys under `SYSTEM.*`, alongside `SYSTEM.MANDATORY`. `npm run 
i18n:check` is a CI gate and will catch a missing one.
   
   **One thing to be careful about.** Every field in this form is 
`[disabled]="isEditMode"`, because Fineract only permits narrow kinds of change 
to an existing table. Follow that — the new checkboxes should be disabled in 
edit mode too. Declaring a column unique *after* rows exist is not something 
the platform will honour, and a control that looks editable but silently does 
nothing is worse than a disabled one. Read them back for display; do not make 
them editable.
   
   ## Testing
   
   The platform's own acceptance tests specify this behaviour precisely. From 
`fineract-e2e-tests-runner/src/test/resources/features/Datatables.feature` in 
`apache/fineract` (`develop`):
   
   ```gherkin
   @TestRailId:C3008
   Scenario: Datatable with unique constrained column is indexed
     When A datatable for "Loan" is created with the following extra columns:
       | Name | Type   | Length | Unique | Indexed |
       | col1 | string | 10     | true   | false   |
     Then The following column definitions match:
       | Name | Primary key | Unique | Indexed |
       | col1 | false       | true   | true    |
   
   @TestRailId:C3009
   Scenario: Datatable with indexed column
     When A datatable for "Loan" is created with the following extra columns:
       | Name | Type   | Length | Unique | Indexed |
       | col1 | string | 10     | false  | true    |
     Then The following column definitions match:
       | Name | Primary key | Unique | Indexed |
       | col1 | false       | false  | true    |
   ```
   
   **Read C3008 carefully — it is the interesting case.** The column is 
submitted `Unique: true, Indexed: false` and comes back `Unique: true, Indexed: 
true`. The platform indexes a unique column implicitly. So a round-trip test 
that asserts "what I sent is what I get back" will fail on a correct 
implementation, and the edit screen will legitimately show `indexed` ticked for 
a column the user never ticked it on. Do not "fix" that.
   
   What to write:
   
   - **A unit spec** on the form asserting the submitted body carries `unique` 
and `indexed` per column, and that `loadDatatableData()` maps 
`isColumnUnique`/`isColumnIndexed` back onto the signal. There is no spec file 
for this component yet.
   - **A mocked e2e** that fills a column, ticks both boxes, and asserts the 
intercepted `POST /datatables` body — the `Probe` pattern in 
`e2e/client-servicing-gaps.spec.ts` is the model.
   
   For ticking an `ion-checkbox` inside a form, and especially for any 
`ion-select`, use the helpers in `e2e/utils/` rather than clicking directly — 
`select-in-dialog.ts` documents at length why the obvious approach fails 
against Ionic overlays.
   
   ## Scope
   
   In scope: the two checkboxes, seeding them, reading them back, and the i18n 
keys.
   
   Out of scope: making the edit screen genuinely editable (it currently 
disables everything and PUTs an unchanged body — a real gap, but a separate and 
much larger one), and the datatable query/filter screen.
   
   ## Getting started
   
   - Form: `src/app/features/system/data-tables/datatables-form.component.ts`
   - Request model: `src/app/api/model/postColumnHeaderData.ts`
   - Response model: `src/app/api/model/resultsetColumnHeaderData.ts`
   - `npm test`, `npm run lint:prune`, `npm run i18n:check` and `npm run build` 
must pass.
   - Do not edit anything under `src/app/api` — it is generated, and a CI job 
fails if it drifts from the spec.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to