services/export/pod-export/README.md
The Export Service provides asynchronous data export functionality for Huly workspaces. It allows workspace owners and administrators to export documents and their associated data in multiple formats (JSON, CSV, Unified).
The Export Service is a standalone microservice that:
server.ts): Express REST API server with authenticationexporter.ts): Main export orchestration logic for file exportsworkspace/): Cross-workspace document export functionality
workspace-exporter.ts: Main orchestrator for workspace-to-workspace exportsdocument-exporter.ts: Individual document export logicattachment-exporter.ts: Attachment and blob migrationrelation-exporter.ts: Forward and inverse relation handlingspace-exporter.ts: Space migration and reusedata-mapper.ts: Data transformation and field mappingconverter.ts): Document conversion and type resolutionjson/json-serializer.ts: JSON format outputcsv/csv-serializer.ts: CSV format outputtypes.ts): Unified document model definitionsClient Request → Authentication → Export Job Created → Async Processing
↓
Notification ← Save to Drive ← ZIP Archive ← Serialize ← Convert Docs
/exportAsyncInitiates an asynchronous export job.
Authentication: Required (Bearer token or Cookie)
Query Parameters:
format (required): Export format - json, csv, or unifiedRequest Body:
{
"_class": "task:class:Issue",
"query": {
"status": "active"
},
"attributesOnly": false
}
Parameters:
_class (required): Ref to the document class to export (e.g., task:class:Issue)query (optional): MongoDB-style query to filter documentsattributesOnly (boolean): If true, excludes attachments and collectionsResponse:
{
"message": "Export started"
}
Authorization:
Process:
/export-to-workspaceExports documents from the current workspace to another workspace. This endpoint copies documents, their attachments, and related data to a target workspace while preserving relationships and remapping IDs.
Authentication: Required (Bearer token or Cookie)
Request Body:
{
"targetWorkspace": "target-workspace-uuid",
"_class": "documents:class:ControlledDocument",
"query": {
"_id": { "$in": ["doc-id-1", "doc-id-2"] }
},
"conflictStrategy": "duplicate",
"includeAttachments": true,
"relations": [
{
"field": "references",
"class": "documents:class:ControlledDocument",
"direction": "forward"
}
],
"fieldMappers": {
"documents:class:ControlledDocument": {
"author": "$currentUser",
"owner": "$currentUser",
"state": "draft",
"code": "$ensureUnique",
"seqNumber": "$ensureUnique"
}
},
"objectId": "doc-id-1",
"objectSpace": "space-id"
}
Parameters:
targetWorkspace (required): UUID of the target workspace to export to_class (required): Ref to the document class to export (e.g., documents:class:ControlledDocument)query (optional): MongoDB-style query to filter documents. If not provided and specific documents are selected, uses _id: { $in: [...] }conflictStrategy (optional): How to handle existing documents in target workspace
"duplicate" (default): Create new documents with new IDs"skip": Skip documents that already exist (based on matching criteria)includeAttachments (optional, default: true): Whether to copy attachment blob datarelations (optional): Array of relation definitions to export
field: Field name containing the relationclass: Class of related documentsdirection: "forward" (dependencies) or "inverse" (references)fieldMappers (optional): Field value overrides per document class. Supports special values:
$currentUser: Replaced with current account's employee ID
{ "author": "$currentUser" } sets author to current user$ensureUnique: Ensures the field value is unique by checking the database and modifying if needed
{ "code": "$ensureUnique", "seqNumber": "$ensureUnique" } ensures unique code and seqNumberobjectId (optional): ID of the primary document for notification contextobjectSpace (optional): Space of the primary document for notification contextResponse:
{
"message": "Export started"
}
Authorization:
Process:
Example Use Cases:
Error Handling:
{spaceName}/{className}/{docId}.json{spaceName}/{className}.csv{spaceName}/{className}/{docId}.jsonThe converter transforms Huly documents into a unified format that:
RefTo): Resolved to readable format (e.g., person names)Documents are analyzed and fields are categorized:
markdownFields: Fields containing markdown contentcollabFields: Fields referencing collaborative documentsrefFields: Fields containing document referencescollectionFields: Fields containing nested collectionsattachments: Associated attachment metadata{
"_class": "task:class:Issue",
"_id": "issue-123",
"space": "project-1",
"data": {
"title": "Fix bug",
"description": "...",
"assignee": "John Doe",
"status": "In Progress"
},
"markdownFields": ["description"],
"refFields": ["assignee", "status"],
"collectionFields": ["comments"],
"attachments": [
{
"id": "attach-1",
"name": "screenshot.png",
"size": 45678,
"contentType": "image/png"
}
]
}
Required:
PORT: Service port (default: 4006)SECRET: JWT token secretACCOUNTS_URL: URL to accounts serviceSERVICE_ID: Service identifierStorage configuration (via storageConfigFromEnv):
STORAGE_PROVIDER: Storage backend (minio, s3, etc.)STORAGE_ENDPOINT: Storage endpoint URLSTORAGE_ACCESS_KEY: Storage access credentialsSTORAGE_SECRET_KEY: Storage secret credentialsdocker build -t hardcoreeng/export .
docker run -p 4006:4006 \
-e SECRET=your-secret \
-e ACCOUNTS_URL=http://accounts:3000 \
-e SERVICE_ID=export-service \
-e STORAGE_PROVIDER=minio \
-e STORAGE_ENDPOINT=http://minio:9000 \
hardcoreeng/export
rush build --to @hcengineering/pod-export
cd services/export/pod-export
ACCOUNTS_URL="http://127.0.0.1:3000" SECRET="secret" DB_URL=postgresql://[email protected]:26257/defaultdb?sslmode=disable SERVICE_ID="export" STORAGE_CONFIG="datalake|http://huly.local:4030" rushx run-local
rushx test
export-{workspace}-{class}-{format}-{timestamp}.zip
├── Space Name 1/
│ ├── ClassName/
│ │ ├── doc-1.json
│ │ ├── doc-2.json
│ │ └── attachments/
│ │ ├── file1.pdf
│ │ └── file2.png
├── Space Name 2/
│ └── ClassName/
│ └── docs.csv
Users receive in-app notifications:
Success:
Export completed successfully
[Link to download from Drive]
Failure:
Export failed: {error message}
401 Unauthorized
400 Missing required parameters
_class is providedformat query parameter403 Forbidden
404 Target workspace not found
Export fails silently
docker logs -f export-service
Eclipse Public License 2.0
For issues and questions, see the main Huly Platform repository.