Data display model — additive Custom Views layer + unified inbox subsume + render-shape switcher #5

Open
opened 2026-05-06 14:46:46 +00:00 by mAi · 3 comments
Collaborator

Problem

paliad currently builds a fixed page per use case: /agenda, /events?type=deadline (Fristen), /events?type=appointment (Termine), /inbox (approvals), /dashboard. Each page is bespoke code with hand-tuned filters, render shape, and data hydration. Adding a new viewpoint means a new page + handler + bundle.

m's direction (2026-05-06): rethink this as an additive Custom Views layer on top of the fixed defaults. The deeper substrate question: what is paliad's data-display model? What cards do we render, against what underlying data, with what filter grammar, and what render shapes (calendar / cards / list / kanban / connections-graph)?

Goals

  1. Additive, not replacement. Fixed sidebar entries (Agenda / Fristen / Termine / Inbox / Dashboard) stay as out-of-the-box defaults. No casual user is forced to compose a view.
  2. Custom Views feature. A user can save a view = (filter spec, render shape, data slice) that surfaces as its own sidebar button under a "Meine Sichten" group. The fixed defaults are themselves system-shipped saved views — same data layer, same render components.
  3. Unified data-display model. Single substrate — one filter grammar, one set of render components (Calendar, CardGrid, List, Timeline, ConnectionsGraph), one data-slice contract — used by both system defaults and user-defined views.
  4. Subsume the unified-inbox direction (m, 2026-05-06 16:34–16:42): inbox-as-everything-that-happens (project activity + approval candidates + new cases + status changes + …) is a view, not a separate concept. Configurable granularity ("my projects" vs specific projects, "new cases" vs "changes to events" vs "approvals only" vs everything) is what the filter grammar must express.
  5. Build on existing wins. Events ↔ Files connection visualization, deadline traffic-light, partner-unit-derived team display (t-139 Phase 2) — these surface naturally as render shapes / data slices in the new model. Don't throw them away.

Out of scope (v1)

  • Replacing the fixed pages (they stay as defaults; can be removed later if usage patterns warrant).
  • Cross-user view sharing ("share my view with Anna") — defer; v1 is per-user only.
  • Public / read-only links to views.
  • Real-time push updates ("inbox row appears when someone files an approval"). v1 is fetch-on-load + manual refresh.
  • Cross-project rollups (rolling rows across unrelated projects).
  • Themes / per-view colour palettes.

Locked direction (m, 2026-05-06)

  • Additive. Fixed pages stay; Custom Views ship alongside them.
  • Subsume the unified inbox. Approval-candidate visibility lives in the same substrate.
  • Sidebar layout. Custom views appear in their own sidebar group ("Meine Sichten" / "My Views"), separate from the fixed defaults.
  • In-page visualisation switcher. A user on a view page can swap render shapes (calendar ↔ cards ↔ list) without leaving the view.
  • paliad-only scope. Other projects (otto, fdbck) are out.

Open design questions (for inventor — m will answer in design pass)

Data substrate

  1. What's the fundamental row? Today we have paliad.deadlines, paliad.appointments, paliad.project_events, paliad.approval_requests. Is the new substrate a single virtual view_row that unions all of them, an explicit registry of "data sources" the view picks from, or something else?
  2. Filter grammar shape. SQL-like (WHERE due_date > now() AND project_id IN ...)? Structured JSON ({ "due_date": { ">": "now" }, "project_id": ["..."] })? UI-built only (no DSL exposed)? Inventor: propose, m signs off.
  3. Granularity dimensions. From m's brainstorm: my projects / specific projects / newly added cases / newly added events / changes to events / approved-vs-unapproved / time horizon / event type / role-perspective. Inventor: enumerate the full dimension set and which have UI affordances vs hidden defaults.

Render shapes

  1. Which shapes are first-class for v1? Candidates: Calendar (month / week), CardGrid (current Verlauf style), List (table), Timeline (chronological), Kanban (columns), ConnectionsGraph (events↔files visualisation). Pick a v1 set and defer the rest.
  2. Per-shape config. Each shape has its own knobs (calendar = month vs week, cards = sort order, list = column set). Stored alongside the filter spec, or shape-only-knobs separate?
  3. Empty state per view. When a view has zero matches, what does the user see? "No matches" generic? Filter-aware ("No deadlines match in the next 30 days — try widening the time horizon")?

View persistence + sidebar

  1. Schema for paliad.user_views. Fields: id, user_id, name, filter_spec jsonb, render_shape, render_config jsonb, sort_order, icon, color? Inventor: propose, m signs off.
  2. System views — code or DB? Are the fixed defaults (Agenda / Fristen / Termine / Inbox / Dashboard) hardcoded fallbacks rendered by the same components, OR seeded rows in paliad.user_views flagged is_system=true per user? Inventor proposes; tradeoff is config-as-code (clean, ships with new releases) vs config-as-data (user-editable, drifts).
  3. Sidebar layout. "Meine Sichten" group below the fixed groups, or above? Show user-view icons + names; what's the badge / count behaviour?
  4. Default landing. When a user clicks "Meine Sichten" with N saved views, do we show the most-recently-used? Always-default? "Pick a view" empty state?

View authoring UX

  1. Where do you create a view? Inline button on existing pages ("speichere diese Filter-Kombi als Sicht")? Dedicated /views/new page? Both (saving an ad-hoc filter combo is the common case; full-page editor is the power case)?
  2. Default-first onboarding. New users start with zero saved views. Should we seed N starter examples for them, or empty + tutorial?

Approval / unified-inbox integration

  1. Approval candidates as a granularity dimension. In m's brainstorm, "approved / unapproved" is a filter. Concretely: does the filter grammar carry an approval_status predicate that any view can opt into, OR is "approval candidates" a separate data source that views can union?
  2. The current /inbox page. Stays as a system view? Becomes a Custom View that ships seeded? Or refactored away entirely (the unified-inbox concept replaces it)?

Migration / coexistence

  1. Existing fixed pages — do they reroute through the new substrate, or stay independent? If they reroute, that's bigger blast radius but cleaner long-term. If they stay independent, we have a hybrid where casual users get hand-tuned pages and power users get composable views — works but doubles the surface area.
  2. URL contract. Does /views/{user-view-id} or /views/{slug} make sense? Does it deep-link to filter state (so "open my view with the date set to today" works)?
  3. Auth + RLS. paliad.user_views.user_id is user-scoped. Views never leak across users. What about views that reference a project the user later loses access to — fail open, fail closed, hide?

Performance

  1. Materialisation. If a saved view is "all events from all my projects in the next 90 days, sorted by due_date", and the user has 50 visible projects with thousands of rows each, does the query just run on every page load? Materialised view per saved view (cron-refreshed)? Cap row count + paginate?

References

  • t-paliad-138 — dual-control approvals (just shipped, /inbox page is the v1 of the approval surface)
  • t-paliad-139 — hierarchy aggregation + effective-team + partner-unit derivation (in flight, noether owns Phases 2+3)
  • t-paliad-122 — courts entity + per-country holidays (data substrate adjacent)
  • paliad.deadlines, paliad.appointments, paliad.project_events, paliad.approval_requests — current data tables
  • internal/services/event_service.go — current "union" data path (deadlines + appointments) — closest existing precedent for a unified substrate
  • frontend/src/agenda.tsx, frontend/src/events.tsx, frontend/src/inbox.tsx, frontend/src/dashboard.tsx — current bespoke pages

Inventor brief

  • Role: inventor
  • Worker assignment is HELD until noether's t-paliad-139 Phase 2 + 3 are merged. Then assign a fresh inventor (NOT cronus per m's directive 2026-05-06).
  • Branch convention: mai/<inventor>/inventor-data-display-model
  • Deliverable: docs/design-data-display-model-2026-05-06.md. Three coordinated sub-designs:
    1. Data substrate + filter grammar (Q1–Q3, Q13)
    2. Render shapes + view authoring UX (Q4–Q6, Q11–Q12, Q16)
    3. Persistence + sidebar + system-vs-user-view shape (Q7–Q10, Q14, Q15, Q17, Q18)
  • Inventor STOPs after design. No /mai-coder. Awaits m's go on the design before any coder shift.
  • m available during design pass to answer the 18 open questions above.
## Problem paliad currently builds a fixed page per use case: `/agenda`, `/events?type=deadline` (Fristen), `/events?type=appointment` (Termine), `/inbox` (approvals), `/dashboard`. Each page is bespoke code with hand-tuned filters, render shape, and data hydration. Adding a new viewpoint means a new page + handler + bundle. m's direction (2026-05-06): rethink this as an additive **Custom Views** layer on top of the fixed defaults. The deeper substrate question: **what is paliad's data-display model?** What cards do we render, against what underlying data, with what filter grammar, and what render shapes (calendar / cards / list / kanban / connections-graph)? ## Goals 1. **Additive, not replacement.** Fixed sidebar entries (Agenda / Fristen / Termine / Inbox / Dashboard) stay as out-of-the-box defaults. No casual user is forced to compose a view. 2. **Custom Views feature.** A user can save a view = `(filter spec, render shape, data slice)` that surfaces as its own sidebar button under a "Meine Sichten" group. The fixed defaults are themselves system-shipped saved views — same data layer, same render components. 3. **Unified data-display model.** Single substrate — *one* filter grammar, *one* set of render components (Calendar, CardGrid, List, Timeline, ConnectionsGraph), *one* data-slice contract — used by both system defaults and user-defined views. 4. **Subsume the unified-inbox direction** (m, 2026-05-06 16:34–16:42): inbox-as-everything-that-happens (project activity + approval candidates + new cases + status changes + …) is a *view*, not a separate concept. Configurable granularity ("my projects" vs specific projects, "new cases" vs "changes to events" vs "approvals only" vs everything) is what the filter grammar must express. 5. **Build on existing wins.** Events ↔ Files connection visualization, deadline traffic-light, partner-unit-derived team display (t-139 Phase 2) — these surface naturally as render shapes / data slices in the new model. Don't throw them away. ## Out of scope (v1) - Replacing the fixed pages (they stay as defaults; can be removed later if usage patterns warrant). - Cross-user view sharing ("share my view with Anna") — defer; v1 is per-user only. - Public / read-only links to views. - Real-time push updates ("inbox row appears when someone files an approval"). v1 is fetch-on-load + manual refresh. - Cross-project rollups (rolling rows across unrelated projects). - Themes / per-view colour palettes. ## Locked direction (m, 2026-05-06) - **Additive.** Fixed pages stay; Custom Views ship alongside them. - **Subsume the unified inbox.** Approval-candidate visibility lives in the same substrate. - **Sidebar layout.** Custom views appear in their own sidebar group ("Meine Sichten" / "My Views"), separate from the fixed defaults. - **In-page visualisation switcher.** A user on a view page can swap render shapes (calendar ↔ cards ↔ list) without leaving the view. - **paliad-only scope.** Other projects (otto, fdbck) are out. ## Open design questions (for inventor — m will answer in design pass) ### Data substrate 1. **What's the fundamental row?** Today we have `paliad.deadlines`, `paliad.appointments`, `paliad.project_events`, `paliad.approval_requests`. Is the new substrate a single virtual `view_row` that unions all of them, an explicit registry of "data sources" the view picks from, or something else? 2. **Filter grammar shape.** SQL-like (`WHERE due_date > now() AND project_id IN ...`)? Structured JSON (`{ "due_date": { ">": "now" }, "project_id": ["..."] }`)? UI-built only (no DSL exposed)? Inventor: propose, m signs off. 3. **Granularity dimensions.** From m's brainstorm: my projects / specific projects / newly added cases / newly added events / changes to events / approved-vs-unapproved / time horizon / event type / role-perspective. Inventor: enumerate the full dimension set and which have UI affordances vs hidden defaults. ### Render shapes 4. **Which shapes are first-class for v1?** Candidates: Calendar (month / week), CardGrid (current Verlauf style), List (table), Timeline (chronological), Kanban (columns), ConnectionsGraph (events↔files visualisation). Pick a v1 set and defer the rest. 5. **Per-shape config.** Each shape has its own knobs (calendar = month vs week, cards = sort order, list = column set). Stored alongside the filter spec, or shape-only-knobs separate? 6. **Empty state per view.** When a view has zero matches, what does the user see? "No matches" generic? Filter-aware ("No deadlines match in the next 30 days — try widening the time horizon")? ### View persistence + sidebar 7. **Schema for `paliad.user_views`.** Fields: id, user_id, name, filter_spec jsonb, render_shape, render_config jsonb, sort_order, icon, color? Inventor: propose, m signs off. 8. **System views — code or DB?** Are the fixed defaults (Agenda / Fristen / Termine / Inbox / Dashboard) hardcoded fallbacks rendered by the same components, OR seeded rows in `paliad.user_views` flagged `is_system=true` per user? Inventor proposes; tradeoff is config-as-code (clean, ships with new releases) vs config-as-data (user-editable, drifts). 9. **Sidebar layout.** "Meine Sichten" group below the fixed groups, or above? Show user-view icons + names; what's the badge / count behaviour? 10. **Default landing.** When a user clicks "Meine Sichten" with N saved views, do we show the most-recently-used? Always-default? "Pick a view" empty state? ### View authoring UX 11. **Where do you create a view?** Inline button on existing pages ("speichere diese Filter-Kombi als Sicht")? Dedicated `/views/new` page? Both (saving an ad-hoc filter combo is the common case; full-page editor is the power case)? 12. **Default-first onboarding.** New users start with zero saved views. Should we seed N starter examples for them, or empty + tutorial? ### Approval / unified-inbox integration 13. **Approval candidates as a granularity dimension.** In m's brainstorm, "approved / unapproved" is a filter. Concretely: does the filter grammar carry an `approval_status` predicate that any view can opt into, OR is "approval candidates" a separate data source that views can union? 14. **The current `/inbox` page.** Stays as a system view? Becomes a Custom View that ships seeded? Or refactored away entirely (the unified-inbox concept replaces it)? ### Migration / coexistence 15. **Existing fixed pages — do they reroute through the new substrate, or stay independent?** If they reroute, that's bigger blast radius but cleaner long-term. If they stay independent, we have a hybrid where casual users get hand-tuned pages and power users get composable views — works but doubles the surface area. 16. **URL contract.** Does `/views/{user-view-id}` or `/views/{slug}` make sense? Does it deep-link to filter state (so "open my view with the date set to today" works)? 17. **Auth + RLS.** `paliad.user_views.user_id` is user-scoped. Views never leak across users. What about views that reference a project the user later loses access to — fail open, fail closed, hide? ### Performance 18. **Materialisation.** If a saved view is "all events from all my projects in the next 90 days, sorted by due_date", and the user has 50 visible projects with thousands of rows each, does the query just run on every page load? Materialised view per saved view (cron-refreshed)? Cap row count + paginate? ## References - t-paliad-138 — dual-control approvals (just shipped, `/inbox` page is the v1 of the approval surface) - t-paliad-139 — hierarchy aggregation + effective-team + partner-unit derivation (in flight, noether owns Phases 2+3) - t-paliad-122 — courts entity + per-country holidays (data substrate adjacent) - `paliad.deadlines`, `paliad.appointments`, `paliad.project_events`, `paliad.approval_requests` — current data tables - `internal/services/event_service.go` — current "union" data path (deadlines + appointments) — closest existing precedent for a unified substrate - `frontend/src/agenda.tsx`, `frontend/src/events.tsx`, `frontend/src/inbox.tsx`, `frontend/src/dashboard.tsx` — current bespoke pages ## Inventor brief - Role: inventor - **Worker assignment is HELD until noether's t-paliad-139 Phase 2 + 3 are merged.** Then assign a fresh inventor (NOT cronus per m's directive 2026-05-06). - Branch convention: `mai/<inventor>/inventor-data-display-model` - Deliverable: `docs/design-data-display-model-2026-05-06.md`. Three coordinated sub-designs: 1. Data substrate + filter grammar (Q1–Q3, Q13) 2. Render shapes + view authoring UX (Q4–Q6, Q11–Q12, Q16) 3. Persistence + sidebar + system-vs-user-view shape (Q7–Q10, Q14, Q15, Q17, Q18) - Inventor STOPs after design. No `/mai-coder`. Awaits m's go on the design before any coder shift. - m available during design pass to answer the 18 open questions above.
mAi self-assigned this 2026-05-06 14:46:46 +00:00
Author
Collaborator

LOCKED 2026-05-07 — m signed off (commit 956ff10).

Q4 correction: activity is a content selection (sources + filters), not a render shape. Folded into list shape with density: "compact" + actor/time columns. Shape ⊥ source — any source renders in any shape. Render shapes for v1: list / cards / calendar (3, was 4).

All Q1–Q18 + Q19–Q27 locked at recommended values.

PR split (delegated to inventor):

  • A1 — Backend substrate + Custom Views API: migration 056, FilterSpec/RenderSpec types + validators, ViewService 4-source extension, UserViewService CRUD, SystemView registry, all /api/* endpoints, full backend test coverage. No user-visible change; smoke-testable via curl. ~1800 LoC.
  • A2 — Frontend Custom Views UI: generic view shell (/views/{slug}), editor, 3 render-shape components, sidebar Meine Sichten group, i18n, CSS. Builds on A1. ~1600 LoC.

Merge order: A1 → main → A2 → main.

Inventor → coder transition initiated. noether starts on A1.

**LOCKED 2026-05-07** — m signed off (commit 956ff10). **Q4 correction**: activity is a content selection (sources + filters), not a render shape. Folded into `list` shape with `density: "compact"` + actor/time columns. Shape ⊥ source — any source renders in any shape. Render shapes for v1: **list / cards / calendar** (3, was 4). **All Q1–Q18 + Q19–Q27 locked at recommended values.** **PR split** (delegated to inventor): - **A1 — Backend substrate + Custom Views API**: migration 056, FilterSpec/RenderSpec types + validators, ViewService 4-source extension, UserViewService CRUD, SystemView registry, all `/api/*` endpoints, full backend test coverage. No user-visible change; smoke-testable via curl. ~1800 LoC. - **A2 — Frontend Custom Views UI**: generic view shell (`/views/{slug}`), editor, 3 render-shape components, sidebar Meine Sichten group, i18n, CSS. Builds on A1. ~1600 LoC. Merge order: A1 → main → A2 → main. Inventor → coder transition initiated. noether starts on A1.
Author
Collaborator

A1 SHIPPED — backend substrate + Custom Views API on mai/noether/inventor-data-display @ b516201 (pushed). 15 files, 3134 LoC.

What landed:

  • Migration 056 — paliad.user_views (RLS-bounded to caller, UNIQUE(user_id, slug), no is_system flag)
  • FilterSpec + RenderSpec types with full server-side validators (3 shapes: list / cards / calendar; 4 sources: deadline + appointment + project_event + approval_request)
  • SystemView registry — 5 code-resident defs (dashboard / agenda / events / inbox / inbox-mine)
  • ViewService.RunSpec — 4-source substrate; Q17 fail-open with inaccessible_project_ids attribution
  • UserViewService — CRUD + Touch + MostRecent
  • 9 HTTP handlers wiring /api/user-views/* + /api/views/{slug}/run + /api/views/system + /api/views/run

Tests: 32 pure-Go cases pass (filter + render + system view validators). 12 live-DB CRUD cases skip cleanly when TEST_DATABASE_URL unset. go vet ./... clean.

Coexistence: substrate uses the existing visibility predicate that t-139's migration 055 extends — derivation transparently widens results when 055 lands. Approval source delegates to ApprovalService.ListPendingForApprover / ListSubmittedByUser (already extended for derived_peer authority in t-139 Phase 3).

No user-visible change in A1. Smoke-testable via curl after migration 056 applies.

A2 (frontend Custom Views UI) is the next coder shift — generic view shell, editor, render-shape components, sidebar Meine Sichten group. Awaiting m's go on A1 + merge to main.

**A1 SHIPPED** — backend substrate + Custom Views API on `mai/noether/inventor-data-display` @ `b516201` (pushed). 15 files, 3134 LoC. **What landed**: - Migration 056 — `paliad.user_views` (RLS-bounded to caller, UNIQUE(user_id, slug), no is_system flag) - `FilterSpec` + `RenderSpec` types with full server-side validators (3 shapes: list / cards / calendar; 4 sources: deadline + appointment + project_event + approval_request) - `SystemView` registry — 5 code-resident defs (dashboard / agenda / events / inbox / inbox-mine) - `ViewService.RunSpec` — 4-source substrate; Q17 fail-open with `inaccessible_project_ids` attribution - `UserViewService` — CRUD + Touch + MostRecent - 9 HTTP handlers wiring `/api/user-views/*` + `/api/views/{slug}/run` + `/api/views/system` + `/api/views/run` **Tests**: 32 pure-Go cases pass (filter + render + system view validators). 12 live-DB CRUD cases skip cleanly when `TEST_DATABASE_URL` unset. `go vet ./...` clean. **Coexistence**: substrate uses the existing visibility predicate that t-139's migration 055 extends — derivation transparently widens results when 055 lands. Approval source delegates to `ApprovalService.ListPendingForApprover` / `ListSubmittedByUser` (already extended for `derived_peer` authority in t-139 Phase 3). **No user-visible change in A1.** Smoke-testable via curl after migration 056 applies. A2 (frontend Custom Views UI) is the next coder shift — generic view shell, editor, render-shape components, sidebar Meine Sichten group. Awaiting m's go on A1 + merge to main.
Author
Collaborator

A2 SHIPPED — frontend Custom Views UI on mai/noether/inventor-data-display @ fdde9eb (pushed). 16 files, 2113 LoC. Builds clean.

What landed:

  • TSX shells: /views (most-recently-used redirect or onboarding), /views/{slug}, /views/new, /views/{slug}/edit
  • Three render-shape components in client/views/: shape-list.ts (table for density=comfortable, compact one-line stream for density=compact), shape-cards.ts (day-grouped grid), shape-calendar.ts (month grid + day-pills, mobile fallback notice <600px)
  • Generic view shell that resolves a slug → system view first, then saved user view; POSTs /api/views/{slug}/run, dispatches to shape; 3-button shape switcher swaps live render without re-fetching; inaccessible-projects toast (Q17)
  • View editor: name/slug/icon/show_count, 4 source checkboxes, scope mode (all_visible / my_subtree) + personal_only, time horizon (6 fixed options), shape + list-density. Slug regex enforced client-side mirroring server validator. Save → POST/PATCH; delete → simple yes/no (Q25)
  • Sidebar Meine Sichten group between Arbeit and Werkzeuge (Q20). Hydrates from /api/user-views. Always shows + Neue Sicht even when empty. Optional count badge per view (show_count=true opt-in)
  • 91 new i18n keys DE+EN (views.* + nav.group.user_views)
  • ~250 lines of CSS for views shell + list/cards/calendar shapes + sidebar group

Render shapes: list / cards / calendar (3, per Q4 lock-in 2026-05-07). Activity-feed look = shape: list + density: compact + actor/time columns when sources include project_event/approval_requestnot a separate shape.

Build: i18n codegen 1700→1791 keys. IIFE wrap intact on new bundles. go build + vet + test ./... all clean.

Ready for browser smoke against deployed A1 substrate. After A2 merges, design's Phase B (refactor system pages onto the substrate internally) is a separate task.

**A2 SHIPPED** — frontend Custom Views UI on `mai/noether/inventor-data-display` @ `fdde9eb` (pushed). 16 files, 2113 LoC. Builds clean. **What landed:** - TSX shells: `/views` (most-recently-used redirect or onboarding), `/views/{slug}`, `/views/new`, `/views/{slug}/edit` - Three render-shape components in `client/views/`: `shape-list.ts` (table for `density=comfortable`, compact one-line stream for `density=compact`), `shape-cards.ts` (day-grouped grid), `shape-calendar.ts` (month grid + day-pills, mobile fallback notice <600px) - Generic view shell that resolves a slug → system view first, then saved user view; POSTs `/api/views/{slug}/run`, dispatches to shape; 3-button shape switcher swaps live render without re-fetching; inaccessible-projects toast (Q17) - View editor: name/slug/icon/show_count, 4 source checkboxes, scope mode (all_visible / my_subtree) + personal_only, time horizon (6 fixed options), shape + list-density. Slug regex enforced client-side mirroring server validator. Save → POST/PATCH; delete → simple yes/no (Q25) - Sidebar **Meine Sichten** group between Arbeit and Werkzeuge (Q20). Hydrates from `/api/user-views`. Always shows `+ Neue Sicht` even when empty. Optional count badge per view (`show_count=true` opt-in) - 91 new i18n keys DE+EN (`views.*` + `nav.group.user_views`) - ~250 lines of CSS for views shell + list/cards/calendar shapes + sidebar group **Render shapes**: list / cards / **calendar** (3, per Q4 lock-in 2026-05-07). Activity-feed look = `shape: list` + `density: compact` + actor/time columns when sources include `project_event`/`approval_request` — *not* a separate shape. **Build**: i18n codegen 1700→1791 keys. IIFE wrap intact on new bundles. `go build + vet + test ./...` all clean. Ready for browser smoke against deployed A1 substrate. After A2 merges, design's Phase B (refactor system pages onto the substrate internally) is a separate task.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: m/paliad#5
No description provided.