Getting Started with Files & Drive
Create your first shared space, configure a storage backend (S3, R2, GCS, Azure), enable AI auto-tagging, configure WebDAV, set up WOPI for browser-based Office viewing, and configure retention policies.
Create Your First Shared Space
Navigate: Files & Drive → Spaces → Create Space
Space configuration:
```typescript // Space = shared drive (like Google Drive team drive) { name: "Marketing Team", description: "Shared files for the marketing department", storageQuotaBytes: 10737418240, // 10GB limit storageBackend: "r2", // or "s3", "gcs", "azure", "local" isPublic: false, // Private to members members: [ { userId: "usr_abc", role: "admin" }, // Can manage members + settings { userId: "usr_xyz", role: "editor" }, // Can upload/edit/delete ], }
// Storage backend config (in Files Settings): { backend: "r2", bucket: "aeion-files", accountId: "your-cloudflare-account-id", accessKeyId: "...", secretAccessKey: "...", // Encrypted at rest } ```
Permission roles:
- Admin: Manage members, settings, storage quota, retention policies
- Editor: Upload, edit, delete, share files
- Viewer: Read-only access, can download
Space hierarchy:
Marketing Team (space)
├── Campaigns (folder)
│ ├── Q1-2026 (folder)
│ │ ├── campaign-brief.pdf
│ │ └── budget.xlsx
│ └── assets (folder)
├── Brand Guidelines (folder)
│ └── logo-pack.zip
└── Reports (folder)
Configure Storage Backend
Navigate: Files & Drive → Settings → Storage
Local disk (development/default):
```bash # No configuration needed — files stored in /var/aeion/files # Works out of the box for development
LOCAL_STORAGE_PATH=/var/aeion/files ```
Amazon S3:
bash
S3_BUCKET=my-files
S3_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
# Optional: custom endpoint for S3-compatible (MinIO)
S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
Cloudflare R2:
bash
R2_BUCKET=my-files
R2_ACCOUNT_ID=your-cloudflare-account-id
R2_ACCESS_KEY_ID=...
R2_SECRET_ACCESS_KEY=...
# R2 uses S3-compatible API — same client as S3
R2_ENDPOINT=https://xxx.r2.cloudflarestorage.com
Google Cloud Storage:
bash
GCS_BUCKET=my-files
GCS_PROJECT_ID=my-project
GCS_KEY_FILE=/path/to/service-account.json
# Or use ADC: gcloud auth application-default login
Azure Blob:
bash
AZURE_STORAGE_ACCOUNT=myfiles
AZURE_STORAGE_KEY=...
AZURE_CONTAINER=aeion-files
AZURE_STORAGE_ENDPOINT=https://myfiles.blob.core.windows.net
Each space picks one storage backend at creation time. Multi-backend hot/cold tiering with age-based routing rules isn't available yet — if you need it, talk to your account team.
Upload and Organize Files
Navigate: Files & Drive → [Space] → Upload
Simple upload (small files < 100MB):
bash
# Via API
curl -X POST https://api.your-domain.com/files/nodes \
-H "Authorization: Bearer <token>" \
-F "spaceId=spa_abc" \
-F "parentId=nod_xyz" \
-F "file=@report.pdf"
Chunked upload (large files, resumable):
```typescript // Step 1: Initiate const { uploadId, chunkSize, totalChunks } = await initiateUpload({ spaceId: "spa_abc", parentId: "nod_xyz", filename: "video.mp4", size: 524288000, // 500MB mimeType: "video/mp4", });
// Step 2: Upload each chunk
const chunkSize = 5242880; // 5MB
for (let i = 0; i < totalChunks; i++) {
const chunk = fileSlice(i chunkSize, (i + 1) chunkSize);
await uploadChunk(uploadId, i, chunk, {
onProgress: ({ loaded, total }) => console.log(${loaded}/${total}),
});
}
// Step 3: Complete const file = await completeUpload(uploadId); // → Assembles chunks → verifies SHA-256 → stores → version created ```
AI auto-tagging (automatic on upload):
```typescript // Default: AI processing runs on every upload // Disable for specific files: { skipAIProcessing: true, // Privacy-sensitive or large binary files }
// AI results appear in file metadata: { metadata: { aiTags: ["invoice", "Q1-2026", "Acme Corp"], summary: "Invoice for consulting services, $15,000", extractedText: "...", // plus a semantic embedding used for concept-based search } } ```
WebDAV — Configuration Today, Full Mounting Coming Soon
Navigate: Files & Drive → Settings → WebDAV
The WebDAV panel lets you enable the feature for a space and see its connection status. Full protocol serving — the part that lets Windows/macOS/Linux actually mount a space as a network drive (GET/PUT/MKCOL/DELETE/MOVE/COPY/PROPFIND/LOCK) — isn't wired up in this release, so drive-letter mounting doesn't work yet even with the toggle on.
If your workflow needs file access today, use the browser UI or the upload/download API from Step 3. Ask your account team for the WebDAV rollout timeline if drive mounting is a requirement for your team.
Set Up WOPI (Browser-Based Office Editing)
Navigate: Files & Drive → Settings → WOPI
Connect Collabora Online:
```bash # Option 1: Self-hosted Collabora COLLABORA_URL=https://collabora.your-domain.com COLLABORA_SECRET=your-secret
# Option 2: ONLYOFFICE ONLYOFFICE_URL=https://onlyoffice.your-domain.com ONLYOFFICE_SECRET=your-secret ```
WOPI flow:
```typescript // 1. User opens a .docx file in Files & Drive // 2. Clicks "Edit in Browser" (WOPI button) // 3. Files module creates WOPI session: { fileId: "nod_abc", wopiServerUrl: "https://collabora.your-domain.com", accessToken: "wopi_token_xxx", expiresAt: "2026-05-11T11:00:00Z", }
// 4. Browser loads Collabora/ONLYOFFICE iframe with access token // 5. WOPI server fetches file content from Files module // 6. User edits in browser // 7. WOPI server saves back to Files module on close
// Supported formats: .docx, .xlsx, .pptx ```
Current status: file locking (open-for-edit / release) is fully wired. Saving edits back to Aeion Files on close isn't persisted yet in this release — treat browser-based editing as view/annotate for now, and keep using upload/download for anything you need saved.
Configure Retention Policies
Navigate: Files & Drive → [Space] → Settings → Retention
Retention policy example:
```typescript // Policy for a compliance-required space { name: "Financial Records Retention", rules: [ { retentionDays: 2555, action: "archive" }, // 7 years (SOX compliance) { retentionDays: 365, action: "delete" }, // auto-cleanup after 1 year ], }
// Policy for a project space (shorter retention) { name: "Project Files", rules: [ { retentionDays: 90, action: "delete" }, ], } ```
Current enforcement: per-rule enforcement of the policy above isn't wired up yet. Today, a separate daily cron prunes old versions using a simple global version-count cap, not your configured per-rule policy — treat the Retention tab as your policy of record for audits, but verify actual cleanup behavior directly until per-rule enforcement ships.
Version labels: Mark versions as "draft", "final", "reviewed" for manual protection. Labeled versions are exempt from auto-cleanup unless explicitly included.
Search — Full-Text and Semantic
Navigate: Files & Drive → Search
Full-text search:
```bash # Search file names and content POST /api/files/search?q=invoice+Acme # → Matches: "invoice" AND "Acme" in filenames, extracted text, tags
# Filters ?q=invoice&mimeType=application/pdf&spaceId=spa_abc&createdAfter=2026-01-01
# Full query syntax ?q=(invoice OR contract) AND tag:financial AND size:>1MB ```
Semantic search (AI-powered):
typescript
// "Find files similar to this contract"
const similar = await aiService.findSimilarFiles({
fileId: "nod_abc",
limit: 10,
});
// → Ranked by embedding similarity, not just keyword match
OCR for scanned documents: Images and PDFs without text layers go through OCR automatically. Scanned contracts, receipts, and documents become searchable.
Complete Setup — Marketing Team Space Example
// 1. Create spaceconst space = await createSpace({ name: "Marketing Team", storageBackend: "r2", members: [ { userId: "usr_marketing_admin", role: "admin" }, { userId: "usr_designer", role: "editor" }, { userId: "usr_copywriter", role: "editor" }, ],});// → space.id: "spa_01HQ..."
// 2. Create folder structureawait createFolder(space.id, { name: "Campaigns" });await createFolder(space.id, { name: "Brand Guidelines" });await createFolder(space.id, { name: "Reports" });
// 3. Upload files (AI auto-tags run in background)const campaignBrief = await uploadFile(space.id, { file: fs.readFileSync("Q1-campaign.pdf"), name: "Q1-campaign.pdf", parentId: "folders/campaigns",});// → { id: "nod_abc", metadata: { aiTags: ["campaign", "Q1-2026", "marketing"] } }
// 4. Share with external clientconst shareLink = await createShareLink({ nodeId: "nod_abc", shareType: "link", permissions: "viewer", expiresAt: "2026-06-01",});// → shareLink: "https://your-domain.com/files/shared/abc123"
// 5. Set retention policyawait createRetentionPolicy(space.id, { name: "Campaign Files", rules: [{ retentionDays: 730, action: "archive" }],});