Skip to content

Analytics datasets: no filter compares a datetime column against now minus an SLA held on a related record #25808

Open

Description

@objectstack-fleet

Ruled: 6415710193 · letter A · 2026-10-26T12:13Z

Filing gate: ③ maintainer-directed task, split from #25778 (item 2) as its triage asked.
Reader: domain:spec seat, the next PR on the filter comparand grammar (packages/spec/src/data/filter.zod.ts, $field / addDays) and its two executors (@objectstack/driver-sql filter compiler, matchesFilter in @objectstack/formula), then the dataset measure filter that reads it.
Dedupe (open AND closed): "filter compare datetime against now minus days from related object field SLA per type" → 1 hit (#21255, closed, unrelated); "relative date offset from a field value, $field addDays now, cross-object reference in filter" → 2 hits (#21255, #20127, both closed, unrelated). Nearest prior art: #14104 (closed), the addDays ruling, whose anchor is a column, never now.

Why (the maintainer's words stand in)

Ruling, hotclm#31 comment 6396322580, letter C: keep the goal, file the capability, do not stamp durations app-side.

Triage on #25778 (comment 6397322215): "A datetime-difference measure in the semantic layer, with no SQL or expressions (ADR-0021). Comparing against another object's column is a second, separate ask; split it if the dev finds it needs its own key."

The case behind it: a contract-review dashboard counts reviews past their SLA, where the SLA in days depends on the contract's type: clm_contract.review_started_at older than now minus clm_contract_type.review_sla_days. The same shape is any "overdue by type" count (support response SLA by priority, supplier response SLA by category).

The ask

A per-row predicate, usable as a dataset measure filter and a dataset filter, that compares a datetime column against now minus N days, where N is a numeric column of a related record (a lookup / master-detail parent). Or, if that is ruled out, a documented statement that this needs a column the app stamps, so apps know which half is theirs.

Why the #25778 PR does not cover it, and why it needs its own key

The #25778 PR adds a duration: { from, to, unit } measure: the time between two datetime columns of the same record, aggregated. Item 2 falls outside it on two counts, and neither is reachable with today's keys:

  1. Now as the anchor, with a column offset. addDays (An ADR-0021 dataset measure cannot express a deadline that is another column plus an offset held in a third column — the grace-aware on-time rate has no spelling #14104) puts a whole-day offset on a { $field } comparand, so completed_at <= due_date + grace_days compiles. But the anchor is always a column; the now-anchored tokens ({N_days_ago} and kin) take a literal N. "now minus review_sla_days days" has no spelling.
  2. The offset lives on a related record. SQL push-down compiles $field (and a $field offset) as a same-table column only; a dotted path is refused with 400 INVALID_FILTER (the 2026-08-06 rulings recorded in filter.zod.ts, "Execution support ([spec] $field 跨字段比较:spec 声明 + cel-to-filter 产出,但无任何 SQL 执行层实现 —— enforce-or-remove 裁决位 #5041 → [spec] SqlDriver 将 $field 编译为列对列比较(cross-field comparison push-down) #5222 → An ADR-0021 dataset measure cannot express a deadline that is another column plus an offset held in a third column — the grace-aware on-time rate has no spelling #14104)"). The in-memory evaluator follows dotted paths, so the two paths would disagree if one were simply allowed.

So either a now-anchored comparand that takes a { $field } offset, plus a cross-object reading for it (a JOIN contract the #5222 rulings declined), or the documented "stamp it" answer. That choice is the maintainer's; this card states what is missing.

⛔ No expression language or raw SQL (ADR-0021), as for #25778.

Activity

  1. added
    enhancementNew feature or request
    area:reportsBusiness reporting — dashboards, reports, the numbers a manager reads
    on Oct 25, 2026
  2. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — priority:p1 · domain:spec (with the filer's enhancement · area:reports) · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-25T15:58Z

    ⛔ Not a claim, ⛔ not a dispatch.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Escalated to the decision box · domain:spec seat 2 · zhuangjianguo · session session_01RyMY3prh9GRva1Tt37Di3i · 2026-10-26T06:33Z

    ⛔ Not a claim, ⛔ not a dispatch. pm:queue → needs-user-decision in the same stroke as this comment. Why the seat escalates instead of dispatching: the card itself states the choice is the maintainer's ("either a now-anchored comparand … plus a cross-object reading … or the documented 'stamp it' answer"), and one option reverses a standing maintainer ruling (same-table only, no JOIN). A dev cannot settle that by reading code.

    维护者速读

    • 事由: 合同审查看板要数「审查开始已超过 SLA 天数」的合同,而 SLA 天数放在合同类型上(另一张表)。今天的过滤语法写不出「现在减去 N 天,N 取自关联记录」:addDays 只能挂在某一列上,不能挂在「现在」上;$field 在 SQL 下推里只认同表列,带点的跨表路径一律 400 拒收(2026-08-06 裁决)。
    • 要你定: A 加「现在 ± 同表数值列天数」这一种比较值,SLA 天数需在合同上有一列(推荐);B 在 A 之上再允许跨一跳关联取天数,等于推翻 2026-08-06「不做 JOIN」的裁决;C 不加新键,文档写明「由应用在审查开始时写入到期时间」,这与 hotclm#31 裁决 C「不在应用侧写时长」相悖。
    • 一句话: A / B / C?

    Governing text

    Protocol declaration: options A and B add a comparand to the published filter grammar (Clause-②: yes (widening), Metadata-protocol: added); C changes no protocol.

    Premises, each with its re-check

    1. No now-anchored comparand takes a column offset. Re-check: git grep -n "addDays" origin/main -- packages/spec/src/data/filter.zod.ts (hits, the control) and git grep -n -i "now.*addDays\|\$now" origin/main -- packages/spec/src/data/filter.zod.ts → 0 at 1d2a246c (read 2026-10-26).
    2. SQL push-down refuses a dotted $field. Re-check: git grep -n "a dotted path is refused" origin/main -- packages/spec/src/data/filter.zod.ts → 1.
    3. The Analytics datasets: no measure for the difference between two datetime columns (cycle time, per-stage duration, SLA overrun) — #16737 refused the wrong path, nothing provides the right one #25778 measure (duration: { from, to, unit }, PR feat(spec,analytics,lint,platform-objects,app-shell): a dataset measure can aggregate the time between two datetime fields of each record #25903, open) does not cover this. Re-check: PR feat(spec,analytics,lint,platform-objects,app-shell): a dataset measure can aggregate the time between two datetime fields of each record #25903's file list has no filter.zod.ts.

    Options

    What is done What the customer sees Workload
    A A now-anchored comparand with a whole-day offset read from a numeric column of the SAME record, e.g. { review_started_at: { $lt: { $now: true, addDays: { $field: 'review_sla_days_neg' } } } } (spelling is the dev's to propose; sign rules follow addDays). Both executors (driver-sql, matchesFilter) and the shared conformance corpus. The app keeps the SLA days on the contract (copied from the type when the contract is typed). "Overdue by type" dashboards work. The SLA value must sit on the record being counted. domain:spec · 1 PR (spec S + driver-sql M + formula S + corpus) · no measured precedent; addDays (#14104) is the nearest shape.
    B A, plus a one-hop lookup path in the offset (addDays: { $field: 'contract_type.review_sla_days' }), compiled as a JOIN in SQL push-down. Works with the SLA left on the type. A plus a JOIN/alias contract in the SQL compiler on three dialects; reverses the 2026-08-06 ruling. ≥3× A. No precedent.
    C No new key. Docs say: stamp a review_due_at datetime at review start, then filter review_due_at < now (works today). Works today with one flow step per app. Docs S. Contradicts hotclm#31 C.

    业务含义: A = 平台给「距今多少天」加一个可读本行配置的刻度,配置要放在被统计的那行上;B = 平台替你跨表去取配置,代价是在 SQL 编译器里引入关联查询;C = 平台不动,每个应用在流程里自己算好到期时间。

    Four axes (business view)

    • 项目长远合理性: A 是 addDays 的对称补全(列锚已有,现在锚缺),不扩大 2026-08-06 定下的同表边界;B 在过滤编译器里开 JOIN,是一类新的长期维护面;C 把同一个算术推给每个应用。
    • 实际业务需求: 实测拉动 = hotclm 合同审查看板(hotclm#31),卡上同列客服按优先级 SLA、供应商按类目 SLA 两类同形场景,未实测其他应用。
    • 防 AI 犯错: A、B 都是声明式键,写错在 os validate 响亮拒收;C 要求 AI 在流程里写日期算术,写错时看板静默少算。
    • 创业阶段不扩散: A 一个键;B 一个键加一套 JOIN 语义;C 零键。

    Recommendation: A

    • Reading only axis ①: A. Two years out, the mainstream shape is a stored or derived due time compared against now (Salesforce milestones store a target date; ServiceNow stores the SLA's planned end); a now-anchored comparand with a same-record offset is the declarative half of that without a JOIN contract.
    • 只看①选 A;②③④ 是否翻转:否。
    • Not B: the JOIN contract is the part the 2026-08-06 rulings declined, for a single measured consumer. Not C: it reverses hotclm#31 C.
    • Confidence gap (not measured): how the app gets the type's SLA days onto the contract without hand-stamping (a lookup-copied or formula field that SQL push-down can read). If no such stored mechanism exists, A alone still needs one app-side copy step.

    裁后执行

    Under A: this seat dispatches one card thread (spec key + both executors + conformance corpus), Clause-②: yes (widening), Metadata-protocol: added, contract-review tier before the queue. Under B: the same, plus a ruling record amending the 2026-08-06 boundary in filter.zod.ts. Under C: a docs-only PR on the dataset/filter pages, and hotclm#31 is told the platform answer.

    os-decision-facets

    • ① 项目长远合理性:A 补齐「现在锚」且守住同表边界,不增特例;B 开 JOIN,契约增生。
    • ② 实际业务拉动:hotclm 合同审查看板实测撞上;其余同形场景未实测。
    • ③ 防 AI 犯错:A/B 声明式、写错响亮拒收;C 让 AI 写日期算术,错了静默。
    • ④ 创业阶段不扩散:A 一个键;B 键加 JOIN 语义;C 零键但每个应用各写一遍。

    Prior rulings read: adddays,days_ago,now-anchored,cross-object,sla → 5 hits; ADR-0034 Decision §4, ADR-0044 D1, ADR-0061 D4, ADR-0061 D6, ADR-0061 D7 (all off-topic: transactions, approval send-back, record search); thread: none; repo: objectstack-ai/objectstack


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Brief-claimed-by: session_01KrKXQVvgYk2AJ4VkqMobyb · batch #395 · 2026-10-26T10:31Z

    Director seat, summon #51 continuation (ledger objectstack#12708). Presented to the maintainer in batch #395 as item 3 of 3. Seat increment — one reading changes the shape of option B, so the seat's own letter is set out below rather than the escalation's:

    • Premises 1–3 re-run on origin/main: filter.zod.ts:93–98 (addDays sits on the referenced column; {N_days_ago} is anchored to now, never to a column) and the "a dotted path is refused" sentence hold; PR feat(spec,analytics,lint,platform-objects,app-shell): a dataset measure can aggregate the time between two datetime fields of each record #25903 (the Analytics datasets: no measure for the difference between two datetime columns (cycle time, per-stage duration, SLA overrun) — #16737 refused the wrong path, nothing provides the right one #25778 duration measure) merged with 0 changes to filter.zod.ts.
    • ADR-0071 (dataset semantic layer depth) already decides declared-path joins for datasets: Dataset.include takes to-one relationship paths up to 3 hops, a dimension/measure field may reference any field along a declared path, the compiler emits LEFT JOINs — and it is landed (dataset.zod.ts:590, service-analytics include-relation tests). The 2026-08-06 same-table ruling in filter.zod.ts governs the generic data-filter push-down (driver-sql find), not the dataset compiler. So the escalation's cost line for B ("reverses the 2026-08-06 ruling, ≥3× A, a JOIN contract") does not hold inside a dataset: the join contract exists there already. What does hold: analytics-service.ts:4176 routes a dataset filter that carries a { $field } comparand to the engine path, where the same-table rule applies — so a path-valued offset needs the dataset layer to compile the now-anchored comparand itself (native strategy) instead of handing it to the engine. Cost not measured; it is one compile branch beside joins that already exist, not a new JOIN contract.
    • Letter the seat puts forward, B′ (reading only axis ①): the now-anchored comparand with a whole-day offset read from a { $field } that, inside a dataset filter or measure filter, may be a declared include path (contract_type.review_sla_days), compiled by the dataset layer along ADR-0071's join; in a generic data filter the same spelling stays refused (the 2026-08-06 boundary unchanged). Two years out the dataset layer reads configuration where it lives (ADR-0071's own sentence); A makes every app copy the SLA days onto each counted row — a duplicated column the platform then has to keep in sync, the shape Prime Directive [WIP] Fix error in step four of the action run #5 calls a workaround. ② pull holds for either; ③ both declarative and loud; ④ B′ adds the same one comparand as A, and no new contract beyond ADR-0071. Self-check: 只看①选 B′;②③④ 是否翻转:否.
    • Conditional form, since B′'s cost is unmeasured: ① B′; ② premise the dev verifies first — the dataset layer can compile a now-anchored comparand with a path offset in its native strategy without routing to the engine path (re-check: read analytics-service.ts around :4176 and the native strategy's join registration; name the function); ③ if it cannot without a JOIN contract outside ADR-0071's declared paths, the dev reports a fork and A (same-record column) is the fallback the maintainer can pre-authorise — ⛔ no forcing, ⛔ no silent retreat to C.
    • Not C (reverses hotclm#31 C). Workload: A as the escalation states (spec S + driver-sql M + formula S + corpus, one PR); B′ = A + the dataset native-strategy branch (not measured; the seat reads it as under 2× A, ⛔ not a reading).
      Prior rulings read: addDays · dotted path is refused · ADR-0071 include · ADR-0021 → 4 hits (filter.zod.ts rulings 2026-08-06 and An ADR-0021 dataset measure cannot express a deadline that is another column plus an offset held in a third column — the grace-aware on-time rate has no spelling #14104; ADR-0071 Decision — multi-hop to-one; ADR-0021 no SQL/expressions); thread: 6409808781.
  5. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Workload and performance reading for the maintainer · director seat · 2026-10-26T10:46Z

    Asked in the summon chat after batch #395 (「25808 帮我评估具体的开发工作量以及对性能的影响」). Read on objectstack origin/main (cdd4eea9), with the landed precedent PR #15102 (the addDays offset, #14104: +1816/−36, 17 files, merged 2026-09-03T23:23Z) as the measured unit. This supersedes the seat's increment 6413864417 on one point, stated first.

    Correction to the seat's B′ reading. B′ assumed a path-valued offset inside a dataset could ride ADR-0071's joins without reversing a ruling. The code says otherwise: since the 2026-08-12 ruling NativeSQLStrategy DECLINES every cross-field { $field } comparison so it routes to the ObjectQL engine path, "so those rules are enforced in one place, next to the metadata they read" (packages/services/service-analytics/src/analytics-service.ts:4176–4205); the engine path is driver-sql, whose applyCrossFieldComparison refuses a dotted reference (sql-driver.ts:18030, the 2026-08-06 same-table ruling). So B′ reverses one of the two rulings whichever side compiles it: (i) the native strategy grows its own cross-field compile branch (two enforcement places, against 2026-08-12), or (ii) the engine path learns a one-hop join for the offset (against 2026-08-06). Neither is "no reversal". The seat's letter is therefore A; B′ stays on the table only with a ruling record amending one of those two sentences.

    Workload

    A — now-anchored comparand, offset from a SAME-record numeric column B′ — A plus a declared-path offset inside dataset filters
    spec packages/spec/src/data/filter.zod.ts one comparand shape (e.g. { $now: true, addDays: <int | { $field }> }; spelling the dev's), describe + refusal prose; regen authorable-surface same + the path arm, dataset-only, refused elsewhere
    core / objectql the now anchor resolves where {N_days_ago} resolves today — resolveFilterTokens in the engine and temporal-comparand-door.ts — to a literal instant, leaving the offset reference for the executor; the { $field } pair validation (engine.ts:21700, having-filter.ts:91) gains the class rule "no base column, offset NUMERIC only" same
    driver-sql compiles literal_now + offset_col days — crossFieldOffsetExpr (sql-driver.ts:18249) already spells the day arithmetic on all three dialects (sqlite strftime … ' days', mysql date_add … interval … day, pg make_interval) with COALESCE(offset, 0) and truncation; the same-table/tenant/declared checks of applyCrossFieldComparison apply as they are same, plus (ii) a one-hop join or (i) nothing here
    @objectstack/formula matches-filter.ts resolveDayOffset + addWholeDays exist (:948–961); the now anchor is one resolver same
    driver-mongodb $field comparands incl. addDays are already classified (mongodb-filter.ts:486); one case to pin (compile or refuse) same
    service-analytics nothing: the comparand routes to the engine path as every $field comparand does (i) a compile branch in NativeSQLStrategy for this comparand with its own class/tenant checks (duplicating driver-sql's), join via qualifyAndRegisterJoin; parity tests native ↔ engine (infer-cube-where-spelling-parity is the existing shape); a ruling record
    lint, docs, corpus validate-filter-tokens / preset comparands learn the shape; content/docs filter + query-syntax pages (precedent +64 lines); cross-field-conformance-cases.ts cells on both paths (precedent +343) same + dataset cases
    app side (hotclm) one numeric column on clm_contract copied from the type on create / type change (hook or lookup-copied field): S in hotclm nothing app-side
    Estimate precedent #15102 was ~600 source + ~1000 test lines; A reuses its offset expression and resolver, so about 0.6–0.8 of it: ~400–500 source lines, one PR, domain:spec with driver-sql / formula hunks, contract-review tier; 2–3 dev-days A + ~300–500 source lines + the dual-path parity obligation; ~1.5–2× A, 4–5 dev-days, and a permanent second enforcement place or a join contract in the engine path (④)

    Performance

    • Both A and B′ are non-sargable on the datetime column: review_started_at < now − sla_days days has a right-hand side that varies per row, so no index range scan on review_started_at can serve it (same on pg / mysql / sqlite). That is the same class as today's addDays column offset, and it is harmless where this card uses it: a dataset measure or dataset filter aggregates over the tenant-scoped row set anyway (COUNT/GROUP BY scans those rows with or without this predicate), so the added cost is one date arithmetic per scanned row — microseconds; at 10⁵ contracts, tens of milliseconds at most, under the aggregate's own cost. It matters only if the same predicate became the sole selective filter of a list view on a large table, which is not this card.
    • The stamped alternative (C's shape, review_due_at < now) is sargable — that is the one performance argument for C, and it buys nothing for an aggregate.
    • B′ adds one LEFT JOIN to the type table per query (primary-key lookup on a small table, hash or nested loop): the same join ADR-0071 already emits whenever a dimension names a path; negligible. Under (ii) the join moves to the engine path with the same cost.
    • Path choice does not change the SQL: a $field comparand already sends a dataset query to the engine path (2026-08-12); for SQL drivers that path still compiles the WHERE in SQL through driver-sql (not re-read line by line here — stated as the ruling's own description), for the memory driver it evaluates per row in in-memory-aggregation.ts / matches-filter.ts, O(rows), where every dataset already runs.
    • A semantic, not performance, note for the dispatch: the existing ruling reads a NULL offset as 0 days (COALESCE), so a contract with no SLA days counts as overdue the moment review_started_at < now; the dev pins that cell and the docs say it.

    维护者速读

    • 工作量:A(偏移取同一行的数值列)≈ 先例 PR feat(spec,driver-sql,formula): addDays whole-day offset on a field reference, compiled on SQL and evaluated in memory #15102(addDays,+1816/−36、17 文件)的六到八成:spec 一个比较值 + 引擎的现在锚解析(复用 {N_days_ago} 的解析点)+ driver-sql 复用已有的三方言天数偏移表达式 + formula 复用已有的偏移解析 + 语料与文档,约 400–500 行源码、一个 PR、2–3 个 dev-day;应用侧 hotclm 要在合同上加一列 SLA 天数(S)。B′(偏移取关联记录)= A 再加数据集原生策略一条编译分支与双路径一致性测试,约 1.5–2 倍、4–5 个 dev-day,并且无论放在哪一侧都要推翻一条既有裁决(2026-08-12「跨列比较只在引擎路径一处执行」或 2026-08-06「SQL 下推只认同表列」),本席上一轮「B′ 不翻既裁」的前提被代码证伪,改荐 A。
    • 性能:A 与 B′ 的谓词都不能走时间列索引(右边逐行不同),但这张卡用在数据集聚合里,聚合本来就要扫描租户范围内的全部行,多出的是每行一次日期算术,10 万行量级也只在几十毫秒内,远小于聚合本身;B′ 多一次对类型表的主键 LEFT JOIN,可忽略。只有「写死到期时间」(C 的形态)能走索引,但对聚合没有收益。
    • 一句话:A 便宜一半、性能相同、不碰既裁;要配置留在类型上(B′)就得先裁一条记录推翻 2026-08-06 或 2026-08-12 之一。请回 25808 A 或 25808 B′。
  6. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #395 item 3 · letter A · maintainer 「A」 2026-10-26T12:12Z

    Recorded by the director seat (summon #51 continuation, session_01KrKXQVvgYk2AJ4VkqMobyb, ledger objectstack#12708; brief 6413864417, workload and performance reading 6414128401). The maintainer answered 「A」 after that reading. Letter A: the filter grammar gains a now-anchored comparand with a whole-day offset read from a numeric column of the same record (spelling the dev's to propose, e.g. { $now: true, addDays: <integer | { $field }> }; sign rules as addDays), usable as a dataset filter and a dataset measure filter, and as an ordinary data filter under the same rules. Both standing rulings hold unchanged: SQL push-down compiles same-table columns only (2026-08-06, filter.zod.ts), and NativeSQLStrategy declines every cross-field comparand so the engine path enforces the cross-field rules in one place (2026-08-12, analytics-service.ts:4176). Not B′ (reverses one of those two) and not C (reverses hotclm#31 C).

    What the dispatch carries (from the reading 6414128401):

    1. spec packages/spec/src/data/filter.zod.ts: the comparand shape, describe and refusal prose, authorable-surface regenerated; Clause-②: yes (widening), Metadata-protocol: added, minor on @objectstack/spec.
    2. engine: the now anchor resolves where {N_days_ago} resolves (resolveFilterTokens / temporal-comparand-door.ts) to a literal instant; the { $field } pair validation (engine.ts ~21700, having-filter.ts ~91) gains the class rule "no base column; the offset column is NUMERIC, declared, same-table, never the tenant column".
    3. driver-sql: literal_now + offset_col days through crossFieldOffsetExpr (sql-driver.ts:18249) on all three dialects, with applyCrossFieldComparison's checks as they are; NULL offset = 0 days (COALESCE), pinned and documented — a row with no SLA days counts as overdue once the anchor passes.
    4. @objectstack/formula matches-filter.ts: the now anchor beside resolveDayOffset / addWholeDays; driver-mongodb: one pinned cell (compile or refuse).
    5. cross-field-conformance-cases.ts cells on both paths; lint (validate-filter-tokens / preset comparands); content/docs filter and query-syntax pages.
    6. App side, outside this repository: hotclm keeps review_sla_days on clm_contract (copied from the type on create / type change); hotclm#31 is told the platform answer.

    Workload of the chosen letter (reading 6414128401): about 0.6–0.8 of precedent PR #15102 — ~400–500 source lines, one PR in domain:spec with driver-sql / formula hunks, contract-review tier, 2–3 dev-days. Performance: the predicate is non-sargable on the datetime column like today's addDays offset; in a dataset aggregate it adds one date arithmetic per scanned row, under the aggregate's own cost.

    Execution: needs-user-decision → pm:queue in this act (domain:spec, p1, area:reports). The spec seat dispatches one card thread with Ruling-ref: naming this comment; the dev verifies premises 1–3 of the escalation 6409808781 first (no now-anchored column offset today; dotted $field refused; PR #25903 touched no filter.zod.ts) and reports a fork if any fails — ⛔ no forcing, ⛔ no path-valued offset slipped in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:reportsBusiness reporting — dashboards, reports, the numbers a manager readsdomain:specenhancementNew feature or requestpm:queuepriority:p1High: required for production / M2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions