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.
86 lines
4.6 KiB
Markdown
86 lines
4.6 KiB
Markdown
# project-export Spec
|
|
|
|
## Purpose
|
|
|
|
Enable users to export a complete Planka project hierarchy (boards, lists, cards, labels, tasks, comments) to a portable JSON format for backup, migration, or documentation purposes.
|
|
|
|
## Requirements
|
|
|
|
### Requirement: Export project hierarchy to JSON
|
|
The system SHALL export a complete project hierarchy as a JSON object to stdout. The export SHALL include: project metadata, boards, lists, labels, cards (with list and label name references), task lists, tasks, and comments.
|
|
|
|
#### Scenario: Export entire project
|
|
- **WHEN** user runs `pcli project export <project-id-or-name>`
|
|
- **THEN** the system outputs a JSON object to stdout containing the project and all its boards with their full hierarchy
|
|
|
|
#### Scenario: Export with board filter
|
|
- **WHEN** user runs `pcli project export <project-id-or-name> --board <board-name-or-id>`
|
|
- **THEN** the system outputs a JSON object containing only the specified board (and its full hierarchy) under the project
|
|
|
|
#### Scenario: Board filter does not match
|
|
- **WHEN** user runs `pcli project export <project> --board <nonexistent>`
|
|
- **THEN** the system exits with an error indicating the board was not found
|
|
|
|
### Requirement: Export format uses version envelope
|
|
The export JSON SHALL contain a `version` field (integer, currently `1`), an `exportedAt` timestamp (ISO 8601), and a `project` object.
|
|
|
|
#### Scenario: Export envelope structure
|
|
- **WHEN** an export is generated
|
|
- **THEN** the root JSON object contains exactly `version`, `exportedAt`, and `project` keys
|
|
- **THEN** `version` is `1`
|
|
- **THEN** `exportedAt` is a valid ISO 8601 timestamp
|
|
|
|
### Requirement: Export uses name-based references
|
|
The export SHALL use names instead of IDs for all cross-references. Cards SHALL reference their list by `listName` and their labels by `labelNames` (array of label name strings). No Planka IDs SHALL appear in the export.
|
|
|
|
#### Scenario: Card references list by name
|
|
- **WHEN** a card belongs to a list named "In Progress"
|
|
- **THEN** the exported card has `"listName": "In Progress"` instead of a list ID
|
|
|
|
#### Scenario: Card references labels by name
|
|
- **WHEN** a card has labels "Bug" and "Urgent"
|
|
- **THEN** the exported card has `"labelNames": ["Bug", "Urgent"]`
|
|
|
|
### Requirement: Export preserves ordering
|
|
The export SHALL include `position` fields for boards, lists, labels, and cards to maintain their display ordering on import.
|
|
|
|
#### Scenario: List ordering preserved
|
|
- **WHEN** a board has lists "Todo" (position 1), "Doing" (position 2), "Done" (position 3)
|
|
- **THEN** the exported lists include their position values
|
|
|
|
### Requirement: Export includes comment attribution
|
|
Each exported comment SHALL have its text prefixed with `(Original comment by <username>)\n` where `<username>` is resolved from the comment's userId. If the userId cannot be resolved, the prefix SHALL use `unknown user`.
|
|
|
|
#### Scenario: Comment with known author
|
|
- **WHEN** a comment was authored by user "jsmith"
|
|
- **THEN** the exported comment text starts with `(Original comment by jsmith)\n`
|
|
|
|
#### Scenario: Comment with unresolvable author
|
|
- **WHEN** a comment's userId does not match any known user
|
|
- **THEN** the exported comment text starts with `(Original comment by unknown user)\n`
|
|
|
|
### Requirement: Export excludes user-specific data
|
|
The export SHALL NOT include cardMemberships, creatorUserId, or userId fields. Only textual comment attribution (as a text prefix) SHALL preserve user information.
|
|
|
|
#### Scenario: Card memberships excluded
|
|
- **WHEN** a card has members assigned
|
|
- **THEN** the exported card does not contain membership data
|
|
|
|
### Requirement: Export includes task lists and tasks
|
|
The export SHALL include task lists and their tasks for each card. Each task list SHALL contain its tasks inline. Tasks SHALL include `name` and `isCompleted` fields.
|
|
|
|
#### Scenario: Card with task lists
|
|
- **WHEN** a card has a task list "Checklist" with tasks "Item 1" (complete) and "Item 2" (incomplete)
|
|
- **THEN** the exported card includes the task list with both tasks and their completion status
|
|
|
|
### Requirement: Project identified by name or ID
|
|
The `<project-id-or-name>` argument SHALL accept either a Planka project ID or a project name. If a name is provided, the system SHALL look up the project by name. If multiple projects match the name, the system SHALL exit with an error.
|
|
|
|
#### Scenario: Project by name
|
|
- **WHEN** user provides a project name that matches exactly one project
|
|
- **THEN** the system exports that project
|
|
|
|
#### Scenario: Ambiguous project name
|
|
- **WHEN** user provides a project name that matches multiple projects
|
|
- **THEN** the system exits with an error listing the matches
|