Updated docs
This commit is contained in:
10
AGENTS.md
10
AGENTS.md
@@ -2,6 +2,14 @@
|
||||
|
||||
Also see the other related technical documentation in the docs folder.
|
||||
|
||||
## Tools
|
||||
|
||||
These tool paths should be used instead of any entry in the PATH environment variable:
|
||||
|
||||
- Python is installed in `C:\Users\frank\AppData\Local\Programs\Python\Python314`.
|
||||
- MiKTeX portable is installed in `D:\Code\miktex-portable\texmfs\install\miktex\bin\x64`.
|
||||
- Tesseract is installed in `C:\Program Files\Sejda PDF Desktop\resources\vendor\tesseract-windows-x64`.
|
||||
|
||||
## Rules
|
||||
|
||||
- This is a Windows environment, WSL is not installed (i.e. sed is not available). You're running under PowerShell 7.5.5. Due to platform restrictions, file deletions are not possible. Replacing the entire file content via a context diff is a viable alternative.
|
||||
@@ -16,4 +24,4 @@ Also see the other related technical documentation in the docs folder.
|
||||
- Check if the code compiles with a compile-only `dotnet build` to avoid artifact conflicts.
|
||||
- After the implementation is finished, verify all changed files, and run `python D:\Code\crlf.py $file1 $file2 ...` only for files you recognize, in order to normalize all line endings of all touched files to CRLF.
|
||||
- If there's documnentation present, always keep it updated.
|
||||
- At the end perform a git commit with a one-liner summary.
|
||||
- At the end perform a git commit with a one-liner summary.
|
||||
|
||||
383
TASKS.md
383
TASKS.md
@@ -1,383 +0,0 @@
|
||||
# Critical Curation UX Plan
|
||||
|
||||
## Goal
|
||||
|
||||
Extend the importer and web app so critical results can be curated with direct visual reference to the source PDF cell, tracked with an explicit curated state, and protected from later importer runs.
|
||||
|
||||
## Current State Summary
|
||||
|
||||
- The importer extracts XML text from PDFs, parses tables, writes debug artifacts, then deletes and reloads an entire critical table into SQLite.
|
||||
- `CriticalResult` currently stores text/effect data and `ParseStatus`, but it does not track curation state or source-image metadata.
|
||||
- The `/tables` page renders compact cells and opens `CriticalCellEditorDialog`, but the editor has no source-image panel and the table has no curated-status affordance.
|
||||
- The importer currently destroys all existing results for a table during reload, which would erase any manual curation.
|
||||
|
||||
## Recommended Design Decisions
|
||||
|
||||
### 1. Persist both curation state and source-image linkage on `CriticalResult`
|
||||
|
||||
Add explicit fields instead of hiding this inside `ParsedJson`.
|
||||
|
||||
Recommended additions:
|
||||
|
||||
- `IsCurated` `bool not null default false`
|
||||
- `SourcePageNumber` `int?`
|
||||
- `SourceImagePath` `string?`
|
||||
- `SourceImageCropJson` `string?`
|
||||
|
||||
Rationale:
|
||||
|
||||
- `IsCurated` is queried and displayed directly in the UI and import logic.
|
||||
- The editor needs a stable way to request the PNG for a result without reconstructing crop geometry on every request.
|
||||
- Keeping source-image metadata separate from `ParsedJson` avoids mixing importer provenance with manual-editor snapshot state.
|
||||
|
||||
### 2. Treat imported source images as importer-managed artifacts
|
||||
|
||||
Store generated page PNGs and per-cell crop PNGs under the existing artifact root, for example:
|
||||
|
||||
- `artifacts/import/critical/<slug>/pages/page-001.png`
|
||||
- `artifacts/import/critical/<slug>/cells/<group-or-none>__<column>__<roll-band>.png`
|
||||
|
||||
Rationale:
|
||||
|
||||
- This fits the existing importer artifact workflow.
|
||||
- It keeps raw extraction/debug output outside the Blazor app project.
|
||||
- File naming can be deterministic from the logical result key.
|
||||
|
||||
### 3. Serve source images through an API endpoint, not raw filesystem paths
|
||||
|
||||
Add an API endpoint that resolves the result’s stored relative image path and streams the PNG.
|
||||
|
||||
Recommended endpoint:
|
||||
|
||||
- `GET /api/tables/critical/{slug}/cells/{resultId:int}/source-image`
|
||||
|
||||
Rationale:
|
||||
|
||||
- Avoids exposing arbitrary filesystem paths to the browser.
|
||||
- Lets the app return `404` cleanly when an image is missing.
|
||||
- Keeps the editor response simple by returning either an image URL or enough information to build one.
|
||||
|
||||
### 4. Preserve curated results by switching the importer from table replacement to keyed merge/upsert
|
||||
|
||||
Importer matching key:
|
||||
|
||||
- `table slug`
|
||||
- optional `group key`
|
||||
- `column key`
|
||||
- `roll band label`
|
||||
|
||||
Behavior:
|
||||
|
||||
- If no existing result exists, insert a new result.
|
||||
- If an existing result exists and `IsCurated == false`, replace importer-managed fields and child rows.
|
||||
- If an existing result exists and `IsCurated == true`, preserve curated text/effect/branch fields and do not overwrite them.
|
||||
- Still allow importer-managed source-image metadata to be refreshed if it can be done without changing curated content.
|
||||
|
||||
Rationale:
|
||||
|
||||
- The current delete-and-reload flow is incompatible with requirement 5.
|
||||
- The logical table coordinates already form a stable identity for each result.
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
## Phase 1: Schema and Domain Model
|
||||
|
||||
### 1.1 Extend `CriticalResult`
|
||||
|
||||
Planned files:
|
||||
|
||||
- `src/RolemasterDb.App/Domain/CriticalResult.cs`
|
||||
- `src/RolemasterDb.App/Data/RolemasterDbContext.cs`
|
||||
- `src/RolemasterDb.App/Data/RolemasterDbSchemaUpgrader.cs`
|
||||
- `docs/critical_tables_schema.sql`
|
||||
- `docs/critical_tables_db_model.md`
|
||||
|
||||
Tasks:
|
||||
|
||||
- Add the new persisted properties to `CriticalResult`.
|
||||
- Configure lengths/indexes in `RolemasterDbContext` where needed.
|
||||
- Extend `RolemasterDbSchemaUpgrader` with additive SQLite migrations for the new columns.
|
||||
- Document the new fields and their purpose in the schema/model docs.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Existing databases upgrade in place.
|
||||
- New databases include the new columns.
|
||||
- The schema documentation matches the implementation.
|
||||
|
||||
## Phase 2: Importer Provenance and Image Extraction
|
||||
|
||||
### 2.1 Capture per-result source geometry during parsing
|
||||
|
||||
Planned files:
|
||||
|
||||
- `src/RolemasterDb.ImportTool/Parsing/ParsedCriticalResult.cs`
|
||||
- `src/RolemasterDb.ImportTool/Parsing/ParsedCriticalCellArtifact.cs`
|
||||
- `src/RolemasterDb.ImportTool/Parsing/StandardCriticalTableParser.cs`
|
||||
- `src/RolemasterDb.ImportTool/Parsing/VariantColumnCriticalTableParser.cs`
|
||||
- `src/RolemasterDb.ImportTool/Parsing/GroupedVariantCriticalTableParser.cs`
|
||||
- shared parser helpers under `src/RolemasterDb.ImportTool/Parsing/`
|
||||
|
||||
Tasks:
|
||||
|
||||
- Extend the parsed-result models to carry source page number and crop/bounding-box metadata.
|
||||
- Derive a reliable bounding rectangle from the fragments assigned to each parsed cell.
|
||||
- Ensure grouped/variant parsers emit the same provenance data shape as standard tables.
|
||||
- Include the geometry in debug artifacts to make extraction problems inspectable.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Every parsed result has enough provenance to locate and crop its source region.
|
||||
- `parsed-cells.json` shows page/crop metadata for manual debugging.
|
||||
|
||||
### 2.2 Add page rendering and per-cell PNG crop generation
|
||||
|
||||
Planned files:
|
||||
|
||||
- `src/RolemasterDb.ImportTool/PdfXmlExtractor.cs`
|
||||
- `src/RolemasterDb.ImportTool/CriticalImportCommandRunner.cs`
|
||||
- `src/RolemasterDb.ImportTool/ImportArtifactPaths.cs`
|
||||
- new helper classes in `src/RolemasterDb.ImportTool/`
|
||||
- `docs/critical_import_tool.md`
|
||||
|
||||
Tasks:
|
||||
|
||||
- Extend extraction so the importer renders source PDF pages to PNG in addition to XML.
|
||||
- Add a crop step that uses the parsed cell bounding boxes to generate one PNG per critical result.
|
||||
- Store deterministic relative image paths on parsed results before load.
|
||||
- Extend artifact path helpers to include `pages/` and `cells/` folders.
|
||||
- Document any required external tool dependency, expected command line, and artifact layout.
|
||||
|
||||
Implementation note:
|
||||
|
||||
- Validate which Poppler/image tool is already available in this environment before coding. The plan should prefer reusing the existing PDF toolchain if possible.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Running the importer for a table produces page PNGs and cell PNGs alongside the existing JSON artifacts.
|
||||
- Each parsed result can be linked to exactly one crop image.
|
||||
|
||||
## Phase 3: Importer Load Strategy That Preserves Curated Results
|
||||
|
||||
### 3.1 Replace destructive table reload with merge/upsert
|
||||
|
||||
Planned files:
|
||||
|
||||
- `src/RolemasterDb.ImportTool/CriticalImportLoader.cs`
|
||||
- `src/RolemasterDb.ImportTool/CriticalImportCommandRunner.cs`
|
||||
- importer tests under `src/RolemasterDb.ImportTool.Tests/`
|
||||
- `docs/critical_import_tool.md`
|
||||
|
||||
Tasks:
|
||||
|
||||
- Stop deleting an entire table before re-import.
|
||||
- Load existing table metadata, columns, groups, roll bands, and results keyed by logical identity.
|
||||
- Rebuild table-level axes as needed, but preserve existing result rows when identity matches.
|
||||
- For non-curated results, replace importer-managed text/effect/branch/source-image fields.
|
||||
- For curated results, preserve manual content and child rows.
|
||||
- Decide whether missing results from the source should remain, be deleted only when uncurated, or be flagged for review. Recommended default: only delete unmatched results when they are uncurated.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- Re-import keeps curated results intact.
|
||||
- Re-import still updates uncurated results and newly discovered cells.
|
||||
- Re-import remains transactional.
|
||||
|
||||
### 3.2 Define importer ownership boundaries clearly
|
||||
|
||||
Tasks:
|
||||
|
||||
- Explicitly identify which fields are importer-owned versus curator-owned.
|
||||
- Make the merge code preserve curator-owned fields on curated rows.
|
||||
- Keep source provenance/image fields importer-owned unless that causes user-visible regressions.
|
||||
|
||||
Recommended ownership split:
|
||||
|
||||
- Importer-owned: raw extracted text, generated quick-parse baseline, parse status, source page/image/crop metadata.
|
||||
- Curator-owned when curated: description overrides, branch edits, effect edits, curated flag.
|
||||
|
||||
Open point to resolve during implementation:
|
||||
|
||||
- Whether `RawCellText` should remain importer-owned even for curated rows, or frozen once curated. Recommended approach: freeze it for curated rows to preserve the exact human-reviewed context shown in the editor.
|
||||
|
||||
## Phase 4: API and Service Contract Changes
|
||||
|
||||
### 4.1 Extend editor and table-detail contracts
|
||||
|
||||
Planned files:
|
||||
|
||||
- `src/RolemasterDb.App/Features/LookupContracts.cs`
|
||||
- `src/RolemasterDb.App/Features/CriticalCellEditorResponse.cs`
|
||||
- `src/RolemasterDb.App/Features/CriticalCellUpdateRequest.cs`
|
||||
- `src/RolemasterDb.App/Features/LookupService.cs`
|
||||
- `src/RolemasterDb.App/Program.cs`
|
||||
- `src/RolemasterDb.App/Components/Pages/Api.razor`
|
||||
|
||||
Tasks:
|
||||
|
||||
- Add curated-state fields to table-cell detail and editor responses.
|
||||
- Add source-image URL or source-image presence/metadata to the editor response.
|
||||
- Extend update requests so the editor can mark a result curated or not curated.
|
||||
- Add the source-image streaming endpoint.
|
||||
- Update API documentation page to reflect the new payload shape and endpoint.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- `/tables` can render curation state without opening the editor.
|
||||
- The editor can load the image URL and curated flag from a single response.
|
||||
- Saving a cell persists the curated flag.
|
||||
|
||||
## Phase 5: Editor UX for Curation
|
||||
|
||||
### 5.1 Show the source PNG inside `CriticalCellEditorDialog`
|
||||
|
||||
Planned files:
|
||||
|
||||
- `src/RolemasterDb.App/Components/Shared/CriticalCellEditorDialog.razor`
|
||||
- `src/RolemasterDb.App/Components/Shared/CriticalCellEditorModel.cs`
|
||||
- `src/RolemasterDb.App/wwwroot/app.css`
|
||||
|
||||
Tasks:
|
||||
|
||||
- Add a dedicated source-reference panel near the editor header or beside the quick-input section.
|
||||
- Render the PNG with useful alt text containing table, roll band, group, and column context.
|
||||
- Handle missing-image state gracefully with a compact fallback message.
|
||||
- Ensure the dialog still works on smaller screens without the image overwhelming the form.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- A curator can see the original source cell while editing.
|
||||
- The editor remains usable on desktop and mobile widths.
|
||||
|
||||
### 5.2 Add explicit curation controls in the editor
|
||||
|
||||
Tasks:
|
||||
|
||||
- Add a clear curated-state badge and a toggle or checkbox for marking a result curated.
|
||||
- Make the current state visible in the header so the curator knows whether the cell is protected from importer overwrite.
|
||||
- Consider a short explanatory note when toggling to curated, since that changes importer behavior.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- A curator can mark and unmark a result without leaving the editor.
|
||||
- The protected state is obvious before saving.
|
||||
|
||||
## Phase 6: Table UX for Curated vs Needs Curation
|
||||
|
||||
### 6.1 Surface curation state on the `/tables` grid
|
||||
|
||||
Planned files:
|
||||
|
||||
- `src/RolemasterDb.App/Components/Pages/Tables.razor`
|
||||
- `src/RolemasterDb.App/Components/Shared/CompactCriticalCell.razor`
|
||||
- `src/RolemasterDb.App/wwwroot/app.css`
|
||||
|
||||
Tasks:
|
||||
|
||||
- Add a high-contrast, low-noise visual distinction between curated and needs-curation cells.
|
||||
- Keep the state visible even when the cell text is dense.
|
||||
- Add accessible labels/tooltips so keyboard and screen-reader users get the same state information.
|
||||
- Decide whether empty cells should remain neutral rather than “needs curation”.
|
||||
|
||||
Recommended UI pattern:
|
||||
|
||||
- Curated: subtle success-toned chip or corner marker plus label in tooltip.
|
||||
- Needs curation: warm warning-toned chip or border treatment.
|
||||
- Empty: unchanged neutral empty state.
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- A table can be scanned quickly for work that still needs curation.
|
||||
- The curation marker does not reduce readability of the compact cell content.
|
||||
|
||||
### 6.2 Consider lightweight summary affordances
|
||||
|
||||
Optional follow-up tasks if the basic state marker is not enough:
|
||||
|
||||
- Add curated vs needs-curation counts in the table header.
|
||||
- Add a filter toggle to show only needs-curation cells.
|
||||
|
||||
These should be deferred unless the initial implementation still feels too noisy or too hard to scan.
|
||||
|
||||
## Phase 7: Tests and Verification
|
||||
|
||||
### 7.1 Importer tests
|
||||
|
||||
Planned files:
|
||||
|
||||
- `src/RolemasterDb.ImportTool.Tests/`
|
||||
|
||||
Tests to add:
|
||||
|
||||
- Parsed result includes source page/crop metadata.
|
||||
- Import run generates expected image artifacts for a known sample table.
|
||||
- Re-import updates uncurated results.
|
||||
- Re-import preserves curated results and their edited child rows.
|
||||
- Re-import behavior for missing/unmatched results is deterministic.
|
||||
|
||||
### 7.2 App/service tests
|
||||
|
||||
Planned scope:
|
||||
|
||||
- Add or extend tests around `LookupService` if a test project already exists or can be added cheaply.
|
||||
|
||||
Tests to add:
|
||||
|
||||
- Editor response includes curated state and image URL.
|
||||
- Update request persists curated state.
|
||||
- Table detail response carries curated state for each cell.
|
||||
- Source-image endpoint returns `404` for missing images and `200` for valid ones.
|
||||
|
||||
### 7.3 Manual verification
|
||||
|
||||
Manual checks:
|
||||
|
||||
- Import a representative table and confirm cell PNGs look correctly cropped.
|
||||
- Open several cells in `CriticalCellEditorDialog` and confirm the displayed image matches the edited result.
|
||||
- Mark a result curated, re-run importer, and confirm no curated fields are overwritten.
|
||||
- Mark a result back to needs curation, re-run importer, and confirm importer updates resume.
|
||||
- Check `/tables` scanning on both desktop and mobile layouts.
|
||||
|
||||
## Documentation Updates Required During Implementation
|
||||
|
||||
Planned files:
|
||||
|
||||
- `docs/critical_import_tool.md`
|
||||
- `docs/critical_tables_db_model.md`
|
||||
- `docs/critical_tables_schema.sql`
|
||||
- `src/RolemasterDb.App/Components/Pages/Api.razor`
|
||||
|
||||
Required updates:
|
||||
|
||||
- Describe the new importer artifact layout for page and cell PNGs.
|
||||
- Document the curated flag and source-image metadata in the logical data model.
|
||||
- Document the non-destructive importer behavior for curated rows.
|
||||
- Document the new API response fields and source-image endpoint.
|
||||
|
||||
## Suggested Execution Order
|
||||
|
||||
1. Implement schema/domain changes first so both importer and app can compile against the new fields.
|
||||
2. Add parser provenance and image artifact generation next.
|
||||
3. Refactor importer load behavior from destructive replace to merge/upsert with curated preservation.
|
||||
4. Extend service/API contracts.
|
||||
5. Add editor image panel and curated toggle.
|
||||
6. Add `/tables` curated-state indicators.
|
||||
7. Finish with docs, tests, and manual verification.
|
||||
|
||||
## Risks and Mitigations
|
||||
|
||||
- Risk: Crop coordinates are slightly wrong because PDF text geometry and rendered page PNG scale differ.
|
||||
Mitigation: Persist page number plus raw bounding box metadata, and verify crop alignment against a few known tables before broad rollout.
|
||||
|
||||
- Risk: Preserving curated rows while rebuilding axes could break foreign-key relationships if columns/groups/roll bands are recreated blindly.
|
||||
Mitigation: Reuse or reconcile axis rows by logical key before touching result rows.
|
||||
|
||||
- Risk: Importer ownership versus curator ownership is ambiguous for `RawCellText`, `ParseStatus`, and `ParsedJson`.
|
||||
Mitigation: Set this policy explicitly before coding and enforce it in one merge path.
|
||||
|
||||
- Risk: Serving images from artifact storage could expose unsafe file access if implemented with arbitrary path input.
|
||||
Mitigation: Resolve images by result identity and stored relative path only.
|
||||
|
||||
## Approval Gate
|
||||
|
||||
Implementation should start only after this plan is approved, because the importer-load refactor and schema changes affect both data safety and future curation workflow.
|
||||
@@ -1,789 +0,0 @@
|
||||
# Player And Gamemaster UX Redesign Plan
|
||||
|
||||
## Purpose
|
||||
|
||||
This document defines a frontend UX direction for the Rolemaster web app with players and gamemasters as the primary audience during play.
|
||||
|
||||
The current UI exposes too much implementation detail:
|
||||
|
||||
- importer ownership
|
||||
- tech stack details
|
||||
- import source details
|
||||
- SQLite and storage details
|
||||
- table counts and reference-data counts
|
||||
- parse/debug fields
|
||||
- raw JSON artifacts
|
||||
- technical labels that matter to development but not to play
|
||||
|
||||
That information is useful for engineering and data curation, but it is noise during a session. The redesign should make the gameplay outcome the center of the experience and move technical detail behind developer-only tooling.
|
||||
|
||||
## Audience Priority
|
||||
|
||||
### Primary
|
||||
|
||||
- gamemasters resolving attacks and criticals quickly during a session
|
||||
- players checking the resulting card and consequences without reading import metadata
|
||||
|
||||
### Secondary
|
||||
|
||||
- curators repairing imported cells
|
||||
|
||||
### Tertiary
|
||||
|
||||
- developers working on importer/debug workflows
|
||||
|
||||
The key design rule is that secondary and tertiary needs must not dominate the primary experience.
|
||||
|
||||
## Current UX Problems
|
||||
|
||||
The current app structure already shows the main issues.
|
||||
|
||||
### Home page
|
||||
|
||||
The current landing page in [Home.razor](D:\Code\RolemasterDB\src\RolemasterDb.App\Components\Pages\Home.razor) emphasizes:
|
||||
|
||||
- starter dataset wording
|
||||
- importer-managed wording
|
||||
- attack table count
|
||||
- critical table count
|
||||
- armor type count
|
||||
- SQLite file name
|
||||
|
||||
This is system status, not gameplay guidance.
|
||||
|
||||
### Lookup result card
|
||||
|
||||
The current lookup card in [CriticalLookupResultCard.razor](D:\Code\RolemasterDB\src\RolemasterDb.App\Components\Shared\CriticalLookupResultCard.razor) exposes:
|
||||
|
||||
- table key
|
||||
- column role
|
||||
- parse status
|
||||
- critical family
|
||||
- source document
|
||||
- roll band internals
|
||||
- raw imported cell
|
||||
- parsed JSON
|
||||
|
||||
Only a small subset of that is useful to a player or GM during play.
|
||||
|
||||
### Critical tables page
|
||||
|
||||
The current tables page in [Tables.razor](D:\Code\RolemasterDB\src\RolemasterDb.App\Components\Pages\Tables.razor) presents the page as an importer authority surface and frames the legend, groups, columns, and full matrix primarily from a data-management perspective.
|
||||
|
||||
### Cell editor popup
|
||||
|
||||
The current edit dialog in [CriticalCellEditorDialog.razor](D:\Code\RolemasterDB\src\RolemasterDb.App\Components\Shared\CriticalCellEditorDialog.razor) exposes nearly the full persistence model, including internal fields such as:
|
||||
|
||||
- `ParseStatus`
|
||||
- `ParsedJson`
|
||||
- branch `ConditionJson`
|
||||
- branch `ParsedJson`
|
||||
- effect `SourceType`
|
||||
- raw affix text everywhere
|
||||
|
||||
That makes the editor feel like a database inspector instead of a card editor.
|
||||
|
||||
### Critical table cell layout
|
||||
|
||||
The current cell layout in [CompactCriticalCell.razor](D:\Code\RolemasterDB\src\RolemasterDb.App\Components\Shared\CompactCriticalCell.razor) and [app.css](D:\Code\RolemasterDB\src\RolemasterDb.App\wwwroot\app.css) already pushes affix badges downward with `margin-top: auto`, but branch stacks are not explicitly bottom-aligned as part of the same card layout contract. That weakens visual consistency in dense table rows.
|
||||
|
||||
## UX Design Principles
|
||||
|
||||
### 1. Gameplay first
|
||||
|
||||
The first screenful must answer:
|
||||
|
||||
- what happened
|
||||
- how many hits
|
||||
- what critical applies
|
||||
- what effects matter now
|
||||
- what optional follow-up input is still needed
|
||||
|
||||
### 2. Remove technical noise
|
||||
|
||||
Do not show implementation details in player/GM flows unless the user has explicitly entered an advanced curation mode.
|
||||
|
||||
### 3. Edit the result, not the database row
|
||||
|
||||
When a critical cell is edited, the main object is the rendered card the user wants to fix. The underlying import/debug representation should be derived where possible, not manually curated in parallel by default.
|
||||
|
||||
### 4. Fastest common action wins
|
||||
|
||||
During play, the most common action is a direct resolution flow. The interface should reduce required reading, scrolling, and field-by-field interpretation.
|
||||
|
||||
### 5. Progressive disclosure
|
||||
|
||||
Show simple information by default. Reveal advanced detail only when the user asks for it.
|
||||
|
||||
### 6. Shared parsing logic
|
||||
|
||||
The same import interpretation rules should drive the import tool and the web editor. The user should not need to manually keep quick parse input, OCR provenance, and normalized fields in sync.
|
||||
|
||||
## Target Information Architecture
|
||||
|
||||
The application should separate into three user-facing layers.
|
||||
|
||||
### Layer 1: Session tools
|
||||
|
||||
Primary navigation for live play:
|
||||
|
||||
- Attack lookup
|
||||
- Critical lookup
|
||||
- Critical tables
|
||||
|
||||
This layer must contain no importer/debug framing.
|
||||
|
||||
### Layer 2: Curation tools
|
||||
|
||||
Accessible to advanced users:
|
||||
|
||||
- Edit critical cell
|
||||
- Generate from quick parse input
|
||||
- Compare rendered result before and after changes
|
||||
|
||||
This layer is still user-focused, not developer-focused.
|
||||
|
||||
### Layer 3: Engineering diagnostics
|
||||
|
||||
Hidden from normal users and placed in a separate developer/admin surface:
|
||||
|
||||
- parse status
|
||||
- parsed JSON
|
||||
- source document internals
|
||||
- import artifacts
|
||||
- schema/debug diagnostics
|
||||
|
||||
## Proposed UX Direction By Surface
|
||||
|
||||
### 1. Landing Page / Main Lookup
|
||||
|
||||
Replace the current technically framed hero with a task-first entry point.
|
||||
|
||||
### Proposed hero
|
||||
|
||||
- title focused on fast resolution during play
|
||||
- one sentence of instruction
|
||||
- immediate access to the two main lookup actions
|
||||
|
||||
### Remove from the hero and main summary
|
||||
|
||||
- tech stack references
|
||||
- SQLite references
|
||||
- import source references
|
||||
- table counts
|
||||
- importer-managed wording
|
||||
- starter dataset wording
|
||||
- reference-data framing
|
||||
|
||||
### Proposed attack lookup flow
|
||||
|
||||
Fields:
|
||||
|
||||
- attack table
|
||||
- armor type
|
||||
- attack roll
|
||||
- enemy db (attack malus)
|
||||
- optional critical roll
|
||||
|
||||
Controls:
|
||||
|
||||
- resolve button
|
||||
- dice button beside attack roll
|
||||
- dice button beside critical roll
|
||||
|
||||
Behavior:
|
||||
|
||||
- if attack roll is present and critical roll is empty, stop after attack result
|
||||
- if a critical is produced and no critical roll is entered, show a prominent next-step prompt
|
||||
- if critical roll exists, show the full critical card inline
|
||||
|
||||
### Proposed direct critical lookup flow
|
||||
|
||||
Fields:
|
||||
|
||||
- critical table
|
||||
- column
|
||||
- optional group, only when required
|
||||
- critical roll
|
||||
|
||||
Controls:
|
||||
|
||||
- resolve button
|
||||
- dice button beside critical roll
|
||||
|
||||
Behavior:
|
||||
|
||||
- hide irrelevant group controls when the selected table has no groups
|
||||
- use human-readable labels, not implementation terminology
|
||||
|
||||
### 2. Lookup Result Card
|
||||
|
||||
The lookup card should become a gameplay card, not a parser inspection panel.
|
||||
|
||||
### Keep visible by default
|
||||
|
||||
- critical table name
|
||||
- chosen severity or column label
|
||||
- group label when relevant
|
||||
- roll used
|
||||
- main prose result
|
||||
- normalized effect chips
|
||||
- branch cards with conditions and effects
|
||||
|
||||
### Remove from default card
|
||||
|
||||
- parse status
|
||||
- critical family
|
||||
- source document
|
||||
- column key
|
||||
- column role
|
||||
- raw imported cell
|
||||
- parsed JSON
|
||||
- roll band implementation details
|
||||
|
||||
### Optional advanced disclosure
|
||||
|
||||
If advanced users still need provenance, place it behind a collapsed "Technical details" disclosure that is hidden by default and not present in the main lookup flow for ordinary users.
|
||||
|
||||
### Visual direction
|
||||
|
||||
- result prose should be the dominant element
|
||||
- effects should scan as chips/badges
|
||||
- branch cards should read as conditional outcomes, not nested records
|
||||
- warning and follow-up effects should be grouped by urgency if possible
|
||||
|
||||
### 3. Critical Tables Page
|
||||
|
||||
The tables browser should support reading and choosing results quickly.
|
||||
|
||||
### Reframe the page
|
||||
|
||||
Current framing centers imported data. The new framing should center reading the table during play and correcting a result when necessary.
|
||||
|
||||
### Page goals
|
||||
|
||||
- pick a table quickly
|
||||
- scan a row and column intersection quickly
|
||||
- open a clean card editor when correction is needed
|
||||
|
||||
### Remove or demote
|
||||
|
||||
- importer authority language
|
||||
- source-document-first labeling
|
||||
- any explanation centered on how the data was loaded
|
||||
|
||||
### Keep
|
||||
|
||||
- table name
|
||||
- notes only if they help interpret the table in play
|
||||
- affix legend because it helps users read chip meaning
|
||||
|
||||
### Cell layout requirement
|
||||
|
||||
`.critical-branch-stack` should be bottom-aligned with `.critical-cell`.
|
||||
|
||||
Practical CSS intent:
|
||||
|
||||
- make `.critical-cell` a full-height column flex container
|
||||
- reserve flexible vertical space above branches
|
||||
- ensure the branch stack sits at the bottom edge of the cell card
|
||||
- keep affix badges and branch cards visually anchored
|
||||
|
||||
This creates a stable reading rhythm across rows with uneven prose length.
|
||||
|
||||
### 4. Critical Cell Editing
|
||||
|
||||
The edit popup should become a compact result editor with quick parse support.
|
||||
|
||||
### Editing goal
|
||||
|
||||
A curator should be able to correct a result quickly in a dense popup without giving up space to a separate preview panel.
|
||||
|
||||
### Default editor content
|
||||
|
||||
Show:
|
||||
|
||||
- quick parse input
|
||||
- one-line result text editing when manual override is needed
|
||||
- compact inline affix/effect rows with the same badges/icons used in read mode
|
||||
- compact inline condition rows with their own effect chips
|
||||
|
||||
Hide from default editing:
|
||||
|
||||
- parse status
|
||||
- parsed JSON
|
||||
- condition JSON
|
||||
- effect source type
|
||||
- other importer/debug-only properties
|
||||
|
||||
### Editor structure
|
||||
|
||||
1. Quick parse input
|
||||
2. Compact inline parsed sections the user can adjust
|
||||
3. Save actions
|
||||
4. Optional advanced diagnostics disclosure
|
||||
|
||||
There should be no dedicated preview panel in the popup. The edit rows themselves should carry the same affix badges, branch labels, and visible wording that the final result uses.
|
||||
|
||||
### OCR source versus quick parse input
|
||||
|
||||
The app should stop treating OCR-shaped pdf text as the main editing language.
|
||||
|
||||
Two separate sources are needed:
|
||||
|
||||
- `OCR source`: the imported pdf text, shown for provenance and troubleshooting
|
||||
- `Quick parse input`: the curator-facing typed input used for regeneration
|
||||
|
||||
`OCR source` should be read-only by default and placed in advanced disclosure. It exists so curators can inspect the imported source when necessary, but they should not be expected to type or repair extravagant OCR symbols such as `π`, `∑`, `∏`, and `∫`.
|
||||
|
||||
`Quick parse input` should be the normal text-generation surface.
|
||||
|
||||
### Quick parse input grammar
|
||||
|
||||
The grammar should be intentionally small and easy to type.
|
||||
|
||||
Rules:
|
||||
|
||||
- the first line is always the main prose result
|
||||
- each following line is either a base affix line or a conditional affix line
|
||||
- affixes on those lines are comma-separated
|
||||
- a conditional line uses `condition: affix, affix, affix`
|
||||
|
||||
Examples:
|
||||
|
||||
```text
|
||||
Foe brings his guard up, frightened by your display.
|
||||
+5, 1mp
|
||||
```
|
||||
|
||||
```text
|
||||
Blast arcs through shield rim and into sword arm.
|
||||
+10, 2s, -15
|
||||
w/o shield: +15, 3s, 3np, 1hpr, -20, +20b
|
||||
```
|
||||
|
||||
### Friendly affix aliases
|
||||
|
||||
The quick parse input should accept friendly aliases instead of OCR symbols.
|
||||
|
||||
Examples:
|
||||
|
||||
- `+15` for direct hits
|
||||
- `3s` for stunned 3 rounds
|
||||
- `3np` for no parry 3 rounds
|
||||
- `1mp` for must parry 1 round
|
||||
- `1hpr` for 1 hit per round bleed
|
||||
- `-20` for foe penalty
|
||||
- `+20b` for attacker bonus next round
|
||||
|
||||
The parser may continue to accept OCR-era symbols as compatibility aliases, but they must not be required in the normal editor workflow.
|
||||
|
||||
### Generate behavior
|
||||
|
||||
When the user edits `QuickParseInput`:
|
||||
|
||||
- allow manual generate with a clear button
|
||||
- optionally support debounced generation after input stabilizes
|
||||
- regenerate description, effects, branches, and conditions from shared parser logic
|
||||
- preserve user edits only where the user explicitly overrode generated values
|
||||
- surface parser notes in advanced disclosure instead of spending default popup space on them
|
||||
|
||||
### No-silent-loss parser rule
|
||||
|
||||
The generator must never silently drop recognized content.
|
||||
|
||||
Requirements:
|
||||
|
||||
- if a token is recognized, the generated card must contain the corresponding effect
|
||||
- if a token is not recognized, the compare/review workflow must surface that token explicitly
|
||||
- generated-versus-current comparison must call out dropped or unresolved affix tokens in plain language
|
||||
|
||||
This rule is more important than preserving OCR fidelity. A parser that quietly loses `1mp` or `π` is not acceptable for curation.
|
||||
|
||||
### Manual override model
|
||||
|
||||
A critical result should support two states:
|
||||
|
||||
- imported from the pdf
|
||||
- quick parse input manually overridden and derived fields generated from quick parse input or also manually overridden
|
||||
|
||||
This avoids the current problem where re-imports using the tool discards user curations.
|
||||
|
||||
### 5. Affix Editing UX
|
||||
|
||||
Adding affixes should not require editing raw structured records.
|
||||
|
||||
### Proposed interaction
|
||||
|
||||
- show each effect as a compact inline row with its affix badge and dropdown
|
||||
- keep add/remove actions small and local to the row
|
||||
- let the user choose the effect type from the same row they are editing
|
||||
- show only the minimum value input needed for that effect type
|
||||
- update the visible badge and label directly in the row without a separate preview area
|
||||
|
||||
### Requirements
|
||||
|
||||
- chip labels must use user-facing terminology
|
||||
- the affix legend and effect codes must map cleanly
|
||||
- the editor should support friendly alias affixes and numeric affixes
|
||||
- deleting an affix should be one click from the row
|
||||
- do not waste space on a redundant title when the dropdown already identifies the effect
|
||||
- do not show a `Target` field for `direct_hits`
|
||||
- do not show a `Permanent` checkbox in the default editor
|
||||
- keep source metadata and internal links out of the default row layout
|
||||
|
||||
### 6. Condition And Branch Editing UX
|
||||
|
||||
Branch editing should follow the same interaction model as affixes.
|
||||
|
||||
### Proposed interaction
|
||||
|
||||
- branches render as compact inline condition rows
|
||||
- include a small add button for `Add condition`
|
||||
- user selects or types the condition text directly in the row
|
||||
- user enters optional outcome prose inline
|
||||
- branch effects are edited with the same compact affix rows used on the base result
|
||||
|
||||
### Branch card contents
|
||||
|
||||
- condition label
|
||||
- optional prose outcome
|
||||
- effect chips
|
||||
|
||||
### Remove from default branch editing
|
||||
|
||||
- condition JSON
|
||||
- parsed JSON
|
||||
- internal branch kind values unless required by the UX
|
||||
|
||||
If internal branch kinds remain necessary in the model, map them to friendly labels and keep raw values hidden.
|
||||
|
||||
### 7. Dice Button Support
|
||||
|
||||
Both lookup flows need an alternative to manual roll entry.
|
||||
|
||||
### Automatic Attack Lookup
|
||||
|
||||
Add dice buttons beside:
|
||||
|
||||
- attack roll input
|
||||
- critical roll input
|
||||
|
||||
### Direct Critical Lookup
|
||||
|
||||
Add a dice button beside:
|
||||
|
||||
- critical roll input
|
||||
|
||||
### Behavior
|
||||
|
||||
- clicking the button fills the corresponding input with a random legal value
|
||||
- for attack roll, use the supported app range
|
||||
- for critical roll, use `1-100`
|
||||
- allow reroll without extra confirmation
|
||||
|
||||
### UX value
|
||||
|
||||
This supports fast table use at the table and removes the need to type known random values manually.
|
||||
|
||||
## Shared Import Assembly Direction
|
||||
|
||||
The import tool and the web app should stop duplicating or bypassing import logic.
|
||||
|
||||
### Goal
|
||||
|
||||
Move critical parsing, normalization, and re-parse behavior into a shared assembly consumed by both:
|
||||
|
||||
- `RolemasterDb.ImportTool`
|
||||
- `RolemasterDb.App`
|
||||
|
||||
### Candidate shared responsibilities
|
||||
|
||||
Based on the current importer structure under [src/RolemasterDb.ImportTool](D:\Code\RolemasterDB\src\RolemasterDb.ImportTool), the shared assembly should own:
|
||||
|
||||
- raw cell parsing
|
||||
- quick parse input parsing
|
||||
- affix legend interpretation
|
||||
- affix-to-effect normalization
|
||||
- branch extraction
|
||||
- condition key normalization
|
||||
- parsed artifact creation for a single cell or branch
|
||||
- validation rules for structurally invalid cells
|
||||
|
||||
### Why this matters
|
||||
|
||||
Today the import tool is the authority for generating normalized critical content, but the web editor exposes many of the final persisted fields directly. That encourages manual edits to derived data instead of reusing the parser.
|
||||
|
||||
A shared assembly would allow the web app to:
|
||||
|
||||
- generate a single cell from quick parse input
|
||||
- regenerate effects and branches consistently with bulk import
|
||||
- reduce manual entry
|
||||
- remove most debug/import fields from the user-facing editor
|
||||
|
||||
### Proposed architecture
|
||||
|
||||
### New shared project
|
||||
|
||||
Create a new assembly for critical import/domain transformation logic, for example:
|
||||
|
||||
- `src/RolemasterDb.CriticalParsing`
|
||||
|
||||
### Move or extract into the shared assembly
|
||||
|
||||
- parsing contracts for cell-level input and output
|
||||
- affix parsing logic
|
||||
- branch extraction logic
|
||||
- normalization helpers
|
||||
- validation logic
|
||||
|
||||
### Keep in the import tool
|
||||
|
||||
- CLI command surface
|
||||
- manifest loading
|
||||
- artifact extraction from PDFs
|
||||
- batch import orchestration
|
||||
- artifact writing for diagnostics
|
||||
|
||||
### Keep in the app
|
||||
|
||||
- HTTP endpoints
|
||||
- Blazor UI
|
||||
- persistence orchestration for save/update flows
|
||||
|
||||
### Web editor workflow after shared parsing
|
||||
|
||||
1. User opens a critical cell.
|
||||
2. The app shows quick parse input and compact inline edit rows for the visible result.
|
||||
3. User edits quick parse input.
|
||||
4. The app calls shared parsing logic for that cell.
|
||||
5. The parser returns normalized description, affixes, conditions, branches, and validation messages.
|
||||
6. The UI updates the inline editing rows automatically.
|
||||
7. The user makes small manual fixes only where generation is insufficient.
|
||||
8. Save persists quick parse input, OCR provenance, and the normalized result.
|
||||
|
||||
This is the key UX shift: the system uses a curator-friendly text grammar at cell scope instead of forcing the curator to either type OCR-era symbols or manually edit every derived field.
|
||||
|
||||
## Implemented Foundation
|
||||
|
||||
The following groundwork is already implemented in the web app as of March 15, 2026:
|
||||
|
||||
- visible technical chrome has been removed from the primary lookup and table flows
|
||||
- lookup result cards now lead with gameplay outcome instead of parse metadata
|
||||
- the critical table browser is framed for play use rather than import administration
|
||||
- critical cells support re-parse from shared parser logic
|
||||
- advanced diagnostics have been separated from the primary editing flow
|
||||
- advanced curation now includes a generated-versus-current comparison view for re-parse review
|
||||
- critical cells now open with quick parse input derived from the imported result instead of requiring OCR-era symbol typing
|
||||
|
||||
These changes are real and complete, but they are no longer the active roadmap because the detailed acceptance checklist still has unfinished items.
|
||||
|
||||
## Remaining Implementation Phases
|
||||
|
||||
### Phase 1: Complete live lookup flow ergonomics
|
||||
|
||||
Status:
|
||||
|
||||
- implemented in the web app on March 15, 2026
|
||||
|
||||
Scope:
|
||||
|
||||
- add dice buttons to the attack and direct critical lookup inputs
|
||||
- support fast reroll without manual typing
|
||||
- tighten any remaining lookup prompts so a first-time GM can move through the flow without reading extra copy
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- both lookup flows support random roll entry without typing
|
||||
- the main lookup page fully satisfies the live-play checklist item for random lookup support
|
||||
|
||||
### Phase 2: Compact inline cell editor
|
||||
|
||||
Status:
|
||||
|
||||
- implemented in the web app on March 15, 2026
|
||||
|
||||
Scope:
|
||||
|
||||
- remove the dedicated preview panel from the critical cell popup
|
||||
- convert effect editing to dense inline rows with badges/icons and minimal controls
|
||||
- convert branch editing to the same compact inline model
|
||||
- remove redundant effect titles and any non-essential controls from the default edit surface
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- the popup spends its space on actual editing rather than preview duplication
|
||||
- common effect and branch corrections require less scrolling than the current popup
|
||||
- `direct_hits` has no unused `Target` field in the default editor
|
||||
- the default editor has no `Permanent` checkbox
|
||||
|
||||
### Phase 3: Generated versus overridden state model
|
||||
|
||||
Status:
|
||||
|
||||
- implemented in the web app on March 15, 2026
|
||||
|
||||
Implemented model:
|
||||
|
||||
- result-level override flags separate generated description and collection state from manual edits
|
||||
- effect rows and condition rows carry explicit origin keys plus override markers
|
||||
- re-parse now merges generated parser output with the current override state instead of replacing the whole editor payload
|
||||
- saved editor state is persisted so later edit sessions keep the same generated-versus-overridden boundaries
|
||||
|
||||
Scope:
|
||||
|
||||
- explicitly track which values are parser-generated and which values were manually overridden
|
||||
- ensure re-parse refreshes generated values without silently discarding intentional edits
|
||||
- define how save and future import refresh flows respect manual overrides
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- shared parsing can regenerate derived data without clobbering preserved overrides
|
||||
- the manual override model described in this document is implemented rather than only implied
|
||||
|
||||
### Phase 4: Compare and review workflow
|
||||
|
||||
Status:
|
||||
|
||||
- implemented in the web app on March 15, 2026
|
||||
|
||||
Implemented model:
|
||||
|
||||
- re-parse now returns the freshly generated parser output alongside the merged editor state
|
||||
- the editor captures the pre-reparse card as a review baseline before applying the merged state
|
||||
- advanced curation shows side-by-side cards for the prior edit, the fresh generated parse, and the merged post-reparse result when available
|
||||
- diff summary chips call out result-text, base-effect, and condition changes without requiring raw JSON inspection
|
||||
|
||||
Scope:
|
||||
|
||||
- add a clear comparison surface for generated result versus current edited result
|
||||
- let curators review what changed after re-parse before accepting or keeping overrides
|
||||
- keep this comparison workflow in advanced curation, not in the primary live-play path
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- curators can inspect generated-versus-current differences without reading raw JSON first
|
||||
- compare tooling exists for the override workflow described above
|
||||
|
||||
### Phase 5: Final tooling boundary cleanup
|
||||
|
||||
Status:
|
||||
|
||||
- implemented in the web app on March 15, 2026
|
||||
|
||||
Implemented model:
|
||||
|
||||
- the primary critical-cell editor now keeps only compact correction tools plus advanced review for generated-versus-current comparison
|
||||
- engineering-only parser metadata, source text, and payload inspection moved to a dedicated Diagnostics page in the main navigation
|
||||
- normal curation no longer mixes raw JSON and storage-facing diagnostics into the default correction flow
|
||||
|
||||
Scope:
|
||||
|
||||
- verify that normal curation mode contains only user-facing correction tools
|
||||
- move any remaining engineering-only diagnostics into a separate developer or admin surface if they still leak into curation mode
|
||||
- leave advanced curation available without forcing ordinary users through engineering concepts
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- the primary play flow stays clean
|
||||
- compact curation remains available
|
||||
- engineering diagnostics remain accessible without defining the normal correction UX
|
||||
|
||||
### Phase 6: Friendly quick parse input
|
||||
|
||||
Status:
|
||||
|
||||
- implemented in the web app on March 15, 2026
|
||||
|
||||
Implemented model:
|
||||
|
||||
- the editor now treats quick parse input as the primary generation surface
|
||||
- existing imported results are translated into quick parse notation on the fly when the editor opens
|
||||
- the popup shows a supported shorthand legend directly under the quick input field
|
||||
- generation supports all currently available effect types, including power-point modifiers such as `+2d10-3pp`
|
||||
- OCR glyph tokens remain accepted as compatibility aliases, but they are no longer the primary editing language
|
||||
|
||||
Scope:
|
||||
|
||||
- add a dedicated `Quick parse input` field distinct from OCR provenance
|
||||
- define the first-line prose rule plus affix and conditional-affix follow-up lines
|
||||
- support comma-separated affix tokens and user-friendly aliases such as `1mp`, `3s`, `3np`, `1hpr`, `-20`, and `+20b`
|
||||
- keep OCR glyph support only as a backward-compatible parser alias, not the primary typing model
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- a curator can type a valid result without entering `π`, `∑`, `∏`, or `∫`
|
||||
- the parser accepts the documented first-line-plus-affix-lines grammar
|
||||
- conditional affixes can be entered with `condition: affix, affix, affix`
|
||||
- the default editor teaches the friendly grammar instead of relying on symbol lore
|
||||
|
||||
### Phase 7: Parser trustworthiness and token review
|
||||
|
||||
Status:
|
||||
|
||||
- implemented in the web app on March 15, 2026
|
||||
|
||||
Implemented model:
|
||||
|
||||
- quick-parse generation now records explicit token-review items for unknown or partially parsed affix tokens instead of relying only on generic note strings
|
||||
- advanced review calls out unresolved tokens directly alongside generated comparison so curators can see what needs manual attention
|
||||
- shared affix parsing no longer consumes unsupported legacy matches silently, preventing recognized content from disappearing without review
|
||||
- regression coverage now includes unknown-token surfacing and keeps Arcane Aether B16 stable through load and re-parse flows
|
||||
|
||||
Scope:
|
||||
|
||||
- remove silent-loss behavior from generation
|
||||
- surface unknown or dropped tokens directly in compare/review
|
||||
- ensure known affix tokens produce stable effects across re-generation
|
||||
- add targeted examples and tests for problematic tables such as Arcane Aether
|
||||
|
||||
Acceptance criteria:
|
||||
|
||||
- a recognized affix token never disappears silently from the generated card
|
||||
- unknown tokens are shown explicitly to the curator in compare/review
|
||||
- example regressions such as Arcane Aether B16 are covered by tests
|
||||
|
||||
## Detailed Acceptance Checklist
|
||||
|
||||
The redesign should be considered successful when all of the following are true.
|
||||
|
||||
- A first-time GM can resolve an attack or critical without reading technical copy.
|
||||
- The main result card shows gameplay consequences without raw JSON or parse details.
|
||||
- The critical table browser feels usable during a session, not like an import admin screen.
|
||||
- Editing a critical cell starts from the rendered card and quick parse input, not persistence internals.
|
||||
- Adding an affix or condition is a small chip-driven action.
|
||||
- Shared parsing logic can regenerate most derived data from minimal quick parse input.
|
||||
- Dice buttons support random lookup flows without manual typing.
|
||||
- A curator can type common affixes without OCR-era symbols.
|
||||
- The compare workflow makes dropped or unknown tokens explicit.
|
||||
|
||||
## Risks And Tradeoffs
|
||||
|
||||
### Risk: loss of technical visibility
|
||||
|
||||
If technical detail is removed completely, curation becomes harder.
|
||||
|
||||
Mitigation:
|
||||
|
||||
- move technical detail to an advanced mode, not the primary mode
|
||||
|
||||
### Risk: parser and UI divergence
|
||||
|
||||
If the web app implements its own light parser, it will drift from the import tool.
|
||||
|
||||
Mitigation:
|
||||
|
||||
- one shared parsing assembly
|
||||
- one canonical normalized result contract
|
||||
|
||||
### Risk: override complexity
|
||||
|
||||
Generated fields and manual overrides can conflict.
|
||||
|
||||
Mitigation:
|
||||
|
||||
- explicit generated vs overridden state for editable sections
|
||||
|
||||
## Recommended Next Step
|
||||
|
||||
Implement Phase 7 next. The remaining parser gap is trustworthiness under imperfect input: unknown tokens still need stronger surfaced review, and no-silent-loss behavior should be enforced comprehensively across compare output and regression coverage.
|
||||
Reference in New Issue
Block a user