Skip to content

Commit 78be554

Browse files
committed
chore(platform-objects): translate the dataset form's Duration row
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AKPixnkg91qCkQCVFDJuqW
1 parent b2ddd35 commit 78be554

5 files changed

Lines changed: 15 additions & 1 deletion

File tree

‎.changeset/25778-dataset-duration-measure.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22
'@objectstack/spec': minor
33
'@objectstack/service-analytics': minor
44
'@objectstack/lint': minor
5+
'@objectstack/platform-objects': minor
56
---
67

7-
feat(spec,analytics,lint): a dataset measure can aggregate the time between two datetime fields of each record
8+
feat(spec,analytics,lint,platform-objects): a dataset measure can aggregate the time between two datetime fields of each record
89

910
Clause-②: yes (widening)
1011
Metadata-protocol: added
1112

1213
- **`@objectstack/spec`**: `DatasetMeasureSchema` gains an optional `duration: { from, to, unit }`, in place of `field`. `from` and `to` name two `datetime` fields of the dataset's own object by their bare names, `unit` is `seconds`, `minutes`, `hours` or `days`, and the measure's `aggregate` is `avg`, `min`, `max` or `sum` of `to` minus `from`. A relationship path, an expression or the row wildcard in either column, the same column twice, another unit, a counting aggregate, or a `field`, `derived` or `currency` beside it is refused at parse. New exports: `DatasetMeasureDurationSchema`, `DatasetDurationUnit`, `DATASET_DURATION_UNIT_SECONDS`, `DATASET_DURATION_AGGREGATES`, `DATASET_DURATION_FIELD_TYPE` and the `DatasetMeasureDuration` / `DatasetDurationUnit` types.
1314
- **`@objectstack/service-analytics`**: the dataset compile refuses a duration column declared anything but `datetime` (`400 DATASET_INVALID`, naming the column and its type). The native-SQL strategy computes the duration as one statement on SQLite, PostgreSQL and MySQL, in double precision on each; SQLite and PostgreSQL are tested live to answer the same number: a record missing either instant is left out, a `to` before its `from` counts as negative, and over a group with no such record `sum` answers `0` and the others `null`. Measure filters, derived measures, ordering and the draft preview serve it. A query the native strategy does not serve (a time dimension bucketed by `granularity`, a field-to-field filter, an object served through engine middleware or an external datasource, a non-SQL datasource) is refused with `400 INVALID_FIELD` naming the measure. Its two columns pass the field-level read gate like any measure's field. The temporal half of the aggregate × field-type refusal now names the duration measure instead of a stored "days open" number.
1415
- **`@objectstack/lint`**: `os validate` refuses a duration column not declared `datetime` with the new gating rule `measure-duration-field-type-refused` (at `datasets[N].measures[M].duration.from` / `.to`), with an `os explain` entry. `dataset-field-unknown` now also reports a duration column the object does not declare.
16+
- **`@objectstack/platform-objects`**: the dataset form's new **Duration** row is translated in every shipped locale.
1517

1618
What to do: nothing. A dataset without `duration` parses, compiles and answers exactly as before.

‎packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,6 +2069,9 @@ export const enMetadataForms: NonNullable<TranslationData['metadataForms']> = {
20692069
},
20702070
"measures.derived": {
20712071
label: "Derived From"
2072+
},
2073+
"measures.duration": {
2074+
label: "Duration"
20722075
}
20732076
}
20742077
},

‎packages/platform-objects/src/apps/translations/es-ES.metadata-forms.generated.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,6 +2069,9 @@ export const esESMetadataForms: NonNullable<TranslationData['metadataForms']> =
20692069
},
20702070
"measures.derived": {
20712071
label: "Derivada de"
2072+
},
2073+
"measures.duration": {
2074+
label: "Duración"
20722075
}
20732076
}
20742077
},

‎packages/platform-objects/src/apps/translations/ja-JP.metadata-forms.generated.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,6 +2069,9 @@ export const jaJPMetadataForms: NonNullable<TranslationData['metadataForms']> =
20692069
},
20702070
"measures.derived": {
20712071
label: "派生元"
2072+
},
2073+
"measures.duration": {
2074+
label: "所要時間"
20722075
}
20732076
}
20742077
},

‎packages/platform-objects/src/apps/translations/zh-CN.metadata-forms.generated.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,6 +2069,9 @@ export const zhCNMetadataForms: NonNullable<TranslationData['metadataForms']> =
20692069
},
20702070
"measures.derived": {
20712071
label: "派生自"
2072+
},
2073+
"measures.duration": {
2074+
label: "时长"
20722075
}
20732076
}
20742077
},

0 commit comments

Comments
 (0)