BaryoDev / BaryoDev/barakoCMS

Content: computed fields and rollups, stored and kept in step

Open
#836 0 comments 0 reactions 0 assignees View on GitHub
core
Dominant language
C#
Stars
6
Forks
7
Avg merge
4h 42m
Merged PRs (30d)
307

Description

Comes up with almost every client: hours on a time entry, a line total on an order, a teacher's hours this month, an invoice's balance. Today a value like that is typed in by hand or written by a workflow after the save, so it can be wrong or stale, and a workflow cannot compute one at all yet (#575).

## Change

**Computed fields.** A field declares how it is computed from other fields of the same entry:

```json
{ "name": "Hours", "type": "decimal", "computed": { "fn": "hours", "args": ["TimeIn", "TimeOut"], "round": 2 } }
```

- Computed inside the write transaction, stored, so it can be filtered, sorted and delivered like any field.
- Recomputed whenever an input changes, including through a transition.
- Read only: a write that sets it is refused with a 400 naming the field.
- A fixed list of functions, the same one the workflow `calculate` step uses (#575): `add`, `subtract`, `multiply`, `divide`, `round`, `min`, `max`, `hours`, `days`, `duration`, `concat`, `coalesce`, `if` over a choice value (#803). No expression language and no code.
- Validated when the type is saved: inputs exist, types fit the function, no field computes from itself or through a cycle.

**Rollups.** A field summarising related entries that reference this one:

```json
{ "name": "HoursThisMonth", "type": "decimal", "rollup": { "from": "timeEntry", "via": "Teacher", "fn": "sum", "field": "Hours", "where": { "createdAt": "thisMonth" } } }
```

- `count`, `sum`, `min`, `max`, `avg`, over one reference hop.
- Updated when a related entry is created, changed or removed, asynchronously after commit, and marked with the time it was last updated, so a reader knows it can lag by seconds.
- A rollup over Sensitive fields is only visible to roles that may read those fields.

**Adding one later.** Adding a computed or rollup field to a type with entries fills existing entries in the background, with progress visible, instead of leaving them empty.

## Done when

- A time entry's Hours is correct after time out, changes when TimeOut is edited, and a request setting Hours directly is a 400.
- A teacher's HoursThisMonth reflects a new time entry within the lag, and a test proves concurrent time entries sum correctly.
- A cycle between two computed fields is refused when the type is saved.

## Where it lives

Core: field definitions, the write path and the rollup projection. A computed value that a module could skip would not be a rule.

Contributor guide

Open the contributing guide

Research direction

Begin by locating the core field-definition, write-path, and rollup-projection entry points; the issue does not name specific files or tests. Use the listed done conditions as the acceptance checks: recomputation and read-only enforcement, concurrent rollup correctness, and cycle rejection when a type is saved.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend, databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.