All checks were successful
Build, test and publish / verify (push) Successful in 1m21s
161 lines
7.2 KiB
Markdown
161 lines
7.2 KiB
Markdown
# S1 — School JSON import and export
|
|
|
|
Status: implemented
|
|
|
|
## User story
|
|
|
|
**As** a school maintainer,
|
|
**I want** to export and import my dance school as a JSON file,
|
|
**so that** I can store my school configuration locally while the application does
|
|
not offer persistent storage,
|
|
**and so that** I retain ownership of my data.
|
|
|
|
## Intent
|
|
|
|
Export downloads a complete snapshot of one dance school to a local JSON file.
|
|
Import restores that snapshot as a new school or replaces the corresponding
|
|
existing school after explicit confirmation.
|
|
|
|
## Scope
|
|
|
|
### In scope
|
|
|
|
- Exporting an existing school to a readable JSON file.
|
|
- Importing a school that does not exist or no longer exists.
|
|
- Replacing an existing school with the complete imported snapshot.
|
|
- Preserving all configured school data and relationships, including:
|
|
- School details and its persistent unique key.
|
|
- Dancers and their details.
|
|
- Dance groups, types, age ranges and styles.
|
|
- Dancer memberships, including dancers belonging to multiple groups.
|
|
- Shows, dates, day parts and any existing group assignments to day parts.
|
|
- Coaches and any existing links between coaches and groups.
|
|
- Full validation, an import preview, confirmation and clear error messages.
|
|
|
|
Preserving existing data does not add management screens for coaches or the
|
|
ability to assign groups to show day parts.
|
|
|
|
### Out of scope
|
|
|
|
- Merging an imported snapshot with an existing school.
|
|
- Persistent server-side storage.
|
|
|
|
The existing-school prompt includes a merge option, but selecting it only displays
|
|
that merging is not yet supported. It must not change any data. Implementing merge
|
|
behavior requires a separate specification.
|
|
|
|
## Identity and file format
|
|
|
|
- Every school has a persistent unique key that is included in exports and
|
|
preserved through imports and subsequent exports.
|
|
- Import identifies an existing school by that key, not by its name or a
|
|
runtime-generated numeric ID. The key remains meaningful after a server restart.
|
|
- A school with the same name but a different unique key is a separate school.
|
|
- A file contains one school and all data needed to restore it without accessing
|
|
another school or the original server state.
|
|
- The readable, documented JSON format includes a `formatVersion` field.
|
|
- Users may edit the JSON manually. Edited files undergo the same validation as
|
|
files produced by the application.
|
|
- Unknown fields and unsupported format versions are rejected explicitly; data
|
|
must not be silently ignored.
|
|
- Relationships in the file must be unambiguous and restored correctly. Internal
|
|
numeric IDs need not remain identical, provided school identity and all
|
|
relationships are preserved without collisions with other schools.
|
|
|
|
## Export flow
|
|
|
|
1. The maintainer opens an existing school's management screen.
|
|
2. The maintainer selects the JSON export option.
|
|
3. The application downloads a JSON file containing a consistent, complete
|
|
snapshot of that school.
|
|
4. Export does not change the school or any other application data.
|
|
|
|
## Import flow
|
|
|
|
1. The maintainer selects the JSON import option and chooses a local file.
|
|
2. The application validates the entire file before changing any stored data.
|
|
3. For a valid file, the application shows a preview containing the school name
|
|
and the numbers of dancers, dance groups and shows.
|
|
4. If the unique school key is unknown, the maintainer confirms adding the school
|
|
or cancels the import.
|
|
5. If the key already exists, the application identifies the school that would be
|
|
replaced and offers replace, merge or cancel:
|
|
- **Replace:** explicitly warn that the existing school is replaced completely.
|
|
After confirmation, replace all its configured data with the snapshot.
|
|
- **Merge:** show a message that this functionality is not yet supported and
|
|
leave all data unchanged.
|
|
- **Cancel:** leave all data unchanged.
|
|
6. A confirmed import is committed as one operation. The application must not
|
|
expose a partially imported or partially replaced school.
|
|
7. If validation or importing fails, show **"Import niet gelukt"** together with
|
|
the concrete cause. The user can correct the file and try again.
|
|
|
|
## Validation and failure behavior
|
|
|
|
- Validate JSON syntax, the supported file structure and format version, required
|
|
data, field values and all relationships before applying the import.
|
|
- Reject unknown fields and references to missing objects, including a group's
|
|
reference to a dancer absent from the snapshot.
|
|
- A failure must not create a partial school, partially replace an existing
|
|
school, or modify another school.
|
|
- A replacement must not remove the original school until the complete
|
|
replacement can succeed. If it fails, the original school remains intact.
|
|
- Error messages explain the cause specifically enough to correct the file.
|
|
For example: **"Import niet gelukt: groep Hiphop verwijst naar een onbekende
|
|
danser."**
|
|
|
|
## Acceptance criteria
|
|
|
|
### Export
|
|
|
|
1. Each existing school offers a JSON-file export that can be downloaded and
|
|
stored locally.
|
|
2. The export includes its persistent unique key, `formatVersion`, all configured
|
|
data listed in scope and all relationships between those objects.
|
|
3. Exporting leaves the application data unchanged.
|
|
4. A school with no dancers, groups or shows can be exported and imported.
|
|
|
|
### Adding a school
|
|
|
|
5. A valid file with an unknown school key shows the preview before any data is
|
|
added. Confirming creates the complete school; cancelling changes nothing.
|
|
6. An exported school can be restored after the original school is deleted or
|
|
the in-memory server state is lost.
|
|
7. An existing school with the same name but a different key is neither replaced
|
|
nor treated as the same school.
|
|
|
|
### Replacing a school
|
|
|
|
8. A valid file with an existing school key prompts the user to replace, merge or
|
|
cancel and clearly identifies the existing school.
|
|
9. Confirming replacement replaces the complete configuration. Objects and
|
|
relationships present only in the previous configuration are not retained as
|
|
part of the replaced school.
|
|
10. Other schools remain unchanged by replacement.
|
|
11. Selecting merge displays that merging is not yet supported and changes
|
|
nothing. Cancelling also changes nothing.
|
|
|
|
### Validation and errors
|
|
|
|
12. Malformed JSON, unsupported format versions, unknown fields, missing required
|
|
data, invalid field values and unresolved relationships cause the entire
|
|
import to fail.
|
|
13. Each failed import displays **"Import niet gelukt"** and a concrete cause.
|
|
14. A failed new-school import adds nothing. A failed replacement preserves the
|
|
entire existing school. Other schools are unaffected in either case.
|
|
15. After a failure, the user can select a corrected file and retry.
|
|
|
|
### Round-trip integrity
|
|
|
|
16. Exporting and importing a school preserves every configured field and
|
|
relationship, including a dancer's membership in multiple groups, shows and
|
|
their day parts, and any existing coaches or day-part group assignments.
|
|
17. Exporting the restored school again preserves its unique school key and
|
|
equivalent configuration, even if internal numeric IDs changed.
|
|
|
|
## Implementation handoff
|
|
|
|
This specification records agreed behavior. Backend endpoints, the detailed JSON
|
|
schema and frontend implementation remain implementation work; this review does
|
|
not implement the feature.
|