feat: add project export and import functionality

- 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.
This commit is contained in:
2026-03-04 19:53:55 +00:00
parent e352fd530f
commit e973b2ce20
49 changed files with 1492 additions and 3303 deletions
@@ -0,0 +1,92 @@
## 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)