# System-Wide Paper Document Phase 0-1 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build the reusable system-wide paper-document foundation and apply it to the highest-priority warehouse documents: special inbound/outbound, production material outbound, and production ledger inbound settlement.
**Architecture:** Add generic `Document*` form components under `frontend/src/components/documentForms`, then make existing warehouse wrappers delegate to them so current warehouse documents do not break. Convert only the P0 warehouse forms in `InventoryLedgerView.vue` to the shared paper control language, preserving all existing data models, computed values, validation, submit functions, archive behavior, and backend APIs.
**Tech Stack:** Vue 3 SFC, Vite, project CSS in `frontend/src/styles/main.css`, Node built-in test runner.
---
## Scope
This plan covers:
- Phase 0: system-wide paper document component foundation.
- Phase 1: warehouse P0 documents.
- P0 warehouse documents: `特殊入库 / 特殊出库`, `生产出库`, `生产台账入库结算单`.
This plan does not cover:
- Reworking sales, purchase, receipt, quality, delivery, return pages beyond ensuring the new generic foundation does not break them.
- Backend archive schema changes. Existing `document_archives` and document archive routes remain unchanged.
- Business logic, inventory calculation, production calculation, PDF generation rules, or database migrations.
## File Structure
- Create `frontend/src/components/documentForms/DocumentFormShell.vue`: generic form shell around `DocumentPaper`.
- Create `frontend/src/components/documentForms/DocumentSection.vue`: generic paper section wrapper.
- Create `frontend/src/components/documentForms/DocumentActionBar.vue`: generic action bar that teleports to the paper bottom.
- Create `frontend/src/components/documentForms/DocumentField.vue`: generic paper field wrapper for input/select/textarea/read-only slots.
- Create `frontend/src/components/documentForms/DocumentSelectorPanel.vue`: paper-native panel for searchable select/multi-select controls.
- Create `frontend/src/components/documentForms/DocumentInlineSummary.vue`: paper-native summary strip.
- Create `frontend/src/components/documentForms/DocumentSettlePanel.vue`: paper-native settle/exception panel.
- Modify `frontend/src/components/documentForms/DocumentPaper.vue`: add generic action host while keeping warehouse-compatible host.
- Modify `frontend/src/components/documentForms/WarehouseDocumentFormShell.vue`: delegate to `DocumentFormShell`.
- Modify `frontend/src/components/documentForms/WarehouseDocumentSection.vue`: delegate to `DocumentSection`.
- Modify `frontend/src/components/documentForms/WarehouseDocumentActionBar.vue`: delegate to `DocumentActionBar`.
- Modify `frontend/src/views/InventoryLedgerView.vue`: convert P0 warehouse forms.
- Modify `frontend/src/styles/main.css`: add generic paper document styles and keep compatibility aliases.
- Modify `frontend/src/views/InventoryLedgerView.test.js`: add P0 regression checks.
- Create `frontend/src/components/documentForms/documentForms.test.js`: component foundation source-level regression checks.
## Task 1: Lock Generic Document Foundation Tests
**Files:**
- Create: `frontend/src/components/documentForms/documentForms.test.js`
- Read: `frontend/src/components/documentForms/DocumentPaper.vue`
- Read: `frontend/src/components/documentForms/WarehouseDocumentFormShell.vue`
- Read: `frontend/src/styles/main.css`
- [ ] **Step 1: Write the failing test**
Create `frontend/src/components/documentForms/documentForms.test.js`:
```js
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { readFileSync } from "node:fs";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
function readComponent(name) {
return readFileSync(join(__dirname, name), "utf8");
}
const mainCss = readFileSync(resolve(__dirname, "../../styles/main.css"), "utf8");
describe("document form foundation", () => {
it("provides generic system-wide paper form components", () => {
[
"DocumentFormShell.vue",
"DocumentSection.vue",
"DocumentActionBar.vue",
"DocumentField.vue",
"DocumentSelectorPanel.vue",
"DocumentInlineSummary.vue",
"DocumentSettlePanel.vue"
].forEach((name) => {
const source = readComponent(name);
assert.match(source, /document-/);
});
});
it("keeps warehouse wrappers as compatibility adapters over generic document components", () => {
assert.match(readComponent("WarehouseDocumentFormShell.vue"), /import DocumentFormShell/);
assert.match(readComponent("WarehouseDocumentSection.vue"), /import DocumentSection/);
assert.match(readComponent("WarehouseDocumentActionBar.vue"), /import DocumentActionBar/);
});
it("exposes a generic action host without removing the existing warehouse host", () => {
const paper = readComponent("DocumentPaper.vue");
assert.match(paper, /data-document-action-host/);
assert.match(paper, /data-warehouse-document-action-host/);
});
it("defines generic document paper controls and keeps warehouse aliases compatible", () => {
assert.match(mainCss, /\.document-form-shell/);
assert.match(mainCss, /\.document-section-grid/);
assert.match(mainCss, /\.document-paper-field/);
assert.match(mainCss, /\.document-selector-panel/);
assert.match(mainCss, /\.document-inline-summary/);
assert.match(mainCss, /\.document-settle-panel/);
assert.match(mainCss, /\.warehouse-paper-control-grid/);
});
});
```
- [ ] **Step 2: Run test to verify it fails**
Run:
```bash
cd frontend
node --test src/components/documentForms/documentForms.test.js
```
Expected: FAIL because `DocumentFormShell.vue`, `DocumentSection.vue`, `DocumentActionBar.vue`, `DocumentField.vue`, `DocumentSelectorPanel.vue`, `DocumentInlineSummary.vue`, and `DocumentSettlePanel.vue` do not exist yet.
## Task 2: Add Generic Document Components
**Files:**
- Create: `frontend/src/components/documentForms/DocumentFormShell.vue`
- Create: `frontend/src/components/documentForms/DocumentSection.vue`
- Create: `frontend/src/components/documentForms/DocumentActionBar.vue`
- Create: `frontend/src/components/documentForms/DocumentField.vue`
- Create: `frontend/src/components/documentForms/DocumentSelectorPanel.vue`
- Create: `frontend/src/components/documentForms/DocumentInlineSummary.vue`
- Create: `frontend/src/components/documentForms/DocumentSettlePanel.vue`
- Modify: `frontend/src/components/documentForms/DocumentPaper.vue`
- [ ] **Step 1: Add `DocumentFormShell.vue`**
Create `frontend/src/components/documentForms/DocumentFormShell.vue`:
```vue
```
- [ ] **Step 2: Add `DocumentSection.vue`**
Create `frontend/src/components/documentForms/DocumentSection.vue`:
```vue
{{ value || "-" }}