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, then HMR, then an 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.