e973b2ce20
- Implemented `pcli project export` command to export project hierarchy as JSON. - Added `pcli project import` command to import project data from JSON. - Created user client to fetch user details for comment attribution. - Introduced new data structures for export and import processes. - Ensured name-based references in exports and handled conflicts during imports. - Added versioning and progress reporting for import operations. - Updated documentation and specifications for new features.
93 lines
4.2 KiB
Markdown
93 lines
4.2 KiB
Markdown
## Why
|
|
|
|
There's no way to backup, migrate, or clone project data between Planka instances using pcli. Users need to export a project (or specific board) to a portable file and import it elsewhere — useful for backups, instance migration, and sharing project templates.
|
|
|
|
## What Changes
|
|
|
|
- Add `pcli project export` command: exports a project (optionally filtered to a specific board) as a self-contained JSON file to stdout
|
|
- Add `pcli project import` command: reads a JSON export file and creates the project/board(s) on the target instance
|
|
- Export uses **names** (not IDs) as the portable identity — IDs are Planka-instance-specific and regenerated on import
|
|
- Export includes the full hierarchy: project → boards → lists → labels → cards → card-labels → task lists → tasks → comments
|
|
- Import uses **fail-if-exists** strategy: if the project+board name combination already exists on the target, import stops with an error. Project existing alone is fine (board gets added to it).
|
|
- User-specific references (cardMemberships, creatorUserId) are **excluded** from export — these are instance-specific and not portable
|
|
- Comments are exported with **text attribution**: each comment is prefixed with `(Original comment by <username>)` so authorship is preserved textually even though the userId is not portable. This requires a one-time user list fetch during export to resolve userId→name.
|
|
|
|
### Export format
|
|
|
|
Single JSON object to stdout. Structure:
|
|
|
|
```json
|
|
{
|
|
"version": 1,
|
|
"exportedAt": "2026-03-04T...",
|
|
"project": {
|
|
"name": "...",
|
|
"description": "...",
|
|
"boards": [
|
|
{
|
|
"name": "...",
|
|
"position": 1,
|
|
"lists": [...],
|
|
"labels": [...],
|
|
"cards": [
|
|
{
|
|
"name": "...",
|
|
"listName": "...",
|
|
"labelNames": ["..."],
|
|
"description": "...",
|
|
"taskLists": [
|
|
{
|
|
"name": "...",
|
|
"tasks": [{ "name": "...", "isCompleted": false }]
|
|
}
|
|
],
|
|
"comments": [{ "text": "(Original comment by jsmith)\nActual comment text here" }]
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
Key design choices:
|
|
- **Name-based references**: cards reference `listName` and `labelNames` instead of IDs
|
|
- **Nested hierarchy**: no ID cross-references to resolve — everything is inline
|
|
- **Version field**: allows future format changes
|
|
- Positions preserved to maintain ordering
|
|
- User fields stripped (not portable) except for textual attribution on comments
|
|
- Comments prefixed with `(Original comment by <username>)` — requires fetching user list during export to resolve userIds to names. If a userId can't be resolved, falls back to `(Original comment by unknown user)`
|
|
|
|
### Import behavior
|
|
|
|
1. Look up project by name — create if it doesn't exist
|
|
2. For each board in the export: check if project already has a board with that name → **fail with error** if so
|
|
3. Create board, then lists, labels, cards (mapping listName→list ID, labelNames→label IDs), task lists, tasks, comments — all with fresh Planka IDs
|
|
4. Ordering maintained via position fields from the export
|
|
|
|
### CLI interface
|
|
|
|
```
|
|
pcli project export <project-id-or-name> [--board <name-or-id>] > backup.json
|
|
pcli project import < backup.json
|
|
# or
|
|
pcli project import --file backup.json
|
|
```
|
|
|
|
## Capabilities
|
|
|
|
### New Capabilities
|
|
- `project-export`: Export project hierarchy to portable JSON (project → boards → lists → labels → cards → task lists → tasks → comments)
|
|
- `project-import`: Import project hierarchy from JSON export file, creating all resources with new IDs
|
|
|
|
### Modified Capabilities
|
|
_(none — these are new commands added to the existing project resource)_
|
|
|
|
## Impact
|
|
|
|
- **New files**: `client/export.go`, `client/import.go`, `client/users.go`, `cmd/export.go`, `cmd/import.go`
|
|
- **Model changes**: new export-specific types in `model/types.go` (portable structs without IDs/user references), new User type
|
|
- **API usage**: export requires multiple API calls (user list for name resolution, board GET for bulk data, then per-card fetches for comments/tasks) — could be slow for large projects
|
|
- **No breaking changes**: purely additive new subcommands
|
|
- **Dependencies**: none new (standard library JSON encoding)
|