Directories

Directories are the hierarchical organization unit for files within a workspace. They are DB-only — R2 storage is flat and keyed by file id.

Directories are the hierarchical organization unit for files within a workspace. They are pure metadata — R2 storage is flat and keyed by file id , so a directory never corresponds to any R2 prefix. Moving a file between directories is a single SQL update; nothing moves in object storage.

Root directories

Every workspace has a synthetic root directory created automatically on workspace.created. User-created directories descend from the root. The root directory is flagged with isRoot: true and cannot be deleted or moved. Files that don't specify a destination directory on upload land in the root.

Shape

A directory row carries:

  • id — prefixed dir_*
  • workspaceId
  • parentId — the containing directory, or null for the root
  • name — display name
  • slug — URL-safe identifier. Defaults to slugify(name). Unique among siblings (same parentId).
  • slugPath — denormalized full path from the workspace root (e.g. /photos/trips/), always ending in /. Recomputed on rename or reparent.
  • isRoottrue for the workspace root

Operations

  • GET /api/directories — list directories, filter by workspace_id or parent_id (direct children)
  • GET /api/directories/:id — retrieve a single directory
  • POST /api/directories — create a new directory under parentId (defaults to the workspace root)
  • PATCH /api/directories/:id — rename or move (reparent)
  • DELETE /api/directories/:id — delete a directory. The root cannot be deleted.

All operations are available via the CLI ( aeontel directory list/get/create/update/delete), the MCP server, and the @aeontel/react hooks.

Events

  • directory.created
  • directory.updated — rename or reparent
  • directory.deleted