# Tablo Details No-Code Overview Builder (V1) - Design

Date: 2026-03-14  
Status: Approved in brainstorming session (user confirmations captured in chat)

## 1) Problem and Outcome

`apps/main/src/pages/tablo-details.tsx` currently renders the `Aperçu` layout in a fixed order.  
Goal: make the overview feel "no-code" by letting editors drag-and-drop existing overview blocks to reorganize the page, directly inside xtablo.

V1 outcome:
- Edit mode lives inside `tablo-details` (no separate builder page).
- Drag-and-drop reorders existing blocks only.
- Reordering is limited to fixed zones (left zone reorders internally, right zone reorders internally).
- Changes auto-save on each drop.
- Shared layout: everyone in the tablo sees the same saved order.
- Reset to default layout is available.

## 2) Scope

### In scope (V1)
- `Aperçu` section only.
- Existing overview blocks only:
  - `description`
  - `myTasks`
  - `files`
  - `info`
- Auto-save after drop.
- Reset action to restore default order.
- Graceful fallback to default order if saved config is missing/invalid.

### Out of scope (V1)
- Adding brand-new block types.
- Resizing blocks.
- Cross-zone moves (left -> right or right -> left).
- Layout customization for non-overview tabs.
- Version history / undo timeline.

## 3) Product Decisions Captured

- Layout storage: per `tablo`.
- Editing access: tablo admins + organization members (aligned with existing org-wide tablo access model).
- Entry point: in-page `Edit layout` toggle in `tablo-details`.
- Reorder area: `Aperçu` only.
- Visibility of result: shared for all tablo members.
- Drag model: fixed zones.
- Persistence mode: auto-save + `Reset default`.

## 4) Architecture Overview

Recommended architecture for V1: store layout JSON on `public.tablos` as `layout_overview_v1`.

Why:
- Smallest change that fully supports shared per-tablo layout.
- Uses existing update route (`PATCH /api/v1/tablos/update`) and query invalidation flow.
- Keeps V1 fast while leaving room to migrate later to a dedicated layout table if needed.

### Units and Boundaries

1. **Layout Schema Unit**
   - Owns valid overview layout shape + sanitization.
   - Input: unknown JSON.
   - Output: safe `OverviewLayoutV1` + fallback behavior.

2. **Overview Renderer Unit**
   - Owns data-driven rendering order of overview blocks.
   - Input: `OverviewLayoutV1`.
   - Output: JSX for left/right zones in correct order.

3. **Edit Interaction Unit**
   - Owns edit mode UX and drag/drop reorder events.
   - Input: current zone arrays + drop event.
   - Output: reordered arrays + save trigger.

4. **Persistence Unit**
   - Owns optimistic save, rollback on failure, and reset flow.
   - Input: reordered layout.
   - Output: mutation call + success/failure UI feedback.

Each unit is testable independently and can evolve without rewriting the others.

## 5) Data Model and Contracts

## 5.1 Database

Add column:
- `public.tablos.layout_overview_v1 jsonb null`

No default required in DB; default layout is resolved in app if null.

## 5.2 Layout JSON shape

```json
{
  "version": 1,
  "leftZone": ["description", "myTasks"],
  "rightZone": ["files", "info"],
  "updatedAt": "2026-03-14T12:00:00.000Z",
  "updatedBy": "user_id"
}
```

Notes:
- `version` is mandatory for forward compatibility.
- Allowed IDs in V1:
  - Left zone: `description`, `myTasks`
  - Right zone: `files`, `info`
- Unknown IDs are ignored by sanitizer.

## 5.3 Type-level model (frontend)

- `OverviewBlockId = "description" | "myTasks" | "files" | "info"`
- `OverviewLayoutV1 = { version: 1; leftZone: OverviewBlockId[]; rightZone: OverviewBlockId[]; updatedAt?: string; updatedBy?: string }`

## 5.4 API contract usage

Reuse existing `PATCH /api/v1/tablos/update` payload:
- `{ id: tabloId, layout_overview_v1: <OverviewLayoutV1> }`

No new endpoint in V1.

## 6) Frontend Design (`apps/main/src/pages/tablo-details.tsx`)

## 6.1 Render strategy

Replace hardcoded block order with configuration-driven rendering:

- Define block registry:
  - key: block id
  - value: render function/component for that block
- Render left and right zones by iterating `layout.leftZone` and `layout.rightZone`.

## 6.2 Edit mode UX

- Add `Edit layout` button visible only to allowed editors.
- Toggle to `Done editing` while active.
- In edit mode:
  - Show drag handles on block cards.
  - Enable draggable containers per zone.
  - Show subtle "saved" status after successful drop save.

## 6.3 Drag-and-drop behavior

- HTML5 DnD approach (consistent with current kanban style in codebase).
- Reorder within same zone only.
- Cross-zone drop is blocked in V1.
- On valid drop:
  1. Compute next zone order.
  2. Optimistically update local UI.
  3. Persist via `useUpdateTablo`.
  4. On failure, revert to last persisted layout snapshot.

## 6.4 Reset flow

- `Reset default` sets:
  - `leftZone = ["description", "myTasks"]`
  - `rightZone = ["files", "info"]`
- Writes reset layout via same mutation path.

## 7) Permissions and Access

Current backend `updateTablo` checks `tablo_access.is_admin = true`.  
Organization migration sync already grants org members admin tablo access.

Therefore V1 permission model aligns with existing backend rules:
- Editors: users with current update permission on tablo.
- Viewers: everyone with read access sees saved layout.

No special permission endpoint needed.

## 8) Error Handling and Resilience

- Missing/null layout in DB -> use default layout.
- Invalid/corrupted JSON -> sanitize; if invalid after sanitize, fallback default.
- Save failure:
  - Revert optimistic state.
  - Toast: layout save failed.
  - Keep edit mode active.
- Partial/unknown block IDs:
  - Filter unknown IDs.
  - Reinsert required missing IDs into default zone positions.

## 9) Testing Strategy

## 9.1 Unit tests

- `sanitizeOverviewLayoutV1`:
  - null input -> default
  - unknown IDs removed
  - missing required IDs recovered
  - duplicates deduplicated
- Reorder helper:
  - same-zone reorder correctness
  - no-op behavior on invalid target indices
  - cross-zone rejection

## 9.2 Page/component tests

- `Aperçu` renders default order when no saved layout.
- Saved layout order is respected.
- Drop action calls mutation with `layout_overview_v1`.
- Mutation failure rolls back UI order.
- Reset action writes canonical default layout.

## 9.3 Integration confidence checks

- Existing tabs (`tasks`, `files`, `discussion`, `events`, `etapes`, `roadmap`) render unchanged.
- Non-editor users do not see edit controls.

## 10) Rollout Plan

1. Add DB migration for `layout_overview_v1`.
2. Regenerate shared DB types.
3. Implement frontend schema + renderer + edit interactions.
4. Add tests.
5. Ship behind normal deploy (no feature flag required for V1 scope).

## 11) Future Extensions (Post-V1)

- Hide/show blocks.
- Cross-zone moves.
- Block sizing and grid spans.
- New widget catalog (metrics, activity feed, shortcuts).
- Dedicated `tablo_layouts` table for multi-surface layouts and version history.

