Files API¶
CRUD over project files. Source: services/api/src/routes/project-files.ts and services/api/src/routes/project-files/.
The filesystem is the source of truth (PROJECTS_ROOT/<projectId>/). The project_files table is a fast-read cache kept in sync by the API.
List¶
Returns a flat list:
[
{ path: "package.json", size: 423, updatedAt: "..." },
{ path: "src/App.tsx", size: 1820, updatedAt: "..." },
...
]
Add ?tree=1 for a nested tree response (for the file explorer).
Read¶
Returns the raw file body with Content-Type guessed from the extension. Binary files are streamed as application/octet-stream.
Create / replace¶
Creates parent directories as needed. The path is always validated to stay within the project root — ../ traversal returns 400 path_traversal.
After write:
- The file is staged in the project's Git repo.
- The
project_filescache is updated. - The WS service rebroadcasts the new content into the collaboration room.
Delete¶
Bulk operations¶
POST /projects/:projectId/files/bulk
{
"operations": [
{ "op": "write", "path": "src/a.ts", "content": "..." },
{ "op": "rename", "from": "src/b.ts", "to": "src/c.ts" },
{ "op": "delete", "path": "old.ts" }
]
}
Atomic per file; the whole batch is committed once.
Search¶
Server-side grep confined to the project root.
Live preview integration¶
When a file is written, the project's Vite dev server picks up the change via filesystem watching → HMR → instant browser update. The frontend iframe listens for HMR events and surfaces build errors in a banner.
Permissions¶
Identical to the parent project: read-only for visibility = public, full access for workspace members.