Owner-based Group Border Visualization Guide

This document is a guide for frontend developers using the SLAAAD API to implement owner-based group border visualization on a Terrain grid.

Overview

The Group Border feature visually groups adjacent plots that share the sameownerId into a single contiguous region.

Core Principles

  1. Compare adjacent plots: Compare the current plot ownerId with theownerId of the top, bottom, left, and right neighbors.
  2. Remove inner borders: If two neighboring plots have the same owner, hide the shared border so they appear as one.
  3. Emphasize outer borders: Only render the outer edges of the grouped region.
  4. Handle special status: Plots with moderationStatus of TAKEN_DOWN are excluded from grouping and can be rendered with dashed borders.

API Response Shape

GET /v1/public/terrains/:id

{
  "success": true,
  "data": {
    "id": 1,
    "name": "Main Terrain",
    "rows": 5,
    "cols": 4,
    "plots": [
      {
        "id": "p-1",
        "positionRow": 1,
        "positionCol": 1,
        "ownerId": "user-a",
        "moderationStatus": "APPROVED",
        "imageUrl": "https://example.com/a.png",
        "targetUrl": "https://example.com"
      }
    ]
  }
}

Implementation Guide

Below is an example of the minimal logic required to compute which borders should be rendered for a given plot.

1) Data Model

type Plot = {
  id: string;
  positionRow: number;
  positionCol: number;
  ownerId: string | null;
  moderationStatus?: "APPROVED" | "PENDING" | "TAKEN_DOWN";
  imageUrl?: string | null;
  targetUrl?: string | null;
};

2) Neighbor Lookup

function getNeighbor(plots: Plot[], row: number, col: number): Plot | undefined {
  return plots.find((p) => p.positionRow === row && p.positionCol === col);
}

3) Border Computation

function computeGroupBorders(plots: Plot[], current: Plot) {
  const top = getNeighbor(plots, current.positionRow - 1, current.positionCol);
  const bottom = getNeighbor(plots, current.positionRow + 1, current.positionCol);
  const left = getNeighbor(plots, current.positionRow, current.positionCol - 1);
  const right = getNeighbor(plots, current.positionRow, current.positionCol + 1);

  const isSameOwner = (a?: Plot, b?: Plot) =>
    !!a &&
    !!b &&
    a.moderationStatus !== "TAKEN_DOWN" &&
    b.moderationStatus !== "TAKEN_DOWN" &&
    a.ownerId !== null &&
    b.ownerId !== null &&
    a.ownerId === b.ownerId;

  return {
    showTop: !isSameOwner(top, current),
    showBottom: !isSameOwner(bottom, current),
    showLeft: !isSameOwner(left, current),
    showRight: !isSameOwner(right, current)
  };
}

4) Rendering Notes

  • Hide borders between plots with the same owner; keep only outer borders to create grouping.
  • Render TAKEN_DOWN plots with dashed borders and exclude them from grouping.
  • For performance, consider building a 2D matrix (rows × cols) for O(1) neighbor access.