Recommended allocations

Retrieve and review AI-generated allocations at the people, team, or zone level for each day, and optionally adjust them manually.

Prerequisites

  • Completed Start forecasting and Optimise your first location (Evolve)

  • Node.js v18+ and npm v9+

  • A valid gospace API key in your .env file

  • A location_id with at least one successful evolution

Allocations can be zone/neighbourhood level, team level, or people level. You can fetch recommendations with getAllocations() and optionally override them with createAllocations(), updateAllocations(), and deleteAllocations().


Allocation record shape

Depending on allocation type, fields will be populated as follows:

type Allocation = {
  starts_at: string;         // ISO timestamp (interval start)
  ends_at: string;           // ISO timestamp (interval end)
  location_id: string;
  location_name: string;
  layer_id: string;          // floor/layer allocated to
  layer_name: string;
  spaces: string[];          // array of space IDs allocated
  type: string;              // "SPACE" or "ROOM" (type of allocation)
  people_id?: string;        // present for people allocations
  team_id?: string;          // present for team allocations (or people with team assignment)
  room_id?: string;          // present only on room allocations
};

Create get-allocations.ts:

import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.system.getAllocations({
    location_id: "68824ca5369c856b7c670510",
    starts_at: "2025-07-01T00:00:00Z",
    ends_at:   "2025-07-31T23:59:59Z",
    // Optional filters:
    // team_id: "68518a549c86c18f01ee84a3",
    // people_id: "68518a559c86c18f01ee84e4",
    // layer_id: "layer_123",
    // type: "ROOM" | "SPACE",
    skip: 0,
    limit: 250,
  });

  const allocations = res.data.allocations as Allocation[];
  console.log(JSON.stringify(allocations.slice(0, 5), null, 2));
}

main().catch((err) => {
  console.error("getAllocations failed:", err);
  process.exit(1);
});

2) Summarise allocations per day

type DaySummary = { date: string; desks: number; rooms: number; total: number };

function dayKey(a: Allocation) {
  return (a.starts_at ?? "").slice(0, 10);
}

export function summarizeByDay(rows: Allocation[]): DaySummary[] {
  const map = new Map<string, DaySummary>();
  for (const r of rows) {
    const key = dayKey(r);
    if (!map.has(key)) map.set(key, { date: key, desks: 0, rooms: 0, total: 0 });
    const entry = map.get(key)!;
    if (r.type === "SPACE") entry.desks += r.spaces.length;
    if (r.type === "ROOM") entry.rooms += (r.spaces?.length || 1);
    entry.total = entry.desks + entry.rooms;
  }
  return Array.from(map.values()).sort((a, b) => a.date.localeCompare(b.date));
}

3) Inspect by level: zone/neighbourhood, team, people

// Zone/neighbourhood-level: no people_id, no team_id
const zoneLevel = allocations.filter(a => !a.people_id && !a.team_id);

// Team-level
const teamLevel = allocations.filter(a => !!a.team_id && !a.people_id);

// People-level
const peopleLevel = allocations.filter(a => !!a.people_id);

You can also filter by layer_id to analyse a specific floor, or by type to focus on ROOM vs SPACE allocations.


4) Make manual adjustments (create/update/delete)

You might want to tweak AI recommendations—for example, swap spaces between two teams or assign a specific person to a different desk on a given day.

A) Create manual allocations

// create-manual-allocation.ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.system.createAllocations({
    allocations: [
      {
        starts_at: "2025-07-15T00:00:00Z",
        ends_at:   "2025-07-15T23:59:59Z",
        location_id: "68824ca5369c856b7c670510",
        location_name: "London HQ",     // if supported/returned
        layer_id: "layer_123",
        layer_name: "Level 1",
        type: "SPACE",
        team_id: "68518a549c86c18f01ee84a3",
        spaces: ["space_A1", "space_A2"],
      },
    ],
  });

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((e) => {
  console.error("createAllocations failed:", e);
  process.exit(1);
});

B) Update allocations (e.g., swap spaces)

// swap-spaces.ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

// Helper: get the first matching allocation for a team and day
async function getTeamAllocationForDay(
  gospace: GospaceAI,
  location_id: string,
  team_id: string,
  date: string
) {
  const res = await gospace.system.getAllocations({
    location_id,
    team_id,
    starts_at: `${date}T00:00:00Z`,
    ends_at:   `${date}T23:59:59Z`,
    limit: 1,
  });
  return (res.data.allocations ?? [])[0] as Allocation | undefined;
}

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);
  const location_id = "68824ca5369c856b7c670510";
  const date = "2025-07-15";

  const teamA = "team_A";
  const teamB = "team_B";

  const allocA = await getTeamAllocationForDay(gospace, location_id, teamA, date);
  const allocB = await getTeamAllocationForDay(gospace, location_id, teamB, date);

  if (!allocA || !allocB) throw new Error("Missing allocations for one or both teams");

  // Swap a single space between teams (example)
  const [spaceFromA] = allocA.spaces;
  const [spaceFromB] = allocB.spaces;

  const updatedA = { ...allocA, spaces: [spaceFromB, ...allocA.spaces.slice(1)] };
  const updatedB = { ...allocB, spaces: [spaceFromA, ...allocB.spaces.slice(1)] };

  // Your API may require allocation IDs; include them if provided by getAllocations().
  const res = await gospace.system.updateAllocations({
    allocations: [updatedA, updatedB],
  });

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((e) => {
  console.error("updateAllocations failed:", e);
  process.exit(1);
});

C) Delete allocations

// delete-allocations.ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  // First, fetch the allocations you intend to remove
  const res = await gospace.system.getAllocations({
    location_id: "68824ca5369c856b7c670510",
    starts_at: "2025-07-15T00:00:00Z",
    ends_at:   "2025-07-15T23:59:59Z",
    team_id: "68518a549c86c18f01ee84a3",
    limit: 50,
  });

  // Assume each allocation has an `_id` or `allocation_id` field
  const toDelete = (res.data.allocations ?? [])
    .map((a: any) => ({ allocation_id: a._id || a.allocation_id }))
    .filter(x => !!x.allocation_id);

  if (toDelete.length === 0) {
    console.log("Nothing to delete.");
    return;
  }

  const del = await gospace.system.deleteAllocations({ allocations: toDelete });
  console.log(JSON.stringify(del.data, null, 2));
}

main().catch((e) => {
  console.error("deleteAllocations failed:", e);
  process.exit(1);
});

5) Common patterns

  • Paginate long ranges with skip/limit.

  • Filter by team_id, people_id, layer_id, type to narrow scope.

  • Respect intervals — allocations are effective from starts_at to ends_at.

  • Manual overrides — use create/update/delete to pin critical changes (e.g., VIP desks, event days).

  • Audit your swaps — log original vs. updated spaces arrays to keep a trail of changes.

Last updated

Was this helpful?