比较提交
37
次代码提交
70af0c6b9a
...
main
| 作者 | SHA1 | 提交日期 | |
|---|---|---|---|
|
|
c251729267 | ||
|
|
3a4a5969bb | ||
|
|
36b949ecf6 | ||
|
|
5469db585c | ||
|
|
89f46790e8 | ||
|
|
314274b5a9 | ||
|
|
377bda322e | ||
|
|
b85ff6a9bf | ||
|
|
3c5cc544f5 | ||
|
|
91fe31f0db | ||
|
|
db919dc6f6 | ||
|
|
4a5cd8f2b3 | ||
|
|
2063ff1e93 | ||
|
|
45737ccb9a | ||
|
|
c1034bbe38 | ||
|
|
beb9f02c19 | ||
|
|
1c4633b62a | ||
|
|
8e17e8dfa1 | ||
|
|
98bab39798 | ||
|
|
18315d1183 | ||
|
|
5a7a13524e | ||
|
|
ce11dea976 | ||
|
|
4c37fceeb4 | ||
|
|
1dd840655b | ||
|
|
7a48a1e76f | ||
|
|
431c36eae3 | ||
|
|
2e00d30fd0 | ||
|
|
14aee82d5c | ||
|
|
db28706177 | ||
|
|
3fb33fe93c | ||
|
|
b88790d396 | ||
|
|
b639422211 | ||
|
|
1989f666ac | ||
|
|
f6d1025d85 | ||
|
|
9cbefdf243 | ||
|
|
b6f0c83608 | ||
|
|
a6ff2dc3b1 |
@@ -127,6 +127,35 @@ QA script patterns over new abstractions.
|
||||
|
||||
### Receipt OCR Matching Service Boundary
|
||||
|
||||
- Ordinary bank-payment evidence must retain a versioned `document` classification
|
||||
(`bank_receipt`, `non_final`, `unknown`) in the encrypted recognition/proposal.
|
||||
Bound local PDF inspection by input size, page count, worker memory and time;
|
||||
unreadable text remains unknown. Preserve provider disclaimers as restrictions.
|
||||
A title, matching fields, or absence of an extracted disclaimer is not sufficient.
|
||||
Automatic matching needs a supported final receipt, explicit successful payment
|
||||
and no incoming direction or conflicting document facts. Keep this gate in
|
||||
evidence construction and final reconstruction, not the shared `matchBankSlip`
|
||||
helper used by failed/voided/terminal-fact comparisons.
|
||||
- Manual `paymentProof` must attest a checked original and record the basis/note.
|
||||
`booked_debit` requires a valid non-future bank booking date and an empty original
|
||||
success status; preserve `transactionStatusRaw=null` rather than fabricate bank
|
||||
wording. New proof always needs the batch's applicable confirmation mode.
|
||||
Non-final disclaimers, incoming direction and known contradictory facts cannot
|
||||
be removed by manual corrections. Manual-source evidence is not automatic OCR.
|
||||
Browser fixtures entering synthetic receipt facts manually must supply the
|
||||
checked-original proof supported by that fixture's actual contents; bounded
|
||||
parsing may legitimately stay unknown. Report only safe document categories
|
||||
and allowlisted business reason codes on failure, never raw banking fields.
|
||||
- Old unconsumed evidence without document inspection cannot default to final.
|
||||
Finance may explicitly POST `receipt-attachments/:attachmentId/document-check`
|
||||
with `expectedVersion`; use the existing batch/claim/attachment locks, scope and
|
||||
maker checks. Verify stored bytes against size/SHA, create a new version and audit
|
||||
atomically, preserve history and never call cloud OCR. Old manual approval does
|
||||
not transfer to the new version. Reinspect and settle under the same batch lock;
|
||||
runtime tests must cover both orders, stale versions and audit rollback.
|
||||
A historical OCR result with zero known pages must still expose the inspection
|
||||
action; reject malformed/out-of-range counts without allocating from them.
|
||||
|
||||
- Failed evidence persistence is not OCR failure. In a separate bounded transaction,
|
||||
lock the batch then conditionally update the attachment by version/SHA/processing
|
||||
and active governance predicates. Persist only allowlisted system_failed,
|
||||
@@ -1115,11 +1144,34 @@ await canReadReimbursementBusinessFact(prisma, reimbursement, employee.id);
|
||||
## Company Loan Principal And Retired ERP Consumers
|
||||
|
||||
- `09-17-company-loan-principal-repayment` adds the explicit `loan_repayment` payment source: one retained repayment/batch/item, multiple allocations to confirmed same-company/lender/CNY loans. Preserve original principal and confirmed opening evidence; Decimal reservations and settlements must not exceed opening outstanding principal. SQL checks/deferred triggers complement locked application validation.
|
||||
- Loan management requires an explicit finance/finance_mgr role plus loan.manage. Independent review requires active manager/CEO with review permission and excludes maker, submitter and lender OA identity; admin wildcard cannot replace these identities. External lenders require explicit verified no-OA identity. Account changes revoke identity confirmation and invalidate old unpaid snapshots.
|
||||
- Loan management requires an explicit finance/finance_mgr role plus loan.manage. Independent review requires active manager/CEO with review permission and excludes maker, submitter and lender OA identity; admin wildcard cannot replace these identities. External lenders require explicit verified no-OA identity. Manual account changes revoke identity confirmation and invalidate old unpaid snapshots; explicit employee-source refresh renews confirmation under the checks below.
|
||||
- `LoanLenderAcknowledgement` is the lender's declaration, separate from company-representative authority. Finance proposes 1–50 unconfirmed loans for one verified employee lender/company, freezing principal, opening balance/date, incoming originals and identity versions. `loan.acknowledge_own` permits only the frozen employee's own records/originals/decision; manager or administrator status cannot substitute for that identity. Keep the finance maker distinct, originals checked on confirmation, strict request-key/hash binding and audit atomicity.
|
||||
- Header, scope snapshots and the single confirm/return decision are immutable. SQL triggers invalidate the whole group permanently after any member's material terms, incoming original or lender association/version changes; restoring source values cannot reactivate it. Additional accounting evidence, balance confirmation and ordinary loan version increases do not invalidate. Returned/invalid statements can be reissued; overlapping current pending/confirmed scopes cannot. After balance confirmation, reissue is allowed only with invalidated declaration history for that loan; never rewrite the original balance confirmation, loan version or terms. Service, SQL scope guard and `lenderAcknowledgementRenewable` UI projection must agree. Purely paper-confirmed loans do not gain first-time online declaration scope.
|
||||
- `assertEvidenceComplete` accepts paper agreement OR a valid confirmed declaration. Incoming originals, accounting reconciliation and required historical-repayment adjustment evidence stay mandatory at balance and repayment consumers. Balance confirmation must lock lender then loan, reread the lender association and evidence, and refuse after a concurrent invalidation; locking only that loan misses sibling-original and identity changes. Declaration writes lock lender → sorted loans → declaration → employee (`FOR NO KEY UPDATE`). Preserve existing payment-batch lock order.
|
||||
- Declaration-scoped downloads expose only frozen incoming originals after current source and physical digest checks, with purpose, audit and no-store; never expose accounting attachments or other loans via this scope. JSON POSTs through `apiRequestBlob` must explicitly set `Content-Type: application/json`. UI requests are actor-scoped and cancellable; a late 401 cannot replay an old decision under a new account. Ordinary employees have no permanent company-loan entry in workspace navigation, NavLinks fallback or MobileMePage; keep own-only route access independent of navigation visibility. Finance and company representatives retain their existing entries.
|
||||
- Proposals create one `loan.lender_acknowledgement_requested` in-app notification for the frozen lender employee, in the same transaction as the declaration and audit. Idempotent retries do not create another notification, and a notification write failure rolls back all three. Keep copy free of lender names, amounts, bank details and originals; do not add this type to IM support or external delivery/outbox. Desktop/mobile notification targets use `loan_lender_acknowledgement` and the declaration ID to open details via `lenderAcknowledgementId`, independent of the list page. The URL ID is the single source of current selection and overrides proposal mode; ID changes clear drafts/confirmation state and cancel old requests. Existing ownership and invalidation checks still govern historical links.
|
||||
- Verify declaration contracts with `RUN_ISOLATED_LOAN_ACK_ONLY=1` on the isolated loan runner and `RUN_ISOLATED_LOAN_BROWSER=1` for desktop/mobile originals, confirm/return, accounting requirement and actor-switch cancellation. Retain full-loan regression. Migration `20261010010000_loan_lender_acknowledgements` adds history without backfilling acceptance; preserve it on rollback. An older application cannot consume online-only agreement evidence, so post-use rollback requires compatibility planning.
|
||||
- Employee-source preview/link/refresh additionally require `employee.bank.read` or `employee.bank.manage`. `loanLenderEmployee` reads the active employee, supported bank and encrypted account on the server; the strict write body carries employee/company IDs, source version and an explicit confirmation, never client-supplied account/name replacements. A source version binds actual source fields, ciphertext and the chosen debtor, not only `updated_at`. Missing, unreadable, stale or unsupported sources reject without a partial lender/audit write; previews expose masks only.
|
||||
- Same-company employee association includes archived/history rows in duplicate checks, including the old identity-confirmation entry. Reuse a unique matching lender; reject ambiguous links and require explicit refresh for different data. Existing-lender actions lock lender before sorted employees. New creation never locks an existing lender after employees: finish and reacquire in the correct order if a link appeared. Use employee `FOR NO KEY UPDATE` to serialize association/source edits while allowing audit/actor FK `KEY SHARE`; `FOR UPDATE` can deadlock against another employee's refresh/audit. Persist and serialize each actor's request-key binding for both creation and reuse, with audit in the same transaction.
|
||||
- Explicit employee refresh rejects reserved repayments, checks source/identity/account versions and advances both lender versions with renewed finance identity confirmation. This invalidates old company-representative grants without changing principal or historical payment snapshots. Employee-linked lenders cannot use the manual account PATCH; employee-master edits alone never rewrite the loan copy. Verify the actual audit-FK interleaving, duplicate/legacy races, refresh versus repayment creation, audit rollback and reverse mutations using `RUN_ISOLATED_LOAN_EMPLOYEE_ONLY=1` and optional `RUN_ISOLATED_LOAN_EMPLOYEE_MUTATIONS=1` on the isolated loan runner; retain the original full-loan regression.
|
||||
- Related-party loans use the explicit `loanApprovalPolicy` branch, not a global reviewer exception. Finance proposes `LoanRelatedAuthorization` for one company/lender, its verified employee identity and specific confirmed loans; that designated active manager/CEO confirms it. Grants, scope and lifecycle events are append-only. Resolve the latest confirmed version without falling back to an older grant when the new scope is narrower or stopped; a superseded version cannot receive stop events.
|
||||
- The authorization selector calls `GET /loan-lenders?eligible=related_authority` under the existing finance/`loan.manage` gate. Filter verified, employee-linked, non-self lenders before both pagination and count; this selector filter does not replace final representative-role/scope checks. Omitted `eligible` preserves the ordinary list, unsupported values reject, and opening the dialog resets to page 1. Browser pagination waits for a loaded, changed option list and checks the intended IDs, including cache hits; a network response alone is insufficient. After evidence upload, select the exact returned evidence ID when its option is attached, never the last option or placeholder. Verify genuine page 3 with desktop/mobile scope registration and designated confirmation, an unchanged-page counterexample, and distinct synthetic payer/payee accounts for direction refusals. Set `RUN_ISOLATED_LOAN_BROWSER_DIAGNOSTIC` to `authorization-pagination` or `refund` with the existing isolated DB/browser switches; diagnostic checks do not confer release eligibility.
|
||||
- Freeze `LoanRepayment.approval_mode`, `authorization_id` and `approval_context` at creation. Only `related_party` waives the designated payee-conflict reason. Keep maker/submitter/exporter/uploader/manual-entry/proposer conflicts as a separate union of all history, including voided and superseded materials; do not remove the payee employee from that union. Reject designated-reviewer participation at maker entry points as well as decision/final-consumer checks. Old independent loans and shared reimbursement/travel rules do not switch modes.
|
||||
- New payment creation/approval/export checks current payment authority; new reconciliation decisions and final reservation release check current reconciliation authority. `decisionFields()` stores purpose, actual actor, target, scope, authorization version/event and conflict identities. `assertDecision()` validates immutable historical provenance at receipt reconstruction, settlement, terminal/recovery consumption and bank-event booking; it does not require the old reviewer to remain active or the old grant to remain enabled. Stopping payment and stopping reconciliation are separate events. Previously approved bank facts remain usable if their evidence and all money/transaction checks still hold.
|
||||
- Related payment review may return an application with `decision=reject` and a reason. This records an immutable decision without releasing reservations; it cannot later be approved, exported or paid. Finance uses safe never-sent cancellation and creates a corrected application. The UI, responsibility and notification consumers must distinguish this from an approved payment or an independent review.
|
||||
- Shared loan error reasons must describe confirmation under the batch's rules rather than require independent review for every mode. Keep registry text, client mapping and fixed message fixtures together; independent-only reviewer failures and Q6 still state their independent-review requirements. Wording does not relax any actor or evidence guard.
|
||||
- Creation locks lender, sorted loans, then day sequence; it never waits for a previously existing batch. Existing settlement locks batch, global receipt identity, attachments, lender/reviewer, sorted loans. Source maintenance never locks an existing batch. Claims, allocation settlement, batch/item payment facts and audit commit atomically.
|
||||
- Export/upload marks bank outcome unknown without reducing principal. Unknown/in-transit cannot release reservations. A never-sent cancellation or independently reviewed, current and exactly matching failed-bank evidence may release; preserve the old request. Paid and terminal allocation/history facts are immutable. Accounting handoff is a separate audited reference, not a second payment state.
|
||||
- Authority lifecycle changes lock the lender and never wait for an existing batch. Existing-batch decisions acquire the lender only after the batch/receipt locks, then repeat authority checks; creation locks lender and loans and creates a new batch. Test both interleavings of stopping authority against approval, export, fact confirmation and final release; do not introduce lender-to-existing-batch lock inversion.
|
||||
- Export/upload marks bank outcome unknown without reducing principal. Unknown/in-transit cannot release reservations. A never-sent cancellation or current, exactly matching failed-bank evidence confirmed under the frozen approval mode may release; preserve the old request. Paid and terminal allocation/history facts are immutable. Accounting handoff is a separate audited reference, not a second payment state.
|
||||
- Repayment BIFF8 uses encrypted account-name snapshot and purpose 还款/归还借款本金; receipt matching/manual review explicitly supports loan source and shares the reimbursement claim/alias namespace. Real bank/OCR acceptance is not established by synthetic recognition tests.
|
||||
- Loan evidence uses governed PDF/image bytes, random object keys, bounded content/hash checks and audit-before-download. Finance reads the ledger; reviewers can download only materials in an eligible payment's allocations, not the full ledger.
|
||||
- Loan evidence uses governed PDF/image bytes, random object keys, bounded content/hash checks and audit-before-download. Finance reads the ledger; reviewers can download only materials in an eligible payment's allocations or their own designated authorization scope, not the full ledger. Related reviewers retain scope-limited historical reading after authority stops while still requiring current reader eligibility. Full accounts/originals require purpose, audited access and no-store responses; do not grant global `loan.manage` to make review pages accessible. UI capabilities project the same policy and never replace transaction-level authorization.
|
||||
- SR recovery of a still-reserved `confirmed_failed`/`confirmed_not_paid` batch never rewrites the bank outcome or reopens export/payment. Once any recovery round exists, final cancellation must consume the latest valid approval; rejected, withdrawn or superseded rounds must not fall back to the original cancellation path. Consumption, allocation release, batch cancellation and audit share the transaction; deferred SQL checks protect the release/consumption pairing.
|
||||
- Recovery snapshots bind material revisions, submission/fact/receipt identities, verification versions, participants under the explicit approval mode and the current same-amount candidate set. Material writers (including OCR persistence) serialize on the batch; candidate formation also locks the lender. A local batch revision alone cannot detect another batch becoming a candidate. Validate at submission, approval and final cancellation, with physical document digest checks before release.
|
||||
- JSONB can reorder object keys. Compare snapshots using recursive key-canonicalized hashes, retaining array order, rather than hashing raw `JSON.stringify` results before and after storage. Keep snapshot payloads out of public response mapping. New evidence for the same bank transaction still requires new review.
|
||||
- Verify loan and recovery paths through `RUN_ISOLATED_LOAN_DB_TEST=1 node scripts/qa/test-company-loan-db.cjs` with the locked BIFF8 Python environment: real HTTP/evidence/OCR, stale-round repair, no fallback after withdrawal, atomic rollback and deterministic interleavings with evidence, submissions, OCR and candidate formation. Add `RUN_ISOLATED_LOAN_BROWSER=1` for actual desktop/mobile actions, including the two-actor related workflow; mock only cloud OCR output. `RUN_ISOLATED_LOAN_RELATED_ONLY=1` selects the related suite, and `RUN_ISOLATED_LOAN_RELATED_UI_ONLY=1` is browser setup only and must report HTTP as not run. Preserve the old independent regression; inline self-review is not independent review.
|
||||
- Manual no-submission is a separate terminal fact, never a bank termination claim: fixed documentary categories, complete reviewed export/submission inventory, two distinct independent reviews, material/candidate snapshot and physical digest checks at final release. An empty submission attestation is valid only for actual exports and no historical submission rows; withdrawn submissions do not prove non-submission.
|
||||
- Q6 manual no-submission is unavailable in related-party mode at proposal, review and final release, with database guards as well as hidden controls. Neither two-person confirmation nor OCR supplies missing attribution, instruction termination or return evidence. Once related decisions exist, do not downgrade to code that cannot interpret their mode/provenance or delete those fields; stop new payments and use an approved compatible fix.
|
||||
- Late-payment supplements and bank returns use an append-only ledger, not exportable payment batches. Include supplemental principal in both application balance calculations and SQL capacity checks. Their keyed transaction claims must exclude ordinary receipt claims and aliases in both directions under the shared receipt lock. Freeze causes close independently; partial returns and unresolved reservation conflicts keep their own causes active. The ordinary pre-payment gate must not block factual reconciliation.
|
||||
- ERP-specific API/adapters/jobs/enqueues are retired by `09-17-erp-exclusive-retirement`. Shared outbox/notification/WeCom and historical records remain. New ERP enqueue and direct dispatch reject; pending selection excludes `erp.*`; historical retry returns `integration.erp_retired` without mutating records. Never restore these retired consumers solely to satisfy old success-path tests.
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,22 @@ operations require explicit approval and evidence.
|
||||
`deploy/trialrun/.env.example` before deployment; `deploy/trialrun/deploy.sh`
|
||||
runs `node deploy/trialrun/validate-env-contract.js` at step 0 and must fail
|
||||
if the example contract drifts.
|
||||
- Current backup policy is manual Tencent Lighthouse snapshots only, as selected
|
||||
in `08-28-production-arm-backup-transfer-incident/prd.md`. Do not introduce
|
||||
object storage, ARM/hyinda-20c backup or automatic snapshot rotation by default.
|
||||
Before each approved production deployment, confirm the OA target and coverage
|
||||
of database/attachment disks, then wait for snapshot creation to succeed.
|
||||
Record target/coverage confirmation, creation time and success without resource
|
||||
IDs. Check current console quota before any separately authorized old-snapshot
|
||||
deletion; preserve an existing successful recovery point during rotation.
|
||||
Recoverability is limited to existing snapshot times and covered disks; this
|
||||
policy provides neither a daily recovery-point guarantee nor an independent copy.
|
||||
- Policy selection does not prove automatic backups have stopped. Follow the
|
||||
same task's reviewed transition plan: preserve the service-based deployment
|
||||
identity contract, adapt backup timer checks before disabling those timers,
|
||||
and separately approve remote configuration changes. Preserve historical
|
||||
backups and independent public-health monitoring. Legacy backup contracts below
|
||||
describe retained tooling; they do not authorize re-enabling backup services.
|
||||
- After deployment, report commit hash, `/ready`, public smoke results and
|
||||
whether the user can test.
|
||||
- Real business writes are manual unless the current Trellis task explicitly
|
||||
@@ -2489,6 +2505,7 @@ DEPLOY_SERVER=<tencent-oa-production-target> bash deploy/trialrun/deploy-existin
|
||||
- An early aggregate item fails -> all independent items still run, the fixed summary reports every FAIL, and no remote write begins.
|
||||
- Root SSH returns transport 255 -> `root_identity_unavailable`; remote 126/127 or missing probe marker -> `refresh_program_unavailable`.
|
||||
- Helper runs but final service build differs -> `unit_build_not_refreshed`; builds match but any timer is disabled/inactive -> `timer_not_active`.
|
||||
- Backup mode file `/etc/hyb-oa-backup-mode` absent -> automatic mode, all backup and ops timers must be enabled/active. Content exactly `manual_snapshot` (root-owned regular file) -> the three automatic-backup timers must be disabled/inactive, otherwise `backup_timer_not_disabled` (45); `hyb-oa-warch3-ops.timer` stays required (`timer_not_active`). Any other content, symlink or ownership -> `backup_mode_invalid` (44). In manual mode every backup `.service` must also be `inactive` or `failed`; an in-flight run -> 45. `probe` runs the same mode and timer/service checks, so a mismatch fails the pre-deploy aggregate as `refresh_program FAIL` (run the forced-command `probe` directly to read the category on stderr) before any release write; `refresh` re-checks after the release. Never mask or delete backup units: deploy identity still reads the daily backup service environment.
|
||||
- A similarly named environment key such as `OLD_BUILD_SHA` matches the active value while exact `BUILD_SHA` remains stale -> treat the service as stale; build verification parses exact keys and applies the last systemd override.
|
||||
- Post-deploy installer still embeds the previous build SHA, any managed timer is inactive, or the real backup/watchdog fails runtime identity or off-host freshness -> deployment recovery remains incomplete even when `/ready` is green.
|
||||
- A later deployment attempt is blocked by `backup_build` after `DEPLOYED_BUT_CONTRACT_REFRESH_FAILED` -> expected fail-closed behavior; repair with direct forced-command `refresh`, not another application release.
|
||||
|
||||
@@ -10,6 +10,17 @@
|
||||
|
||||
## Receipt Verification Dialog
|
||||
|
||||
- Show document nature separately from extracted transaction status. A booked
|
||||
official debit receipt may use the actual booking date and checked-original
|
||||
declaration; do not ask the operator to invent a successful bank status.
|
||||
Show that basis to the reviewer and keep save/review separate from settlement.
|
||||
Non-final receipts or contradictory directions have no manual override.
|
||||
- Old evidence needing local document inspection exposes an explicit finance
|
||||
action in the existing dialog; retain history and explain the need to recheck.
|
||||
Reset document-proof choices along with corrections on refresh. Verify the
|
||||
actual desktop/mobile proof entry, required original check, applicable reviewer,
|
||||
final settlement and non-final refusal through the rendered dialogs.
|
||||
|
||||
- When readiness is unmet and an active receipt has a system/key/snapshot failure,
|
||||
the batch banner must direct prerequisite repair, not an unavailable verification
|
||||
dialog. This is display only: a retained failed attachment must not block other
|
||||
@@ -29,6 +40,13 @@
|
||||
actions when false; actual review still checks role, permission and all participants.
|
||||
Save/review never call payment execution or upload.
|
||||
|
||||
## Employee Lender Source Selection
|
||||
|
||||
- The default lender action uses `LoanEmployeeLenderDialog` to select an existing employee and confirm the debtor company, name, bank and masked account. Keep employee/company selectors explicitly labelled; do not add duplicate account/name inputs or infer the debtor solely from employment. Missing data directs qualified users to the existing employee-maintenance page; preserve an explicit non-employee route.
|
||||
- Source query keys include actor, employee and company and forward `AbortSignal`; hide cached summaries without current bank-read permission. Disable background form refetch, clear the confirmation on explicit reload/source changes, and require a separate explicit refresh for differing existing lender data. Show the in-flight block and the need to renew company-representative authority after refresh.
|
||||
- Both employee link and refresh writes pass the component's abort signal through `saveLoanAction(path, body, method, signal)`. Abort on unmount/identity change as well as checking actor before success callbacks: a callback guard alone cannot prevent a late 401 from replaying the old POST with the new session. This is a scoped fix, not a claim that all older application mutations have this lifecycle.
|
||||
- Browser acceptance uses the existing isolated loan runner with `RUN_ISOLATED_LOAN_BROWSER=1`: actual desktop/mobile employee selection, historical loan/balance setup and two-person authority confirmation. Test delayed 401 responses across real logout/login in one document, canceled old writes and unchanged lender/audit data; preserve successful same-identity refresh/retry and the original non-employee workflow. Synthetic data and bank tests do not grant production payment authority.
|
||||
|
||||
## Source Of Truth
|
||||
|
||||
- Reminder cooldown hints render server UTC timestamps in Asia/Shanghai with an
|
||||
@@ -159,6 +177,8 @@ and verification contracts. Do not copy broad aesthetic guidance from
|
||||
- At the narrowest viewport where the fixed sidebar appears, the main detail column is at least `560px`, the action column is at least `280px`, and the document has no horizontal overflow beyond a `2px` rendering tolerance.
|
||||
- Business identifiers and normal company-time date strings use DOM line-count or geometry assertions; `position: sticky` alone is not proof that the layout is usable.
|
||||
- A Playwright spec writes screenshots only to its own current output directory. Never reuse an archived Trellis task's evidence directory as a live test target.
|
||||
- Before a first screenshot after SPA navigation, assert the intended page identity and required controls are ready (for example, login heading and identifier visible, submit enabled). `goto`/load or font completion alone does not prove React has rendered the intended view. Preserve the original screenshot and test budget; do not convert capture failures into retries or assume a screenshot error proves authentication failed.
|
||||
- When comparing alignment inside an animated ancestor (for example `.page-scaffold`'s `page-reveal`), read all relevant `getBoundingClientRect()` values in one synchronous browser `evaluate`/`evaluateAll` callback. Sequential `boundingBox()` calls, or calls grouped with `Promise.all`, can observe different animation frames. Keep the original alignment assertions and pixel tolerances; do not hide the race with sleeps, retries or disabled page animations.
|
||||
|
||||
### 4. Validation & Error Matrix
|
||||
|
||||
@@ -253,6 +273,7 @@ and verification contracts. Do not copy broad aesthetic guidance from
|
||||
- A spec that depends on Playwright route mocks must block Service Workers when
|
||||
it can run a PWA build. Do not rely on Service Worker installation or takeover
|
||||
timing to keep requests visible to `page.route`.
|
||||
- Cover both default `{ page }` fixtures and manually created contexts. A mobile `browser.newContext({ serviceWorkers: "block" })` does not protect the default desktop fixture; register full-navigation refresh/profile response witnesses before navigating and verify their synthetic source when diagnosing session loss.
|
||||
- Vite dev success is not equivalent evidence: the generated PWA worker is a
|
||||
production-build behavior and may be absent in dev.
|
||||
- Blocking the worker is a fixture boundary, not an authentication bypass. The
|
||||
@@ -337,6 +358,7 @@ test.beforeEach(async ({ page }) => {
|
||||
- Synthetic APIs must be served by a loopback HTTP harness. Do not use `page.route` or `context.route`, because a real Service Worker owns worker-originated requests.
|
||||
- Switch the same server/origin from build A to B, close the A page while retaining the BrowserContext, then revisit the same route. Do not change port, hostname or profile.
|
||||
- After switching to B, test code must not reload, clear cookie/cache, unregister a worker, create another BrowserContext or emulate hard refresh. Application-owned update behavior is the subject under test.
|
||||
- Wait for B's document version with a locator attribute assertion within the existing convergence deadline. A raw `page.evaluate` inside `expect.poll` can throw when the application's expected navigation destroys the old execution context. Keep the version expectation, deadline and all joint witnesses; do not hide arbitrary errors or add test-owned navigation.
|
||||
- Prove B with a joint witness: controller change or worker version change, controller equals the active registration, browser-fetched no-store `sw.js` fingerprint matches build B, document SHA is B and a B-only hashed asset loaded successfully. The constant `/sw.js` URL alone is not version evidence.
|
||||
- Assert the business route and synthetic session survive, old-only hashed assets leave Cache Storage, and there are no login fallbacks, JS/CSS 404s, chunk/preload errors, page errors or reload loops.
|
||||
- If the first B witness fails, freeze the safe ledger and stop. Do not add a second navigation or reload to turn the first failure into an intermittent result.
|
||||
@@ -997,7 +1019,9 @@ point and prevents each route from inventing a different title/action layout.
|
||||
hidden unless `leave.manage`; attendance correction forms are hidden unless
|
||||
`attendance.manage`. Labels must say `OA 应急` / `提交应急审批` /
|
||||
`提交应急修正` instead of generic `提交`.
|
||||
- When a page repeats the same title in the page header and a content section,
|
||||
- Title assertions should use an exact heading role within the intended panel;
|
||||
broad `getByText("票据详情")` can also match transient loading copy. When a
|
||||
page repeats the same title in the page header and a content section,
|
||||
Playwright assertions should target the page header (`h1` or the header test
|
||||
id) rather than `getByRole("heading", { name })`, which becomes ambiguous.
|
||||
- `个人设置` stays in the topbar account menu. Notifications stay in the topbar
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# 生产到 ARM 备份传输中断设计
|
||||
|
||||
## 2026-10-05 手动快照切换方案(本地适配已完成,远端切换待批准)
|
||||
|
||||
用户已选定仅手动快照,本节替代下方历史修复路径。用户 2026-10-05 批准后本地适配已实施并验证(结果见 implement.md);远端切换尚未执行,需另行批准。
|
||||
|
||||
1. 发布适配:`scripts/refresh-deployment-contract.sh` 的 `verify_timers` 当前强制要求三个备份 timer enabled/active;`deploy-existing.sh`、生产身份引导器和聚合检查仍从 daily service 读取部署身份。已增加显式、受控的手动快照模式(根属 `/etc/hyb-oa-backup-mode` 内容为 `manual_snapshot`),校验备份 timer disabled/inactive 且备份 service 已退出(inactive/failed),`probe` 部署前与 `refresh` 部署后均检查,保留身份、构建、数据目录及非备份运维 timer 的验证。不得删除单位、全局跳过 timer 检查或靠错误吞并放行。
|
||||
2. 本地验证:扩展既有发布合同测试,覆盖手动模式三个备份 timer 停用可通过、意外启用失败、非备份 timer 失败仍阻断及旧模式回归。受控入口的模式配置与候选版本一并绑定。用户回传 `f6d1025d` 同模型独立只读复核通过、无阻断项;本轮仅补其测试与说明缺口,原结论不自动延伸到后续新提交。
|
||||
3. 远端切换范围:生产 `hyb-oa-automatic-backup-{daily,watchdog,drill-reminder}.timer` 与 ARM `hyb-oa-offhost-deadman.timer`。先核实际单位及既有运行状态;先禁用定时器阻止新任务启动,再有界等待在途 service 退出(上限预先写定),超时停止切换并报告、不强杀。执行批准中须预先选择超时处置:允许回滚则恢复本次停用的 timer 原启用状态并验证自动模式;选择保持停用则不写模式文件,明确记录“切换未完成、部署被阻断”,等待后续处置。没有获批回滚时不擅自重新启用,不将该中间态报告为完成;最终核验含对应 service inactive/failed。ARM dead-man 由用户 sudo 停用并单独核验,生产侧 `refresh` 成功不代替 ARM 核验。源码默认名称须与现场一致,不猜测替代单位。
|
||||
4. 保留 unit 文件及其环境、历史归档/partial、状态、凭据和共享告警工具,不调用带删除行为的 installer uninstall。公网健康探针与 `hyb-oa-warch3-ops.timer` 不在备份停用范围,hyinda-20c 未安装本项目备份任务,无迁移或清理动作。
|
||||
5. 顺序为先完成兼容适配、再获批部署适配并停用定时器、最后只读核验与记录。执行前保留旧模式/单位启用状态作为回退依据;出现异常停止,恢复旧模式和定时器需在本次获批回滚范围内执行。不得出现脚本仍强制 active 而定时器已关闭的未处理状态。
|
||||
|
||||
安装前置:`install-deployment-contract-refresh.sh` 从所在代码目录的 `scripts/refresh-deployment-contract.sh` 复制 helper,不会自动取得本地新提交。必须先把最终获批提交中的安装器与 helper 送达生产目标代码目录,校验来源提交和文件摘要,再安装;不能在尚为旧源码的目录直接执行 installer。来源同步也是远端写入,纳入切换批准清单,不把它等同于应用发布或默认重启 OA。
|
||||
|
||||
回滚副作用:生产三个备份 timer 与 ARM dead-man 的生成配置均为 `Persistent=true`。若停用期间错过日历触发点,`enable --now` 可能立即补跑备份/新鲜度检查/季度提醒或 dead-man,并可能产生告警。现场须核对实际配置;回滚授权应包含该可能的自然补跑和通知,不承诺“重新启用只等下一次计划时间”。不清除 timer 时间戳、改 Persistent 或手工补跑来规避此行为。
|
||||
|
||||
本方案不购买存储、不创建或删除快照、不删备份、不恢复业务数据。远端具体配置、版本和回滚清单须在实施后形成可审阅结果再申请执行批准;当前选择不等于远端切换已完成。
|
||||
|
||||
## 设计结论
|
||||
|
||||
采用“先只读判因、再最小变更、最后两个自然周期验证”的事件处置路径。传输修复和容量处置属于同一个 P1 operations 任务,但每项远端写操作维持独立审批;恢复演练作为下游消费者保持阻塞,不参与本任务的根因修复。
|
||||
|
||||
@@ -1,5 +1,69 @@
|
||||
# 生产到 ARM 备份传输中断实施计划
|
||||
|
||||
## 2026-10-05 同模型独立复核回执及第 1–4 项补漏
|
||||
|
||||
用户回传对 `f6d1025d` 的同模型独立只读复核:通过、无阻断项、5 条非阻断问题;复核代理使用独立上下文,未修改仓库或访问远端。此处引用用户回执,不将其写成主会话独立执行,也不将旧提交结论自动套用到新改动。
|
||||
|
||||
- [x] 补齐三个测试缺口:watchdog 与 drill-reminder 分别仍在运行、timer disabled 但 active、模式文件为断链;分别覆盖 probe/refresh,沿用现有合成 systemctl/SSH/Docker fixture,不改生产脚本。
|
||||
- [x] design 与下方切换步骤同步超时后的两种明确处置、安装前最终获批源码必须送达并核验、Persistent timer 重新启用可能立即补跑及告警。
|
||||
- [x] `bash scripts/qa/run-deployment-contract-refresh-contract.sh` PASS;`node deploy/trialrun/validate-env-contract.js` PASS。三个 helper 临时副本分别注入“只检查 daily service”“手动模式忽略 timer active”“断链当不存在”:使用 `git show f6d1025d:scripts/qa/run-deployment-contract-refresh-contract.sh` 的旧测试三次均 exit 0,使用当前测试三次均 exit 1(`KILLED_BY_NEW_TEST`),证明此次新增断言分别捕获原来的覆盖缺口。变异仅在自动清理的临时目录运行,生产 helper 源码未改。
|
||||
- [x] `python3 .trellis/scripts/task.py validate 08-28-production-arm-backup-transfer-incident`、`node scripts/qa/check-trellis-governance.mjs`、`node scripts/qa/check-process-contract.mjs --baseline --json`、三个改动文件的 `scanSensitiveText` 检查及 `git diff --check` 均通过;`node scripts/qa/audit-docs.mjs --check-registry` 无错误,保留既有 22 个未登记文档警告。本轮只改测试与说明,不重复执行未受影响的业务/数据库生命周期测试。
|
||||
- 第 5 条 `refresh_program FAIL` 分类细化保留为非阻断后续,不扩入本轮。
|
||||
|
||||
本轮仅测试和任务说明补漏,不提交、不推送、不连接或修改生产/ARM。远端批准清单仍待形成;本轮结果不代表实际停用完成。
|
||||
|
||||
## 2026-10-05 最新决定与本地落实:仅手动快照
|
||||
|
||||
用户明确选择仅手动快照,不用其他厂商对象存储,也不再选 ARM/hyinda-20c 承担备份。此前对象存储选型、ARM 修复或替换、两个自然周期验收不再作为当前推进目标;原始结果保留,不勾成通过、不自动归档。
|
||||
|
||||
- [x] 复用本 task,更新 PRD 当前目标、design 切换方案及部署规则;不再询问备份产品选择。
|
||||
- [x] 本地确认停用依赖:`scripts/refresh-deployment-contract.sh:verify_timers` 要求三个自动备份 timer 启用且运行;生产身份仍取自 daily service。不能直接卸载或停 timer 后宣称发布兼容。
|
||||
- [x] 本地 task validate、Trellis governance、process baseline、敏感扫描及 diff 检查通过;docs registry 无错误,保留 22 个未登记文档的既有警告,本轮未改动 docs 或处理这些文件。
|
||||
- [x] 用户 2026-10-05 批准适配后本地实施并验证:
|
||||
- `scripts/refresh-deployment-contract.sh`:新增根属普通文件 `/etc/hyb-oa-backup-mode` 显式模式。文件不存在 = 原自动模式(行为不变);内容恰为 `manual_snapshot` 时要求三个自动备份 timer `disabled:inactive`(否则 exit 45 `backup_timer_not_disabled`),`hyb-oa-warch3-ops.timer` 仍须 `enabled:active`(43);其他内容/符号链接/非 root 属主 → exit 44 `backup_mode_invalid`,`probe` 同样校验。不删除、不 mask 备份 unit,部署身份仍取自 daily service。
|
||||
- `deploy/trialrun/deployment-contract-lib.sh` 增加 44/45 分类;`validate-env-contract.js` 增加必需片段;部署规约 Validation Matrix 增加对应条目。
|
||||
- 验证:`run-deployment-contract-refresh-contract.sh` PASS(新增自动模式下停用失败、手动模式通过/全部运行/部分运行/ops 停用/内容非法/多行/符号链接/移除模式文件回归共 10 组断言);两个源码变异(手动模式接受运行中 timer、跳过内容校验)均使测试变红;`validate-env-contract.js` exit 0;`deployment-safety-contract` 39/39、`deployment-db-lifecycle` 52/52。
|
||||
- [x] 复核补充(同日):①`probe` 也执行模式与 timer/service 一致性检查,部署前即拦截,`refresh` 部署后复检;②手动模式还要求三个备份 `.service` 为 `inactive`/`failed`,在途运行 → 45。新增 7 条断言(probe 拦截运行中/部分运行、自动模式 probe 拦截停用、服务 active/activating 拒绝、failed 放行);`probe` 去掉 timer 检查、去掉 service 检查两个变异均使测试变红;合同测试、env 合同、部署安全 + DB 生命周期 91/91 通过。注意:自动模式下 timer 异常现在部署前就失败(原先只在部署后失败),属有意收紧。
|
||||
- [ ] 远端切换(另批;生产需 root 安装权限,ARM 需用户 sudo)。顺序:
|
||||
1. 先将最终获批提交的安装器和 helper 同步到生产目标代码目录,核对来源提交与文件摘要(同步本身也需远端写入批准);installer 从该目录取源,不会自动取得本地提交。再用 `install-deployment-contract-refresh.sh install` 安装新 helper;无模式文件时仍为自动模式,forced-command `probe` 须 PASS。
|
||||
2. 先 `systemctl disable --now` 三个生产备份 **timer**(只停定时器,阻止新任务启动,不动 service)。
|
||||
3. 有界等待三个备份 service 变为 `inactive`/`failed`(上限预先写定,例如 90 分钟);超时则停止切换,**不强杀**。执行前明确批准超时处置:恢复本次停用 timer 的原启用状态并验证自动模式,或保持停用且不写模式文件、记录“切换未完成,部署被阻断”。回滚未获批时使用后一种停止状态并报告,不擅自重启或宣称切换完成。
|
||||
4. 写入 `/etc/hyb-oa-backup-mode`(root:root 0644,内容 `manual_snapshot`),forced-command `refresh` 返回 PASS。
|
||||
5. 由用户 sudo 在 ARM 上 `disable --now hyb-oa-offhost-deadman.timer` 并**单独核验** timer `disabled:inactive`、service 非 active;生产侧 `refresh` 成功不能代替 ARM 核验。未停 dead-man 时,生产停传后 ARM 会发一次 `archive_stale`。
|
||||
- 回滚:按保存的原状态恢复模式文件和本次变更的 timer;原为自动模式时移除本次模式文件,重新启用原本 enabled 的 timer,再跑 `refresh`。源码确认生产备份及 ARM dead-man timer 均配置 `Persistent=true`;现场复核后,将重新启用可能立即补跑及产生告警纳入回滚批准,不将其描述为无执行副作用。历史备份、unit 文件、公网健康探针均不动。
|
||||
- [x] 用户回传 `f6d1025d` 同模型独立只读复核通过,无阻断项;5 条非阻断问题及本轮补漏见顶部。新改动的本地验证与该次独立复核分别记录。
|
||||
- [ ] 形成固定版本、模式配置、四个备份 timer 及回滚清单,另获生产/ARM 配置变更批准后执行与核验。
|
||||
|
||||
运行状态:未连接生产或 ARM,自动备份/告警可能仍按旧配置运行;未停用定时器、未删除历史备份、未创建快照。原适配已提交为 `f6d1025d`,本轮测试与说明补漏未提交,未推送或归档。当前选择不自动停用独立公网健康监控。手动快照执行时记录目标确认、覆盖确认、创建时间及成功状态,不记录真实资源标识。
|
||||
|
||||
## 2026-10-05 告警频繁的只读核验(用户当轮授权,ARM 普通账号)
|
||||
|
||||
背景:用户反馈群内仍频繁出现“内部 OA 运维恢复通知”及“OA 公网健康告警/恢复”。授权范围为生产与 ARM 只读核验;生产主机读取被本机工具权限策略拦截,未执行,生产侧数据全部为 NOT_RUN。
|
||||
|
||||
ARM 侧结果(13:30–13:45 CST,只记聚合值,不记地址/路径/日志原文):
|
||||
|
||||
- dead-man:timer active/enabled,10-05 06:30 service success/0。说明当日 06:30 时 ARM 最新归档未超 26h 阈值;归档完整性未复核(目录及 sudo 仍不可用)。
|
||||
- 公网健康探针:timer active/enabled,13:30 那次 service 以 exit-code/1 失败,耗时约 11s(与 10s 超时一致);具体类别在 root-only 状态/journal,普通账号读不到(journal 返回“无条目”)。
|
||||
- ARM → OA 公网入口:ping 三轮丢包 67% / 74% / 52%,RTT 约 143ms;HTTPS `/ready` 40 次中 11 次超时(10s)、13 次 TCP 建连 >1s、平均 3.35s。
|
||||
- 对照:ARM → 其他三个国内目标 ping 0% 丢包;ARM 本机 DNS 解析约 1ms(已缓存),当前不是 DNS 阶段问题。本机开发环境经代理(假 IP 段)访问,40/40 成功,但路径不同,不能证明生产入口对普通用户正常。
|
||||
|
||||
判断(假设,未结案):当前公网健康告警的主要成因是 ARM 到生产入口这条线路持续丢包导致请求超时,不是 OA 应用不可用。同一条线路的丢包也可能是历史 rsync 传输中断(partial)的成因,需生产侧传输记录印证。丢包发生在 ARM 运营商一侧还是生产入口一侧尚未区分;若在生产入口一侧,真实用户也可能受影响。
|
||||
|
||||
未完成 / 下一步:
|
||||
- 生产侧(备份/watchdog 服务结果、告警状态、容量、近 7 天告警类别与部署时间对照):需用户放开本机对生产主机只读命令的权限,或由用户手动执行。
|
||||
- ARM root-only 公网健康状态文件和 journal 中的类别统计:需用户以 sudo 手动执行固定只读命令。
|
||||
- 区分线路问题在哪一侧:需要第三个直连观测点(不经代理)对生产入口测丢包。
|
||||
|
||||
### 2026-10-05 候选替代节点 hyinda-20c 只读摸底(用户当轮授权)
|
||||
|
||||
- 形态:Windows 主机上的 WSL2(Ubuntu 22.04,x86_64,20 核,15 GiB 内存),经动态域名 + 非标端口映射访问;普通账号 sudo 需密码;无 Docker。
|
||||
- 可用性:开机约 9 天;近两个月重启记录集中在 09-26(多次)与 08-22(多次),生命周期受 Windows 开关机/更新/WSL 实例回收影响。
|
||||
- 存储:WSL ext4 显示 1 TiB 虚拟盘,实际受宿主 Windows 盘余量约束(宿主两盘分别约 167G / 88G 可用);未见 Linux 层磁盘加密,宿主 BitLocker 未知。
|
||||
- 网络:节点流量(含指定公共 DNS 的解析)均被本机透明代理接管为假 IP 段,到 OA 入口 HTTPS 70/70 成功、平均约 0.13s,但不是直连测量,不能作为线路证据。
|
||||
- 容量需求参照:既有记录单批次聚合约 11 MB 量级,容量和带宽对任何候选节点都不是约束;选型关键是常在线、独立、可控访问与恢复能力。
|
||||
- 用户决定(2026-10-05):不购买轻量“自动备份”(备份点按 60GB 盘容量预付至实例到期,约 983 元);采用**每次部署前手动创建轻量免费快照**(配额 2,满则删最旧),已写入 `.trellis/spec/hyb-oa/deployment-trialrun.md` Rules。快照随实例销毁而删除,不替代实例外副本;实例外副本(另一厂商对象存储)与 ARM 链路退役待用户另行决定。用户确认控制台中名为“Windows Server”的轻量实例即 OA 生产(实际为 Linux,仅实例名称历史遗留),快照对象即此实例。
|
||||
- 结论:不建议 hyinda-20c 作为主要异机备份节点(WSL 生命周期、代理接管网络、虚拟盘依赖宿主、无加密证据);可作为额外副本候选。主要节点建议改评国内云的独立厂商对象存储或小型云主机,待用户决策。
|
||||
|
||||
|
||||
## 2026-09-17 结案缺口与最小补证方案(本地整理,未执行远端观察)
|
||||
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# 生产到 ARM 备份传输中断
|
||||
|
||||
## 2026-10-05 当前决策:仅使用手动快照
|
||||
|
||||
用户明确决定不使用其他厂商对象存储、ARM 或 hyinda-20c 备份,只使用已确认 OA 生产轻量实例的手动快照。此决策取代本任务继续修复异机链路、选型迁移及两个自然备份周期验收的目标;以下原始要求和 AC 保留为历史,未完成项不追认为通过。关联 `08-23-isolated-backup-restore-drill` 的历史部分恢复结果不变,本决策不授权继续真实恢复。
|
||||
|
||||
- 当前备份方式为部署前手动快照;确认目标、磁盘覆盖和创建成功后再部署,不新增自动快照脚本或其他副本方案。恢复范围受现存成功快照的时间点与覆盖磁盘限制,不承诺每日恢复点或实例外副本。
|
||||
- 选择备份方式与实际停用分开记录。本轮落实本地合同;发布脚本适配、生产/ARM 定时任务停用方案见 design/implement,非微小代码实施和远端配置变更待方案批准。
|
||||
- 历史备份、快照、凭据和 unit 文件不因本决策自动删除;公网健康监控是独立功能,不把“停用备份”解释为关闭全部监控。
|
||||
|
||||
### 当前验收
|
||||
|
||||
- [x] S1:当前选择已同步到任务及部署规约,本地文档/治理检查通过;旧未验项与当前决策明确区分。文档审计保留既有未登记文件警告,详见 implement。
|
||||
- [ ] S2:获批的发布适配与备份任务停用完成,停用状态及发布兼容性有据;此前不得称“已经只运行手动快照方案”。
|
||||
|
||||
## Goal
|
||||
|
||||
恢复腾讯云生产到 ARM 的自动异机备份链,消除持续扩大的异机恢复点缺口,同时把生产备份落盘容量恢复到可持续范围,并证明修复不是一次偶然成功。
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-08-28",
|
||||
"completedAt": null,
|
||||
"branch": null,
|
||||
"branch": "main",
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
|
||||
@@ -1,3 +1,40 @@
|
||||
## 2026-10-09 手机首次截图就绪检查(N3 第四轮后)
|
||||
|
||||
原回执 `artifacts/release-gate/loan-receipt-n3-20261009-r4/`:候选 `8e17e8df`,82 迁移、服务端 4558 通过/1 项既有可选跳过;浏览器 371 通过/1 失败、零跳过/重试。前几轮修正后的报销付款、PWA 升级和企微历史三项均通过。
|
||||
|
||||
- [x] 收齐错误栈和截图:R106 在手机首次 `page.screenshot` 返回 Chromium 协议错误,尚未执行手机登录。截图前只有 `goto`,缺少页面就绪断言;原运行没有足够证据唯一归因于渲染时序、Worker 或认证。安全日志及失败摘要保存在 N3 准备目录,原 FAIL 不改写。
|
||||
- [x] 在原截图前确认登录标题、账号输入可见和提交按钮可用,保留原截图、全部巡检、真实登录、Worker 设置和预算。不引入截图重试、刷新、休眠或业务代码修改。
|
||||
- [x] 受管 `retained-local` 完整 R106 文件 1 项通过,零失败/跳过/重试,浏览器阶段约 32.7 秒。14 张截图、员工及管理员后续巡检和报告实际生成,自动报告无 finding;环境、源码一致性及自有资源清理通过。这不是独立视觉审查,也不据单次通过唯一归因历史错误。
|
||||
- [ ] 主会话差异、任务/治理检查后按既有授权本地提交,再由借款 N3 对干净新候选执行第五轮原完整门禁。
|
||||
|
||||
定向证据为准备目录的 `r106-readiness-focused/`、`r106-focused-process.json` 和 `r106-focused-summary.json`,完整回执为 `artifacts/release-gate/loan-receipt-n3-20261009-r5/`。验证期间冻结源码/测试/文档,结果写 ignored 回执。独立代码复核仍待;无推送、部署、生产访问或真实 OCR。
|
||||
|
||||
## 2026-10-09 桌面模拟接口隔离补齐(N3 第三轮后)
|
||||
|
||||
原回执 `artifacts/release-gate/loan-receipt-n3-20261009-r3/`:候选 `98bab397`,82 迁移、服务端 4558 通过/1 项既有可选跳过,浏览器 371 通过/1 失败。PWA 升级和报销付款主链路通过;唯一失败位于桌面企微历史标题等待,失败快照为登录页。环境、源码一致性及自有资源清理通过。
|
||||
|
||||
- [x] 读取最终错误栈和快照,确认 `page.route` 文件缺默认 context 的 Worker 隔离;手机 helper 已有 `serviceWorkers: block`,不代表默认桌面 fixture 也生效。原请求来源未采集,历史唯一成因仍未证实。
|
||||
- [x] 文件级补既有隔离设置;在桌面原导航前同时等待 refresh 与 `/api/me`,断言 200、非 Worker、匹配该 fixture 的 requestId。保持原登录、三项用例、页面/只读/布局断言、截图和预算。
|
||||
- [x] 受管 `retained-local` 全文件三项通过、零失败/跳过/重试,浏览器用例总耗时 9.1 秒;生产构建、两种 context 的全导航及桌面响应来源检查通过,环境、源码一致性及清理通过。原第三轮 `login-portal-ux` 16 项及 R101 3 项按未变输入保留,不计入此次三项结果;不据单次通过追认历史唯一根因或真实银行/生产验收。
|
||||
- [ ] 主会话检查和任务/治理通过后形成新的本地提交;N3 对干净新候选执行原完整门禁。此次是已有模拟隔离合同补漏,不修改产品认证或 PWA,也不提高预算/重试到绿。
|
||||
|
||||
准备目录中的 `internal-readiness-focused/`、`internal-readiness-focused.log` 记录定向结果,下一轮完整回执为 `artifacts/release-gate/loan-receipt-n3-20261009-r4/`。测试时冻结受测输入,结果写 ignored 回执。独立代码复核待完成;未推送、部署、查询生产或使用真实材料。
|
||||
|
||||
## 2026-10-09 PWA 跨导航版本等待修正(N3 候选验证接续)
|
||||
|
||||
来源为借款任务 N3 的 `18315d11` 完整回执:服务端 4558 通过/1 项既有可选跳过,浏览器 371 通过/1 失败、零跳过/重试。栈明确位于 `expect.poll` 回调中的 `documentBuildSha`:页面自动更新销毁旧执行环境后,直接 `page.evaluate` 抛错,未等完原定 45 秒。冻结诊断已观察到文档 B、B 控制器摘要匹配、旧资源缓存归零、B 资源加载、会话保留及零静态 404;这些事后观察不改写原失败。
|
||||
|
||||
- [x] 定位具体失败及保存第二轮完整回执,确认环境、源码一致性与自有资源清理通过。
|
||||
- [x] 仅把 B 版本等待改为 Playwright 对当前 `html` 元素的属性断言,保留 45 秒上限和后续全部联合见证;不用吞掉所有异常的 `catch`,不加刷新、清缓存或重试。
|
||||
- [x] 受管 `retained-local` 选择完整的 `pwa-cross-version-upgrade.spec.ts`:1 项通过、零失败/跳过/重试,浏览器用例总耗时 9.4 秒。A/B 联合见证、会话及全部否定断言通过;实际单文件 1 worker,不改全局并发。受管生产构建、环境、源码一致性及自有资源清理通过。
|
||||
- [ ] 完成主会话差异及任务/治理检查后本地提交;返回借款任务 N3,对干净新候选另开完整 `verify-candidate`。前端应用未变,复用第二轮已通过的类型检查并保留本次受管构建;第三轮正式门禁仍完整执行类型检查/构建。不沿用原候选资格。
|
||||
|
||||
定向记录在 `artifacts/qa-flow/loan-receipt-n3-20261009/pwa-navigation-focused/` 及同级日志,下一轮完整回执在 `artifacts/release-gate/loan-receipt-n3-20261009-r3/`。验证时冻结受测文件,实际结果追加到回执;本节下方历史授权和结果只代表各自时点。没有产品、资金状态机、权限、迁移或发布入口改动,不触发真实业务操作;独立代码复核未完成。
|
||||
|
||||
## 2026-09-27 首个受管完整门禁 PASS 并发布(历史时点)
|
||||
|
||||
候选 `70af0c6b` 在本机(2 核/8G,4 worker)经 6 轮 verify-candidate 取得 PASS(372/372,`artifacts/release-gate/20260926-202856`)。期间处理:付款主链路 300→420s、视觉组 180→240s(`34675e1a`,项目默认 180s 回执校验不变);采购「审批后页面旧状态」查明为 SW 3s 网络超时回退缓存的产品缺陷并修复(`0931b1ea`,任务 09-26-approve-success-state-unchanged);资产 E2E 后退前等 `data-unsaved-changes=false`(`70af0c6b`)。浏览器源缓存/BIFF8 venv 位于用户级缓存目录并按 copy-browser-cache 复制独占副本。已经 deploy 入口消费回执发布至生产,详见 09-26 任务 implement 顶部。本机负载下另见采购提交事务偶发 P2028(生产同写法,待另立任务)。
|
||||
|
||||
## 2026-09-19 R101补验已接收,保存新候选并准备独立完整请求(当前)
|
||||
|
||||
Claude报告claude-focused-5m9p8_o7:copy/focused/wrapper均0,351.918秒,3/3 expected、零失败/跳过/重试;实际1worker(全局4未改)。原失败用例两张截图及全部响应/页面断言走完,native/guest、owner清理通过。主会话实算112输入、5份after/before一致;原报告“稳定通过”仅按单次通过接收,不扩大因果结论。
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
## 2026-10-09 手机首次截图就绪检查(N3 第四轮接续)
|
||||
|
||||
候选 `8e17e8df` 第四轮完整门禁为 FAIL:浏览器 371 通过/1 失败、零跳过/重试,其余阶段通过。失败栈明确在 R106 的手机登录页首次截图,Chromium 返回 `Page.captureScreenshot: Unable to capture screenshot`;字体等待已结束,手机账号尚未填写。不是登录断言失败,也没有证据证明真实认证或 Worker 有问题。原测试在 `goto` 后直接截图,没有检查 React 页面是否已经可用;尚未证明这一缺口是 Chromium 协议错误的唯一成因。
|
||||
|
||||
本次最小修正只在原截图前确认登录标题、账号输入和提交按钮已就绪,使用原断言预算。保留原全页截图、真实隔离后端登录、Worker 策略、电脑/手机/管理员全部巡检及报告,不重试截图、不增加休眠或测试预算、不改产品认证/资金代码。先以 `QA_RETAINED_SPECS=r106-visual-audit.spec.ts bash scripts/qa/run-web-gates.sh retained-local` 重验完整文件,再按 N3 既有授权形成本地候选并运行原完整门禁;新结果不能覆盖第四轮 FAIL。独立代码复核、真实还款和发布仍待完成。
|
||||
|
||||
修正后的受管完整文件 1 项通过、零失败/跳过/重试;14 张截图和报告实际生成,环境、源码一致性及清理通过。不据单次通过宣称已证明 Chromium 历史错误的唯一成因;完整候选资格仍待第五轮回执。
|
||||
|
||||
## 2026-10-09 桌面模拟接口隔离补齐(N3 第三轮接续)
|
||||
|
||||
候选 `98bab397` 第三轮完整门禁为 FAIL:浏览器 371 通过/1 失败、零跳过/重试;报销付款与 PWA 升级已通过。唯一失败是 `internal-readiness-ui.spec.ts` 的桌面企微历史页在整页导航后未出现标题,失败快照为登录页。该文件的手机手动 context 已屏蔽 Service Worker,使用 `page.route` 的桌面默认 context 却遗漏了既有隔离合同。原运行没有请求来源证据,不能宣称历史唯一根因已证明。
|
||||
|
||||
本次只补测试边界:默认 context 在首次导航前屏蔽 Service Worker;桌面整页导航必须观察到 refresh 与 `/api/me` 的 200 响应、来自预设模拟接口而非 Worker。保留真实页面登录操作、会话提示、全部三项用例、桌面只读和手机空态/详情/布局断言及截图,不改产品认证、PWA、权限、资金、预算或全局并发。先受管定向全文件,再固定本地候选并由 N3 完整复验;保留第三轮 FAIL,不用定向结果拼接资格。
|
||||
|
||||
修正后受管定向 3 项通过、无失败/跳过/重试,原页面断言、截图及新增响应来源检查通过,环境/源码一致性/自有资源清理通过。新候选完整门禁仍待第四轮回执;独立代码复核未完成。
|
||||
|
||||
## 2026-10-09 借款候选验证中的 PWA 导航观测修正
|
||||
|
||||
`09-17-company-loan-principal-repayment` 的 N3 接续已获本地提交、验证及必要测试修正授权。其候选 `18315d11` 第二轮完整门禁为 FAIL:浏览器 371 通过/1 失败、零跳过/重试;唯一失败为 PWA 跨版本测试的版本读取在应用自动导航时抛出 `Execution context was destroyed`。报销付款主链路已通过,受管环境、源码一致性及清理通过。原回执保留在 `artifacts/release-gate/loan-receipt-n3-20261009-r2/`。
|
||||
|
||||
本任务承接这处验收测试修正:版本等待必须容忍被测应用正常的自动导航,并在原有 45 秒内确认新文档的版本属性。保留同一 origin/BrowserContext、A 前提、B 的控制器与文件摘要、缓存和实际资源加载、会话、错误及导航次数全部断言;不增加测试重试、人工刷新或运行预算。产品 PWA、付款资金规则和正式门禁范围不变。先受管定向重验该文件,再形成新的本地候选并由 N3 执行完整门禁;定向通过不能抵扣原 FAIL。当前 inline 下由主会话实施和检查,独立代码复核另记待完成;不推送、部署或访问生产。
|
||||
|
||||
修正后的受管定向回执为 1 项通过、无失败/跳过/重试,A/B 联合见证与全部原断言走完;环境、源码一致性和自有资源清理通过。新的完整候选资格仍待第三轮正式回执,不能把此次单例通过与旧 371 项拼成完整 PASS。
|
||||
|
||||
## 2026-09-19 R101定向3/3接收,固定新候选进入最终验收
|
||||
|
||||
R101一次生产构建定向复验3/3通过,零失败/跳过/重试;只读补审通过,接收时112输入及5份before/after均一致。新增响应来源检查、准确到达、原标题/入口/设计断言与两张截图全部走完。只证明该次通过,不宣称统计稳定性或历史唯一根因已确定。
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
## 2026-10-11 报销真实 OCR 余项移交(当前文档接续点)
|
||||
|
||||
接收来源任务 `08-29-reimbursement-expense-policy-invoice-guard` 与部署子任务 `08-30-reimbursement-expense-policy-invoice-guard-deploy` 的报销发票 OCR 及财务科目映射余项;合同入口为 [PRD 的移交节](./prd.md#2026-10-11-接收余项报销真实-ocr-验收与财务科目映射)。本节不更新下方其他工作线的历史结果,独立复核与真实银行/通知/恢复等义务继续按原合同跟进。
|
||||
|
||||
### 本轮文档移交
|
||||
|
||||
- [x] 对照原父任务最新记录,区分指定样票真实腾讯单独调用、mock 提供商隔离审批整链、真实腾讯线上合成草稿三层证据;原 2026-09-10 草稿 PASS 不降级,也不扩大到公网审批或全票种。
|
||||
- [x] 双向登记 RC-OCR-1–4、责任和退出条件;接回 RC-ACCOUNT,保留财务负责人、原已过目标日期和无科目表留空规则。
|
||||
- [x] 本机确认 `live-draft-result-v6.json`、`live-draft-final-readback.json` 及原测试脚本仍在既有发布目录;本轮未重跑它们。本地 Git 祖先检查确认 `6e999d5`、`e5685f1` 已包含于用户报告的生产版本 `4a5cd8f2`,不据此声称本轮公网复核或业务验收。
|
||||
- [x] 基线 `89f46790` 的本地文档移交检查通过:三个任务 `task.py validate`、流程基线、Trellis 治理、敏感内容扫描与 `git diff --check` 均 exit 0;文档登记检查 errors=0、warnings=1(既有 22 个文件未登记)。完整差异仅三个任务的 prd/implement/notes,历史正文与复选框保留,状态/提交锚点/任务关系未改;未跑业务回归、云端或公网检查,不是独立复核。
|
||||
- 补充核对通过:九文件范围、新移交链接/锚点、JSON 末尾换行及历史 notes 后缀均正确。正文保留检查初版用“原全文必须是连续子串”误把标题后插入判为改写;修正为逐行仅允许新增后通过,没有为此改动历史正文。
|
||||
- 未提交、未归档,两个来源任务仍为 `in_progress`;不以移交自动授权完成旧部署清单或原生产操作。
|
||||
|
||||
### 后续验收接续(未执行)
|
||||
|
||||
1. 执行端先界定候选、环境和样票,复用原脚本前核对其当前合同;提供商检查与业务上传使用同一获准样票摘要,不能复用真实票号绕过查重。
|
||||
2. 明确云调用与业务写入范围、测试身份、审批隔离及清理前提后,再执行 PRD 的 RC-OCR-1–4;前提不足保留缺口,不反复尝试生产登录或交给真人员工试错。
|
||||
3. 逐项回填字段一致性、实际队列及状态、页面/数据库消费者、异常回归和清理结果;区分草稿、审批、付款及既有 mock 证据。只有本项全部退出条件满足后才可收口 RC-OCR。
|
||||
4. RC-ACCOUNT 等财务正式映射及回填日期;没有依据保持 null,生产回填另批。旧独立复核余额仍由本任务已有复核工作线跟进,不把主会话文档检查记为独立通过。
|
||||
|
||||
本轮仅任务文档,不改产品/规约/数据库,不跑业务回归或完整发布门禁。没有新增可复用工程规则,沿用现有 `docs-and-evidence.md` 与报销 OCR 规约。
|
||||
|
||||
## 2026-09-19 当前进度:本地完整验收通过
|
||||
|
||||
g20-full-r6从static完成同一冻结候选:后端4437通过/1原条件跳过、372本地浏览器全过,零失败/跳过/重试;33页与33PNG、采购/报销付款整链、新旧编号及财务同页进度全部通过。回执PARTIAL仅dirty_candidate,localChecksPassed=true,无部署资格;环境/输入/归属清理PASS。
|
||||
|
||||
@@ -1,3 +1,33 @@
|
||||
## 2026-10-11 接收余项:报销真实 OCR 验收与财务科目映射
|
||||
|
||||
本节接收 `08-29-reimbursement-expense-policy-invoice-guard` 及其部署子任务 `08-30-reimbursement-expense-policy-invoice-guard-deploy` 的未完成责任。移交只改变跟进归属,不把原未勾选项判为通过;本任务继续 `in_progress`。原付款、真实银行、通知及独立复核余项保留。
|
||||
|
||||
### RC-OCR 报销真实 OCR 验收
|
||||
|
||||
范围是**报销发票**的“上传→真实腾讯 OCR→实际队列→我的发票选票→生成/关联明细→保存刷新→提交审批”及字段核对,不是借入回单或付款回单的 BankSlipOCR。借款/银行回单证据不能代替本项。
|
||||
|
||||
已完成证据按原环境分别保留:
|
||||
|
||||
- 2026-09-09:指定样票 `SAMPLE-PDF-INVOICE-FIRST` 单独调用真实腾讯,归一化必填字段检查通过;没有逐字段人工核对识别精度,也没有通过该调用完成业务上传/队列/浏览器链路。来源为原父任务 implement 同日“用户指定样票的真实腾讯 OCR 验证”节。
|
||||
- 2026-09-09:隔离数据库、真实认证和 pg-boss、电脑/手机到提交及三段审批通过,但 provider 为 mock;不能与样票单独调用结果相加成真实腾讯整链通过。
|
||||
- 2026-09-10:在 `e5685f1` 线上用全合成样票完成真实腾讯、队列、选票、分类编辑、草稿保存/刷新及电脑转手机操作;`PASS_DRAFT_ONLY`,未提交、未审批、未付款。来源为原父任务 implement 顶部及 `artifacts/qa-flow/20260909-release-e5685f1/live-draft-result-v6.json`、`live-draft-final-readback.json`。这已满足原“真实腾讯识别合成样票”的草稿阶段要求,不重复列作从未验证。
|
||||
|
||||
仍待验收:
|
||||
|
||||
- [ ] RC-OCR-1:执行端记录本次候选、获准环境、样票别名及摘要,将真实提供商、队列任务、票据状态、页面操作和持久化回读关联到同一次运行。复用历史证据时保留版本与范围,不能当作新候选复测。
|
||||
- [ ] RC-OCR-2:对约定样票的号码、日期、金额/税额/合计和购销方等适用字段与原件核对,只记录是否一致、缺失或需人工修正;不记录真实字段值。执行端核对测试样票与技术结果,财务负责真实业务原件核对及费用用途/分类确认;不把商户名称推断为费用用途,不扩成全票种精度承诺。
|
||||
- [ ] RC-OCR-3:同一候选、同一获准环境完成真实腾讯到选票、可编辑明细、保存刷新及提交/审批的串联,证明添加前零新增明细、用户添加后关联正确、必要字段/票面金额门禁有效。生产审批隔离条件不足时停在草稿并保留审批缺口,不改真人审批路由,不以历史 mock 审批替代本项。
|
||||
- [ ] RC-OCR-4:接回原范围的重复/占用、识别失败或缺字段、人工补正、手改不被刷新覆盖与重试不重复建明细等回归证据;逐项注明 mock、本地或真实提供商层次。记录本轮清理与回读,归档票据不等于物理删除附件/OCR/审计。
|
||||
|
||||
责任:执行端负责技术前置、自动化、结果核验和证据回填,不由真实员工承担软件回归;财务提供/批准可用业务材料并核对业务字段;用户决定云端发送、生产账号/数据/配置写入及提交审批的操作授权。原样票单次调用和过去合成验收授权不自动扩展到新真实票据、生产写入、真实消息或真实付款。付款回单与借入回单仍由各自既有合同验收。
|
||||
|
||||
### RC-ACCOUNT 财务科目映射回填
|
||||
|
||||
- [ ] 财务负责人提供正式科目表后,核对并回填 `account_code_default` 的映射结果,执行端记录依据与结果;生产回填须另获明确授权。未提供时继续保持 null,不编造编码、不阻塞票据门禁,也不将其记为已完成。
|
||||
- 原目标回填日期 `2026-09-05` 已过,当前未找到正式科目表及回填证据;责任角色仍为财务负责人,下次日期待其确认,本轮不虚构或自动延期。
|
||||
|
||||
本轮只落移交记录、核对引用并运行文档治理检查,不执行以上验收。两个来源任务的归档、此次提交,以及云调用/生产操作均保留各自授权边界。
|
||||
|
||||
## 2026-09-18 G19 最新验收状态
|
||||
|
||||
分层验收已获明确批准并本地实施验证:完整发现65/365,351本地、12同候选公网义务、2冻结旧链。74项覆盖/runner、7项诊断检查和2条本地冻结保护通过;原完整full-r2仍失败,公网NOT_RUN_LOCAL、独立PENDING,R1未启用。具体合同、证据、失败保留及后续顺序见implement顶部;未提交部署或执行真实操作。
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"children": [],
|
||||
"parent": null,
|
||||
"relatedFiles": [],
|
||||
"notes": "2026-09-19 g20-full-r6:4437后端通过/1原跳过,372本地浏览器全过;PARTIAL仅dirty_candidate,独立PENDING/无部署,旧registry保护例外保留且无新增漂移。当前余额见implement顶部。\n2026-09-18 G19分层验收已批准并本地实施验证,74+7合成检查和2条冻结保护通过;公网12义务/完整门禁/WebKit/R1/独立及真实事实保持开放。\n2026-09-18 G18本地接续完成:33路由项、R108、OCR;并发4/4、认证/OCR18/18、unit131。原full-r2不回写;12live/2冻结验收G19本地实施验证完成,公网义务待兑现、WebKit/R1/独立/外部事实仍开放。新包local-coverage-g18-20260918,未提交推送部署。\n2026-09-18协调更新:09-06完成G16/G17本地批次,普通全量仍失败;14原失败观测及2串行缺失已定向重验,WebKit/冻结差旅/完整覆盖与可靠性、R1/独立及外部事实仍开放。借款T1–T4、报销反馈与ERP退役维持此前本地完成,非公网事实。最新入口见implement顶部。\n2026-09-17本轮W8/W6:22任务231条件逐项处置,154历史支持/56部分/11外部/4替代/4冻结/2条件未触发;82引用定位,接回AP/seed/预检b87cc55发布事实。B34损坏导入500与合成日志内容已复现并规划、未修;低年份分支分类完成,AP反向保持原语义,73项通过。K0/G8两主题完整性与运行时保持、独立PENDING;无新产品、远端或提交发布。\n连续推进至D10/D11,另9文件61通过;后续剩HR多格式策略、589错误遗留及各外部门禁,未宣称全部结束。\n2026-09-17后期连续执行:日期D5-D9、9原因及520本地验证完成;事件六缺口方案、22历史task231条件索引、借款T1a技术草案落盘;独立/恢复/自然业务/产品准入仍开放,无生产或提交发布。\n2026-09-17后期总表:官方current已切回本task,仅整理规划;K0本地30项/166键、B1/B2的450项与前端构建、D1–D4的192项/治理均有各自回执,未提交/发布,独立复核PENDING。按8条既有收口/治理+1条借款新功能共9条工作线编排;错误债务577指纹/598命中/58扫描分组,2026-10-05到期不变;日期新D5–D8只规划。K1/K2、历史缺件/完整计时、备份事件、自然付款/通知、22项历史任务验收映射均保留。借款planning,4阶段/8项AC待实现验收。原受限恢复PARTIAL与入口已消费不变,未连接生产/ARM、读真实秘密/备份或重跑恢复,未提交推送部署归档。最新范围、依赖、量级和人工节点见implement顶部,不按测试数量宣称全量完成。",
|
||||
"notes": "2026-10-11 接收08-29及08-30部署子任务的报销发票真实OCR余项(RC-OCR-1–4)与财务科目映射(RC-ACCOUNT),详见prd/implement顶部。保留真实腾讯单次样票、mock隔离审批及真实腾讯线上合成草稿三层证据;余项未执行,独立/真实业务等原义务开放。本轮仅文档移交,未提交、未归档、未调用云端或生产。\n2026-09-19 g20-full-r6:4437后端通过/1原跳过,372本地浏览器全过;PARTIAL仅dirty_candidate,独立PENDING/无部署,旧registry保护例外保留且无新增漂移。当前余额见implement顶部。\n2026-09-18 G19分层验收已批准并本地实施验证,74+7合成检查和2条冻结保护通过;公网12义务/完整门禁/WebKit/R1/独立及真实事实保持开放。\n2026-09-18 G18本地接续完成:33路由项、R108、OCR;并发4/4、认证/OCR18/18、unit131。原full-r2不回写;12live/2冻结验收G19本地实施验证完成,公网义务待兑现、WebKit/R1/独立/外部事实仍开放。新包local-coverage-g18-20260918,未提交推送部署。\n2026-09-18协调更新:09-06完成G16/G17本地批次,普通全量仍失败;14原失败观测及2串行缺失已定向重验,WebKit/冻结差旅/完整覆盖与可靠性、R1/独立及外部事实仍开放。借款T1–T4、报销反馈与ERP退役维持此前本地完成,非公网事实。最新入口见implement顶部。\n2026-09-17本轮W8/W6:22任务231条件逐项处置,154历史支持/56部分/11外部/4替代/4冻结/2条件未触发;82引用定位,接回AP/seed/预检b87cc55发布事实。B34损坏导入500与合成日志内容已复现并规划、未修;低年份分支分类完成,AP反向保持原语义,73项通过。K0/G8两主题完整性与运行时保持、独立PENDING;无新产品、远端或提交发布。\n连续推进至D10/D11,另9文件61通过;后续剩HR多格式策略、589错误遗留及各外部门禁,未宣称全部结束。\n2026-09-17后期连续执行:日期D5-D9、9原因及520本地验证完成;事件六缺口方案、22历史task231条件索引、借款T1a技术草案落盘;独立/恢复/自然业务/产品准入仍开放,无生产或提交发布。\n2026-09-17后期总表:官方current已切回本task,仅整理规划;K0本地30项/166键、B1/B2的450项与前端构建、D1–D4的192项/治理均有各自回执,未提交/发布,独立复核PENDING。按8条既有收口/治理+1条借款新功能共9条工作线编排;错误债务577指纹/598命中/58扫描分组,2026-10-05到期不变;日期新D5–D8只规划。K1/K2、历史缺件/完整计时、备份事件、自然付款/通知、22项历史任务验收映射均保留。借款planning,4阶段/8项AC待实现验收。原受限恢复PARTIAL与入口已消费不变,未连接生产/ARM、读真实秘密/备份或重跑恢复,未提交推送部署归档。最新范围、依赖、量级和人工节点见implement顶部,不按测试数量宣称全量完成。",
|
||||
"meta": {
|
||||
"g18Local": "verified_scoped_not_full_gate",
|
||||
"independentReview": "PENDING",
|
||||
|
||||
@@ -1,5 +1,503 @@
|
||||
## 2026-10-11 G:材料区域最小精简设计(已批准并实施)
|
||||
|
||||
沿用 `CompanyLoansPage.tsx` 的现有材料区域、表单和 tab 切换,保持现有组件样式。本轮只调整信息显示,不迁移到新详情页、不复制 `LoanLenderAcknowledgements` 的发起流程,也不新建材料管理面板。
|
||||
|
||||
- 材料是否满足只从当前借款 DTO 推导:未归档、审核可用的 `incoming` 和 `accounting_confirmation`;有效 `lenderAcknowledgement` 或审核可用的 `agreement`;当登记期初未还小于原本金时还需审核可用的 `adjustment`。金额按现有精确金额处理约定比较,不拿后续 `outstanding` 代替期初值。
|
||||
- 上传控件按 PRD G 的条件显示,既有材料链接保留;协议入口注明二选一。余额材料始终提供原 `accounting_confirmation` 上传入口,前台“余额依据说明”继续提交 `accountingConfirmationRef`,不更名数据库或 API。
|
||||
- 原 `setTab("acknowledgements")` / `setTab("authorizations")` 用于跳转;无有效声明且已关联员工时提示到原栏目查看/办理,未关联员工保留原纸质路径。现有借款 DTO 不足以判断 pending/returned 或授权是否完成,本轮不补聚合查询、不抓取全量分页,以中性导航文案表达。
|
||||
- 缺项投影与按钮禁用共用同一判断;上传提交、等待列表刷新及刷新失败期间不使用旧快照启用确认。返回页面或确认栏目后按现有查询约定更新数据;服务端继续负责防止并发版本变化、声明失效和资料缺失的提交。
|
||||
- 确认完成后的授权链接仅用于适用既有关联方授权条件的借款;外部出借人继续原独立审批路径。保持借款声明、余额确认、公司代表授权三种不同业务动作,不自动推进任何状态。
|
||||
|
||||
界面仅提示财务如何准备银行流水/代账明细和填写出处,不宣称上传即完成余额核对。实施时同步现有操作手册对应段落,注明银行流水作为附件核对,不是新增银行流水导入能力。
|
||||
|
||||
## 2026-10-10 D:浏览器遗留失败排查设计(已批准实施、产品复核及本地补验完成,未提交)
|
||||
|
||||
沿当前借款任务 AC46–AC51,先补最小可观察实验,再定位并修复;不预判两项都是测试脚本问题。没有迁移、生产连接或新的业务规则。
|
||||
|
||||
最终产品行为:授权出借人列表使用可选 `eligible=related_authority`,在服务端分页和计数前排除未核实、未关联员工及财务本人;未传参数的原列表保持原行为,无效取值拒绝。授权弹窗每次打开重置出借人页码为 1。追回上传仍先关闭弹窗、再刷新;等待刷新后才关闭的试验已撤回,刷新期间禁用选项列为 P3,未实现。下面保留获批的实验合同,实际完成与证据以 implement 顶部为准。
|
||||
|
||||
提交前复核发现第三页诊断原先只验证选项,没有直接在第三页完成授权;追回旧策略诊断原先只记录选项,没有实际提交;资金回滚原例仅测晚到成功。按原 AC46/AC49/AC50 补实际第三页经办/本人确认、原生验证零 POST、精确 POST 的拒绝/pending/200 后刷新门闩,以及独立和关联两模式的追回金额、交易重复、审计失败回滚。补验不修改产品代码。
|
||||
|
||||
### D0:采证与定向运行
|
||||
|
||||
- 复用 `test-company-loan-db.cjs` 的隔离数据库、真实 Fastify/鉴权、合成 PDF 和真实浏览器。增加仅测试使用的可选 `RUN_ISOLATED_LOAN_BROWSER_DIAGNOSTIC=authorization-pagination|refund` 定向入口,严格校验值并要求已有 DB/browser 开关;输出明确标为定向范围,不能冒称完整回归。现有员工专项入口保留。
|
||||
- 白名单事件时间线:设备、阶段、相对时间、角色别名、接口路径与必要页码/类别、请求开始/结束/取消、HTTP 状态、requestId、安全 reasonCode、按钮 pending/disabled、已显示页的合成 ID 和证据 ID。禁止 token/cookie、原始请求响应 payload、账号、真实原件及完整本地路径。表单采证仅记录有效性和字段是否存在,不保存账号值。
|
||||
- 监听在动作之前安装,退出/失败时统一收拢 Promise、移除监听并清理测试自有资源。截图和限定环节的浏览器 trace 只用合成页面;保留失败证据,控制产物大小。原 r6/r7、full-loan-r1 证据不覆盖不删除。
|
||||
- 同步区分浏览器原生验证无 POST、网络 pending/失败、服务端拒绝、提交成功但界面刷新失败;200 不能单独证明流程完成,DOM 关闭也不能单独证明写入成功。
|
||||
|
||||
### D1:授权翻页实验
|
||||
|
||||
受影响入口:`company-loan-employee-fixture.cjs` / `company-loan-employee-browser.cjs`,必要时 `LoanRelatedAuthorizations.tsx` 及 `/loan-lenders` 查询;保留每页 30 条、姓名/ID 排序与现有授权过滤。
|
||||
|
||||
1. 隔离 fixture 固定建立至少 65 名活跃、身份核实、员工关联且非财务本人的出借人,用稳定的合成姓名排序;通过实际列表 API 校验第二/第三页目标位置。位置不满足即 fixture 失败,不能跳过翻页或依赖其他测试多建的资料。
|
||||
2. 电脑/手机执行第一页→第二页→第三页→第二页→第三页,明确断言各页真实选项和目标 ID;选择目标借款、登记授权、本人确认,验证授权关联与审计、零还款创建。旧 `open()` 没有重置 lenderPage 的行为仅作为待观察条件,不预先增加“每次回第一页”的产品要求。
|
||||
3. 使用可控路由门闩而非任意 sleep:首次响应正常/快速、第二页响应延迟、无关同路径的其他页响应先到、5 秒有效期内返回缓存页、关闭重开。缓存场景以选项正确到达为结果,不强制等待不存在的新 GET;需要等待响应时精确识别目标 page/pageSize 与 actor,并继续检查渲染。
|
||||
4. 控制实验让页码不变化或返回错误页,证明测试确实抓到停在旧页。还原旧等待方式时从保留版本/差异取证,若不能逐字还原则注明限制;人为注入的等待失败不是原事故根因证据。仅在同条件能复现历史失败并通过单一修复消除后,才归因。
|
||||
|
||||
### D2:追回到账实验
|
||||
|
||||
受影响入口:`company-loan-reconciliation-browser.cjs`、`company-loan-related-browser.cjs`、相应 HTTP fixture;必要时 `LoanBankReconciliation.tsx`、`paymentBatches.js` / `loanBankResults.js`。复用既有退款证据类别 `incoming_return`、相反账户方向、booked 的晚到成功父事件、金额/归属/声明/审计和银行交易唯一保护。
|
||||
|
||||
1. 为每台设备和审批模式各建独立场景,不用一次场景的成功代替另一模式。保留原始独立模式失败链,当前关联模式由不同身份的财务/公司代表分别办理。
|
||||
2. 先产生已登记晚到成功和 40 元待追回,再分别上传合成退款证据、追回 15 和 25 元。上传响应绑定本批次 POST;保存返回的 evidenceId,等待该 ID 出现在实际 options,断言选中后才提交;用旧“最后一个 option”策略与延迟刷新作对照,不假定这一竞争就是旧事故原因。
|
||||
3. 对每次登记精确观察 `/payment-batches/:id/loan-bank-results` POST;检查 returned event 的 parent/evidence/金额,再由另一人复核和财务入账。200 后分别等待对应列表刷新与状态显示,读取数据库确认待追回金额、交易占用、冻结原因与原借款/原终态/批次数;不把等待弹窗消失作为 HTTP 请求的替代品。
|
||||
4. 小矩阵覆盖:提交时无有效证据、上传完成但列表读取延迟、登记 POST 延迟、200 后刷新延迟、有效可见的拒绝信息,以及实际事务内审计失败回滚。既有 HTTP 反例优先复用;补本次遗漏而非复制整套资金守卫。
|
||||
5. 重试按既有请求键/银行交易身份合同检验:相同键同内容幂等,新的声明可按既有取代规则保留历史,但同一交易不能重复入账;部分追回不解除其他原因冻结,不能改成直接消除本金或生成退款付款批次。
|
||||
|
||||
### 修复、验证与兼容边界
|
||||
|
||||
采证先定位层次;纯等待/fixture 问题只改测试。已证实的界面或接口缺陷才做对应最小改动,不扩展通用组件、不统一放大超时、不加盲目重试。触及权限、状态消费、资金保护时补只读独立 review;若需要改既定合同或新增迁移,返回方案确认。
|
||||
|
||||
最终分别重验强制触发的两项场景(每设备连续 3 轮),再一次完整借款回归及受影响层检查;未改业务代码时无需为测试变化重复前端构建。提交/发布另行授权,测试修复不自动部署。原事故无法复现时可交付采证与稳定分支覆盖,但结论仍为原根因未定,不凭多轮绿灯结案。
|
||||
|
||||
## 2026-10-10 N5-C 出借人在线确认设计
|
||||
|
||||
1. 新增专用声明、借款快照及单次决定三张表,记录固定的公司/出借人/关联员工、财务发起人、请求键、日期、金额、原件 ID/摘要和版本。声明与范围在一个事务内完整成立,数据库约束保障范围一致及历史不可改删;失效只允许从有效到无效,保留原决定。
|
||||
2. 快照读取数据库当前值,客户端仅提交借款 ID/版本及出借人身份版本。限定同公司同出借人、身份已核实、有入账原件;首次发起限定尚未确认期初余额,已确认余额仅在有失效在线声明历史时开放重发。重发不修改借款版本、金额、截止日、原余额确认人/时间、状态或代账引用。同一有效范围的待确认/已确认记录不重复发起,返回已存在提示;退回或失效后允许新请求。多笔声明是一组,任一关键源变化使该组失效。
|
||||
3. 发起/决定按“出借人 → 排序后的借款 → 声明 → 人员”取锁,重读来源;决定必须为冻结的关联员工本人且不是发起人。新请求及决定均有幂等和审计原子性。数据库在借款条款、入账原件或出借人关联/版本变化时自动失效该组,不以普通 `loan.version` 增量推定失效,避免确认余额和补代账材料误伤声明。
|
||||
4. 新 API 提供财务全量及本人范围内的声明列表、详情、发起、确认/退回;详情只返回冻结明细及原件元数据。原件沿既有下载校验、用途及审计,新增声明范围绑定,不能借此读取整个台账、代账文件、他人原件或当前关联身份已变化的原件。声明请求和原件引用均不写入浏览器长期存储。
|
||||
5. 公司借款页增加“出借人确认”,与“公司代表授权”明确分开。普通员工只读/办理自己的声明,不需要经理身份;根据发布前入口调整,普通员工通过站内通知进入,常驻电脑导航/后备导航/手机“我的”仅供财务和公司代表使用。本人的路由及接口权限保持。沿现有组件/样式实现;查询按账号隔离,新写动作及下载支持取消,账号变化中止旧请求,保留同身份令牌恢复。
|
||||
发起声明事务复用 `createNotifications`,仅为冻结的关联员工创建一条 `loan.lender_acknowledgement_requested` 通知,目标类型为 `loan_lender_acknowledgement`、目标 ID 为声明 ID;通知文本不复制姓名、金额、账号或原件内容。不调用 IM/outbox/企业微信派发,也不加入外部消息支持类型。通知与声明/审计同事务提交,幂等返回不再次通知。电脑和手机通知链接分别指向公司借款页的 `lenderAcknowledgementId` 参数,按账号隔离加载单条详情并直接打开;不依赖其位于列表第一页。URL 为当前详情的单一来源,非空 ID 优先于发起草稿;切换声明或浏览器返回时清除旧草稿、核对状态及错误,并取消旧请求。失效/他人记录继续沿现有详情服务校验,不凭通知恢复权限或效力。
|
||||
6. `assertEvidenceComplete` 的协议类依据接受有效声明,余额确认与后续还款消费者统一使用;有效性既看决定与失效状态,也重比当前条款、身份和原件。余额确认先读出借人 ID,再按出借人 → 借款取锁、重读并核对关联,使同组另一笔原件或身份变化与材料消费串行;不能仅锁当前借款后消费旧对象。纸质依据继续可用,原件/代账/必要调整证据不放宽。出借人确认不推进余额、授权、付款状态。
|
||||
7. 增量迁移预计从 82 到 83,无存量回填或生产操作。回退保留新增历史表,不回删确认记录;旧应用不认识在线替代材料,线上已消费在线依据后不得声称可无影响回退到旧版,应使用兼容修复或先核实纸质依据覆盖。发布与生产迁移仍另行批准。
|
||||
|
||||
验证沿现有隔离 PostgreSQL/HTTP/browser runner,新增定向 fixture;真实账号、回单、生产数据和外部服务不用于开发验证。重点验证本人越权、快照不可变、改回旧值不复活、必要材料不放宽、决定/变更并发及审计回滚。完成后启动只读 reviewer;inline 主会话自行实施和检查,不派 implement/check 子代理。
|
||||
|
||||
## 2026-10-09 N5-P 原借入回单识别预填设计(历史规划记录,已实施发布)
|
||||
|
||||
### P-A 现有能力与方案选择
|
||||
|
||||
对应 PRD P1–P6、AC32–AC39。基线为 `45737ccb`,沿 `CompanyLoansPage` 登记入口及 `CompanyLoan` / `LoanEvidence` 模型实施,不新建凭证中心、银行流水系统或业务草稿表。现有创建后的 `confirmation_status=unconfirmed`、三类附件余额确认及公司代表授权继续使用。
|
||||
|
||||
| 已检查来源 | 事实与设计影响 |
|
||||
| --- | --- |
|
||||
| `client/src/pages/CompanyLoansPage.tsx:176`;`server/src/routes/companyLoans.js:262`、`:314` | 创建与上传分离;新入口需一个有原件的保存动作,不能由浏览器串行两次写入冒充原子成功。 |
|
||||
| `server/src/services/paymentReceiptDocument.js:101`;`paymentReceiptDocumentWorker.js:3` | 已有受限 PDF 文字读取。抽出或复用受限读取层供本地字段提取,旧 `inspectReceiptDocument` 输出与付款分类语义保持。 |
|
||||
| `server/src/services/paymentReceiptMatching.js:41`;`paymentReceiptOcr.js:19` | 付款归一化包含金额/账户/编号,但没有到账日期/双方名称,且字段识别依赖腾讯。新增借入专用白名单解析,复用底层客户端及值解析;不改变旧付款输出与判定。 |
|
||||
| `server/prisma/schema.prisma:3973`、`:4063` | 已有经办请求键、同主体/出借人/原引用唯一约束及附件摘要,可实现本期保存和幂等,不计划迁移或新任务队列。 |
|
||||
| `server/src/services/crypto/index.js:103`;`purchaseAttachmentPolicy.js` | 复用认证加密及实际字节验证;预填结果只经短期、专用用途的加密上下文往返,不能把完整 OCR 结果塞入可读签名 token。 |
|
||||
|
||||
采用“浏览器暂存所选文件 → 无业务持久化识别 → 核对 → 携同一文件保存”的方案。用户只选一次原件;网络上识别与保存各传一次,换取无需新建临时附件池、清理任务或跨设备草稿。关闭前尚未保存的内容不续存,成功保存的文件仍按原借款附件治理。
|
||||
|
||||
### P-B 识别合同与最小字段
|
||||
|
||||
拟增加 `POST /company-loans/incoming-receipt/recognize`,严格 multipart 一份 PDF。授权沿财务角色加 `loan.manage`;涉及员工银行卡比对时追加既有银行卡权限,不授予经理全局借款读取能力。先执行文件扩展名/MIME/实际字节与大小检查,再在事务外执行受限解析:5 MiB、20 页、既有 5 秒/128 MB 工作者上限。损坏、加密不可读或不安全文件不能保存为正常识别附件。
|
||||
|
||||
1. 本地提取页面文本后,按明确字段标签与版面行关系提取,不使用任意数字猜测。金额保持十进制字符串/最小单位,日期用真实日历校验,不以打印时间、导出时间代到账日期;两个同类值矛盾则留空。标识保留字符串及前导零,流水号和凭证号分别取值,稳定排序选唯一引用。多页重复同一交易可合并;不能证明同一笔时拒绝预填,不只处理首页。
|
||||
2. 名称、币种、付款/收款账号用于判断候选及冲突;原始文本仅内存处理。给浏览器的字段是最小业务白名单、遮罩账号、`source=pdf_text|ocr|manual`、逐字段缺项/歧义说明、凭证性质和入账方向提示,不返回完整账号、原文或提供商响应。凭证正式性和成功状态分别表示,识别成功不称为银行验真。
|
||||
3. 本地必需字段充分时零云调用;不足时只使用既有已配置银行 OCR,在每份文件的一次受限识别请求内处理必要页,每页最多一次,整请求有总时限,不能随轮询或组件重挂自动重试。复用客户端时读取借入所需日期/名称后立即白名单压缩,不让旧付款归一化丢掉这些字段;不因提供商结果覆盖本地已发现的非最终/失败/多交易限制。OCR关闭或失败保留本地有效字段,并允许财务手工补齐;刷新识别是显式用户动作。
|
||||
4. 借入按付款人→个人、收款人→公司判断,不能复用会拒绝贷方的 `paymentDocumentReady`。公司支出方向是相对于所选公司判断,不能仅见票面“借方”就拒绝个人付款方出具的回单。完整名称/唯一关系可建议匹配已有公司与出借人,歧义不默认选第一条;历史付款账号与员工当前收款账号不同只提示核对,不自动刷新或否定历史关系。确认为其他收款主体、非人民币或明确银行失败/处理中/非最终时,此文件不能经新入口保存为有效借入原件。
|
||||
5. 初步识别与选择主体后的校验可共享同一上下文,无需为切换出借人再次调用 OCR。服务端以最小加密上下文保存字段/性质供下一请求核对,绑定用途 `loan_incoming_prefill`、经办员工、文件 SHA-256、解析版本、签发时间和到期时间(30 分钟),只经请求体传输且 `no-store`;不放 URL、localStorage 或日志。解密后校验用途/时限/身份,不能借字段加密的完整性省略业务校验。
|
||||
|
||||
### P-C 确认保存、重复与原件
|
||||
|
||||
拟增加 `POST /company-loans/from-incoming-receipt`,严格 multipart:同一原件、加密预填上下文、请求键、现有登记字段和明确核对声明。人工改正仅允许本金/日期/引用及用户本来就需填写的登记字段;身份只能选择现有出借人,不接受账户替换、`confirmed` 或银行成功状态。未知结果可人工补填,token中明确矛盾不能被浏览器删字段消除;OCR关闭的人工路径同样需要文件校验和身份绑定。
|
||||
|
||||
- 保存先重验实际原件、摘要、上下文及登记字段,再校验所选出借人/公司和其版本;要求已查看原件、核对借款性质和主体。`openingOutstandingPrincipal` / `balanceAsOf` 必填且不由识别预填为已核实事实;仍执行本金上限、日期顺序和非未来截止日。
|
||||
- 文件写存储放在短事务外。事务内创建借款、`kind=incoming` 的受控附件及两项必要审计;对外只在全部成功后返回。失败只删除本次新写对象;重试读取已成功事务并核验相同字段和文件摘要,不重新上传关联。对象存储与 PG 无分布式事务,进程崩溃可留未引用对象:不将其暴露为成功记录,清理失败留脱敏告警与原存储运维处置边界,不新增通用扫盘/删除服务。
|
||||
- 沿用 `(created_by, request_key)` 幂等与 `(legal_entity_id, lender_id, origin_reference)` 唯一约束;请求等价比较必须包含原件摘要。新保存以出借人行锁串行,同主体/出借人已存在相同 `incoming` 摘要时返回已有登记提示,不新建。普通原件追加路径也参加同一重复核对,覆盖新保存与旧上传的竞争,既有历史重复不自动合并/删除。
|
||||
- 保持“出借人 → 借款 → 编号”方向,与还款创建一致。已有借款原件上传先只读定位出借人,再锁出借人、锁借款并重验归属;不能在已持借款锁后新增出借人锁。新建持出借人锁后只创建新借款/编号,不再锁或修改已有借款,不与付款批次建立反向依赖。实施前用确定性交错验证该顺序,覆盖原件上传与还款创建;发现与既有约束冲突时先修订设计,不靠加长超时。重复摘要仅证明相同文件;不同扫描件且引用不同时,不能宣称已具备全银行交易去重。
|
||||
- 成功仍为余额待核实,原件可按既有用途下载接口读取,审计只留来源、摘要、解析版本和修正字段名等必要元数据,不保存明文 OCR 输入或完整账号。协议/余额核对/调整依据沿原入口,识别不推进授权、余额确认、付款或核销。
|
||||
|
||||
### P-D 页面与兼容
|
||||
|
||||
`CompanyLoansPage` 的登记借入弹窗增加“上传回单预填/手工登记”路径,复用原 Dialog/Input/Button 和现有字段。上传处理中、待核对、需人工补充、文件不适用和保存失败均有就地提示;能纠正的字段可修改,识别结果须明确仍待核对。当前缺少 `frontend-design` skill,本阶段仅复用既有组件及样式,不做新视觉裁决。
|
||||
|
||||
文件只存在当前表单内存,预填结果按身份/文件请求序号隔离;选择新文件显式重置其提取字段,任何迟到返回都不能覆盖新文件或已手改值。识别/保存都传 AbortSignal,卸载/身份变化取消并清理;保持同身份合法401恢复,禁止新身份重放旧写请求。待保存时阻止重复提交,提交结果丢失时以同请求键回读原结果。
|
||||
|
||||
银行候选匹配不更改员工资料;缺出借人使用现有登记出借人入口。原手工 JSON 登记及材料上传仍可用,不强制所有历史借款都经过 OCR。新入口仅支持 PDF,原图片附件能力和旧付款回单支持范围保持。
|
||||
|
||||
### P-E 运行边界与回退
|
||||
|
||||
本期不计划数据库迁移,不增加提供商、生产密钥、全局文件预览或长期识别存储。保存结果使用旧模型,可回退新入口及专用接口后继续按原页面管理,不删除已登记借款或原件;回退仍遵守原关联方模式最低兼容版本限制。
|
||||
|
||||
本地测试只用合成 PDF/人员和提供商替身。真实云识别、当前银行产品额度与费用边界须在首次获准实样验收时确认;不从发票 OCR 的额度结论推定 BankSlipOCR 可用,也不自动启用服务或修改计费。未知可人工填写是本期明确降级,不以真实材料未调用为由伪报自动识别已验。发布按最终候选门禁和另行部署授权执行。
|
||||
|
||||
## 2026-10-09 N5 员工出借人选择方案(已批准,已本地实现)
|
||||
|
||||
本节对应 PRD 的 AC28–AC31。员工资料已存在于 `Employee`;现有 `loan-lenders/identity-options` 仅提供身份选择,借款登记尚未复用银行卡。目标是让财务选择现有员工并核对资料,服务端建立或复用借款出借人关系,保持现有贷款、授权和付款快照模型。
|
||||
|
||||
1. **选择与资料来源**:在原借款页面增加员工选择流程,复用现有选择框与人员检索样式。返回允许的身份摘要、公司关联、银行与遮罩账号、资料是否完整及来源版本;不向浏览器传完整账号或身份证件。来源为员工主档的当前银行资料,账户名沿现有员工付款规则使用真实姓名。公司关联可作为借款主体默认值,但必须由财务确认借款所属公司,不能把任职公司自动当作债务人。
|
||||
2. **服务端关联**:新增明确的“从员工关联出借人”动作,只接收员工、借款公司、所见来源版本、核对声明及幂等键。服务端重读员工与银行资料,校验可选身份、公司、银行支持、账号格式/可解密性及资料版本,再沿现有加密方式保存借款侧资料、员工关联和审计。不能通过客户端提供姓名或账号覆盖来源。身份核对由财务此次明确确认完成,不再让同一员工先手填、再另做一次身份绑定。
|
||||
3. **敏感权限与维护入口**:保留 `loan.manage` 的财务角色条件,并沿用 `employee.bank.read` / `employee.bank.manage` 的现有银行卡读取权限;不借员工选择扩展到完整人员档案、身份证件或银行卡明文查看。资料不全时定位原员工资料维护入口,有维护权限才可修正。姓名、开户行或账号修改不在借款选择弹窗内重复提供。
|
||||
4. **重复选择及锁序**:同公司同员工存在唯一可用登记时复用;多个历史登记时返回明确冲突,不自动合并借款、账户或授权。新建关联在事务内对来源员工及经办人排序串行,重查重复并保存创建/复用的请求键绑定;刷新已有出借人沿“出借人 → 人员”的顺序锁定,不持人员锁反向锁已有出借人。员工使用 `FOR NO KEY UPDATE`,保留串行保护并兼容审计外键的 `KEY SHARE`。旧身份关联路径也参加同一重复检查;发现并发关系变化时结束事务,按正确锁序重新核对或拒绝,不建立错误关系。
|
||||
5. **资料变更与历史**:预览至保存间来源变化要求重新核对。已有借款资料与员工主档不同,不静默覆盖;显式“使用当前员工资料”动作由服务端读源、比较版本,沿既有在途禁止修改、账户/身份版本与授权失效规则处理并留审计。已审批或已付批次仍消费原冻结快照。后续员工资料维护不直接重写出借人、付款批次、银行事实或本金。
|
||||
6. **数据与范围**:优先复用 `employee_id`、出借人版本和既有审计,无需为员工再建一套人员档案。不得为减少手工录入而增加无依据身份、放宽审批排除或恢复 Q6。若实施研究证明必须新增数据库约束或字段,先明确迁移、存量与兼容影响,再扩展本方案;本节不预先授权存量合并、生产迁移或业务录入。
|
||||
|
||||
验证包括:资料完整的员工正常关联、缺字段/账号不可用/银行不支持、无银行卡读取权限、客户端伪造、重复及并发选择、预览后资料改变、已有借款资料不一致、在途禁止刷新、员工改号后旧付款快照保持,以及财务/马经理后续授权分工。只用合成数据,不读取真实账户或调用银行/OCR;沿现有测试入口完成针对性验证和只读复核。
|
||||
|
||||
界面查询按身份/员工/公司隔离;两个新写动作透传取消信号,随组件卸载或身份变化终止请求,成功回调再次核对身份。不能只隔离回调而让迟到 401 在另一身份下重发原动作;保留同身份的正常令牌刷新。只保护本次入口,不改变共享 HTTP 恢复语义。
|
||||
|
||||
## 2026-10-08 实样发现后的凭证处理方案(N1–N2 已本地实现)
|
||||
|
||||
本节对应 PRD 顶部 R4/AC5 补充及 implement 的 N1–N2,用户已明确“开始执行”。沿用已实现的两人关联模式、回单存储、人工核对和核销流程;不重新设计 S1–S8/SR,不把 S002 专项格式兼容纳入必修范围。
|
||||
|
||||
实现收敛:本地使用 PDF 文本解析读取票面限制,无法可靠解析的维持未知;新增的结构化凭证依据随既有加密核验/人工提案保存。人工可按正式回单的已记账支出和记账日期确认,不生成虚假的银行状态原文。旧证据通过有权经办显式发起的本地重检生成新版本,保留历史、不调用云 OCR;最终资金动作不默认接受缺少新版依据的旧记录。
|
||||
|
||||
本轮采用现有表,无新增迁移。新增 `paymentReceiptDocument` 服务和受限 PDF 文本工作线程,使用 `pdfjs-dist`;单文件最多 5 MB、20 页,工作线程限时 5 秒、旧生代内存上限 128 MB。结构化凭证类型为正式回单、非最终回执或未知,原始票面文字不落日志;识别异常维持未知,不能自动核销。
|
||||
|
||||
人工依据分“原件明确成功”和“正式回单已记账支出”。后者须填写真实且不晚于当天的记账日期、原件已核对声明及依据说明,保存 `transactionStatusRaw=null`;新增人工依据必须按该批次模式确认。既有非最终说明、贷方入账、多个回单或失败/处理中矛盾均不能由人工覆盖。自动凭证检查位于核验构建与最终重建,未放入失败/终态事实也使用的低层字段匹配函数。
|
||||
|
||||
旧记录显式重检接口为 `POST /payment-batches/:id/receipt-attachments/:attachmentId/document-check`,要求当前版本、财务权限和经办资格,核对原件实际大小与摘要、未被消费,再在同一事务新增核验版本与审计;旧人工确认不得转移到新版本。历史 OCR 为 0 页时详情仍可打开重检入口,负数、超上限等无效页数继续拒绝。已核销历史不自动重写。实现及验证证据见 implement 顶部;独立代码复核和真实还款闭环不在本轮完成结论内。
|
||||
|
||||
### 凭证性质、字段读取、交易归属分别判断
|
||||
|
||||
1. 凭证性质先区分已确认的最终付款依据、明确非最终依据、尚不确定。银行限制说明、实际记账方向和入账/付款信息属于判断依据;文件名、标题、OCR 请求成功或没有提取到免责声明均不足以判为最终依据。公司贷方借入和借方还本分开处理。
|
||||
2. 自动路径只开放经过实际材料核验的格式与字段组合;识别来源必须能覆盖判断凭证性质所需内容。当前 `BankSlipOCR` 的六类归一化字段不能证明完整覆盖票面说明。可在本地核对 PDF 文字,缺文字/提取异常保持未知;本阶段不以接入新的云服务或实现所有扫描件 OCR 为前提。
|
||||
3. 人工路径在原件实际信息足够时使用。沿既有财务录入、马经理关联方确认,补充可追溯的凭证性质及已记账依据,不补造成功状态。明确非最终的回执不能经普通人工决定升级;需要取得对应正式付款证据。没有可用最终证据则保持待核对,不能以“以后会补回单”先核销。
|
||||
4. 凭证足以证明付款也不自动证明属于哪个批次。金额、币种、双方账户、付款方向、银行交易身份及既有候选/提交关联继续分别检查;回单编号、客户方流水号和网银指令号分开保存或引用,不靠人工照抄使之相等。编号不足时保持待对账。
|
||||
|
||||
### 依据留存、旧数据和最终消费
|
||||
|
||||
- 在既有证据模型上留存原件摘要/版本、凭证判断及其依据、自动或人工来源、决定上下文;核验结果持久化、人工冷重建和最终核销都必须保留并重验这些信息。不能只在上传时或页面增加提示。
|
||||
- 换件、重新识别、作废和候选变化继续使旧依据失效。旧核验记录缺少凭证判断时不能默认通过;已记账记录保持历史不可变,需要核查的问题另行登记,不自动撤销本金核销或重写生产数据。
|
||||
- 本轮凭证依据随现有加密核验和人工提案留存,未新增迁移。涉及共享回单服务时回归报销消费者,既有独立性、交易唯一性、失败/受理与资金约束保持。
|
||||
- 验收覆盖明确非最终说明、字段中出现成功但票面有限制、无法完整判别、正式凭据没有字面成功状态、借入/支出方向不同、旧结果缺依据、人工重建及最终核销。去除关键凭证检查后,测试必须能区分错误放行或合同退化。
|
||||
|
||||
### 实际材料与完成边界
|
||||
|
||||
- 原四份获授权 PDF 和 OCR 配置读取范围继续有效,无需为相同范围重复授权;先复用既有结果和本地材料,不无目的重跑云端。新增两份正式借入回单目前只做了本地读取;确有必要发送新文件时再明确文件范围。
|
||||
- S001/S003 作为非最终凭证反例;S002 维持既有需复核结果,可用于材料性质/人工依据分析,不要求兼容其全部 OCR 字段,也不为它索取保证金退款材料。新增两份借入回单用于本金及格式核对,不能充作还本付款正例。
|
||||
- 优先用现有材料验证原件字段与人工处理是否可行;只有一个具体交易的完整归属无法核对时,才列明需要该笔交易的正式支出回单及网银实际提交详情。现有无真实借款还款时,不要求制造付款获取样本;借款全链用合成数据,首笔真实银行闭环在获准实际还款后验收。
|
||||
- 正常办理必须有一条经验证可用的自动或人工路径;仅能拦截不代表可启用。首笔前的软件/材料验证与首笔后的实际银行闭环分别记录。异常缺实样保持未验,不提前认定失败释放等已具备真实银行接受性,缺证继续占用。
|
||||
|
||||
## 2026-10-08 财务经办与马经理关联方确认方案(本地实现及合成验证完成,已授权本地提交)
|
||||
|
||||
用户已确认马经理有权代表公司批准,并在规划完成后明确“开始实施”。马经理同时为股东和个人出借收款人;技术员工不参与复核、审批、见证,不增加权限或分派待办。公司授权这一业务事实不再待决。本节是本次权限模式变更的执行合同;本地实现及合成验证已完成,具体证据与剩余验收见 implement 顶部。下方历史设计中的独立复核,除 Q6 外按本节明确区分模式;本地改动不等于生产已具备该模式。
|
||||
|
||||
### RP-A 业务范围与实际分工
|
||||
|
||||
- 默认 `independent` 模式保留原规则;新增 `related_party` 模式只用于经登记的本公司、真实个人出借人、其关联员工以及明确列出的已确认借款。马经理的选择依据真实员工与出借人关联,代码不硬编码姓名、不虚建“非员工出借人”隐藏关系。
|
||||
- 财务办理资料核对、申请、制单、提交记录和银行证据。马经理在公司授权范围内批准或退回,按钮及记录标明“关联方确认:确认人同时为本笔出借收款人”。这是一项真实的利益关联例外,不称为独立审批,不以两人确认或 OCR 抵消该关联。
|
||||
- 付款退回沿原付款决定接口留存 `decision=reject`、理由、决定人和授权上下文;该申请不能再批准或导出,退回本身不释放占用。财务按未发送取消规则取消原申请,再新建更正申请;原退回记录不可改。数据库禁止将退回决定当成已批准付款。
|
||||
- 财务兼任人事行政不影响其经办,但不能自审。同一员工的多账号或多业务角色按同一真实身份处理。经理可以承担本批多个确认环节,不新增第三位审批人;不能承担本批经办、上传或录入等被排除工作。
|
||||
- 正常流程为财务核实本金并发起申请→马经理代表公司确认→财务导出并在网银付款→上传回单沿既有 OCR 核对→证据满足后由财务登记核销。完全满足自动核验的回单无需再增加一次人工回单确认;有人工例外或归属歧义才进入对应确认。
|
||||
- 借入凭据、历史归还和代账核对仍是本金的事实来源。出借人确认余额、账户或收到钱与代表公司批准是不同声明,分别留痕;本方案不把聊天中提及的金额或资料自动录成真实余额。
|
||||
|
||||
### RP-B 公司授权、范围与模式
|
||||
|
||||
采用借款模块内的小范围授权记录,不改变通用角色平台。财务录入已存在的公司授权事实、依据说明/引用、公司、出借人、指定确认人员工标识及覆盖的借款;马经理本人确认后生效。该登记反映用户已经确认的公司代表权,不再要求技术员工或额外第三人批准。
|
||||
|
||||
1. 授权内容按版本保存,覆盖借款用真实关联关系约束,不能包含其他公司、出借人或未确认借款。财务不能单人激活、扩充范围或把自己设成确认人;新增借款需登记新范围版本并由马经理确认。
|
||||
2. 授权确认只是业务授权留痕,不授予新的全局经理/财务权限。每次新决定还要检查当前人员、经理/CEO业务角色及相应现有权限,授权记录不能让离职人员或无权用户通过。
|
||||
3. 新建还款时服务端查找有效且覆盖全部分配借款的范围,冻结 `approval_mode`、授权标识/版本、公司、出借人及指定确认人。界面显示适用模式,不能用客户端参数或调用顺序把无资格的独立单改成关联单;范围缺失或冲突明确拒绝。
|
||||
4. 旧独立批次不自动转换,已送审、已导出或已发生银行事实的模式均不能改写。既有草稿若需改用关联模式,只能满足原安全取消条件后重新申请,不能重用旧审批、导出或银行事实;不安全取消的历史批次另行评估。
|
||||
5. 授权生命周期区分“允许新付款”与“允许处理历史对账”。停止新付款后不能建单、付款前批准或导出;仍覆盖原借款的对账授权不会因付款范围用完或付款期限届满自动失效。停止对账权限阻止新的人工对账决定及最终释放,不能删除旧事实或旧批准。
|
||||
6. 财务或马经理可登记当前版本的停止及理由;已被取代版本不能再停用。恢复或扩大权限采用财务登记、马经理确认的新版本,缩小范围或停止后不得回退使用更早版本。历史内容和生命周期事件保留,不能靠恢复状态让失效材料批准复活。新的对账决定可引用当前覆盖原批次的新授权版本,原批次的付款授权引用与模式不改。
|
||||
|
||||
### RP-C 决定与经办冲突
|
||||
|
||||
独立模式继续要求无利益关联。关联模式只豁免“指定确认人等于出借收款人”这一种冲突;原来各路径的制单、提交、导出、登记、证据上传和人工录入冲突继续生效。参与人检查必须保留冲突原因,不能在算完一组排除员工标识后直接删掉马经理,否则他兼任上传人时也会被错误放行。
|
||||
|
||||
服务端在关联批次的经办入口就拒绝指定确认人创建/提交/导出、登记银行提交或上传/录入/提案银行证据,避免只有两人的配置事后找不到确认人。决定入口再次检查全部相关历史经办记录,包括已作废或被取代的回单,不能靠作废清除冲突。公司授权确认、此前正常审批或收款人声明本身不等同于经办参与。
|
||||
|
||||
| 环节 | 财务职责 | 马经理职责 | 保留的最终条件 |
|
||||
|---|---|---|---|
|
||||
| 授权与未还本金 | 登记授权范围、借入及历史还款依据、与代账核对;只有已确认本金可申请 | 确认其公司授权登记;需要时另作债权/账户声明 | 范围、身份、资料及未还本金有效,授权确认不代替余额核实 |
|
||||
| 付款申请与制单 | 创建、分配、提交、导出、实际网银操作 | 代表公司作关联方付款确认或退回 | 当前授权、角色、身份版本、启用状态、金额和收付款快照、容量与冻结门禁 |
|
||||
| 银行提交与清单 | 逐次登记/撤回提交,确认清单完整 | 关联方确认完整清单 | 新登记、撤回、导出均使原清单确认失效;每次提交分别解释 |
|
||||
| 成功或失败回单归属 | 上传/录入回单,提出证据及排除其他候选的理由 | 对需人工判断的归属作关联方确认 | 交易身份、核验/人工录入记录、完整候选及所覆盖指令一致;同金额/账户或两人声明不足 |
|
||||
| 人工回单例外 | 留存原件并录入 | 核对原件作关联方确认 | 状态、字段和原件可读,失败/处理中/矛盾信息不当成成功;证据重建及核销仍重验 |
|
||||
| 严格失败、银行终态、取消 | 登记逐提交事实及银行证据;条件满足后取消 | 承担当前需要的失败/终态决定,以关联方确认记录 | 严格失败口径、指令对应、全部提交与导出覆盖、3天等待期、无未解决成功/处理中事实;最终释放重验 |
|
||||
| SR补证恢复 | 对原终态补证、重新送审 | 对新增事实和恢复轮次作关联方确认 | 原结论不改;材料变化旧批准失效;不重开付款,最终取消消费最新有效恢复 |
|
||||
| 晚到成功 | 登记原件与事实,触发冻结,条件满足后补记 | 确认归属及银行事实 | 原付款历史快照、唯一交易、逐借款容量;先解决占用冲突,差额列待追回;补记不能导出 |
|
||||
| 误报/重复登记关闭 | 提出更正依据 | 关联方确认更正 | 原记录与更正留存,证据不足不能关闭;不能改变已入账事实或清掉其他冻结原因 |
|
||||
| 部分/全额追回 | 登记真实到账及材料,执行符合条件的入账 | 关联方确认到账 | 实际到账、交易唯一、部分只冲减待追回;全部有效原因关闭才解冻,不做冲抵 |
|
||||
| Q6人工确认未提交 | 本模式不可发起 | 本模式不可确认 | 原规则需两名额外独立复核人;服务端、最终释放及界面共同限制 |
|
||||
|
||||
材料不足的结果仍为待对账、保持占用或冻结。关联确认不降低证据门槛,也不能保证同金额分期都自动核销。若两位实际办理人中没有当前合格确认人,可继续由有权财务留存事实,不以单人确认恢复资金动作。
|
||||
|
||||
### RP-D 当前资格、历史效力与并发
|
||||
|
||||
| 动作类型 | 资格与授权时点 | 停用后的处理 |
|
||||
|---|---|---|
|
||||
| 新申请、付款前批准、导出及重新导出 | 当前经办/确认资格、付款授权、冻结状态及版本;实际导出前再次检查 | 停止新付款即拦截,旧“已批准”不能继续导出 |
|
||||
| 新的银行事实、归属、人工回单、恢复或追回决定 | 当前确认人业务资格及对账授权,绑定本次证据;不要求原付款审批人或出借人恢复旧资格 | 新决定在对账权限停用后拒绝;有权财务仍可登记新事实,冻结照常产生 |
|
||||
| 确认未付款及最终取消释放 | 当前操作人、当前对账授权、有效的对应决定、最新材料与全部释放门禁 | 对账授权停止后不能新释放;付款授权停止本身不阻断有证据的对账释放 |
|
||||
| 已付款核销、已确认银行事实的补记/追回入账 | 当前记账操作人有权;原付款/事实决定当时有权且证据仍有效,按各自冻结模式和快照重验资金条件 | 停止新付款、原审批人/出借员工事后离职或主数据停用不抹掉已付事实;不新增付款指令。需要重新人工确认的失效证据仍按新决定的当前资格规则处理 |
|
||||
|
||||
已作出的关联决定不能伪装成独立批准。最终使用历史决定校验其当时记录的模式、授权版本、范围和参与身份,不再通过“历史收款人必须独立”的旧函数;也不能只认一个 `approved` 状态而不验材料与交易。
|
||||
|
||||
沿用既有批次→回单交易/附件→出借人及人员资格的锁序;创建锁出借人→借款且不等待既有批次。授权停用/新版本生效仅锁出借人,不再取得既有批次锁。资金动作在持出借人锁后重验授权,因而与停用串行;不得新引入出借人→既有批次的逆序。当前资格在决定事务内校验,决定/审计/资金更新原子执行。
|
||||
|
||||
- 付款授权停用先于新批准/导出提交:后者拒绝;导出先完成:保留导出事实,后续停用不能让已下载文件在银行失效。
|
||||
- 对账授权停用先于新决定或最终释放:拒绝;有效决定先完成:保留该历史决定,最终释放仍重验当前对账授权;已确认的真实付款可按历史证据记账。
|
||||
- 材料/候选变化仍按现有机制使旧批准失效。核销/释放只依据事务当时已知事实;之后才出现的新证据进入晚到结果对账,不宣称锁能防止未来事实。
|
||||
- 禁止通过前端能力缓存、自动重试、权限恢复或删掉冲突原因绕过上述时点;幂等请求只返回原事务结果,不重复产生付款或释放。
|
||||
|
||||
### RP-E 数据与完整消费者
|
||||
|
||||
本地新增增量迁移 `20261009010000_loan_related_approval`,仅在隔离合成数据库验证。采用现有还款/事实表加明确模式及授权引用,不建设通用代理审批系统。
|
||||
|
||||
| 数据 | 实现内容与约束 |
|
||||
|---|---|
|
||||
| 借款关联授权、覆盖借款与生命周期事件 | 公司、出借人、确认人员工外键,范围借款外键,版本、依据引用、财务登记/经理确认、两个权限方面的状态事件;内容与已确认事件不可改删,扩大范围必须新版本 |
|
||||
| LoanRepayment付款上下文 | `approval_mode = independent / related_party`、授权标识/版本、确认人及关联身份快照;创建时冻结,之后不可转换;新关联记录缺少范围或身份不能落库 |
|
||||
| 逐次决定上下文 | 批次审批与其审计、归属、提交清单、终态事实、SR恢复、银行事件及借款人工回单决定均留存确认模式、授权版本、关联身份、决定人/时点及证据快照;异常的新决定可引用新的合法授权版本,但不覆盖原付款上下文 |
|
||||
| 历史和数据库保护 | 原记录显式归为独立模式,不补造授权;保留经办人与确认人不同、已复核记录不可改删、交易唯一与资金容量约束;关联字段完整性/外键与模式一致性另加约束,共享报销记录不得标成借款关联模式 |
|
||||
|
||||
快照只保存身份标识、版本、引用与摘要,不复制解密账号或银行原文。待审记录变化仍新建/取代,不回写已作出的决定;驳回也保留当时模式与理由。
|
||||
|
||||
源码已确认的改动消费者如下,实施须覆盖入口、读取/重建与最终使用,不能仅修改 `activeReviewer` 或页面按钮:
|
||||
|
||||
| 位置 | 需要贯通的职责 |
|
||||
|---|---|
|
||||
| `companyLoanPayments.js` | `prepareLoanRepayment` 创建前候选门禁、`eligibleLoanReviewers`、`activeReviewer`、`validateLoanPayment`、`assertApprovedIndependently`、归属确认、严格失败、核销与取消;把冲突原因与模式分开 |
|
||||
| `loanBankSubmissions.js` / `loanBankTerminalFacts.js` | 清单确认、终态参与人及决定、`confirmNotPaid`、材料状态与最终释放重验;保留导出/指令逐次覆盖和等待期 |
|
||||
| `loanReleaseRecoveries.js` / `loanBankResults.js` | 恢复逐事实/整轮确认、最终消费、晚到/更正/追回决定与记账;冻结关闭仍只能由对应事务完成 |
|
||||
| `paymentReceiptManualReview.js` / `paymentReceiptManualPersistence.js` | 人工提案决定、`receiptParticipants`、`assertIndependentReceiptReviewer`、`loadApprovedManualReceiptEvidence`、详情重建及所有复用人工证据的校验;借款分支识别模式,报销/差旅继续原规则 |
|
||||
| `paymentReceiptVerification.js` 及交易认领路径 | 自动核验和最终消费使用正确历史审批上下文,保留唯一交易、字段/状态及候选检查;OCR成功不代替公司批准 |
|
||||
| `loanNotSubmitted.js` 与取消消费者 | 关联模式在发起、决定及最终消费三处拒绝Q6;旧独立Q6双审与材料合同不变 |
|
||||
| `routes/paymentBatches.js` / `routes/companyLoans.js` | 服务端候选、动作能力、授权登记、范围受限的经理材料读取与确认;不得为绕过目前财务专用读取检查而授予经理全局财务权限 |
|
||||
| `CompanyLoansPage.tsx`、还款详情/对账组件、待办及通知消费者 | 依据服务端返回的模式和能力展示动作、材料与历史文案;技术员工不进入候选或通知对象,现有独立模式显示不变 |
|
||||
|
||||
### RP-F 页面、错误与回单
|
||||
|
||||
- 沿用已有页面、对话框和样式。授权及范围在借款业务内登记;还款详情、确认弹窗、历史决定和待办都显示关联身份。按钮区分财务“提交/登记/核销”与经理“关联方确认/退回”,不出现“独立复核通过”的错误描述。
|
||||
- 服务端返回受范围限制的能力和不可用原因;错误码合同区分无有效授权、超范围、经办冲突、证据失效和本模式不支持Q6。未授权人员不通过原因文本获得借款、人员或银行材料详情。经理只获得作出本笔决定所需材料,完整账号/原件仍要求用途、权限和审计。
|
||||
- 收款人多角色不能获得本批经办入口;财务多角色不能获得自己的确认按钮,直接调用接口同样拒绝。电脑和手机均完成授权确认、付款及异常流程操作,不以共用组件替代移动端验证。
|
||||
- 普通回单继续 `BankSlipOCR → normalizeBankSlip → 匹配/必要人工核对`。按获准使用的实际文件确认可读字段和状态;合成测试只替换云端返回。无需提前问银行能否识别,也不能补造回单未记载的流水号或把 OCR 视为银行验真。
|
||||
- 回单流水号/凭证号与提交指令号的关系从实际回单、网银提交记录核对,不默认相同。现有依赖编号的失败/处理中路径继续严格检查;信息不能对应时保持待对账。银行终态或“无提交”的证明属于异常证据问题;Q6在此模式下关闭,官方无结果材料不再作为普通还款启用前提。
|
||||
|
||||
### RP-G 实施、验收及启用边界
|
||||
|
||||
1. RP1:数据、授权范围、两类权限生命周期与冻结模式;RP2:所有服务/路由/证据重建/最终消费;RP3:现有电脑手机界面与范围访问;RP4:合成正反例、并发、资金守卫变异、只读复核和最终候选检查。详细清单及验收映射见 implement 顶部。
|
||||
2. 改动应一起完成到可办理、可对账再启用,不能仅部署放开收款人审批的中间版本。AC20–AC26已有本轮本地合成证据,AC27数据库部分通过、独立代码复核及固定候选正式门禁待完成;原AC3保留独立模式基线,其余资金要求不降级。
|
||||
3. 本地已有A/B/C、S1–S8、SR和电脑/手机界面;本次是在已有流程上调整模式,不重做或声称这些尚未实现。`4c37fcee` 的门禁只证明旧独立模式,关联模式必须绑定自己的测试结果。完成实现后按项目规则只读复核;inline下无法派审则如实保留待独立复核。
|
||||
4. 2026-10-07的获准生产只读核实为OA借款记录0、73迁移已应用;本轮新增后本地82迁移。这只是时点事实。发布前再获准核对存量及实际迁移差集,不能永久复用空存量结论;若出现历史在途独立批次,单独评估且不自动转模式。
|
||||
5. 新决定一旦产生,旧代码不理解关联确认的含义,不允许直接降级、删除模式字段或改写历史。需要停止新付款并采用获批兼容修复/回退方案,保留已发生银行事实及其证据。
|
||||
6. 本轮已授权本地实施与验证;用户随后明确授权将完整的 39 项改动本地提交,并运行新候选正式门禁。真实授权配置、生产查询、推送、部署及真实付款不在此次执行内。运行时验证、主会话检查、独立复核和真实材料验收分别记录,不沿用旧候选回执证明新模式。
|
||||
|
||||
### 已否定方向(历史说明)
|
||||
|
||||
此前讨论过让技术员工获得借款专项复核资格。用户已明确否定,不采用、不实施、不再作为待确认项;现方案不依赖该员工,也不以另建身份或增加通用角色代替他的同意。
|
||||
|
||||
## 2026-10-07 S4–S8 实施细化(沿已批准范围,尚待最终验收)
|
||||
|
||||
- Q6 使用独立的人工声明与复核记录,不混入银行终态事实。三类附件固定分类;查询及对账覆盖首次导出至登记日(公司时区),每个相关导出人均须有文件去向说明。完整空提交清单可以独立复核;撤回登记不能充当“未提交”。混合批次仍逐条验证已提交部分的银行终态。
|
||||
- 每次人工声明绑定材料修订、全部导出/提交/核验、付款快照及同额候选。两名不同且当前合格的复核人分别决定。失效声明可以追加取代,原银行终态不改;最终取消重验全部条件、物理文件摘要及双审,数据库另外约束释放配对。
|
||||
- 冻结按来源事件逐条记录;只在新申请、付款前复核及导出入口检查。关闭函数仅供对账业务事务调用,没有通用解冻接口。误报须经独立人员凭更正证据确认;仅不确定或证据不足不能关闭。
|
||||
- 晚到成功及退款到账以人工核对银行原件的方式登记(不是 OCR 通过)。输入按既有回单归一化规则核对成功状态、双方账号、币种、金额和流水号,原始人工输入加密存储;查询完整输入必须填写用途并记审计。已取消批次可以另存银行证据,但不重开原付款回单、付款项或导出。
|
||||
- 归属批准到入账之间再次出现同额候选,最终入账重验会拒绝。可用同一交易的新登记取代未入账的旧批准,再独立复核;取代时保持至少一条冻结。银行交易的唯一认领在最终入账事务中消费,复核仅做冲突检查,避免尚未入账的失效批准占死交易身份。已入账的银行事实不能被重提覆盖。
|
||||
- 晚到补记与追回使用独立银行事件、交易认领及逐借款补记表,不创建付款批次。交易认领和原核销/别名空间相互排斥;复核与入账同样校验密钥和交易身份。补记成功之后,新申请可用本金要扣掉补记结清额,数据库容量检查也包含这部分。
|
||||
- 未释放的原占用在补记事务中以被银行事实推翻为原因释放,保留原终态和取消信息;其他仅占用的申请须先处理,不能算作已付。已经付掉的部分按差额列待追回;整笔超额时也保留银行全额和零结清记录。追回只接受实际到账并经复核,不用冲抵;部分到账不解冻。
|
||||
- 已有待复核或已批准的晚到成功时,旧终态取消入口拒绝,必须走对账补记;数据库延迟约束同样保护这条边界。取代已产生占用冲突的未入账事件时,同事务先转移冲突冻结再关闭旧原因;新事件入账或凭更正证据确认误报时关闭对应派生原因,不能留下不可处理的旧冻结。
|
||||
- 已用于误报解冻的更正证据属于已消费的复核依据,服务及数据库均禁止再作废。更正记录、原始银行事件及关闭依据保留,不回写原结论。
|
||||
- 终态界面支持一次关联多份同指令处理中回单。复核卡明确展示所选提交、终态类型、证据、了结回单;Q6 展示逐份导出及三类证据的准确绑定,失败归属展示覆盖指令及核验附件。历史作废回单仅可通过实际事实绑定、必填用途的对账读取查看;权限、隔离策略、物理摘要、审计及 no-store 保留,普通作废回单下载仍被拒绝,不恢复其付款效力。
|
||||
- S8 沿用既有 React 对话框和样式,未引入新视觉方案。页面集中展示导出、提交、证据、人工声明、补证轮次、银行事件和冻结原因;原制单不得再次导入网银的提示不是技术保证。
|
||||
- S0 存量已于 2026-10-07 获准只读核实:OA 借款记录为 0,发布前需重核。合格复核人数、银行编号关系及官方材料、真实回单验收仍未完成;本轮资金与界面代理已完成修复后只读静态复核,运行时结果见 implement。该复核不替代异模型或业务人员验收。本地实现/合成验证不代表可以部署或真实还款。
|
||||
|
||||
## 2026-10-07 补证后恢复方案(SR,第 1 版,用户已批准本地实施)
|
||||
|
||||
本方案先完成设计,随后用户明确回复“批准”,授权 SR-A、SR-B 本地实施与验证;SR-C 随 S8,提交、推送与部署未授权。S3 已本地提交 `14aee82d`;下文历史设计及实施记录保留其原时点。本方案补充 3.2 的释放流程,不把普通补证归入 S6 的晚到成功。
|
||||
|
||||
### SR1 问题与边界
|
||||
|
||||
源码依据:`loanBankTerminalFacts.js` 的 `proposeTerminalFact`、`confirmNotPaid` 只接受 `unknown`;作废证据会取代关联事实。`companyLoanPayments.js` 的 `cancelLoanRepayment` 重验当前证据;`guard_loan_repayment_history` 禁止回写既有终态及其依据。因此,已确认未付款但未释放时,旧证据失效后即使取得新的有效终态证据,也无法完成重新登记与释放。
|
||||
|
||||
适用:批次仍为 `reviewed`/`failed`,原银行结论为 `confirmed_not_paid` 或 `confirmed_failed`,所有本金分配仍为 `reserved`。包括补换银行书面证据、同一交易换回单或重新识别、补登遗漏提交、候选批次变化导致归属复核失效。正常 `unknown` 仍走 S3;原有结论与依据仍有效时沿原取消流程,不要求额外恢复复核。
|
||||
|
||||
不适用:已取消释放、已核销、任一分配不再占用、已出现本笔成功事实。成功事实留待 S6;疑似成功或无法识别时可记录补证需求,但不得通过释放复核,继续占用,不把作废当作否定银行事实。处理中回单只能由同一指令的有效终态事实了结。本期不开放 Q6 人工未提交恢复、不降低 S0 存量核实或 S3 证据门槛。真实已付后退款、冲正、退汇仍不等于未付款。
|
||||
|
||||
### SR2 历史结论与当前释放资格分开
|
||||
|
||||
- 原 `bank_result_state`、`bank_result_ref`、审批与分配记录不回写,不把终态改回 `unknown`;新增恢复记录引用原结论及此前恢复轮次。补证不说明原未付款判断必然错误,页面表述为“原结论保留,释放依据待补充”。
|
||||
- 新增恢复轮次(拟表 `loan_release_recoveries`)与审计事件。每轮不可改的内容包括批次、原结论/依据、前轮、发起人、原因;送审时冻结的清单、事实、证据与候选快照另形成不可改的送审记录。
|
||||
- 轮次状态:`collecting`(补证中)→ `proposed`(待复核)→ `approved`/`rejected`;经办可撤回未批准轮次为 `withdrawn`。资料变化可使待复核或已批准轮次为 `superseded`;成功释放为 `consumed`。受控状态与决定事件同事务写入;不可删除,不可修改既有送审字段、复核意见或把已关闭轮次复活。
|
||||
- 每批次至多一轮补证中、待复核或已批准记录。需再次恢复时新建轮次;过期轮次的取代与新轮次创建同事务完成。请求键保证重试不生成重复轮次。
|
||||
- **一旦发起过恢复,最终释放只能依据最新一轮有效批准**。驳回、撤回、资料变回原样、旧批准仍在数据库中,都不能重新启用原结论的释放权限。批准本身不释放额度,仍由财务执行最终取消。
|
||||
- 不生成付款批次或补记付款,不恢复导出、执行付款、已释放占用;本金在补证、送审、复核期间都不变。S5 的出借人冻结原因如已存在,不能被本流程关闭。
|
||||
|
||||
### SR3 补证、送审与独立复核
|
||||
|
||||
1. 当前持 `loan.manage` 的财务发起,说明失效原因;服务端验证适用范围并记录原结论。不得用管理员权限跳过。
|
||||
2. 在有效恢复轮次中,允许终态批次登记新终态事实;只对该入口放开原 `unknown` 限制。证据上传、作废、提交清单登记与复核仍沿 S1/S3 的事实规则;失效事实按既有规则取代,不覆盖旧事实。新登记的事实逐条独立复核。
|
||||
3. 补登提交后必须重做完整清单复核,并为每次有效提交举证。撤回登记仅是材料纠错,不代表银行撤销;新增再撤回也算清单变化。不能通过撤回真实提交消除已知银行事实。每条导出仍须关联已终止提交,历史汇总继续阻断;没有提交的导出留给 S4。
|
||||
4. `confirmed_failed` 的恢复也升级为 S3 的逐提交终态证据集合,不能重写原失败核验 ID。原证据仍可读且有效时可引用;换回单、重新识别后必须引用新核验记录。失败归属仍按提交及当前全部同额候选独立复核。
|
||||
5. 财务送审时,服务端重跑 S3 全部释放条件并冻结完整证据快照,不接受客户端自行宣称“完整”或自报有效版本。
|
||||
6. 当前合格的经理/总经理独立复核。排除本轮发起/送审人、所有相关证据上传人、回单人工录入人、终态事实登记人,以及本批次制单、提交、出借员工、导出、银行提交登记与清单确认经办人。取人员关系时包含旧记录、作废与撤回记录,不能借换材料消除经办身份。原审批人可参与,但必须满足当前资格与上述独立性;不因其是原审批人而自动放行。
|
||||
7. 批准时重新取当前材料和候选,比较快照并重跑全部条件;驳回或证据不足继续占用。原审批人和出借员工的在职/角色、主数据当前启用状态不重验,按历史审批与原冻结快照核对;当前操作人始终核验当前权限。
|
||||
8. 最终取消必须引用这轮批准;核对当前操作人取消权限,再次重验快照、释放条件与分配状态。释放、批次取消、轮次消费和审计一次事务提交,任一步失败全部回滚。已完成的同请求重试返回原结果,不重复释放。
|
||||
|
||||
沿用 S3:逐提交覆盖、逐导出关联、提交清单有效、终态证据有效、失败交易唯一性、必要的失败归属、无未解决成功/处理中事实、无历史汇总、距最后导出满内部等待期。对账单、截图、等待期或两个人确认均不能单独放行。未付款的新证据不要求再机械等待 3 天,但仍必须满足最后一次真实导出的等待期。编号对应关系仍待 S0,不靠人工照抄回单号补足银行证明。
|
||||
|
||||
### SR4 快照失效与并发
|
||||
|
||||
送审快照包含:原结论与依据;原付款快照标识;全部导出;全部提交(含撤回)及清单复核记录;逐提交终态事实与复核记录;银行证据 ID、摘要和作废状态;全部付款回单的 ID、摘要、OCR 版本、核验记录、人工录入/复核记录及作废状态;归属批准及全部候选集合;分配 ID/金额/占用状态。证据只要改变,旧批准就不能沿用,即使银行流水号相同。
|
||||
|
||||
使用服务端单调递增的材料修订号并保存上述快照;材料新增、作废、重识别、人工录入及材料复核均推进修订号,防止“改完又改回”复活旧批准。恢复轮次自身的送审、批准和消费决定不改变材料修订号,避免批准使自己失效。候选变化同时重查实际集合,不只依赖目标批次自己的修订号。证据送审与批准之后的缺失、失效、存储读取错误或摘要不符,均不得放行。
|
||||
|
||||
锁与检查须覆盖所有写入者,而非仅恢复接口:同批次最终释放与证据作废、付款回单上传/核验落库、提交登记/撤回、清单/事实/归属复核串行;同出借人的候选形成与候选检查也串行。沿既有锁相对顺序:批次 → 回单交易 advisory lock(需用时)→ 出借人 → 按 ID 排序借款行,不引入反向加锁。编码前核对所有受影响入口及后台 OCR 写入的实际锁序;多批次场景不在持有出借人锁后反向锁其他批次。
|
||||
|
||||
- 变化先发生:旧送审/批准失效,取消拒绝,本金和占用不变;取代旧轮次后补证重新送审。
|
||||
- 最终释放先发生:只消费一次批准并释放一次;之后证据不允许改写已关闭记录。后来银行事实须走独立对账流程,本设计不能证明未来不会出现成功,不声称串行化消除晚到风险。
|
||||
- 独立性与权限在送审/批准及最终动作所需环节重查;经办人集合变化使旧送审失效。旧逐事实复核人事后离职本身不抹掉当时有效的批准,新的恢复复核人必须当前合格。
|
||||
|
||||
### SR5 数据、接口与页面安排(设计约定;实现状态见 implement)
|
||||
|
||||
预计新增一个增量迁移:恢复轮次/不可变送审与决定记录、材料修订号、唯一索引及历史保护约束;不得放宽原银行终态或已释放分配的保护。存量不自动补造恢复批准、不自动释放;默认未发起恢复,保留 S3 原门禁。回滚前若已有恢复记录,不能退回只按旧结论释放的代码;停止发布并保留数据,另审兼容方案。
|
||||
|
||||
拟接口位于 `/payment-batches/:id/loan-release-recoveries`:发起、送审、独立复核、撤回、查询。沿现有附件/事实/清单接口补证,最终仍走批次取消接口并传恢复轮次与幂等请求标识。终态材料写入口须验证当前轮次,不提供通用“重开批次”。拟新增原因类别:恢复必需、证据已变化、仍有银行事实未解决、无合格复核人;复用已有原因码优先,新增时同步前后端错误码合同。
|
||||
|
||||
S8 还款详情增加“补充释放依据”:并列显示原结论与当前补证/复核/可释放状态、逐提交缺口、失效原因、操作者与证据查看入口。财务与复核人动作分开,服务器仍强制鉴权;详情不能把“批准”显示成“已释放”。PC/手机使用同一组件并实测全流程,敏感字段默认脱敏。界面与对应后端齐备、完成 S0/真实样本/整体验收前不得部署启用。
|
||||
|
||||
### SR6 验收与后续决策
|
||||
|
||||
对应 PRD AC17–AC19,覆盖两种原终态、重复补证、重扫同一流水号、补登第二次提交、多次送审、候选变化、自审/离职、事务回滚、并发交错及禁止重付。关键资金检查做变异测试;必须从真实 HTTP 的上传/核验与复核入口走到取消释放,不能直接调用释放函数代替。只替换云 OCR 响应,使用隔离 PostgreSQL 与合成材料。
|
||||
|
||||
批准的核心选择是“原终态不变,新增恢复轮次决定释放资格”;它覆盖 S3 后的补证恢复,不含 S4–S8 的实施。当前代码及验证进展见 implement 顶部;inline 模式不得将主会话自查写成独立复核。
|
||||
|
||||
## 2026-09-17 实施细化
|
||||
|
||||
## 2026-10-06 失败回单归属与银行结果对账方案(第 3 版,待用户审阅,未实施)
|
||||
|
||||
第 3 版补充:区分制单导出与银行提交尝试、“从未提交银行”的单独路径(待决)、按原因冻结及误报出口、补记不生成可导出指令。第 2 版根据审阅意见修订:未付款证据须证明指令终止、按付款尝试而非附件数判断、占用与已付分开且超额按差额逐笔计算、晚到成功按冻结快照核对并覆盖“已确认失败未释放”、冻结覆盖后续指令且追回须核实到账。
|
||||
|
||||
### 1. 要解决的问题(现状均已在合成测试或代码中确认)
|
||||
|
||||
| 编号 | 现状 | 后果 |
|
||||
|---|---|---|
|
||||
| R1 | 导出制单或上传回单后状态为 `unknown`,只有匹配的失败回单能转 `confirmed_failed` 再取消 | 未付款或网银导入即失败而无回单时,占用永久不释放,且因在途拦截冻结出借人维护 |
|
||||
| R2 | 确认失败要求批次回单总数恰为 1(含作废) | 作废一次即永远无法确认失败;同时“附件数”本身也不能代表付款尝试次数 |
|
||||
| R3 | 存在同金额候选时确认失败一律拒绝 | 等额分期任一期真实失败都无法释放 |
|
||||
| R4 | 确认失败仍按付款前规则校验出借员工在职 | 出借员工离职后无法确认失败 |
|
||||
| R5 | `confirmed_failed`/`confirmed_success` 为终态,已释放/已结清分配不可改;执行状态要求 `confirmed_success` | 失败结论之后银行晚到成功无处补记;同一本金可能被再次申请并付款 |
|
||||
|
||||
线下对账只能查清银行事实,**不能直接解除系统占用**。任何释放、补记、追回都必须走下述有依据、有独立复核、有审计的系统流程;不提供“管理员解除占用”,不直接改库。
|
||||
|
||||
C(同金额回单归属确认)只防止**错误核销**,不能防止银行**实际重复付款**;本方案另设事前冻结(3.5)。
|
||||
|
||||
### 2. 总体原则
|
||||
|
||||
1. 释放占用只能基于“银行对本批次每一次提交都已到达不再执行的终态”的正面证据;“暂时没看到付款”、对账单无支出、等待期届满都不能单独作为依据。唯一例外是 3.2a 的“人工确认未提交”:须满足全部证据与双人复核,记录和页面均标注为人工确认,与“银行确认指令终止”严格区分。
|
||||
2. 每条银行事实绑定具体证据及其核验记录,由当前有资格、且不是登记人、导出人、证据上传人、批次创建人、提交人或出借员工的经理/总经理独立复核。
|
||||
3. 银行事实登记属付款后环节:按**原批次冻结的收付款快照与历史审批身份**核对,不要求与出借人当前资料版本一致;只判断当前操作人的权限与独立性。
|
||||
4. 历史只增不改:推翻先前结论时新增记录并标记原结论,不回写终态。
|
||||
5. 无合格独立复核人时保持占用并显示业务阻塞原因,不降级为单人确认。
|
||||
|
||||
### 3. 方案
|
||||
|
||||
#### 3.1 付款尝试与银行事实记录
|
||||
|
||||
- **制单导出记录**:每次导出落一条记录(序号、时间、导出人、文件摘要、制单行客户方流水号 `批次号-R00n`、金额、收付款快照摘要)。重导出沿用同一客户方流水号,所以导出次数不等于向银行提交的次数:下载两次可能只提交一次,下载一次也可能被重复提交。现有 `payment_order_export_count` 只计数,需落表。
|
||||
- **银行提交尝试**:由财务登记实际向银行提交的每一次指令(提交时间、渠道、所用导出记录、银行指令号或网银批次号、客户方流水号),并附银行凭据。一次提交关联一条导出记录;一条导出记录可以对应零次、一次或多次提交。登记清单本身也要经独立复核,确认“这就是全部提交”。
|
||||
- **银行事实确认**:把 `loan_receipt_attributions` 扩为银行事实确认,新增 `kind` 与可选 `attempt_id`:
|
||||
- `settlement`:现有归属确认,含义不变;
|
||||
- `failure`:某次银行提交被拒绝或失败(失败回单),须写明覆盖哪些银行指令,并绑定交易指纹与证据;存在同金额候选时必须有已复核的 `failure`(R3);
|
||||
- `terminated`:某次银行提交已撤销或拒绝、不再待执行(无回单时的指令终态证据,见 3.2);须写明覆盖的指令,不能以一条指令的终态推定其他提交已结束;
|
||||
- `not_submitted`:导出后从未提交银行(见 3.2a,是否支持待用户决定);
|
||||
- `late_success`:晚到成功,见 3.4。
|
||||
- 以上沿用登记、独立复核、失效取代、证据绑定、历史只增不改。
|
||||
|
||||
#### 3.2 释放占用的证据门槛(R1、R2)
|
||||
|
||||
释放(`unknown` → 新终态 `confirmed_not_paid`,或沿用 `confirmed_failed` 后取消)必须同时满足:
|
||||
|
||||
1. **逐次提交有终态**:已复核的银行提交清单中,每一次提交都有已复核、且明确覆盖该指令的 `failure` 或 `terminated` 事实;每一条导出记录要么关联了已终止的提交,要么有已复核的 `not_submitted` 事实(3.2a)。
|
||||
2. **终态证据须能唯一定位指令**:银行书面回复、网银“指令查询”的官方导出 PDF 等,须载明该尝试的客户方流水号(或银行指令号)及其终态(已拒绝、已撤销、已失败),并表明不再待执行。对账单只能作辅助核对,不能单独证明未付款。截图、口头说明、“网银查不到”一律不接受。
|
||||
3. **无未解决的成功或待定事实**:作废附件只改变材料使用状态,不抹掉银行事实。曾核验为成功的回单直接阻断释放;曾为待定(处理中、受理)的,须由同一尝试后续的终态证据(失败或撤销)关闭后才不再阻断。
|
||||
4. **内部等待期**:距最后一次导出满 N 个自然日(建议 3 日)。这只是内部谨慎期,不代表银行时限,也不能替代第 1、2 条。
|
||||
5. **独立复核**:导出人、证据上传人、登记人不能复核。
|
||||
6. 释放后系统禁止该批次再次导出;**但 OA 无法让已下载的制单文件在网银中失效**,页面仅作提示。此剩余风险由 3.4 晚到成功与 3.5 冻结兜底,不作技术保证表述。
|
||||
|
||||
#### 3.2a 只导出、从未提交银行(待用户决定)
|
||||
|
||||
这种情况下,银行可能根本没有可出具终态的指令。若本期坚持“银行终态是唯一释放依据”,这类批次将**仍然不能释放**,R1 只算部分解决。如需支持,规则单列如下,不视为满足银行终态条件:
|
||||
|
||||
- 证据(须全部具备):
|
||||
- 网银“指令查询”官方导出 PDF,覆盖首次导出日至登记日,按该客户方流水号及收款账号、金额查询无结果;
|
||||
- 同期付款账户对账单,经逐笔核对无对应支出;
|
||||
- 导出人书面说明文件去向,以及未提交的原因。
|
||||
- 内部等待期满。
|
||||
- 双人复核:两名彼此不同、当前有资格的经理或总经理分别独立复核。两人都不能是登记人、导出人、证据上传人、批次创建人、提交人或出借员工。
|
||||
- 定性:这是“查无提交”的人工谨慎结论,不是银行保证。数据上记为独立终态 `confirmed_not_submitted`(区别于银行确认终止的 `confirmed_not_paid`),页面显示“人工确认未提交”。之后若出现该流水号的成功回单,按 3.4 处理,并另记“未提交结论被推翻”。
|
||||
- 实际限制:
|
||||
- 需要两名额外的合格复核人,且都不能是登记人、出借人、导出人等相关人员。公司人数少,是否满足尚未核实;人员不足时,这条路径不可用,额度继续占用。
|
||||
- 建设银行能否出具“查询无结果”的官方导出 PDF,尚未确认;拿不到时同样继续占用。因此不能宣称“只导出未提交”的所有情况都能解决。
|
||||
|
||||
#### 3.3 确认失败的修正(R4)
|
||||
|
||||
确认失败改按付款后规则:不要求出借员工当前在职,不要求出借人当前资料版本与提交时一致,改为核对批次冻结快照;当前操作人仍按当前资格与独立性校验。
|
||||
|
||||
#### 3.4 晚到成功:补记与差额计算(R5)
|
||||
|
||||
触发:已核验的成功回单属于某个已有失败或未付款结论的批次(无论是否已取消释放),并经 `late_success` 类独立复核确认归属;核对对象是该批次冻结的收付款快照、历史审批身份与交易唯一性认领。
|
||||
|
||||
处理步骤:
|
||||
|
||||
1. **推翻原结论**:新增事实记录,标记原批次结论“已被银行事实推翻”,并写审计,不回写原终态。
|
||||
2. **即时冻结**:可信晚到成功一经登记(复核前即生效),冻结该出借人,见 3.5。
|
||||
3. **逐笔分配计算**:按原批次的原借款分配逐笔处理。对每笔借款 L,设晚到付款分摊到 L 的金额为 a:
|
||||
- 其他**已付并结清**的还款,在 L 上已结清 S;L 的未还本金为 O(已扣除 S)。
|
||||
- L 上其他**未付款、仅占用**的申请属于占用冲突,不是超额。这些申请须先处理:未导出的可取消;已导出或待查证的按 3.2 举证或等待其事实。处理完毕前,L 的补记暂停。
|
||||
- 冲突清除后,可补记结清额为 `min(a, O)`,差额 `a − min(a, O)` 列为对出借人的待追回款。
|
||||
4. **补记方式**:由于原分配为终态(已释放)或原批次状态受限,补记生成一条关联原批次与该交易的“补记还款”,按上一步计算结果占用并立即结清。若原分配仍为占用(已确认失败但未取消),在同一事务内以“被晚到成功推翻”为原因释放,再由补记还款结清。整个过程受数据库约束“占用加结清不超过未还本金”保护。
|
||||
- 数据边界:补记只记录已经发生的银行付款,**不生成付款批次、不可导出、不可再次付款**。即使整笔都是超额(可结清本金为零),也必须完整记录银行付款金额、交易指纹与待追回金额。
|
||||
5. **示例**:本金 100 元,晚到成功 80 元。
|
||||
- 另一笔新申请占用 70 元、尚未付款:这是占用冲突,暂停该申请的后续付款并处理该占用;处理后补记结清 80 元,剩余本金 20 元。
|
||||
- 另一笔已付款并结清 60 元:剩余本金 40 元,补记结清 40 元,另 40 元列为待追回款。
|
||||
|
||||
#### 3.5 冻结与解冻
|
||||
|
||||
- **按原因冻结**:冻结以“原因记录”为单位,挂在出借人上。每条记录写明原因类型(晚到成功待确认、占用冲突、待追回款)、来源事件、状态(生效或已关闭)以及关闭依据。只要出借人仍有任一生效原因,就处于冻结状态。
|
||||
- **冻结时机**:可信晚到成功登记时(复核前即生效),或产生占用冲突、待追回款时。
|
||||
- **冻结范围**:该出借人的新还款申请、其他在途申请的复核与导出(含重新导出)一律拒绝。
|
||||
- **不冻结**:已发生银行事实的登记、回单上传与核验、事实复核、对账与追回登记。
|
||||
- **追回**:以银行到账证据(出借人退款入账回单)登记,须独立复核,支持部分追回,逐笔冲减待追回款。本期不支持冲抵后续本金。
|
||||
- **原因的出口**:
|
||||
- 确认为真实晚到成功:完成补记后,占用冲突与待追回款作为新的原因分别处理;晚到原因在补记完成时关闭。
|
||||
- 确认为误关联或重复登记(例如回单传错批次、对应的交易已在别处登记):保留原登记记录,经独立复核、附依据后关闭该原因,不补记。
|
||||
- 证据仍不确定:原因保持生效,继续冻结。
|
||||
- 待追回款:全额实际到账并经复核后关闭;部分追回只冲减金额,不关闭。
|
||||
- **解冻**:出借人的**全部生效原因都已关闭**才解冻。不因其中一笔处理完就整体放开;仅“登记了追回结果”也不能关闭原因。
|
||||
|
||||
#### 3.6 权限与离职
|
||||
|
||||
| 环节 | 操作人 | 复核人 |
|
||||
|---|---|---|
|
||||
| 登记付款尝试、失败、终态、晚到成功、追回到账 | 当前持财务角色和 `loan.manage` 的人员 | 当前经理或总经理,且不是登记人、导出人、证据上传人、批次创建人、提交人或出借员工 |
|
||||
|
||||
原审批人、出借员工离职,以及法人或银行停用、出借人资料事后合法变更,都不影响上述环节(均按冻结快照核对)。人员不足时,页面显示具体环节与缺少合格复核人的原因类别。
|
||||
|
||||
### 4. 页面
|
||||
|
||||
在还款详情的“银行结果”区,按付款尝试列出每次导出及其事实状态,只显示当前可做的动作:
|
||||
|
||||
- 待查证:登记失败或终态证据(显示内部等待期剩余天数);
|
||||
- 全部尝试已终止:取消释放;
|
||||
- 已推翻:晚到事件、逐笔补记结果与待追回款;
|
||||
- 冻结中:说明原因与解冻条件,提供追回登记入口。
|
||||
|
||||
各表单写明证据要求:须能定位具体指令;对账单与时间吻合只能作辅助。
|
||||
|
||||
### 5. 验收(实施时转为 PRD AC)
|
||||
|
||||
1. 只导出未付款:无指令终态证据、也不满足 3.2a 特别复核例外时,等待期满也拒绝;有能定位指令的终态证据并经独立复核后可释放;满足 3.2a 全部证据并经双人复核后,可作为“人工确认未提交”释放,记录与页面显示为人工确认;仅对账单、截图或时间依据被拒;导出人、登记人自审被拒。
|
||||
2. 导出与提交分开:多次导出、一次提交,或一次导出、多次提交,都按提交清单逐条举证;一条指令的终态不能证明其他提交已结束;提交清单未经复核即不能释放。若采纳 3.2a:只导出未提交须满足全部证据并经双人复核,否则继续保持占用。
|
||||
3. 作废的成功回单持续阻断;作废的待定回单在同一尝试取得终态证据后不再阻断。
|
||||
4. 存在同金额候选时,失败经 `failure` 归属确认后可以释放,否则保持占用。
|
||||
5. 离职或出借人资料事后合法变更后,确认失败、终态、晚到成功仍可由当前合格人员完成,并按冻结快照核对。
|
||||
6. 晚到成功覆盖四种情况:已释放、已确认失败但未释放、占用冲突(先暂停后补记)、已付冲突(按差额补记加待追回);多借款合并还款逐笔计算;同一笔交易不能用于两次补记或核销。
|
||||
7. 冻结按原因管理:覆盖新申请和其他在途申请的复核与导出,但不阻止事实登记;误报的晚到成功经复核关闭原因后不补记;证据不确定时继续冻结;多个原因并存时,只关闭其中一个不会解冻;部分追回不解冻。
|
||||
8a. 补记不生成可导出指令;整笔超额时补记结清为零,但仍完整记录银行付款与待追回金额。
|
||||
8. 全部只增不改、审计完整,不存在单人释放路径;合成全流程测试含确定性并发(终态登记与晚到回单、补记与新申请、冻结与导出),每类关键守卫都有变异测试。
|
||||
|
||||
### 6. 不在本方案内
|
||||
|
||||
银行接口直连、对账单自动解析与 OCR、利息、冲抵后续本金、手机端专门优化(沿用共用组件)、生产存量处理(生产是否已有真实还款仍待核实)、部署。
|
||||
|
||||
### 7. 需要用户确认(采纳审阅建议作为默认)
|
||||
|
||||
| 问题 | 默认 |
|
||||
|---|---|
|
||||
| Q1 内部等待期 | 3 个自然日,仅作内部谨慎期 |
|
||||
| Q2 证据 | 按内容判断:须唯一定位指令并证明终态;银行官方导出 PDF 可以;对账单只能辅助 |
|
||||
| Q3 冻结 | 冻结新付款与未发出的后续指令,保留事实登记、对账、追回入口 |
|
||||
| Q4 冲抵 | 本期只支持实际退款到账 |
|
||||
| Q5 迁移 | 由最终数据设计决定(预计包括导出记录、银行提交尝试、事实记录扩展、补记还款、冻结原因、追回记录,以及 `confirmed_not_paid`、`confirmed_not_submitted` 两个状态);部署另行批准 |
|
||||
| Q6 只导出未提交(3.2a) | 用户 2026-10-06 确认支持,作为经特别复核的人工例外(全部证据加双人复核);受合格复核人数和银行能否出具查询 PDF 限制,不满足时继续占用 |
|
||||
|
||||
|
||||
`origin_reference`作为主体+出借人范围的原借入凭据唯一引用,防止更换幂等键重复登记。期初已还差额必须有adjustment证据。身份与账户分别版本控制,改账户同时撤销身份确认,旧未付快照失效。
|
||||
|
||||
新申请持lender→排序loan→日序号锁,只创建本事务尚未可见的新batch;所有既有batch路径先锁batch,核销沿receipt advisory→排序附件→lender/审批身份→排序loan,台账/身份维护不反向锁batch。取消保留旧申请和批次,不原位重提;一申请恰好一个保留批次。下载制单或上传回单转unknown,均不扣减本金。首期不能仅凭理由解除unknown。
|
||||
@@ -35,7 +533,12 @@
|
||||
|
||||
## 4. 权限与回单
|
||||
|
||||
新台账沿财务全账读取与付款审查分离:财务管理台账,审批人只读其有权审批的申请及必要证据,普通员工无全账入口。制单人、提交人、出借收款人身份集合统一传给提交预检/批次复核/人工回单复核/登记重验;在职状态和业务权限不吃历史批准,admin通配不能替代独立身份。
|
||||
新台账沿财务全账读取与付款审查分离:财务管理台账,审批人只读其有权审批的申请及必要证据,普通员工无全账入口。制单人、提交人、出借收款人身份集合统一传给提交预检/批次复核/人工回单复核/登记重验;admin通配不能替代独立身份。
|
||||
|
||||
2026-10-05 修订(取代原“在职状态和业务权限不吃历史批准”):资格按环节区分。
|
||||
- 付款前(新建申请、批次复核、导出制单、确认银行失败):校验当前在职、当前角色/权限、出借人就绪(身份已核实、未归档、法人与银行主数据启用)及出借员工在职。
|
||||
- 付款后(回单 OCR 认领、人工回单参与人、核销登记):原审批人与出借员工的资格以审批时为准,不再复核其当前在职/角色,也不再复核法人、银行主数据当前启用状态。理由:银行已实际付出的事实不能因事后人员或主数据变化而无法登记,否则本金永久占用且未还本金多记。仍须满足:身份已核实;身份/账户版本与提交时一致(在途期间维护被 `loan.lender_in_flight` 阻止);付款快照收款资料一致;`reviewed_by/reviewed_at` 存在且审批人不是制单人、提交人或出借人关联员工(这三者之间可重合);回单的账号、金额、币种、状态与交易唯一性匹配。审批时资格的依据是复核路由当时已用当前角色校验并写入 `reviewed_by/reviewed_at`。
|
||||
- 当前操作人(上传、人工复核、执行、会计交接)始终按当前权限与独立性校验。
|
||||
|
||||
银行备注采用短本金语义,年份不一致时不生成误导性单一年份;长事由留OA。对现有建行制单模板使用显式业务用途映射,原报销用途不变。回单识别范围只有经过新来源快照和权限校验才可扩展,不能无条件对新业务调用腾讯;真实样本/云调用另批,未验证前不宣称自动支持。
|
||||
|
||||
|
||||
文件差异内容过多而无法显示
加载差异
@@ -1,19 +1,250 @@
|
||||
# 公司借款台账与本金归还
|
||||
|
||||
## 2026-10-11 G:借款材料区域精简(用户已批准;已实施,本地验证与只读复核完成,复核 P2 已修复关闭;未提交)
|
||||
|
||||
### 目标与已确认方向
|
||||
|
||||
用户同意只显示当前需要办理的事项,选择公司银行流水作为本次余额核对材料来源,并要求按 KISS 原则收敛。采用现有页面的条件显示与文案调整;复用“出借人确认”栏目,不另建发起入口。本节是具体待批方案,不代表产品已变更。
|
||||
|
||||
### 范围
|
||||
|
||||
1. 原借入凭据已满足要求时,收起上传控件,显示“已保存,可查看”;无有效材料时显示上传。材料只有未归档且 `governanceStatus=approved` 才算满足,其他状态不能冒充已齐全。
|
||||
2. 有服务端返回的有效在线确认时,收起协议上传控件,显示“出借人已在线确认”。没有有效在线确认时保留原协议入口,并明确“有效在线确认或协议/借款确认书,任选一种”;关联员工的出借人可跳转原“出借人确认”栏目。已有文件仍可查看,不新增“其他确认方式”折叠区。
|
||||
3. 系统外已还本金依据只在登记的 `openingOutstandingPrincipal < originalPrincipal` 时显示上传;不能使用随正常还款减少的当前余额 `outstanding` 判断。既有依据仍可查看。
|
||||
4. 余额核对材料始终显示,按钮为“上传余额核对材料”,说明为“公司银行流水或代账明细账,覆盖从借入到截至日”。确认表单的“代账余额确认引用”改名“余额依据说明”,示例为“公司银行流水,借入日至核对截止日,已逐笔核对借入及还款”;不自动填入“已核对”声明。服务端字段名称和现有必填规则不变,说明与材料由财务实际核对。
|
||||
5. “确认期初余额”统一改名“确认借款余额”。提交前就近列出缺项,材料不足、数据加载/刷新或上传处理中禁用确认;齐全后仍由财务显式确认,保留原金额、截止日、版本与说明校验。余额材料上传可以与等待出借人确认并行。
|
||||
6. 借款卡片只呈现可由当前数据确证的确认状态。现有 DTO 只有有效在线确认及可重发标记,没有未发起/待本人确认/退回状态;无有效确认时用“去出借人确认查看或办理”,不猜测为“等待”或“已退回”,不为本轮增加后端字段或扫描分页列表。余额确认后,对适用现有公司代表授权流程的借款显示“查看或办理公司代表授权”跳转;不把未查询的授权当成未办理,不要求重复授权。
|
||||
|
||||
本次银行流水作为余额核对附件,由财务核对其覆盖期间及相关借还款;不新增银行流水导入、自动对账或自动判定材料真实性。原借入凭据、借款确认依据、余额核对依据及必要的历史还款依据四类服务端要求继续有效,公司代表授权继续单独办理。
|
||||
|
||||
### 验收
|
||||
|
||||
- [x] AC60:有效入账凭据已存在、在线确认有效且期初未还等于原本金时,只显示余额核对材料上传控件;其他已存文件可查看。缺原件、无有效在线确认和有历史还款时,各自出现对应入口与准确缺项提示。
|
||||
- [x] AC61:余额材料与确认表单采用上述中性文案和银行流水示例;不再要求材料只能来自代账,不替财务自动填写核对声明;“确认借款余额”名称在入口、弹窗和操作提示一致。
|
||||
- [x] AC62:上传但尚未有效、被隔离、归档或刷新失败的材料不能使确认按钮误启用;有效在线确认失效并刷新后重新显示缺项。材料齐全仍保留服务端最终校验和确认说明必填。
|
||||
- [x] AC63:复用现有确认/授权栏目跳转,不新增发起流程;卡片不猜测等待/退回/授权状态。正常系统还款不会触发历史还款依据要求,已办理事项不被引导重复办理。
|
||||
- [x] AC64:前端类型检查、构建和电脑/手机针对性验证通过,覆盖上述显隐、缺项、刷新与跳转;原借款后端规则、权限、数据库及历史材料保持。
|
||||
|
||||
### 本轮边界
|
||||
|
||||
只规划页面、相关测试与操作手册的同步;不改后端、接口或数据库,不引入新视觉体系,不调整此前仅记录的“登记时金额/日期默认值”问题。具体方案获批后再实施;提交、发布按现有流程另批。
|
||||
|
||||
## 2026-10-11 F:员工与公司组合数据库唯一约束(已发布 `36b949ec`)
|
||||
|
||||
生产只读排查重复组合为 0 组后,用户批准把“同一公司与员工最多一个出借人(归档计入)”落到数据库。结果见 implement 顶部 F 节。
|
||||
|
||||
- [x] AC56:数据库拒绝同一公司与员工的第二个出借人,含归档行;空员工的手工出借人可多条共存。
|
||||
- [x] AC57:应用触到约束时返回原有“出借人冲突”提示,不报 500、不误报请求重复;代码检查与员工行锁保持。
|
||||
- [x] AC58:借款完整回归通过,并经独立只读复核(涉及迁移)。两轮完整回归各 84 迁移、12 阶段、去重 247 项通过;另一会话只读复核无阻断项、20 个内存探针通过,唯一 P2(缺本迁移回退说明)已在下方补齐。
|
||||
- [x] AC59:发布窗口重跑存量重复计数为 0,并按 1 个待执行迁移部署(2026-10-11:重复 0 组;迁移对账仅该迁移,部署后 pending=none、唯一索引存在)。
|
||||
|
||||
### 迁移回退说明(`20261011010000_loan_lender_employee_unique`)
|
||||
|
||||
- **建索引失败**:迁移只有一条 `CREATE UNIQUE INDEX`,单语句原子执行;若发布窗口内出现重复组合导致失败,索引不会部分建立,Prisma 将该迁移记为失败并阻止后续迁移,应用不切换到新版本。处理方式是停止本次发布,回到只读计数重新排查;不在发布中手工删改出借人数据,不改写已应用的迁移历史。失败迁移记录的处理(如标记回滚后重试)须另行批准后按运维手册执行。
|
||||
- **应用回退**:回退到上一版应用时**保留**该索引,不删除。上一版代码在员工行锁内已拒绝同一组合,正常路径不会触到约束;只有极端情况越过旧检查时,旧版创建路径会把约束冲突报为“请求重复”(409),旧身份确认入口会报 500,两者都不会写入重复数据。
|
||||
- **撤销约束**:如确需取消该约束,另起新迁移 `DROP INDEX` 并单独批准,不回退或删除本迁移文件。
|
||||
|
||||
|
||||
## 2026-10-10 E:追回证据刷新提示与员工资料误报(已实施、本地验证及独立只读复核完成;未提交)
|
||||
|
||||
用户批准两项小问题按方案修复,复用本任务,不含数据库唯一约束(需先查存量重复、单独规划)。结果见 implement 顶部 E 节。
|
||||
|
||||
- [x] AC52:上传银行证据后对话框立即关闭;刷新完成前证据下拉框与确认按钮均不可用并有可见提示,不发出提交;刷新后可选中刚上传的证据。电脑/手机浏览器验证。
|
||||
- [x] AC53:财务预览员工资料后员工登录(含失败再成功),保存不再误报“员工资料已变化”。
|
||||
- [x] AC54:姓名、所属公司、开户行、银行机构、账号的真实变更,以及状态/归档,仍拦截保存;反向变异能被测试发现。
|
||||
- [x] AC55:资料拦截规则改动经独立只读复核(2026-10-11 `REVIEWED_NO_BLOCKER`,回执 `review-20261011.json`)。
|
||||
|
||||
## 2026-10-10 D:授权翻页与追回到账排查(已本地提交 `91fe31f0`,未发布)
|
||||
|
||||
用户要求规划“员工授权翻页超时”和“登记追回到账”两项遗留问题。复用本任务作为执行合同,分成 D1/D2 两个独立验收阶段,不把当前父任务 `in_progress` 当作本轮实施批准。规划基线为 `db919dc6`,开始时工作区干净;线上业务基线仍为 `4a5cd8f2`。本阶段目标是查清失败发生在哪一层,并形成能稳定触发相关分支的回归,避免漏走分支的通过掩盖问题。
|
||||
|
||||
### 规划时点的历史证据及缺口(后续结果见 implement 顶部)
|
||||
|
||||
| 阶段 | 已确认事实及来源 | 尚未确认 |
|
||||
| --- | --- | --- |
|
||||
| D1:公司代表授权的出借人翻页 | 原 `loan-incoming-prefill-20261009/regression-r6.log`、`regression-r7.log` 为 `page.waitForResponse` 30 秒超时,旧任务记录标注手机端;没有对应失败截图。当前 `scripts/qa/company-loan-employee-browser.cjs:160` 仅在目标不在当前选项时翻页,`:163` 等待谓词不限定页码。服务端 `server/src/routes/companyLoans.js:245` 按姓名、ID 排序;`client/src/api/companyLoans.ts:52` 每页 30 条,`client/src/query/queryClient.ts:6` 查询缓存有效期 5 秒。 | 点击是否真正发生、等待是否遗漏/误捕响应、目标实际位于哪页、是否走缓存,以及是否为产品分页问题。 |
|
||||
| D2:登记追回到账 | `loan-lender-ack-20261010/full-loan-r1.log` 只有 `synthetic UI 登记追回到账:` 空提示;没有可据以归因的请求结果。旧脚本按最后一个 option 选证据;当前 `scripts/qa/company-loan-reconciliation-browser.cjs:45`–`:59` 已改为捕获上传 evidenceId 并按 ID 选择,`:32` 增加表单有效性采证,但这不能证明旧失败根因。提交在 `client/src/components/common/LoanBankReconciliation.tsx:59`,退款入账在 `server/src/services/loanBankResults.js:172`。 | 当时选中哪份证据、是否发出 POST、服务端是否拒绝/挂起、是否已经成功但刷新未完成;原日志未记录设备和第几次追回。 |
|
||||
|
||||
### 范围与顺序
|
||||
|
||||
1. D0:核对历史日志、脚本版本及最小采证方案;只使用合成资料和隔离 PostgreSQL/浏览器环境。
|
||||
2. D1 优先:固定至少 65 名满足授权选择条件的出借人,按接口实际排序校验目标在第二/第三页,并强制浏览器走到第三页、返回上一页后再进入。区分首次加载、快速响应、可控延迟、5 秒内命中缓存、弹窗关闭重开及无关同路径响应。
|
||||
3. D2 随后:保留旧失败所属的独立复核模式,并补当前关联方模式对照。固定晚到成功产生待追回 40 元、两次追回 15/25 元的现有合成路径;分别观察上传、证据选项刷新、登记、复核、入账和余额/冻结刷新,不把“弹窗关闭”当作唯一成功依据。
|
||||
4. 先用采证区分测试等待、测试资料、界面状态和服务端规则,再做对应最小修复。如果仅是测试问题,只修改测试;若证实产品问题,修复限定在该分页/登记路径。材料、权限、审批、币种、重复入账和金额边界保持现有合同。
|
||||
|
||||
不包含:生产读写/真实付款、云 OCR、数据库迁移、通用对话框重构、其他 P3、暂停的登记默认值、提交/推送/部署、清理历史证据。若结论要求改变权限、状态机合同、核算规则或迁移,先回到方案确认。相关现有权限/资金守卫的缺陷修复仍须只读独立复核。
|
||||
|
||||
### 验收标准
|
||||
|
||||
- [x] AC46(翻页分支真实触发):电脑、手机均通过实际服务证明目标不在第一页,明确收到/命中第二、第三页数据并显示对应选项;往返及关闭重开不混入其他页或他人的选项,财务登记后由正确公司代表确认,未创建还款。
|
||||
- [x] AC47(翻页归因):采证能区分没有点击、没有请求/合法缓存命中、请求失败/等待错误、响应成功但界面错误。可还原的旧等待方式与当前/修复方式做同条件对照;故意让页码不变或返回错误页时,测试须失败。缓存命中不能被要求“必须再发一次请求”。
|
||||
- [x] AC48(追回成功链):独立复核及关联方模式的电脑/手机均实际完成上传指定证据、登记、不同身份复核、财务入账;待追回从 40 到 25 到 0,仅全额完成后关闭对应追回冻结,不关闭其他原因;原终态、本金、付款批次数及历史事实按既有规则保持。
|
||||
- [x] AC49(追回失败可定位):无有效选择/原生表单阻止提交、可控请求延迟、服务端拒绝、200 后刷新延迟分别有可区分证据;有 HTTP 结果则绑定准确批次、方法、请求 ID 与安全错误理由,无提交则明确记录无 POST,不再仅留空 alert。
|
||||
- [x] AC50(金额与重复保护):错误方向、作废/错误类别证据、超出剩余待追回金额受阻;相同请求键重试不重复创建,同一银行交易不能重复入账,已入账重放不重复计算。拒绝或事务失败不提前减待追回、关闭冻结、改本金或生成付款批次。独立及关联两模式共 20 组补验通过,回执和边界见 implement 顶部。
|
||||
- [x] AC51(验证与结案):两项定向场景各完成电脑/手机连续 3 轮(每轮新隔离环境,含明确缓存分支),随后最终版本一次完整借款回归;必要的类型/构建/后端与合同检查、按实际影响的只读复核通过。结论逐项注明“根因已证实并修复”“已补强但原事故未定”或“待进一步排查”,只有能解释历史失败并经反例对照验证的项才关闭原根因待查。
|
||||
|
||||
技术未知在 design 的实验清单中处理,没有需要先决定的新增产品行为。方案已在 Claude 会话获准实施,授权来源见 implement 顶部;本会话按同一验收范围补齐复核发现的测试证据。提交、推送、部署仍须明确授权。
|
||||
|
||||
## 2026-10-10 N5-C 已发布(4a5cd8f2,真实办理待验收)
|
||||
|
||||
出借人在线确认及站内通知直达已随 `4a5cd8f2b3e04da24551ddf1ee99b4167aa76710` 推送部署。补记时本地 HEAD 与 `origin/main` 一致、工作区干净;已有最终候选验证 PASS,部署前 13/13,唯一待应用迁移为 `20261010010000_loan_lender_acknowledgements`,部署后 83/83、无待应用迁移、合同刷新通过。公网健康、页面与资源正常及未登录接口 401 沿用发布会话转交结果;本轮只读核对本地日志,没有重新访问生产。
|
||||
|
||||
用户回报此次未做手工快照;本会话此前建议做快照,决策来源在 implement 顶部区分记录。部署日志跳过登录后的 live smoke,真实发起声明、本人确认、余额确认、公司代表授权及首笔还款尚未验收。财务/出借人按现有手册办理,代账余额核对材料及必要的系统外已还本金依据继续必需。
|
||||
|
||||
整体任务保持 `in_progress`,N5/N6 和暂停的登记默认值待办继续开放。两项浏览器遗留失败的最新诊断与本地修复见 D 节;本节及以下“根因待查、未提交、未发布、未重跑最终门禁”等表述保留各轮历史时点,以 implement 顶部最新证据为准。文档补记不修改线上版本或工程合同。
|
||||
|
||||
## 2026-10-10 N5-C 出借人在线确认借款(用户已批准实施)
|
||||
|
||||
用户批准将“借款确认书”增加为 OA 内可追溯的出借人声明,范围仅限本功能。此前“先记录、不修改”对本功能的限制由本次批准取代;登记默认值调整仍只记录、不实施。线上记录是本系统接受的借款确认依据,不宣称仅凭账号操作留痕即当然取得与纸质签字相同的法律效力。
|
||||
|
||||
- 财务可对同一公司、同一员工出借人的一笔或多笔尚待核实借款发起确认;已确认余额但存在失效在线声明历史的借款允许重新发起。固定借入日期、原始本金、截至日未还本金、原件摘要及对应身份。保留现有纸质协议/借款确认书上传路径;非员工出借人沿纸质路径办理。
|
||||
- 只有出借人关联的在职员工本人能查看自己的声明范围、核对原件并确认或退回;发起财务不能代确认,其他员工、管理员或公司代表权限均不能替代本人身份。此动作不要求出借人具有经理/CEO 权限,也不赋予其财务台账或他人借款的读取能力。
|
||||
- 确认记录、明细和决定不可改删。借款关键金额、日期、原件或出借人身份关联变化使旧确认失效,改回旧值也不复活;新增余额核对等其他材料不导致无关失效。退回后财务可重新发起。
|
||||
- 确认余额以及后续材料完整性检查接受“纸质协议/借款确认书 **或** 有效在线出借人确认”;原借入凭据、代账余额核对材料和必要的系统外已还本金依据仍必需。出借人声明不自动确认余额,不代替公司代表授权或付款批准。
|
||||
- 不包含通用电子签章、生成协议正文、替代代账核对、登记默认值修复、生产写入/发布或发送外部通知。财务可继续线下准备确认书及代账材料,不依赖开发完成。
|
||||
- 2026-10-10 发布前入口收敛:根据用户给出的两种方案及委托取舍,选择 OA 站内通知入口。普通员工不显示常驻“公司借款”导航;财务及公司代表保留入口,本人确认权限和直达路由继续有效。财务发起时仅为对应出借人创建站内通知,点开直接查看该次声明;不纳入通用待办或外部消息推送。
|
||||
|
||||
验收:
|
||||
|
||||
- [x] AC40(本地合成验收):财务可对一笔/多笔同公司同出借人借款固定快照并发起;跨主体、未核实身份、缺原件、重复及错误重试有明确结果,审计失败全部回滚。
|
||||
- [x] AC41(本地合成验收):本人可在电脑和手机查看快照/原件并确认或退回;财务代确认、他人越权读取/下载/决定、自发自确认和迟到请求跨账号重发受阻。
|
||||
- [x] AC42(本地合成验收):确认与快照不可改删;关键字段/原件/身份变化后旧证据永久失效,确认与变更并发不会消费过期结果,变更再还原不复活旧记录;余额确认后可重发失效声明,不改既有余额确认事实。
|
||||
- [x] AC43(本地合成验收):在线确认只替代协议类材料,代账和原件仍必需;有效在线记录可实际走到余额确认、既有公司代表授权及还款申请,纸质路径回归通过。
|
||||
- [x] AC44(本地验收与交接完成):新增迁移、HTTP/数据库并发与电脑手机验证、独立只读复核及发布边界据实记录;完整借款回归 r4 去重 216 项通过,前期失败及未定根因保留;尚未提交或发布,不宣称线上已可使用。
|
||||
- [x] AC45(入口调整,本地合成验收及只读复核完成):普通员工的电脑导航/后备导航/手机“我的”均无常驻借款入口;财务发起只为该出借人创建一条站内通知,同请求重试/并发不重复,事务失败不残留通知;电脑和手机点击通知直接打开该声明并仍执行本人校验,历史或失效通知不恢复旧确认效力。同 SPA 切换声明/浏览器返回正确定位详情并清空旧草稿。财务/公司代表入口、本人权限及账号切换请求保护不退化。最终入口专项 r5 为 17 HTTP、18 浏览器、9 数据库检查通过,复核无阻断;未提交或部署,尚未重跑最终发布门禁。
|
||||
|
||||
## 2026-10-09 N5-P 原借入回单识别预填(2026-10-10 已发布 2063ff1e,真实业务验收待办理)
|
||||
|
||||
### 目标与依据
|
||||
|
||||
用户在办理 N5 时提出先识别凭证或流水、再自动填写,并明确要求“规划改进任务”。本阶段复用当前借款任务,减少已持有原借入回单时重复录入金额、日期、凭据号及再次上传同一文件的操作。初始授权仅限规划;此后用户批准完整方案,已完成实施、五轮独立复核及发布,详见 implement 顶部记录。真实业务录入、云 OCR 与付款仍按各自授权和验收边界执行。
|
||||
|
||||
规划时页面先手填登记借入、保存后再上传材料(当时的 `client/src/pages/CompanyLoansPage.tsx:176`、`:121`);服务端创建借款和上传凭据是分开的动作(当时的 `server/src/routes/companyLoans.js:262`、`:314`)。当时本地 PDF 工作者能读取文字,但对外只返回凭证分类;银行 OCR 归一化未包含到账日期和双方名称(当时的 `server/src/services/paymentReceiptDocument.js:101`、`server/src/services/paymentReceiptMatching.js:41`)。本阶段因此新增借入预填合同,不能把付款核验通过条件直接用于借入。
|
||||
|
||||
### 范围与要求
|
||||
|
||||
- **P1 单笔原件优先**:登记借入增加“上传原借入回单”路径,一次处理一份、仅含一笔交易的银行回单 PDF,包括扫描 PDF;新识别入口上限 5 MiB、20 页,多页必须属于同一交易。保留手工登记和既有附件能力。默认“历史借入登记”,财务明确确认登记性质;文件日期不能自行产生当天新增现金流。
|
||||
- **P2 字段预填**:识别原始本金、实际到账日期、原凭据唯一引用、人民币币种与付款/收款方摘要。可靠字段预填,缺失或歧义字段留空并说明;流水号与凭证号分别辨识,优先稳定流水号,无则使用明确凭证号,不以文件名或随机编号补造。公司和出借人只从已有记录中建议匹配并由财务确认;没有出借人登记时沿已实现的员工选择入口办理,不依据回单新建员工或替换收款账户。
|
||||
- **P3 识别与业务确认分开**:回单只支持证明历史收款,不推断借款性质、未还本金、余额核对截止日、代账确认或公司代表授权。财务补充余额字段并明确核对原件及借款性质后,才能保存为“余额待核实”。余额确认仍要求三类材料及代账引用;关联审批、在途控制、还本与核销规则保持现有合同。
|
||||
- **P4 降级与方向**:可读 PDF 优先本地提取;文字缺失或必要字段不足时,在现有银行 OCR 配置与调用边界允许的条件下补充识别。关闭、不可用、超时或额度不足时显示人工核对入口,不伪造字段、不切换提供商、不自动反复调用。公司入账回单可用于借入;已知公司支出、失败/处理中、非最终回执、多交易文件或非人民币不作为此路径的有效借入回单。无法判断与已知矛盾分别显示,未知可核对补录,明确矛盾需更换材料。
|
||||
- **P5 核对后保存一次**:识别本身不创建借款、出借人、付款或正式业务附件。确认保存时,借款与其 `incoming` 原件关联一并成立,原件不要求用户再次选择;附件或审计失败不留下可用的半条借款。双击、重试、重复引用、已有相同原件和并发重复需有明确结果。未保存即取消、换账号或离开时清除预填内容;本期不提供跨设备或关闭后续填草稿。
|
||||
- **P6 保留人工修改与来源**:允许核对后改正预填字段,迟到结果不能覆盖人工已改字段或新选择的文件。保存留存识别方式、原件摘要、修正字段及实际经办审计,不把原始票面/OCR payload或完整银行账号写入日志、任务或浏览器长期存储。既有材料下载权限、用途与审计继续适用。
|
||||
|
||||
### 本阶段不包含
|
||||
|
||||
整份银行流水/Excel 批量导入、多交易拆分、自动建立借还对应、自动会计凭证、银行验真、自动确认余额/授权/付款、新银行或 OCR 提供商、图片直传识别、历史记录批量重识别。既有图片附件上传不受影响。规划和本地合成验收不包含真实票据调用云 OCR、生产配置、生产录入或发布。
|
||||
|
||||
验收新增 AC32–AC39,技术合同及执行记录分别见 design、implement 顶部 N5-P。上述方案已实施发布;本地合成验收、真实样本解析、云 OCR、公开发布和真实业务办理分别记录,不互相替代。
|
||||
|
||||
## 2026-10-09 N5 员工出借人选择调整(本地验证完成,未发布)
|
||||
|
||||
用户要求员工出借人从已有员工中选择,复用系统中已维护的资料,不重复录入姓名和银行卡。已核对:员工主档存在姓名、公司关联、银行机构及加密账号;原借款入口要求手填,再另行核实员工关联。用户已确认本方案,授权本地实现与验证;不包含提交、推送、部署或真实业务录入。
|
||||
|
||||
- 员工出借人从已有 OA 员工选择,财务核对姓名、所属公司、开户行和遮罩账号后关联;姓名与银行资料由服务端读取,不接受浏览器另传一套值,也不创建新员工。借款所属公司仍须明确确认。
|
||||
- 沿用现有员工资料和银行卡维护权限;资料缺失、不可用或不符合现行付款条件时,说明缺项并引导有权限的人到员工资料维护,不在借款表单重复填写或自行替换真实开户行。
|
||||
- 同公司同员工已有出借人登记时优先复用;历史重复或资料不一致必须显式处理,不按姓名合并。员工资料更新不自动改写借款授权或在途付款;复用后的账户刷新按既有版本、占用和审计规则核对。
|
||||
- 仅调整员工出借人的资料入口;原非员工个人出借人能力保留,关联方审批、技术员工不参与、Q6 禁用和真实付款授权边界不变。具体实现及验证范围见 design、implement 顶部。
|
||||
|
||||
AC28–AC31 已本地实现并通过独立只读复核:126 组借款 HTTP、45 组电脑/手机浏览器、82 迁移、9 个针对性变异及相关类型/构建/合同检查通过;实际范围、前期失败和完整重跑证据见 implement。未提交、未发布,也未录入真实台账;不把本次软件验收算作 N5 真实登记或 N6 银行还款闭环完成。
|
||||
|
||||
## 2026-10-09 N4 发布完成,真实业务验收待办
|
||||
|
||||
已接收并核对本次发布证据:`beb9f02c` 完整门禁 PASS,独立只读代码复核无阻断项;发布前只读核实借款相关存量均为 0、实际待应用迁移为 9 个。该候选已推送并部署,部署后 82/82 迁移全部应用、13/13 复核及合同刷新通过;公网健康、就绪、浏览器页面和静态资源检查正常(Claude 会话核对、用户转交);部署前按用户决定未做快照。生产合成 PDF 解析冒烟 PASS,运行版本与候选一致,识别为正式支出回单、PDF 文字、明确成功、无问题标记,耗时 521 毫秒。发布中断与补验过程、证据位置及核验边界见 implement 顶部。
|
||||
|
||||
N3/N4 的软件复核及本次发布检查已完成,整体任务继续 `in_progress`。接下来是 N5 真实台账和公司授权登记、N6 首笔真实还款及会计交接;这两项尚未办理。财务按已有材料与已确认事实登记,马经理按既定公司代表身份确认,技术员工不参与;首笔还款的金额、分配及时间在实际办理前确定,发布通过不构成真实业务写入或付款授权。
|
||||
|
||||
本轮仅补发布与接续记录,不修改资金规则。已部署版本和原门禁回执仍绑定 `beb9f02c`;后续文档提交不影响线上运行,也不继承该回执的新候选发布资格。下方各日期的“未推送、未部署、待独立复核”等表述均保留为历史时点。
|
||||
|
||||
## 2026-10-09 N3 独立复核接收与 P2 口径确认
|
||||
|
||||
已接收 `4c37fcee..1c4633b6` 共 62 文件的独立只读复核,结论 **REVIEWED_NO_BLOCKER**;复核前摘要一致,复核人未改源码、未重跑测试。代码验证依据仍为 `1c4633b6` 第五轮完整门禁 PASS,具体接收、P3 后续项及原始报告见 implement 顶部。
|
||||
|
||||
本期接受已批准 N1 保守策略的共享报销影响,并补齐规则事实源:JPG/PNG/WEBP 及无可提取文字的扫描件 PDF 继续支持上传、预览和 OCR 字段提取,付款依据须由财务核对并由另一名合格人员独立复核;可读 PDF 也须满足全部自动核验条件。此处不改变程序、权限或借款关联模式。P3 的锁内解析、旧证据字段差异和记账日期下限留作后续,未实施。
|
||||
|
||||
本次仅三份文档收尾,沿既有授权本地提交并做文档/治理检查;未变代码不重复全量测试。原 PASS 只绑定 `1c4633b6`,最终发布候选须在 N4 取得与其提交一致的门禁回执。独立代码复核已完成,真实还款、生产启用和公网验收仍未完成;整体任务保持 `in_progress`,生产查询、推送、部署及真实业务写入另按明确授权办理。
|
||||
|
||||
## 2026-10-09 N3 第四轮结果及手机截图前置检查
|
||||
|
||||
候选 `8e17e8df` 第四轮完整门禁为 FAIL:82 迁移、服务端 4558 通过/1 项既有可选跳过,静态/构建及业务回归通过;浏览器 371 通过/1 失败、零跳过/重试。报销付款、PWA 升级和企微历史三项均通过。唯一失败为 R106 手机登录前首次截图的 Chromium 协议错误,尚未执行手机登录;不能把这一结果写成认证故障。
|
||||
|
||||
由 `09-06-release-gate-integrity` 补原截图前的登录页面就绪断言,保留全部截图和巡检、真实隔离后端登录及 Worker 设置,不修改产品或资金规则。Chromium 内部唯一成因尚未证明。先受管定向重验完整文件,再按既有授权本地提交并对干净新候选执行原完整门禁。第四轮原始证据及 `local-followup.json` 保留在 `artifacts/release-gate/loan-receipt-n3-20261009-r4/`,第五轮计划回执为 `artifacts/release-gate/loan-receipt-n3-20261009-r5/`,实际结果以回执为准。
|
||||
|
||||
修正后受管完整 R106 文件 1 项通过、零失败/跳过/重试,14 张截图和巡检报告实际生成;环境、源码一致性及清理通过。该结果不替代新候选完整门禁或独立复核。
|
||||
|
||||
独立代码复核、真实还款和公网仍待完成;没有推送、部署、生产查询或真实 OCR。整体任务保持 `in_progress`,不以旧通过项和定向结果拼接完整资格。
|
||||
|
||||
## 2026-10-09 N3 第三轮结果及桌面测试隔离修正
|
||||
|
||||
候选 `98bab397` 第三轮为 FAIL:82 迁移、服务端 4558 通过/1 项既有可选跳过、静态/构建和业务回归通过;浏览器 371 通过/1 失败、无跳过或重试。报销付款主链路和 PWA 升级本轮均通过。唯一失败为桌面企微历史测试在整页导航后等待标题超时,快照已回登录页;现有测试使用模拟接口,却只在手机 context 屏蔽 Service Worker。原请求来源未记录,不将该漏项写成已证实的历史唯一根因。
|
||||
|
||||
`09-06-release-gate-integrity` 已补默认桌面 context 的隔离,并要求原导航实际获得该 fixture 的 refresh/profile 响应。原三项用例、登录、会话、桌面只读、手机布局和截图全部保留;受管定向 3 项通过,环境和清理通过。资金及产品代码、迁移、正式门禁范围和预算未变。按 N3 既有授权形成新的本地提交,第四轮完整回执固定为 `artifacts/release-gate/loan-receipt-n3-20261009-r4/`,以其 `release-result.json` 和 `local-followup.json` 记录实际候选及结论。
|
||||
|
||||
前三轮 FAIL 完整保留,定向通过不能拼接完整资格。独立代码复核和真实还款验收仍开放;没有推送、部署、生产查询或真实材料外发。以下为各历史时点,整体任务继续 `in_progress`。
|
||||
|
||||
## 2026-10-09 N3 第二轮结果及 PWA 测试等待修正
|
||||
|
||||
修复候选 `18315d11` 的完整第二轮仍为 FAIL:82 个迁移、服务端 4558 通过/1 项既有可选跳过、静态/构建及业务回归通过;浏览器 371 通过/1 失败、无跳过或重试。本轮报销付款主链路完整通过;唯一失败为 PWA 自动升级时,测试读取版本号的 `page.evaluate` 遇到正常导航而失去执行环境。错误栈和原回执保留,不把定向通过或事后 B 版本见证替换为整轮 PASS。
|
||||
|
||||
该测试等待修正归属已有 `09-06-release-gate-integrity` 任务:改为当前文档的属性断言,原 45 秒上限、同会话升级及所有结果断言保持。受管定向 1 项通过,环境与清理通过;产品 PWA、借款/报销资金规则、迁移和门禁范围未变。按 N3 的本地修正与提交授权固定新候选,第三轮回执为 `artifacts/release-gate/loan-receipt-n3-20261009-r3/`,实际结果以其 `release-result.json` 和 `local-followup.json` 为准,不预填通过。
|
||||
|
||||
独立代码复核、真实还款、发布和公网验收继续开放;未推送、部署、查询生产、外发原件或写入真实业务。下方记录保留各轮历史时点,任务仍为 `in_progress`。
|
||||
|
||||
## 2026-10-09 N3 本地提交及新候选验证接续
|
||||
|
||||
N1–N2 已本地提交为 `5a7a1352`。首轮完整候选验证为 FAIL:服务端、构建及业务回归通过,浏览器 371 通过/1 失败;人工核验测试提交返回 409,未执行付款。原测试未记录具体业务原因,不能追认解析超时为根因;现已补其确定缺失的人工原件依据及安全诊断,保留全部资金断言。复验安排见 implement 顶部,后续新候选实际结果以 `artifacts/release-gate/loan-receipt-n3-20261009-r2/` 为准,首轮失败回执不覆盖、不改写。
|
||||
|
||||
用户明确“继续下一步”,沿已列明的 N3 处理 N1–N2 的 31 项本地改动:核对上一轮验证清单、补任务记录、单独本地提交并对干净的新候选运行 `verify-candidate`。范围、命令及失败处置见 implement 顶部;首轮实际候选及结果以 `artifacts/release-gate/loan-receipt-n3-20261009/` 为准,不沿用 `ce11dea9` 的通过结论。
|
||||
|
||||
当前 inline 指令禁止派 implement/check 子代理;独立代码复核与真实还款验收继续待完成。提交和候选验证不代表生产启用,未授权推送、部署、生产访问或真实业务写入。下方 N1–N2“未提交”为上一轮历史时点;整体任务保持 `in_progress`,AC5、AC8、AC27 等开放条件不提前勾选。
|
||||
|
||||
## 2026-10-08 实际银行材料核对后的接续(N1–N2 本地完成,未提交)
|
||||
|
||||
用户先要求重新梳理后续任务,随后明确“开始执行,需要我手动操作的及时告诉我”,批准 N1–N2 的本地实施、针对性验证及主会话检查。目标是形成可证明实际付款的回单处理路径,再完成独立代码复核、获准发布和首笔真实还款;执行顺序见 implement 顶部,凭证处理方案见 design 顶部。提交、推送、生产操作及真实付款不在本次范围。
|
||||
|
||||
N1–N2 已完成本地实现及可执行验证:正式/非最终/未知凭证区分、无字面成功状态的已记账支出人工核对、旧证据本地重检、最终核销及电脑/手机交互已贯通;原件限制与交易唯一性不能由人工覆盖。合成借款链和真实历史材料的内存预验分别留证,详细范围见 implement 顶部。新增 31 项本地改动尚未提交,无新增迁移;独立代码复核及真实银行闭环仍待完成。
|
||||
|
||||
- 实施基线为已提交候选 `ce11dea9`,关联方模式正式本地门禁已通过:82 个迁移、服务端 4519 项通过及 1 项既有可选跳过、浏览器 372 项通过且无失败/跳过/重试。证据为 `artifacts/release-gate/loan-ce11dea9-20261008/release-result.json` 及同目录 `local-followup.json`,不覆盖本轮未提交的凭证变化。本地 main 比本地 origin/main 多 13 个提交;未推送、未部署。
|
||||
- 两笔历史借入的正式银行回单已做本地文字核对;用户已确认均未归还本金、本年无新增借还、开卡小额往来已归还且不计借款,并确认沿用原个人收款账户。具体金额、账号及原件仅在受控材料中保留。上述事实不再重复提问;财务正式录入时仍须留存原凭据、已有会计记录引用及核对截止日,不把历史借入当成当天新增收款。
|
||||
- 财务经办、马经理代表公司作关联方确认;技术员工不参与业务复核、审批或见证。代表权不再待决,真实授权及范围尚未写入 OA。关联模式 Q6 继续关闭,不要求补足第三人或取得无结果查询 PDF 来办理正常还款。
|
||||
- 获准的四份 PDF 此前已完成真实 OCR 调用。其中 S001/S003 虽字段匹配,但原件注明不作为最终交易依据;此前实样只执行到本地匹配函数,不能称为已复现生产错误核销。本轮借款完整链只用合成数据;另用 S002-A 的正式支出原件做内存人工核验预验,证明该格式可以留存记账依据,不代表其属于借款或已完成真实还本。S002 专项 OCR 适配仍后置。新取得的两份正式借入回单证明的是历史入账,不能充当未来还本的支出回单;本轮没有新增云 OCR 调用。
|
||||
- 独立代码复核、正常付款凭据及提交归属实样验收、真实业务录入、发布与公网验收保持开放。此前银行流水及原件整理不等于这些项目已完成;2026-10-07 的生产空存量结论仅适用于该查询时点。
|
||||
|
||||
### R4/AC5 本次补充的凭证验收边界
|
||||
|
||||
本小节已随 N1–N2 获准实施,完成状态以 implement 的验证结果为准;其余 R1–R6 和原 AC 编号保持不变。
|
||||
|
||||
- 明确注明非最终依据、仅受理/处理中,或凭证性质不明的材料,可以留存,不能仅因金额、账户、状态字段匹配而核销。机器未提取出限制说明不等于原件没有该说明;普通人工录入或关联确认不能覆盖已知限制。
|
||||
- 正式银行回单是否证明实际付款,应根据已核验格式的记账方向、记账/交易事实和关键字段共同判断。不能仅凭标题推定成功,也不能要求经办补写原件不存在的“交易成功”。正式借入回单的公司入账方向不能当作公司还本的付款方向。
|
||||
- 原件足以证明付款而机器未能提全时,保留有依据的人工核对路径;经办录入原件实际信息、确认人按既定模式核对,记录原件及判断依据。原件不足、交易归属不明、字段冲突或重复交易仍不能放行。自动与人工结论分开记录。
|
||||
- 核验、人工证据重建及最终核销须消费同一份仍有效的凭证依据;旧记录缺少新判断依据时不得直接沿用为自动通过,不能回写已发生的付款历史。验收必须包含最终资金动作及失败后本金/占用未变化,不能止于匹配函数。
|
||||
|
||||
## 2026-10-08 两人办理关联方还款(本地实施与合成验证完成,已授权本地提交及正式验证)
|
||||
|
||||
- 用户确认:实际经办为一名财务兼人事行政;马经理为股东、个人出借收款人,且有权代表公司批准还款。技术员工不参与复核、审批或见证,不增加财务权限,不作为候选、任务接收人或业务验收所需人员。
|
||||
- 按用户“按照这个思路规划”的要求,采用“财务经办 + 马经理代表公司作关联方确认”。公司授权已明确,不再列为待决问题;其授权范围和真实身份在业务启用时留存。该模式具有两名操作者的分工,不具备无利益关联的独立审批,页面、凭据和审计必须如实标明。
|
||||
- 原独立模式在创建时排除出借收款人,按实际人员配置无法办理该笔还款;该默认规则保留。新增关联模式覆盖正常付款及归属、人工回单、提交清单、失败/终态释放、补证恢复、晚到成功、追回和误报关闭,实施验证记录见 implement 顶部。
|
||||
- 新模式只豁免指定确认人的“收款人关联”冲突,不豁免制单、提交、导出、上传、录入或提案等经办冲突。财务可承担多项经办工作;同一真实身份不能通过多个账号或角色自审。Q6“人工确认未提交”在此模式下不启用,原双独立复核条件不降低。
|
||||
- 回单 OCR 已实现,普通回单按实际文件识别和匹配,无需先向银行咨询。银行终态证据与普通 OCR 验收分开;OCR 或两人的确认均不能补足缺失的交易归属,也不能从“没有回单”推断没有付款。
|
||||
- 用户已明确“开始实施”,本轮已完成 RP1–RP4 的本地实现及可执行验证;随后明确授权将 39 项本地改动提交,并运行新候选正式门禁,执行安排见 implement 顶部。AC20–AC26 有本轮合成证据;AC27 的数据库部分已验,独立代码复核及真实材料验收仍待完成。新候选门禁结论以该候选回执为准,旧候选 `4c37fcee` 的通过回执不用于证明新模式;未授权推送、部署或本轮生产查询。
|
||||
|
||||
## 2026-10-07 本地阶段状态(历史时点,现状见 Current Status)
|
||||
|
||||
S4–S8 已本地提交 `431c36ea`;补齐剩余界面后合成回归为 81 迁移、HTTP 95、浏览器 19、数据库约束 9 组通过。应用代码沿用修复后的同模型只读静态复核,本轮只补测试与记录。S0 生产只读查询确认 OA 借款模块当前记录为 0,73 个已应用迁移校验值一致,待执行 8 个;不代表银行或线下没有付款。人员、真实建行材料和业务独立验收仍未完成,正式发布门禁尚待执行;不据此勾选整体真实还款验收或声明已部署。完整证据与限制见 implement.md 顶部。
|
||||
|
||||
## 2026-09-17 实施接续
|
||||
|
||||
用户明确要求借款尽快完成,沿本PRD与design既有个人出借人/CNY本金范围推进本地T1–T4,取代此前暂缓实施的优先级;不扩大为利息、备用金或通用付款。真实资料、余额和账户仍须正式录入核实,本地只用合成样例。风险与独立复核在交付/上线前保持未完成,不通过读取生产密钥或重跑旧恢复为本地开发解阻。
|
||||
|
||||
## Goal
|
||||
|
||||
让财务能按已核实凭据查清公司向个人借入的未还本金,并完成申请、独立审批、网银付款、回单留存和业务本金核销。OA管理业务台账及付款证据,代账系统负责原负债科目记账,不把借款还本变成费用报销。
|
||||
让财务能按已核实凭据查清公司向个人借入的未还本金,并完成申请、有权审批、网银付款、回单留存和业务本金核销。默认保留独立审批;本公司已授权、身份及借款范围明确的关联方还款,按 R3 采用财务经办与公司有权人的关联方确认。OA管理业务台账及付款证据,代账系统负责原负债科目记账,不把借款还本变成费用报销。
|
||||
|
||||
## Background
|
||||
|
||||
- 用户提出历史两笔借入合并一次归还的真实需求;聊天提供的历史日期、金额和“本年无借还”尚未由本任务核验原始凭据,不据此创建真实余额或付款。
|
||||
- 当前代码仅有reimbursement/travel_order付款来源(`server/prisma/schema.prisma:273`);创建依赖已有来源单,不支持自由填收款人金额的通用付款申请。
|
||||
- 建行制单用途/备注按报销生成(`server/src/services/paymentOrderXls.js:158`);通用审批配置也只有既有五类业务(`server/src/routes/workflowDefinitions.js:9`)。回单OCR及人工核对范围须显式适配,不能只改备注。
|
||||
- 本task于2026-09-17获准规划,独立于报销收尾任务,status=planning。先处理08-23恢复关键遗留及09-05到期治理;本次不是实施、真实资料录入或付款授权。
|
||||
- 立项时仅有 reimbursement/travel_order 付款来源,创建依赖已有来源单;本任务后来新增借款还本来源,仍不开放自由填写收款人和用途的通用付款。
|
||||
- 立项时建行用途/备注按报销生成,回单 OCR 及人工核对未覆盖借款。本地已有显式适配,实际材料的识别与银行接受性仍须分别验证。
|
||||
- 本 task 于 2026-09-17 获准规划,独立于报销收尾任务;后续实施授权与证据见 design/implement。目前为 in_progress,本轮已本地实现关联方模式,不扩大真实录入或付款授权。
|
||||
|
||||
## Scope
|
||||
|
||||
@@ -29,47 +260,124 @@
|
||||
|
||||
列表区分未还本金、已占用待付款额、可申请额及核对截止日期,资料覆盖不全时不得回答“已结清”。财务选择借款及本次分配金额,正数、两位小数且合计等于付款额;不得跨公司/出借人/币种合并。并发申请不能超额,已付、取消及有银行在途的状态必须分别处理。
|
||||
|
||||
### R3 有权且独立的审批
|
||||
### R3 有权审批与明确的关联方例外
|
||||
|
||||
财务创建并提交,复用付款批次的经理/CEO独立复核作为首期还款审批,不再加一套重复通用审批链。审批人须在职、有明确业务角色及权限,排除制单/提交人和出借收款人对应的OA身份;身份不清或无人可批则阻止提交,不用admin通配兜底、不靠临时虚建员工绕过。对出借人的OA身份关联必须确认并留痕,执行时重验,不按姓名猜测。
|
||||
财务创建并提交,沿付款批次完成决定,不新增重复的通用审批链。默认 `independent` 模式沿现有经理/CEO独立复核,排除制单/提交人和出借收款人对应的OA身份,无合格人时阻止提交。不得使用 admin 通配、虚建非员工出借人或按姓名猜身份绕过。
|
||||
|
||||
新增 `related_party` 模式,限定公司、真实个人出借人、其关联员工及授权覆盖的已确认借款。财务登记实际公司授权与范围,指定有权的马经理确认;不要求技术员工或第三名员工参与。还款创建时由服务端核定并冻结模式、授权版本和身份;客户端不能自行切换,历史独立批次不能自动转为关联模式。
|
||||
|
||||
马经理作出每个新决定时,须当前在职、有相应经理/CEO业务权限、具备覆盖该事项的公司授权;仅豁免其作为本笔收款人的利益关联。经办、提交、导出、证据上传、人工录入和提案冲突继续拒绝,按真实员工身份判断,同一人兼任角色也不能消除冲突。关联模式的经办入口提前禁止指定确认人参与这些经办动作;其公司授权确认或债权/收款声明不记作独立复核。
|
||||
|
||||
付款申请可由公司代表填写理由退回;退回决定与授权留痕不可改,原申请不得继续批准或导出。退回不直接释放占用,由财务按未发送取消规则取消后重新申请,不修改原申请的付款快照。
|
||||
|
||||
付款前核对当前权限、授权、版本与启用状态;付款后的原审批与出借人资格按当时快照判断。新的银行事实确认仍核对当前确认人的资格。停止新付款不抹掉历史授权、不阻止银行事实留存或符合条件的已付核销;停止后续对账决定单独记录。具体时点及最终动作检查见 design 顶部。
|
||||
|
||||
### R4 付款与回单证据
|
||||
|
||||
审批只占用额度,不减少未还本金。财务在网银实际付款,用途为“还款”,短备注按借款年份/本金语义生成,受现有银行长度校验;详细原借款对应关系留在OA,不硬塞进银行备注。原件可先留存,但金额、币种、付款/收款账户、交易成功状态及唯一身份不满足时不得登记已付。
|
||||
|
||||
复用现有回单核对的自动匹配/人工例外边界,显式支持新付款来源;真实样本适配未验证前不能宣称新来源自动识别可用。OCR不清或不可用时,原件留存、经办录入、独立人员复核不能伪称机器核实或银行验真;明确失败、受理中、账户/金额不符及重复交易不得靠普通理由放行。独立人工复核继续排除收款人和提案人。
|
||||
复用现有回单核对的自动匹配/人工例外边界,显式支持借款来源;真实样本未验证前不宣称真实识别已验收。普通回单直接沿已有 OCR 处理实际文件,不先向银行询问字段。OCR不清或不可用时,原件留存、经办录入和按 R3 模式作出的人工决定不能伪称机器核实或银行验真;明确失败、受理中、账户/金额不符及重复交易不得靠普通理由放行。独立模式排除收款人和提案人;关联模式仅豁免指定收款人关联,上传/录入/提案等经办冲突继续排除,读取及最终消费人工证据同样执行该规则。
|
||||
|
||||
### R5 核销、异常与会计交接
|
||||
|
||||
只有符合既有付款登记证据门禁并由财务明确登记成功时,才在同一事务内占用交易身份、核销分配本金并更新付款事实;同一请求重试幂等,跨批次/跨报销复用交易拒绝。确认失败或未发起银行付款的取消可释放额度;银行状态未知/在途时不能直接释放后重付。付款已登记后的错误处置保留原事实,另审纠错,不删除或覆盖记录。
|
||||
只有符合既有付款登记证据门禁并由财务明确登记成功时,才在同一事务内占用交易身份、核销分配本金并更新付款事实;同一请求重试幂等,跨批次/跨报销复用交易拒绝。取消须满足相应安全取消或逐提交终态证据门禁;有导出或银行提交后,不能凭口头“没有付款”释放额度。银行状态未知/在途时不能直接释放后重付。付款已登记后的错误处置保留原事实,另审纠错,不删除或覆盖记录。
|
||||
|
||||
付款成功与代账记账分开,记录凭证编号/记账确认及材料交接,不由OA自动生成会计分录。材料包括原借入凭证、协议/确认书、余额核对、审批及还款回单;本金不要求费用发票,不进入费用报销统计或费用预算。关键材料按适用访问权限留存,历史余额/分配不得无审计改写。
|
||||
|
||||
### R6 关联方模式的对账接续与留痕
|
||||
|
||||
R3 的模式同时作用于付款审批、提交清单、成功/失败归属、人工回单、银行终态、失败确认、SR补证、晚到成功、误报关闭和追回;需要人工决定的事项由财务登记、马经理作关联方确认,最终核销/释放/补记/解冻仍重验各自证据和资金条件。成功回单完全满足自动核验时,不增加一次无必要的人工回单确认。两人确认、时间相近、金额或账户相同均不能替代指令归属、终态或到账证据。
|
||||
|
||||
每次决定记录模式、公司授权及版本、实际决定人与关联身份、材料快照和理由;后续读取、重建、最终消费均使用同一语义。Q6保持两名独立复核人的现有合同,在关联模式下服务端拒绝发起、复核和释放,页面说明不可用;无可用终态证据仍保持占用。旧独立记录及报销/差旅权限不因此放宽。
|
||||
|
||||
## 2026-10-07 S4–S8 本地接续(历史时点)
|
||||
|
||||
用户要求沿已确定工作直接执行。S4–S8 的本地实现和验证继续推进,阶段证据在 implement 顶部;AC9–AC19 不因后端或合成测试通过而自动勾为整体验收通过。新银行事件均标明人工核对,不伪称真实银行/OCR 已验;生产查询、推送、部署仍未执行。
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
勾选表示该项已取得所要求的软件及流程证据,不代替 N5/N6 的真实材料录入与银行闭环验收。原勾选项保留独立模式基线,AC20–AC26 另有关联模式合成证据;AC8、AC27 的独立代码复核、固定候选门禁及本次部署证据现已补齐,既有回退限制继续有效。AC9–AC19 中一般“复核/确认”按 R3 区分独立复核与关联方确认,具体消费者见 design;AC12 的双独立复核不适用此转换。
|
||||
|
||||
- [x] AC1:合成历史两笔借入可登记并确认余额;未确认/重复登记/无凭据不进入还款,历史录入不被统计成当天新增收款。
|
||||
- [x] AC2:同一出借人两笔借款合并一笔付款、部分偿还正确;超额、跨主体/出借人/币种、重复提交和并发占用均拒绝或幂等,金额用精确小数。
|
||||
- [x] AC3:财务不能自审,收款人即使持CEO/manager或多角色也不能批准自己的还款;无合格审批人、身份关联缺失/变动拒绝,无管理通配旁路。
|
||||
- [x] AC3(既有独立模式):财务不能自审,收款人即使持CEO/manager或多角色也不能批准自己的还款;无合格审批人、身份关联缺失/变动拒绝,无管理通配旁路。新关联模式的限定例外另按 AC20–AC27 验收,不以此勾选代替。
|
||||
- [x] AC4:审批/导出/上传回单均不会单独减少本金;处理中保持占用,确定失败/安全取消释放,明确成功登记与分配核销原子完成,数据库异常整体回滚。
|
||||
- [ ] AC5:正确回单可匹配新来源,错金额/账户/币种、失败/受理、同额歧义、重复交易、晚到版本及人工自审分别受阻;真实样本未覆盖的自动识别仍明确待验。
|
||||
- [x] AC6:付款完成可追到原借款分配和会计交接状态;余额查询标明截止/核对状态,不把OA无记录说成银行无还款,不把本金计入费用。
|
||||
- [x] AC7:报销/差旅既有付款、独立复核、制单、回单和权限回归通过;PC/手机沿既有交互,机密字段默认脱敏,普通员工不能读全台账。
|
||||
- [ ] AC8:迁移与回退影响、独立只读复核、恢复风险处置和发布前条件完整;本地合成通过不替代真实银行接受性或部署,真实录入/付款另批。
|
||||
- [x] AC8:迁移与回退影响、独立只读复核、恢复风险处置和发布前条件完整;本地合成通过不替代真实银行接受性或部署,真实录入/付款另批。2026-10-09 本次发布证据见 implement 顶部;未新增恢复演练或自动回退授权。
|
||||
- [ ] AC9(对账,design 3.1/3.3):制单导出与银行提交尝试分别落表并关联;提交清单须经相应模式的确认;确认失败只计未作废附件,但作废的成功或处理中回单仍按事实阻断;确认失败按批次冻结快照核对,出借员工离职不阻断原审批效力;新的事实决定仍须有当前合格确认人;一条指令的终态不能推定其他提交已结束。
|
||||
- [ ] AC10(失败归属,3.1):存在同金额候选时,确认失败须有已复核、写明覆盖哪些指令的失败归属;未确认时保持占用。
|
||||
- [ ] AC11(银行终态释放,3.2;2026-10-07 补充:同一指令的终态事实可了结该指令此前的处理中回单,其他提交不能代替;最终取消释放的事务须重验全部条件,并与新提交、晚到回单串行;终态证据与付款回单分开存放,作废或被替换后不能继续作为依据):每次已登记提交均有能唯一定位指令、经相应模式确认的终态证据,且无未解决的成功或处理中事实,才可转 `confirmed_not_paid` 并释放;对账单、截图、时间依据与等待期均不能单独放行;释放后禁止再导出。
|
||||
- [ ] AC12(人工确认未提交,3.2a,用户 2026-10-06 确认支持):仅独立模式在全部证据加两名不同的独立复核人满足时转 `confirmed_not_submitted`,记录与页面标为人工确认;人员不足或材料缺失时继续占用。关联模式不启用 Q6。
|
||||
- [ ] AC13(冻结,3.5):冻结按原因记录;拦截新申请及其他在途申请的复核与导出,不拦事实登记;误报经相应模式确认后关闭不补记;证据不确定继续冻结;全部原因关闭才解冻。
|
||||
- [ ] AC14(晚到成功,3.4):只增不改并标记原结论被推翻;按冻结快照与历史审批核对;覆盖已释放与已确认失败未释放;逐笔先处理占用冲突再按差额结清,余额列待追回;补记不生成可导出指令,整笔超额也完整记录;同一交易不能两次使用。
|
||||
- [ ] AC15(追回,3.5):凭到账证据经相应模式确认登记,支持部分追回;仅登记不解冻;本期不支持冲抵。
|
||||
- [ ] AC16(存量):历史批次保留已知的导出次数,新增“历史导出汇总”标明已知与待核实信息;它不是一次真实导出或银行提交,不能据此放行额度;上线前须核实生产存量(S0)。
|
||||
|
||||
- [ ] AC17(补证恢复,SR1–SR3;既有实现验证见 implement):已确认失败或未付款且本金仍全部占用时,可补充有效证据并重新按相应模式确认;原结论与依据不可改,旧证据/复核可追溯;恢复不得重开付款、导出或改变本金,不适用于已释放/已结清、成功事实或 Q6 人工未提交。
|
||||
- [ ] AC18(恢复批准有效性,SR2–SR4;既有实现验证见 implement):材料、核验版本、提交清单、归属或同额候选变化使旧恢复批准失效;新建再撤回、换回同一流水号、撤回/驳回恢复均不能复活旧批准或回退原释放依据;补证后能重新送审,不永久卡死;当前确认人合格且不属于任何相关经办身份,关联模式仅例外允许指定收款人身份。
|
||||
- [ ] AC19(最终恢复释放,SR3–SR5;后端验证见 implement):确认与最终取消均满足 S3 全部条件及等待期;最终事务重验最新恢复批准与证据,释放、取消、消费批准、审计原子且幂等;与证据/提交/核验/候选变化确定性交错时不错误释放;成功事实转对账、未知继续占用。PC/手机完整操作与真实银行接受性分别验收。
|
||||
|
||||
- [x] AC20(关联范围):仅经登记确认的公司、个人出借人、关联员工及借款范围可新建关联模式还款;模式由服务端核定并冻结,伪造模式/授权/公司/借款、身份未核实或范围不符均拒绝;旧独立批次、报销与差旅不变。
|
||||
- [x] AC21(两人分工):财务可合并经办角色;指定马经理可以代表公司确认本人的还款,但不能兼任本批经办/提交/导出/上传/录入/提案人。分别测试各冲突与多角色、多账号;不能把其从所有排除列表整体删除,技术员工始终无审批及敏感读取权限。
|
||||
- [x] AC22(真实留痕):所有人工决定及审计记录模式、授权版本、确认人的关联身份和证据快照;详情、待办和最终证据重建一致,不把关联方确认显示为独立复核;已决定记录不可改、不可删除、不可事后换模式或授权。
|
||||
- [x] AC23(完整接续):以财务和收款经理两个合成身份贯通付款、提交清单、成功/失败归属、人工回单、失败/终态释放、SR、晚到补记、误报关闭及部分/全额追回;确认入口、材料读取与最终消费均可执行。缺证、同额归属不明、冲突或重复交易仍拒绝,拒绝后本金、占用和冻结保持正确。
|
||||
- [x] AC24(Q6边界):关联模式的 Q6 发起、双审及最终释放均由服务端拒绝,页面说明不启用;直接调用或伪装旧独立批准也不能绕过。原独立模式双审反例仍通过,无回单不能释放占用。
|
||||
- [x] AC25(资格时点与并发):新申请/批准/导出校验当前付款授权;新的对账决定及最终释放校验当前对账授权;已付核销/已确认银行事实入账使用有效的历史审批与证据,不因停止新付款或原审批人事后离职而失败。新授权不能改写旧模式;授权停止、材料变化与确认/导出/释放按确定性交错验证,先后结果有明确语义。
|
||||
- [x] AC26(页面与访问):电脑和手机以现有组件走通两人流程;财务无自审按钮,经理无经办按钮,必要材料按本批范围及用途审计读取;技术员工不获候选、待办、通知或材料。前端隐藏不能替代服务端鉴权。
|
||||
- [x] AC27(数据与回退):仅新增型迁移,历史记录明确归为独立模式且不伪造授权;新字段、外键、模式/关联身份及不可变约束在数据库验收。新增关联决定后禁止不经评估降回不理解该模式的旧代码;最终候选重新验证并按规则只读复核,不沿用旧门禁宣称通过。数据库合成验收、独立代码复核及 `beb9f02c` 完整门禁已取得,生产已应用 82/82 迁移。
|
||||
|
||||
- [x] AC28(员工选择,本地验收完成):财务可从现有员工选择出借人并使用已有姓名、银行和账号,直接关联真实员工身份;不新建员工、不要求再次录入同一资料,列表与确认页只显示遮罩账号。借款所属公司明确,非员工路径不隐瞒已有员工身份。
|
||||
- [x] AC29(来源与权限,本地验收完成):只有现有合格财务可以选择并关联;银行卡资料权限继续校验,不扩大员工或技术人员权限。缺资料、不可用银行或账号、越权及伪造客户端姓名/账户均拒绝;资料只在原员工维护入口补正。
|
||||
- [x] AC30(重复与版本,本地验收完成):重复或并发选择同公司同员工复用明确的已有登记,不产生新员工或无声合并历史记录;预览至确认间来源变更时要求重新核对。已有出借人刷新保持既有锁序、版本、在途限制和审计;员工主档变化不改写已批准付款、已发生银行事实或本金。
|
||||
- [x] AC31(办理验证,本地验收完成):合成数据贯通选择员工、登记历史借入、确认余额、登记公司授权及经理确认;电脑/手机入口和缺资料提示可用。验证来源变更、并发重复、无权限和旧快照保持的反例,不用真实员工资料或付款作为开发测试。
|
||||
|
||||
- [x] AC32(单笔预填):合成可读入账 PDF 正确预填金额、日期和唯一引用,选择公司/出借人后可核对保存;扫描 PDF 的受控 OCR 返回同样合同。文件中有多笔交易、歧义金额/日期或缺字段时,不取第一笔、不取最大金额、不补造值。
|
||||
- [x] AC33(确认边界):识别和退出不产生业务借款或正式附件;保存后仅为余额待核实且带原件。未还本金、截止日、借款性质由财务确认,缺协议/余额核对材料时不能确认余额或申请还本,不生成付款或改写公司授权。
|
||||
- [x] AC34(主体与方向):公司入账可预填,公司支出、明确失败/处理中、非最终回执、非人民币及多交易文件受阻;付款方同名、旧银行账号或主体不唯一时只提示人工核对,不新增身份、不更改员工/出借人账户,不放宽现有还款回单规则。
|
||||
- [x] AC35(失败可继续):OCR 关闭、缺配置、超时、额度不足、字段冲突和本地无法提取文字均有可理解结果;未知可人工补录,已知矛盾不能靠普通确认消除。断言无虚构字段、无自动重试风暴,充分可读 PDF 不调用云 OCR。
|
||||
- [x] AC36(保存一致性):保存成功同时存在一笔借款及对应 `incoming` 原件;相同请求重试仅返回原结果,换文件/字段复用请求键被拒;同公司同出借人的重复引用、相同原件及并发新入口保存不会生成重复可用借款。存储、附件或审计失败时正确补偿,不虚报成功。
|
||||
- [x] AC37(身份与原件绑定):无财务权限、跨身份结果复用、令牌过期/篡改、确认前换文件及来源变更受阻;电脑/手机换文件、卸载及同文档换账号时取消旧请求,迟到响应不覆盖新表单或以新身份重发保存;保留同身份正常会话恢复。
|
||||
- [x] AC38(原流程兼容与隐私):原手工登记、员工关联、非员工登记、三类材料余额确认、关联授权与还款路径仍通过相关回归;原件下载沿既有权限/用途/审计,无完整账号或原始识别 payload外泄。PDF/文件不安全或超限在持久化前拒绝。
|
||||
- [x] AC39(证据边界;第五轮独立复核 PASS_WITH_NOTES;2063ff1e 已发布,发布日志已核对、公网路由检查沿用发布会话回报;真实样本的姓名、账号、流水号未逐值独立核对,真实云 OCR 和登录后真实业务尚未验收):完成单元、真实隔离 HTTP/数据库及电脑/手机浏览器验证,覆盖失败、并发和清理;完成涉及入口权限/保存流程的独立只读复核,受 inline 限制时明确待独立复核,不冒用旧结论。真实样本与云 OCR 可用性、公开发布分别验收,不以合成结果勾 AC5 或 N5/N6 实际业务完成。
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- 不处理利息、工资/分红、员工向公司借备用金、资本金、债转股、机构借款、外币、退款或债务冲销。
|
||||
- 不处理利息、工资/分红、员工向公司借备用金、资本金、债转股、机构借款、外币、一般退款或债务冲销;仅保留本任务已定义的超额还款实际追回,不做冲抵后续本金。
|
||||
- 不做银行直连、流水自动导入、AI自然语言财务问答、自动会计凭证/税务、跨系统重复审批或全量ERP。
|
||||
- 不伪造报销单承载本金,不改现有报销一单一笔付款规则,不解冻其他低频模块,不引入新视觉设计体系。
|
||||
- 不索取聊天中的完整账号或真实凭证,不读取/轮换生产密钥,不沿用旧恢复/部署/真实付款授权。
|
||||
|
||||
## Test Plan
|
||||
|
||||
真实Fastify路由与隔离PostgreSQL覆盖AC1–AC6的正反例、并发和事务回滚;前端沿现有Vitest/Playwright以合成财务、审批人、收款人和普通员工验证PC/手机权限/动作/余额状态。跨业务重复交易与报销回归单列;仅云端响应可在合成测试中替换,不用预签身份替代正式认证全链。执行端承担软件验证,不让用户制造真实还款来代测。
|
||||
真实Fastify路由与隔离PostgreSQL覆盖资金、身份、并发和事务回滚;前端沿现有Vitest/Playwright验证PC/手机。独立模式保留合成财务、独立审批人、收款人的基线;关联模式使用财务与收款经理两名真实角色的合成身份,技术员工只作无权访问反例,不让实际员工参与财务复核。跨业务重复交易与报销回归单列;OCR沿真实识别/归一化/匹配链,仅替换云端返回,不用预签身份替代正式认证全链。关键资金守卫配定向变异和确定性交错,按 implement 的 RP1–RP4 执行。执行端承担软件验证,不让用户制造真实还款来代测。
|
||||
|
||||
## Current Status
|
||||
|
||||
T1–T4本地合成实施已完成,AC1–AC4、AC6–AC7有本地证据;AC5真实样本及AC8独立/恢复/发布条件保留开放。精确回执见implement顶部。未部署,不声称真实银行接受或真实批次已通知。
|
||||
N5-P“原借入回单识别预填”已实施,经第五轮独立复核 PASS_WITH_NOTES 后,随 `2063ff1e` 于 2026-10-10 推送部署。补记时本地 HEAD 与 `origin/main` 一致;已有候选验证日志 PASS,部署日志确认应用发布与备份合同刷新完整通过,部署前后无待应用迁移、仍为 82 个。公网 `/ready` 版本、页面 200 和识别接口未登录 401 沿用发布会话回报,本次只核对本地版本及日志,未重新访问生产。登录后的 live smoke 在部署日志中明确跳过,真实业务办理尚未验收。
|
||||
|
||||
本轮只补任务记录。财务保存前仍需逐项核对原件并完成两项确认,尤其姓名、账号、流水号;真实云 OCR 未验收。员工授权翻页超时继续标记为根因未定,不以多轮回归通过推定已修复或已排除线上影响。详细证据和交接步骤见 implement 顶部。
|
||||
|
||||
员工选择阶段 AC28–AC31 已本地验收。用户在上一会话回报 `45737ccb` 已推送部署、公网检查正常、生产仍为 82 迁移,并明确尚未在线上登录办理新入口;本会话只核对本地版本和转交记录,未重新连接生产或复跑发布检查。下方及前述 `beb9f02c`、“未发布”等记录保留其历史时点,不能作为 N5-P 的验证证据。
|
||||
|
||||
整体任务保持 `in_progress`。2026-10-10 用户回报财务已完成真实借入录入,截图显示原借入凭据已有附件,但缺少协议/借款确认书和余额核对材料,当前卡在余额确认,公司代表授权尚待办理;本会话未访问生产独立核实。首笔真实还款的网银提交、正式回单、核销及会计交接尚未验收;AC5 及未覆盖的真实材料边界继续开放。无需重新索取已确认的借款事实或要求技术员工参与;真实录入和付款仍按各自授权执行,不从未还本金推定本次全额支付。缺材料的流程问题仅记入 implement,依用户指令暂不修改产品规则。
|
||||
|
||||
后续安排见 implement 顶部:N5 真实登记为业务优先项,授权翻页的确定性排查可并行,N6 按实际付款计划在 N5 后办理。首笔正常成功链路不一次关闭 AC5 或 AC9–AC19 的全部验收;异常分支及仅适用独立模式的 AC12 保留各自适用条件,不为验收制造真实异常交易。
|
||||
|
||||
### 2026-10-08 N1–N2 完成时点(历史记录)
|
||||
|
||||
N1–N2 在 `ce11dea9` 基线上完成本地实现和主会话检查,31 项改动未提交,无新增迁移。最新验证为 82 个迁移、116 组借款 HTTP、9 组数据库约束、18 组关联电脑/手机操作、38 组共享回单数据库/真实认证及 24 项共享报销页面限定重验通过;回单/报销最新定向 292 项通过,9 个资金守卫变异全部捕获。服务端全量为 4554 通过、1 项既有可选跳过,随后合成数据及零页详情的改动由上述最新定向覆盖,不虚报重新全量。Prisma、前端类型/构建及合同检查通过,准确时点和回执见 implement 顶部。
|
||||
|
||||
六份真实材料的本地分类及既有正式支出样本的内存人工录入预验已完成;未用真实借款执行核销,也未验证真实银行提交对应。当前不用用户补材料。独立代码复核、新候选正式门禁、获准发布/真实台账与授权登记、首笔真实还款闭环仍未完成;AC5、AC8、AC27 及整体业务验收不据本地结果勾选。原候选的正式门禁不覆盖当前差异,没有本轮提交、推送、部署、生产访问或真实写入。
|
||||
|
||||
### 关联方模式收尾记录(历史时点,最新状态见上文)
|
||||
|
||||
本地已有 A/B/C、S1–S8、SR恢复及电脑/手机界面,本轮另完成关联方模式 RP1–RP4 的实现与可执行验证,已获准本地提交及新候选正式验证。最新借款专项为82迁移、HTTP 109、浏览器33、数据库约束9组通过;关联模式单列14组HTTP及电脑/手机各7组浏览器,13个有效守卫变异均捕获。报销付款、付款权限和导航35项通过,现行差旅冻结保护另2项通过;一次误选封存差旅整链的403失败保留,未恢复差旅权限。服务端全量4519通过、1项原有跳过,后续小改的77项定向验证通过,详细先后和证据见implement。AC20–AC26仅完成本地合成验收;AC5、AC8、AC27及其余整体业务验收保持开放。
|
||||
|
||||
较早候选 `4c37fcee` 的正式门禁 PASS 只证明旧独立模式;本轮提交后单独生成 `verify-candidate` 回执,不提前宣称通过,主会话检查也不等同独立代码复核。不得以测试数字推定真实银行接受性或生产已经应用。
|
||||
|
||||
生产曾于2026-09-27上线早期版本;上述后续本地提交尚未推送或部署。2026-10-07 22:08–22:09获准只读核实时,OA借款相关记录为0,已应用73迁移;这不是银行/线下无付款的结论,发布前仍需重新获准核对存量及迁移差集。人员条件现已明确为本节两人安排,独立模式无人可办理本笔还款;后续为本轮独立代码复核、真实材料及授权录入验收、固定候选门禁和获准发布,不再将关联模式、S8或SR列为未实现。
|
||||
|
||||
## Planning Status(历史时点,已由顶部实施接续替代)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-09-17",
|
||||
"completedAt": null,
|
||||
"branch": null,
|
||||
"branch": "main",
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": "46a70aa5",
|
||||
@@ -23,4 +23,4 @@
|
||||
"relatedFiles": [],
|
||||
"notes": "2026-09-17 T1–T4本地实施完成:72迁移、9组PG约束/并发、16组正式认证HTTP和3组桌面手机权限浏览器通过;212定向unit及ERP退出后付款128回归通过,最终前端typecheck/build与Prisma通过。AC5真实样本/AC8独立复核、恢复事实与发布门禁仍开放;未提交推送部署。 2026-09-26 更新:本地实现已通过候选分支合并落地到 origin/main(合并提交 46a70aa5),不再是仅存在于未提交分支的工作;但真实样本验证/独立复核/生产切换等验收项仍开放,任务状态维持 in_progress,未视为完成。",
|
||||
"meta": {}
|
||||
}
|
||||
}
|
||||
+10
-3
@@ -1,10 +1,17 @@
|
||||
## 2026-09-26 根因确认与修复(当前)
|
||||
## 2026-09-27 已上线(当前)
|
||||
|
||||
- [x] `verify-candidate` 在 `70af0c6b` PASS(372/372);push 到 origin/main。
|
||||
- [x] 生产部署:生产由 `b1d25d3c` 更新为 `70af0c6b`,`/ready` buildSha `70af0c6b9aa3`。发布期间本地 SSH 在 build-init 阶段断开,远端 deploy.sh 继续完成;随后补跑包装器尾部两步:forced-command 合同 refresh PASS,只读复核 13/13 PASS、`migration_reconciliation pending=none`(loan/numbering 两个迁移已应用)、回滚窗口 OPEN;远端同步源码属主等于部署 UID。
|
||||
- [x] 公网免凭据检查:登录页/入口脚本 200;线上 `sw.js` 的 `app-api-runtime` 不含 `networkTimeoutSeconds`;`/api/me`、`/api/workflow/tasks/summary`、`/api/company-loans`、`/api/reimbursements` 未登录均 401。
|
||||
- [ ] 带账号的公网业务 smoke(smoke 身份验收窗口外为 disabled,未执行);企微手机端慢网络下审批后状态由真人使用观察。
|
||||
|
||||
## 2026-09-26 根因确认与修复
|
||||
|
||||
- [x] 带诊断复现命中(CG-20260926-0006,任务 48d14805):浏览器 01.973 发 GET,**05.049 收到 pending**;服务端 02.255 收到同一 GET,**05.598 才读库且读到 completed**。浏览器拿到的响应早于服务端读库,来源只能是 Service Worker 缓存。
|
||||
- [x] 根因:`client/vite.config.ts` 的 `app-api-runtime` 规则对 `/api/me`、`/api/workflow/tasks*`、`/api/workflow/approvers*`、`/api/notifications*` 用 `NetworkFirst` + `networkTimeoutSeconds: 3`;网络响应超过 3 秒时 SW 返回审批前缓存的旧响应,真实响应被丢弃。自 2026-03 P21PWA2(9112383d)起存在,生产同样受影响(慢网络/企微手机下审批后页面显示未通过,再点报「已处理」,待办列表可能显示已处理单据)。审批写入本身从未丢失。
|
||||
- [x] 修复:去掉 `networkTimeoutSeconds`,仅网络失败(离线)才回退缓存;退出登录清理该缓存(`client/src/pwa.ts:201`)不变。新增 `server/tests/unit/utils/client-pwa-api-cache.test.js`(有修复通过、去掉修复失败);构建产物 `dist/sw.js` 已无超时。
|
||||
- [ ] 修复后复现脚本 3 轮验证(修复前 3 轮命中 2 轮)。
|
||||
- [ ] 通过后 `verify-candidate` 取得 PASS 回执。
|
||||
- [x] 修复后复现脚本 3 轮验证:0 命中(修复前 3 轮命中 2 轮)。
|
||||
- [x] 通过后 `verify-candidate` 取得 PASS 回执。
|
||||
- 后续另议:`/api/workflow/tasks*` 含报销审批内容仍会被 SW 缓存供离线读取,与「报销审批证据不进入离线缓存」口径是否冲突待确认;采购提交事务 P2028 见下方。
|
||||
|
||||
## 2026-09-26 调查进度
|
||||
+1
-1
@@ -27,7 +27,7 @@
|
||||
- [x] 在保留库的环境复现至少一次,并记录失败单据任务/实例/历史的库内真实状态
|
||||
- [x] 给出有证据支撑的根因(代码位置 + 机制),区分测试问题与产品缺陷
|
||||
- [x] 若为产品缺陷:说明影响实体范围,及 `b1d25d3c` 是否同样存在(SW 规则覆盖 /api/me、workflow/tasks、approvers、notifications;自 2026-03 9112383d 起存在,生产同样受影响)
|
||||
- [ ] 修复后 `verify-candidate` 完整通过(取得 PASS 回执)
|
||||
- [x] 修复后 `verify-candidate` 完整通过(取得 PASS 回执):`70af0c6b` 372/372,`artifacts/release-gate/20260926-202856`,`require` 离线复核通过
|
||||
|
||||
## Test Plan
|
||||
|
||||
+5
-5
@@ -3,7 +3,7 @@
|
||||
"name": "approve-success-state-unchanged",
|
||||
"title": "审批通过返回成功但任务状态未变的并发异常调查",
|
||||
"description": "verify-candidate 34675e1a/750a184b 在4 worker负载下采购主链路3轮挂2次:经理approve返回200,随后任务详情仍pending且历史无approve;单跑每次通过。需保留数据库负载复现查库,确认是否为新引入并影响全部审批。",
|
||||
"status": "planning",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "pwa-service-worker",
|
||||
"package": null,
|
||||
@@ -11,11 +11,11 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-09-26",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-09-27",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": null,
|
||||
"commit": "0931b1ea",
|
||||
"pr_url": null,
|
||||
"subtasks": [],
|
||||
"children": [],
|
||||
@@ -25,8 +25,8 @@
|
||||
"server/tests/unit/utils/client-pwa-api-cache.test.js",
|
||||
"client/src/pwa.ts"
|
||||
],
|
||||
"notes": "",
|
||||
"notes": "2026-09-27 完成:SW app-api-runtime 去掉 3s networkTimeoutSeconds(0931b1ea),负载复现修复前 3 轮命中 2 轮、修复后 0;verify-candidate 70af0c6b PASS 并已部署生产(buildSha 70af0c6b9aa3,线上 sw.js 已无超时)。用户授权 Claude 决定收口方式,据此归档。",
|
||||
"meta": {
|
||||
"implementationApproval": "APPROVED_BY_USER_20260926"
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -1,5 +1,9 @@
|
||||
# 报销详情修复部署与公网验证
|
||||
|
||||
## 2026-10-11 收口归档
|
||||
|
||||
本子任务停留在规划阶段,原冻结、审批与部署步骤未在本任务下执行。修复 `46bfa7e0`/`174cb7ac` 及非参与人只读投影 `e8d6766` 已包含于候选 `59dc5f6`,后续“费用政策与票据门禁部署”任务记载其为当时生产运行版本,即由该发布覆盖;现均包含于当前生产 `4a5cd8f2`。原规划记录保留。原未勾选清单为当时规划记录,保留原样、不补勾。经用户 2026-10-11 明确授权归档。
|
||||
|
||||
## Goal
|
||||
|
||||
在 Task A 与非参与人只读投影修复都完成后,冻结新的已发布候选,执行受控生产部署、显式迁移状态校验、角色化公网检查和固定回滚验证。
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"name": "reimbursement-detail-material-preview-deploy",
|
||||
"title": "报销详情修复部署与公网验证",
|
||||
"description": "在报销详情两轮权限修复完成后,以新的已发布候选执行受控部署、迁移状态校验、固定回滚和公网角色验证。",
|
||||
"status": "planning",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "production deployment preflight; migration status; public role and material-preview verification; fixed rollback",
|
||||
"package": null,
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-08-28",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
@@ -23,4 +23,4 @@
|
||||
"relatedFiles": [],
|
||||
"notes": "旧候选 8c28e15 因后续文档提交导致 HEAD 漂移而失效。以本次 PRD 修订提交完成后的最终干净 HEAD 冻结新候选,并在外部审批记录中写死 SHA;冻结后禁止任何仓库变化。push 与生产部署是两个独立授权门,当前均未批准。",
|
||||
"meta": {}
|
||||
}
|
||||
}
|
||||
+4
@@ -1,5 +1,9 @@
|
||||
# 报销详情权限与材料预览缺陷修复
|
||||
|
||||
## 2026-10-11 收口归档
|
||||
|
||||
撤回展示与 EXIF 尺寸修复 `46bfa7e0`(回填 `174cb7ac`)随候选 `59dc5f6` 上线,现包含于当前生产 `4a5cd8f2`;部署子任务由该发布覆盖。`BX-20260828-0017` 首图未显示在只读复现中未重现,按原记录保留。原未勾选清单为当时规划记录,保留原样、不补勾。经用户 2026-10-11 明确授权归档。
|
||||
|
||||
## Goal
|
||||
|
||||
修复报销只读查看者误看到“撤回报销”操作,以及带 EXIF 方向信息的图片进入材料合并预览后页面尺寸错误的问题;同时对 `BX-20260828-0017` 的首张图片未正常显示现象做受控、脱敏、只读诊断,让财务只看到职责内动作,并让图片材料在合并 PDF 中保持正确方向和比例。
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"name": "reimbursement-detail-material-preview-fixes",
|
||||
"title": "报销详情权限与材料预览缺陷修复",
|
||||
"description": "修复财务只读查看报销时误显示撤回操作、EXIF 图片材料合并尺寸错误,并对 BX-20260828-0017 首图异常做脱敏只读诊断。",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "client reimbursement action projection; server material PDF image normalization; production read-only preview diagnostics",
|
||||
"package": null,
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-08-28",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
@@ -26,4 +26,4 @@
|
||||
"relatedFiles": [],
|
||||
"notes": "任务范围内聚焦验证通过。完整 r102 为 5/6,唯一失败是既有用例仍查找已不存在的‘编辑’按钮;本任务新增的管理员撤回不可见断言通过,不把该历史失败静默视为绿色基线。",
|
||||
"meta": {}
|
||||
}
|
||||
}
|
||||
+6
@@ -1,5 +1,11 @@
|
||||
# 实施清单:报销费用口径与票据明细门禁
|
||||
|
||||
## 2026-10-11 余项移交结果(当前接续点)
|
||||
|
||||
已将报销真实 OCR 与财务科目映射移到 [09-08 接收合同](../../../09-08-reimbursement-payment-closeout/prd.md#2026-10-11-接收余项报销真实-ocr-验收与财务科目映射),执行接续见接收任务 implement 顶部。保留指定样票 `SAMPLE-PDF-INVOICE-FIRST` 与 `artifacts/qa-flow/20260909-release-e5685f1/` 原证据;2026-09-10 的 `PASS_DRAFT_ONLY` 仍有效于原合成草稿阶段,不扩为提交/审批或逐字段精度通过。科目映射未回填,财务负责人责任和原目标日期继续记录在 RC-ACCOUNT。
|
||||
|
||||
本轮只移交文档,未调用腾讯、未写生产、未重跑业务或补勾历史清单;原独立复核余额仍在接收任务开放。父任务及部署子任务归档待明确授权,当前未归档、未提交。
|
||||
|
||||
## 当前接续点:已部署,公网草稿闭环验证完成
|
||||
|
||||
### 2026-09-10 公网草稿最终 PASS(本节替代前次样票阻塞状态)
|
||||
+8
@@ -1,5 +1,13 @@
|
||||
# 报销费用口径与票据明细门禁
|
||||
|
||||
## 2026-10-11 余项移交(待归档授权)
|
||||
|
||||
本地 Git 检查确认实现 `6e999d5`、后续发票优先版本 `e5685f1` 均已包含于用户报告的生产 `4a5cd8f2`。本轮未连接生产;下方“未部署”等是原阶段记录,原未勾选项不补勾,不把包含关系当作全部验收通过。
|
||||
|
||||
报销发票真实 OCR 的跟进入口移到 [报销付款收尾 PRD](../../../09-08-reimbursement-payment-closeout/prd.md#2026-10-11-接收余项报销真实-ocr-验收与财务科目映射) 的 RC-OCR-1–4,财务科目映射移到同节 RC-ACCOUNT。责任、原样票别名、既有证据、退出条件和云/生产授权边界均保留;借款回单 OCR 不能代替报销发票验收。原独立复核未完成记录由接收任务既有复核余项继续跟进,不因移交判为通过。
|
||||
|
||||
原 implement 顶部已记录 2026-09-10 真实腾讯线上合成样票到草稿的 PASS,不能继续描述为“合成样票从未真实识别”;尚未具备同次真实腾讯到提交/审批及约定字段精度核对证据。移交后本任务可进入归档审批,当前仍 `in_progress`,未归档、未提交。
|
||||
|
||||
## Goal
|
||||
|
||||
### 当前交付口径(2026-09-09,最终自检收口)
|
||||
+4
-4
@@ -3,7 +3,7 @@
|
||||
"name": "reimbursement-expense-policy-invoice-guard",
|
||||
"title": "报销费用口径与票据明细门禁",
|
||||
"description": "统一企业报销费用类型与材料政策,并以默认关闭的双闸门逐步启用票据—明细强关联和申报金额门禁。",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "expense type policy/schema/master data; reimbursement item invoice relation; staged submit guard",
|
||||
"package": "server,client,docs",
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-08-29",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
@@ -38,6 +38,6 @@
|
||||
"docs/报销发票附件规则.md",
|
||||
"docs/需求-报销发票OCR规约.md"
|
||||
],
|
||||
"notes": "本地实施和只读专项复核已完成;B2 env/DB 双闸仍默认关闭,未部署、未应用生产 migration、未写生产配置。2,000 元/条明细的选类提示阈值已批准。会计科目映射由财务负责人在 B1 生产启用前提供,目标回填日期 2026-09-05;未取得正式科目表时保持 null,不由开发人员猜测。生产只读审计确认 0014/0016/0017/0018 均需退回修正;顺序改为先部署 B1、隔离验证并启用 B2,再由真实财务统一退回。B2 不校验日期粒度,0014 必须按 5 个发票日期拆分并由财务人工复核。部署合同见子任务 08-30-reimbursement-expense-policy-invoice-guard-deploy。B3 财务一页式及行内费用标准提示恢复仍为后续任务。",
|
||||
"notes": "2026-10-11 报销真实OCR余项与财务科目映射已移交09-08-reimbursement-payment-closeout的RC-OCR-1–4/RC-ACCOUNT;责任、证据及原未勾选项保留,独立复核由接收任务既有余项跟进。6e999d5/e5685f1本地祖先检查确认包含于用户报告的生产4a5cd8f2,本轮未查生产。已具备原合成草稿阶段PASS,不扩成审批或精度通过;待归档授权,未提交。以下为历史阶段说明:\n本地实施和只读专项复核已完成;B2 env/DB 双闸仍默认关闭,未部署、未应用生产 migration、未写生产配置。2,000 元/条明细的选类提示阈值已批准。会计科目映射由财务负责人在 B1 生产启用前提供,目标回填日期 2026-09-05;未取得正式科目表时保持 null,不由开发人员猜测。生产只读审计确认 0014/0016/0017/0018 均需退回修正;顺序改为先部署 B1、隔离验证并启用 B2,再由真实财务统一退回。B2 不校验日期粒度,0014 必须按 5 个发票日期拆分并由财务人工复核。部署合同见子任务 08-30-reimbursement-expense-policy-invoice-guard-deploy。B3 财务一页式及行内费用标准提示恢复仍为后续任务。",
|
||||
"meta": {}
|
||||
}
|
||||
}
|
||||
+4
@@ -1,5 +1,9 @@
|
||||
# 取消报销资产事前批准强制
|
||||
|
||||
## 2026-10-11 收口归档
|
||||
|
||||
取消资产事前批准强制 `36c86f1d`(回填 `0f3ecfab`)已上线,包含于当前生产 `4a5cd8f2`。原“上线后再退回 0017”的前提已满足:据用户 2026-09-27 确认,0014/0016/0017/0018 批次已重新提交并经财务审批通过。父任务“费用政策与票据门禁”仍保持开放,不随本子任务归档。原未勾选清单为当时规划记录,保留原样、不补勾。经用户 2026-10-11 明确授权归档。
|
||||
|
||||
## Goal
|
||||
|
||||
纠正 B1 把不存在的公司制度做成系统强制的问题:公司当前不要求办公家具、通用设备或办公电子设备采购事前审批,报销系统不得要求员工填写“事前批准依据”才能保存或提交。保留已上线的兼容字段与历史数据,不做 migration;把 assets 类型的员工说明改为资产登记导向,要求在明细说明中写清物品、使用人或责任人、存放位置。
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"name": "reimbursement-assets-prior-approval-correction",
|
||||
"title": "取消报销资产事前批准强制",
|
||||
"description": "纠正不存在的 assets 事前审批制度:取消报销明细强制批准依据,隐藏无用途 UI,保留兼容字段与历史数据,并把资产类型说明改为登记导向。",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "assets reimbursement validation; PC/mobile item editing; expense-type seed descriptions; reimbursement product/spec contracts",
|
||||
"package": null,
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-08-30",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
@@ -23,4 +23,4 @@
|
||||
"relatedFiles": [],
|
||||
"notes": "生产 0f9f403 已上线 B1/B2;0016 非 assets 可并行作为真人 canary,0017 为家具采购,必须等待本纠偏上线后再退回。无 migration、无 flag 或生产账号写入。",
|
||||
"meta": {}
|
||||
}
|
||||
}
|
||||
+6
@@ -1,5 +1,11 @@
|
||||
# 实施清单:报销费用政策与票据门禁生产部署
|
||||
|
||||
## 2026-10-11 文档接续:余项已移交,未执行旧部署清单
|
||||
|
||||
报销真实 OCR 与财务科目映射已登记至 [09-08 接收合同](../../../09-08-reimbursement-payment-closeout/prd.md#2026-10-11-接收余项报销真实-ocr-验收与财务科目映射),由其 implement 顶部继续安排。父任务 2026-09-10 已有真实腾讯线上合成草稿证据,提交/审批、约定字段核对与科目回填仍开放;原独立复核和真实业务义务不因移交关闭。
|
||||
|
||||
本任务原部署步骤未逐项留有执行证据,保留全部未勾选清单,不用后续部署替它补勾。后续发版须按当时最终候选重新核迁移、运行版本、备份/回滚及授权,不执行下方过期参数。本轮仅本地文档移交,归档、提交待明确授权。
|
||||
|
||||
## 1. 规划与冻结
|
||||
|
||||
- [ ] PRD、design、implement 经用户审查并明确批准进入实施。
|
||||
+8
@@ -1,5 +1,13 @@
|
||||
# 报销费用政策与票据门禁生产部署
|
||||
|
||||
## 2026-10-11 余项移交与旧部署合同边界(待归档授权)
|
||||
|
||||
父任务实现 `6e999d5` 与后续发票优先版本 `e5685f1` 已由后续发布带入用户报告的生产 `4a5cd8f2`,本轮以本地 Git 祖先关系核对,未连接生产。原 B1/B2 分阶段冻结、测试身份准备、灰度/全局启用及单据退回清单保留当时合同;本任务没有逐项执行记录,不能因为后续版本包含而补勾或声称这些步骤都在本任务完成。资产纠偏已由原子任务归档记录单独收口,不回退到旧“资产事前批准硬门禁”重做。
|
||||
|
||||
当前报销发票真实 OCR 及财务科目映射统一移到 [09-08 接收合同](../../../09-08-reimbursement-payment-closeout/prd.md#2026-10-11-接收余项报销真实-ocr-验收与财务科目映射) 的 RC-OCR-1–4 与 RC-ACCOUNT,含原证据、财务/执行端责任及验收边界;未完成责任不取消,不放入借款回单 OCR。原未满足的真实业务、发布/独立证据义务仍按接收任务现有工作线跟进,不由移交判为通过。
|
||||
|
||||
本轮未执行任何生产部署或配置/业务写入;下方固定回滚版本与迁移预期属于旧发布时点,不是下次发版的执行参数。移交后本子任务可进入归档审批,仍 `in_progress`,归档及提交待明确授权。
|
||||
|
||||
## Goal
|
||||
|
||||
把已完成并复核的报销费用政策与票据门禁安全发布到生产:先以 B2 有效关闭的状态完成 B1 migration、主数据和 owner 基线验收,再在隔离部门内验证 B2,最后全局启用并让财务统一退回 4 张真实审批中单据。全过程不得拿真人单据做灰度试验,不得因应用回滚误删 migration 或已建立的票据—明细关系。
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"name": "reimbursement-expense-policy-invoice-guard-deploy",
|
||||
"title": "报销费用政策与票据门禁生产部署",
|
||||
"description": "受控部署 B1 migration 与费用主数据,在隔离部门验证 B2 后全局启用,并统一处置四张审批中报销。",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "production deployment, migration, feature flag rollout, smoke identities, reimbursement remediation",
|
||||
"package": "deploy,server,client,trellis",
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-08-30",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
@@ -28,6 +28,6 @@
|
||||
"server/src/services/featureFlags/index.js",
|
||||
"server/src/routes/reimbursements.js"
|
||||
],
|
||||
"notes": "规划阶段;不执行未单独授权的 push、生产账号/部门/合成数据写入、migration、部署、env 配置、feature flag 更新或真实单据退回。固定应用回滚基线为 59dc5f6。B2 不校验日期粒度,0014 必须依赖退回说明和财务人工复核。employee/manager/finance smoke 终态常驻‘系统测试专用(勿分配员工)’部门;每次灰度前成员集合必须恰好为三个 smoke。finance smoke 含付款能力,仅在获批验收窗口临时 active,窗口外 disabled。普通 employee 无直属 manager 时 workflow 会以 no_manager_found 阻断。B2 DB 记录必须显式存在为 force_off,灰度必须记录 actor 级精确 reason。",
|
||||
"notes": "2026-10-11 报销真实OCR余项及财务科目映射移交09-08-reimbursement-payment-closeout的RC-OCR-1–4/RC-ACCOUNT;原部署清单无逐项执行证据,未补勾。后续发布已包含父任务实现,不虚报按本任务旧冻结/灰度步骤执行。旧回滚/迁移参数不用于下次发版。待归档授权,未提交、未查生产。以下为历史阶段说明:\n规划阶段;不执行未单独授权的 push、生产账号/部门/合成数据写入、migration、部署、env 配置、feature flag 更新或真实单据退回。固定应用回滚基线为 59dc5f6。B2 不校验日期粒度,0014 必须依赖退回说明和财务人工复核。employee/manager/finance smoke 终态常驻‘系统测试专用(勿分配员工)’部门;每次灰度前成员集合必须恰好为三个 smoke。finance smoke 含付款能力,仅在获批验收窗口临时 active,窗口外 disabled。普通 employee 无直属 manager 时 workflow 会以 no_manager_found 阻断。B2 DB 记录必须显式存在为 force_off,灰度必须记录 actor 级精确 reason。",
|
||||
"meta": {}
|
||||
}
|
||||
+4
@@ -1,5 +1,9 @@
|
||||
# B-2a 报销审批内容工作台
|
||||
|
||||
## 2026-10-11 收口归档
|
||||
|
||||
B-2a 实现 `c840574d`(元数据 `6bca91a3`)已上线,并由后续 B-2b 统一工作台承接;已包含于当前生产 `4a5cd8f2`。真人验收随父任务 AC11 收口。原未勾选清单为当时规划记录,保留原样、不补勾。经用户 2026-10-11 明确授权归档。
|
||||
|
||||
## Goal
|
||||
|
||||
先把主管和财务每天真实使用的报销审批页改成可独立完成核验与决策的一页式工作台,并产出后续填写态必须采用的共享“明细 + 票据”组件合同。
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"name": "reimbursement-approval-content-workbench",
|
||||
"title": "B-2a 报销审批内容工作台",
|
||||
"description": "在 PC/移动审批详情中直接展示报销明细、所属票据、附件与快照/实时核验,并建立共享内容组件。",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "client,server,spec",
|
||||
"package": null,
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-09-01",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
@@ -23,4 +23,4 @@
|
||||
"relatedFiles": [],
|
||||
"notes": "父任务第一阶段;独立交付、独立部署。已确认 PC 右侧单一动作面板、主列靠后展示完整历史;报销审批必须联网且证据不得进入离线缓存。",
|
||||
"meta": {}
|
||||
}
|
||||
}
|
||||
+4
@@ -1,5 +1,9 @@
|
||||
# B-2b 统一报销工作台迁移
|
||||
|
||||
## 2026-10-11 收口归档
|
||||
|
||||
B-2b 实现 `abdd2503`、布局优化 `4b974fd8`(元数据 `dda625b1`)已上线;已包含于当前生产 `4a5cd8f2`。真人验收随父任务 AC11 收口。原未勾选清单为当时规划记录,保留原样、不补勾。经用户 2026-10-11 明确授权归档。
|
||||
|
||||
## Goal
|
||||
|
||||
把报销从“填写详情页、审批详情页、旧只读详情页分别组织同一业务对象”收敛为唯一的交互式报销工作台。工作台以报销内容为主体,通过 `edit`、`readonly`、`approval` 三个模式适配器注入数据、状态和能力;审批只是叠加在报销对象上的流程与决策能力,不再复制一套报销页面壳。
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"name": "reimbursement-form-shared-component-migration",
|
||||
"title": "B-2b 统一报销工作台迁移",
|
||||
"description": "把 PC/移动报销编辑、只读、审批收敛为一个工作台壳和三个能力适配器,并删除通用审批页的报销旧分支。",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "client,workflow,spec",
|
||||
"package": null,
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-09-01",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
@@ -23,4 +23,4 @@
|
||||
"relatedFiles": [],
|
||||
"notes": "父任务第二阶段;方案 A 的统一报销工作台已以候选 9fc3b76 部署,生产 build marker 为 9fc3b764382d。上线真人目视反馈触发 KISS 收尾:PC 明细表格、移动明细卡片、票据/附件独立分组、单一文件查看入口和退回动作内渐进引用已完成,实现提交为 4b974fd;typecheck/build、UI strict/self-test、R102/R111/workflow/视觉聚焦回归及治理通过,等待最终复核,尚未 push、部署或触碰真人单据。",
|
||||
"meta": {}
|
||||
}
|
||||
}
|
||||
+7
@@ -1,3 +1,10 @@
|
||||
## 2026-09-27 AC11 真人重提与财务复审(当前)
|
||||
|
||||
- 用户 2026-09-27 口头确认:此前退回的报销单(0014/0016/0017/0018 批次)已由员工重新提交,并经财务审批通过;未反馈新的体验或数据问题。
|
||||
- 证据来源为用户确认;Claude 未读取生产数据(生产读取被权限分类器拦截),未逐项核对员工提示、正文一致性、明细合计、PC 历史位置与进度/历史理解。若需逐项核对,需另行授权只读查询或由财务补充反馈。
|
||||
- 附带核查:SW `app-api-runtime` 缓存的 `/api/workflow/tasks/:id` 对报销只含摘要(单号/状态/合计/日期/事由/申请人/提交人)与历史,不含明细、票据、附件或材料参数;完整明细走 `/api/reimbursements/:id`,不在 SW 规则内,符合 R8「离线只显示摘要/历史」。
|
||||
- 归档建议:父任务及 B-2a/B-2b/只读一致性子任务的实施均已上线,AC11 以用户确认计为完成;待用户确认是否据此收口归档。
|
||||
|
||||
# Implementation Plan:报销审批一页式工作台
|
||||
|
||||
## Delivery Map
|
||||
+4
@@ -1,5 +1,9 @@
|
||||
# 报销审批一页式工作台
|
||||
|
||||
## 2026-10-11 收口归档
|
||||
|
||||
三个子任务实现均已上线(见各子任务收口记录)。AC11 真人重提与财务复审以用户 2026-09-27 口头确认计为完成(记录于 `9cbefdf2`);Claude 未读取生产数据逐项核对。原未勾选清单为当时规划记录,保留原样、不补勾。经用户 2026-10-11 明确授权归档。
|
||||
|
||||
## Goal
|
||||
|
||||
让主管和财务在同一审批页面内完成“看报销内容—核明细与票据—识别风险—填写意见—作出审批决定”,不再把“查看报销单”外链作为取得核心报销内容的必经入口;同时建立可复用的“报销明细 + 所属票据”业务内容组件,并承诺在后续填写态迁移后消除历史布局分叉。
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"name": "reimbursement-one-page-approval-workbench",
|
||||
"title": "报销审批一页式工作台",
|
||||
"description": "拆分交付报销审批一页式内容工作台与填写态共享组件迁移,统一明细、票据和核验信息结构。",
|
||||
"status": "planning",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "trellis,client,server,spec",
|
||||
"package": null,
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-09-01",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
@@ -27,4 +27,4 @@
|
||||
"relatedFiles": [],
|
||||
"notes": "采用 B 路线:B-2a 先审批、B-2b 后迁移填写态;父任务仅在旧重复布局收口后完成。审批页回归既有右侧单一动作面板规则;移动报销审批要求联网且证据不进入离线缓存。规划阶段不编码、不部署、不处理真人单据。",
|
||||
"meta": {}
|
||||
}
|
||||
}
|
||||
+4
@@ -1,5 +1,9 @@
|
||||
# 报销只读内容一致性与审批上下文收敛
|
||||
|
||||
## 2026-10-11 收口归档
|
||||
|
||||
实现 `e48514d5`(回填 `d63ccdf7`)已上线;已包含于当前生产 `4a5cd8f2`。真人验收随父任务 AC11 收口。原未勾选清单为当时规划记录,保留原样、不补勾。经用户 2026-10-11 明确授权归档。
|
||||
|
||||
## Goal
|
||||
|
||||
让同一张报销单在 PC/移动、编辑/只读/审批和不同授权用户眼中保持同一份报销正文语义,同时把审批动作、审批历史和员工处理进度明确留在各自上下文中。补齐费用明细后的权威合计,避免审批人依赖页头回看或自行心算;在不复制内容、不引入第二业务金额来源的前提下保持 KISS。
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"name": "reimbursement-readonly-content-consistency",
|
||||
"title": "报销只读内容一致性与审批上下文收敛",
|
||||
"description": "统一报销工作台三模式的报销正文口径,补齐权威明细合计,并收敛 PC 审批历史与右侧决策上下文。",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "trellis,client,docs",
|
||||
"package": null,
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-09-02",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
@@ -23,4 +23,4 @@
|
||||
"relatedFiles": [],
|
||||
"notes": "本地实施与专项验证完成,等待 diff 复核;权威合计、两类完整性 fail-closed、PC 历史右置和进度/历史职责合同已落地。未 commit、push、部署;AC11 仍待部署后真人单据验证。",
|
||||
"meta": {}
|
||||
}
|
||||
}
|
||||
+20
@@ -1,3 +1,23 @@
|
||||
## 2026-10-11 归档执行完成(用户已批准,未提交)
|
||||
|
||||
用户核对三项页面反馈、实现提交的生产包含关系及独立余项归属后,明确回复“可以归档”。本次仅收口本任务,保留原验收清单,不修改业务代码或关闭其他任务,不提交、推送或部署。
|
||||
|
||||
已使用官方 `task.py archive`,显式 `--no-commit` 禁止自动提交,命令退出 0。该任务直接在 `main` 实施,登记分支与 `base_branch` 同为 `main`,采用工具支持的 `--skip-branch-validation` 归档已有发布的非 PR 任务;没有重复执行一次已知会拒绝的默认命令。6 个文件完整移入 `.trellis/tasks/archive/2026-10/09-04-reimbursement-state-gap-finance-view/`,原目录已不存在;移前移后除 `task.json` 状态更新外摘要一致,随后只补本节和 PRD 的实际归档结果。状态 `completed`、完成日期 `2026-10-11`,活动任务目录从 14 个减为 13 个,当前会话指针已由官方命令清除。
|
||||
|
||||
官方 JSON 写入会再次移除末尾换行,已在归档后的 `task.json` 补回并核实;保留历史 notes 原文。所有 Git 改动仅属本任务记录,尚未暂存或提交,未推送或部署。
|
||||
|
||||
下节是授权前的收口核对时点记录;其中“未归档”“待批准”等表述由本节接续。
|
||||
|
||||
## 2026-10-11 线上反馈收口记录(授权前核对时点)
|
||||
|
||||
本轮接续 B 组本任务的收口核对。开始时工作区干净、HEAD 为 `b85ff6a9`;已通过官方 `task.py start` 切换当前任务并回读,自动登记执行分支 `main`。只更新本任务记录,不改业务代码、数据库或生产配置,不执行归档、提交、推送或部署。
|
||||
|
||||
- 用户确认待组批可找到、他人从未提交草稿不可见、原权限范围内的退回/撤回草稿仍可见;按原回复记录,不补充设备或未明确确认的重复候选结论。
|
||||
- 本地 Git 的祖先关系证明 `f9aee4c9`、`229867f5` 已包含在已确认生产基线 `4a5cd8f2`。基线之后的五个产品文件均属公司借款,不改变本任务的报销实现;这只是本地 Git 核对,不是重新连接生产或实时版本检查。
|
||||
- `0014` 已有后续组批、复核、导出制单记录,不再把旧 AC1/AC11 的“在待组批搜索到 0014”当作当前要求。采用符合条件的现有报销来理解本次用户反馈,不新建生产合成单据、不重复组批。
|
||||
- 本轮只补用户反馈和任务记录,文档/流程检查独立执行;既有业务测试、部署及独立复核证据沿各阶段原记录,不虚报重跑。原未勾清单和历史时点的 PENDING/未部署表述保留,不能据此将整份原清单勾成新一轮通过。
|
||||
- 收口建议:本任务可以进入归档审批,关联真实业务交接和环境验收继续由原任务跟进,不因本次反馈关闭。归档与提交尚须用户明确批准;批准归档后使用官方命令并禁用自动提交。任务在获批前保持 `in_progress`,未移动目录。
|
||||
|
||||
## 2026-09-17 本批最终本地验证
|
||||
|
||||
付款待办已显示当前可复核/办理姓名、站内提醒对象及企微个人发送事实。`paymentResponsibility`9/9,最终借款桌面/手机正式登录浏览器同样验证姓名;多通知接收人的单anchor成功不冒称全部送达。真实批次未查询,不能给出其真实待办姓名或宣称个人消息送达。财务原地进度15/15与排序回归保留;借款及ERP改动后的付款128/128、最终前端typecheck/build通过。F4接续已执行;独立复核PENDING、未部署。保护回执与本批候选见借款implement当前入口。
|
||||
+8
@@ -1,5 +1,13 @@
|
||||
# 报销状态空隙与财务处理视角
|
||||
|
||||
## 2026-10-11 收口归档(用户已批准,未提交)
|
||||
|
||||
用户针对财务线上使用情况回复“1可以找到 2看不到 3能看见”:符合条件的报销可在待组批找到;全范围看不到他人从未提交的私人草稿;原权限范围内的退回或撤回草稿仍可见。设备未注明,不将本次反馈写成电脑、手机双端验收。第一项仅记录“可以找到”,不追加“已有批次不重复”的现场确认,后者仍以既有软件测试为据。
|
||||
|
||||
本地 Git 已核实本任务登记的实现提交 `f9aee4c9`、本人报销发布 `229867f5` 均包含在已确认的生产基线 `4a5cd8f2` 中;本轮未连接生产。原 AC1/AC11 要求 `0014` 位于待组批是历史时点,既有记录表明它后来已组批、复核并导出制单,现在不要求它再次成为候选,也不回放真实业务来满足旧清单。
|
||||
|
||||
三项主要页面行为已有本次用户反馈支持。用户核对记录后明确回复“可以归档”,授权收口本任务;官方归档命令已成功,任务状态为 `completed`、完成日期为 `2026-10-11`,目录位于 `archive/2026-10/`。原勾选清单和历史证据保留,不补勾为全量重新验收;真实银行导入、付款交接、通知送达及恢复验收不由本次页面反馈替代,继续沿各自原任务跟进。本次授权仅归档,不含提交、推送或部署,具体收尾见 implement 顶部。
|
||||
|
||||
## 2026-09-17 真人反馈:审批后进度刷新与付款明细顺序
|
||||
|
||||
用户要求修复财务复核通过后当前页进度仍旧、同批多报销明细未按单号排序。沿本task既有详情一致性范围本地实施,先于借款与精简;不读取真人单据、不重放真实审批。
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"name": "reimbursement-state-gap-finance-view",
|
||||
"title": "报销状态空隙与财务处理视角",
|
||||
"description": "修复报销状态空隙、草稿读取、退回留痕删除及付款详情一致性;追加已批准的财务本人报销CEO一次审批,保留付款独立复核与生产写入边界。",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "server,client,tests,spec",
|
||||
"package": "hyb-oa",
|
||||
@@ -11,8 +11,8 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-09-04",
|
||||
"completedAt": null,
|
||||
"branch": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": "main",
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
"commit": "f9aee4c93272204d18408217358d95334cedcd5e",
|
||||
+1
@@ -2,6 +2,7 @@
|
||||
|
||||
## 当前状态
|
||||
|
||||
- 2026-10-11:已完成范围收口,后续阶段取消(未获批、未执行,不计通过);详见 prd 顶部收口记录。登录后线上冒烟与环境合同由发布门禁任务跟进。以下为历史状态。
|
||||
- in_progress / inline。创建轮使用 task.py create --no-start;用户随后明确批准阶段 0,已 task start 切换到本任务,不授予阶段 1 批量修改权限。
|
||||
- 门禁任务获准 21 文件逐字节未动;HEAD=66f25b1,本地 origin/main=492920c。新任务独立、非子任务,未转移合同阶段 B 的业务验收责任。
|
||||
- 创建轮只读已有 single trace;随后在阶段 0 授权内实际执行一次原合同用例的观测实验,结果 timedOut,未改真实源码。新现场条件与旧 trace 严格分开,见 design.md §1/§3.1。
|
||||
+12
@@ -1,5 +1,17 @@
|
||||
# E2E 认证前置统一
|
||||
|
||||
## 2026-10-11 收口记录(已完成范围收口,后续阶段取消;待归档批准)
|
||||
|
||||
**已完成的范围**(任务记录提交 `096576d8`,证据在 `artifacts/qa-flow/e2e-auth-preconditions/`):
|
||||
- 立项与认证状态合同、范围边界:用户 2026-09-07 批准。
|
||||
- 阶段 0:一次本地定向启动条件取证(单条原合同用例、1 worker、零重试、trace=on,结果 timedOut,未改源码)及静态盘点;用户已独立复核批准,对应 AC1。证据 `phase0-20260907-01/02/03`。
|
||||
- 在线对照:一次相同原用例,确认原生 `navigator.onLine=true`,认证前置断言通过、下游“更多”超时,不记为整条通过;`online-20260907-01/closeout-receipt.json` valid=true。用户认可该结果并撤回默认迁移。
|
||||
|
||||
**取消的后续阶段**:阶段 1 的 31+2 文件迁移、状态合同回归、固定矩阵验证、剩余失败归类及独立复核,均从未获批、未执行,按“取消”记录,不补记为验收通过。AC2–AC6 保持未勾选;207 原浏览器清单撤销决策资格的结论不变,原件保留,不倒写为逐条已证明假失败。
|
||||
|
||||
**转由其他任务跟进,不随本任务关闭**:环境启动合同沿 `09-06-release-gate-integrity` 的 R2/R6 与设计 §10;登录后的线上冒烟由发布门禁任务的发布后公网必跑项跟进(凭据准备另见公司借款任务后续第 6 项)。场景 8、经理权限缺口与 R1 启用不在本任务范围,亦未因收口改变。
|
||||
|
||||
|
||||
## Goal
|
||||
|
||||
先确定合成浏览器验收的运行前提与认证起点,再决定修正环境合同还是认证夹具;不预设需要批量迁移 spec。覆盖登录、会话恢复和注销的真实边界,任务独立于 release-gate-integrity,不以修复全部浏览器红项或启用发布门禁作为完成条件。
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
"name": "e2e-auth-preconditions",
|
||||
"title": "E2E 认证前置统一",
|
||||
"description": "阶段 0 及在线对照已获用户复核认可;31+2 迁移暂缓。207 原浏览器清单撤销决策资格且原件保留;环境合同规划归 release-gate-integrity R2/R6 与设计 §10,本任务保留取证,不实施或重跑。",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dispatch_mode": "inline",
|
||||
"dev_type": "frontend",
|
||||
"scope": null,
|
||||
@@ -12,7 +12,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-09-07",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": "main",
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
+4
@@ -1,5 +1,9 @@
|
||||
# 修复 Trellis 任务切换与执行闭环
|
||||
|
||||
## 2026-10-11 收口归档
|
||||
|
||||
治理修复 `c4025083` 已提交并推送;纯治理与文档,不需要部署。原记录中“下一轮观察真实注入、独立复核未做”保留为历史事实,不补记为已复核。原未勾选清单为当时规划记录,保留原样、不补勾。经用户 2026-10-11 明确授权归档。
|
||||
|
||||
## Goal
|
||||
|
||||
依据已安装官方指南修复任务激活与实际执行脱节,保持 inline 和授权边界,不改运行时或业务代码
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
"name": "trellis-workflow-alignment",
|
||||
"title": "修复 Trellis 任务切换与执行闭环",
|
||||
"description": "依据已安装官方指南修复任务激活与实际执行脱节,保持 inline 和授权边界,不改运行时或业务代码",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "trellis-workflow",
|
||||
"package": null,
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-09-09",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": "main",
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
+4
@@ -1,5 +1,9 @@
|
||||
# ERP 专属遗留实现精简
|
||||
|
||||
## 2026-10-11 收口归档
|
||||
|
||||
ERP 专属实现移除随 `1f8d5b65` 上线(状态同步 `2769408b`),包含于当前生产 `4a5cd8f2`。原未勾选清单为当时规划记录,保留原样、不补勾。经用户 2026-10-11 明确授权归档。
|
||||
|
||||
## Goal
|
||||
|
||||
落实用户“用不到的功能、代码、测试要精简”的要求,沿当前产品不接 ERP 的决定移除专属实现,减少隐藏入口和无效回归。
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
"name": "erp-exclusive-retirement",
|
||||
"title": "ERP 专属遗留实现精简",
|
||||
"description": "按现行不接 ERP 的产品决定移除专属客户端、同步入口、后台作业与失效测试,保留通知、企微、通用 outbox 和历史数据;仅本地验证。",
|
||||
"status": "in_progress",
|
||||
"status": "completed",
|
||||
"dev_type": null,
|
||||
"scope": "erp-exclusive-code-retirement",
|
||||
"package": null,
|
||||
@@ -11,7 +11,7 @@
|
||||
"creator": "shunli",
|
||||
"assignee": "shunli",
|
||||
"createdAt": "2026-09-17",
|
||||
"completedAt": null,
|
||||
"completedAt": "2026-10-11",
|
||||
"branch": null,
|
||||
"base_branch": "main",
|
||||
"worktree_path": null,
|
||||
@@ -23,4 +23,4 @@
|
||||
"relatedFiles": [],
|
||||
"notes": "2026-09-17 本地退役实现完成:6个ERP service、1个job、14个专属测试删除,共享通知/企微/outbox与历史数据保留;新enqueue/dispatch及历史retry拒绝,旧pending不重放。受影响回归、typecheck/build、模块图与strict原因码通过,17条ERP旧债退出后legacy=0。独立复核PENDING,未部署。 2026-09-26 更新:本地实现已通过候选分支合并落地到 origin/main(合并提交 46a70aa5),不再是仅存在于未提交分支的工作;但真实样本验证/独立复核/生产切换等验收项仍开放,任务状态维持 in_progress,未视为完成。",
|
||||
"meta": {}
|
||||
}
|
||||
}
|
||||
某些文件未显示,因为此 diff 中更改的文件太多 显示更多
在新工单中引用
屏蔽一个用户