drawings: VISUAL's rev is the source of truth; attach it when M-Files holds it Effective or Retired
ci / frontend (pull_request) Successful in 43s
ci / server (pull_request) Successful in 11m3s
ci / image (pull_request) Skipped
ci / e2e (pull_request) Successful in 3m52s

When M-Files' Effective rev differs from the rev VISUAL calls, the drawing
job looks that rev up (MFilesKit DrawingLookup.revision). If M-Files has
it as Effective or Retired, the job copies it into drawing_revisions and
attaches it to the draft with no flag and no Clerical approval, so the
draft can auto-release. Past draft, already attached or with a hand
drawing: unchanged, no flag and no change order.

Any other status, or no document at that rev, still flags rev_mismatch
with a note saying why. Packet Station only ever attaches Effective or
Retired drawings. rev_approve stays for that case only.

This replaces the "Use rev V as VISUAL calls it" choice from #46: the
use=called path in rev-approve and its button are removed. A packet that
already kept the rev that way keeps it, since that rev is now used anyway.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-19 16:05:57 -06:00
co-authored by Claude Opus 5.5
parent c5bf48ac50
commit ca407a2db3
16 changed files with 292 additions and 250 deletions
+1 -2
View File
@@ -68,8 +68,7 @@ export const packetsApi = {
databook: (id: number) => api.post<PacketRead>(`${base(id)}/databook`, {}),
/* Phase 3: VISUAL packets. */
revApprove: (id: number, body: { reason: string; use?: "latest" | "called" } & Guarded) =>
api.post<PacketRead>(`${base(id)}/rev-approve`, body),
revApprove: (id: number, body: { reason: string } & Guarded) => api.post<PacketRead>(`${base(id)}/rev-approve`, body),
handDrawing: (id: number, body: { asset_id: string; reason: string } & Guarded) =>
api.post<PacketRead>(`${base(id)}/hand/drawing`, body),
/** Multipart cannot carry JSON, so the signature rides as sign_factor and sign_secret. */
+7 -2
View File
@@ -905,11 +905,13 @@ export interface FoldedOp {
tgt?: number | string;
}
/** The rev VISUAL calls, as M-Files holds it at another status (Retired, say). Set by the drawing job on a draft flagged
* rev_mismatch. `missing` when M-Files has no document at that rev. */
/** The rev VISUAL calls, as M-Files holds it when that is not the Effective rev. Set by the drawing job. A copy (Effective
* or Retired) is attached automatically; `missing` when M-Files has no document at that rev, `refused` when its status
* may not be attached. */
export interface CalledRev {
rev: string;
missing?: boolean;
refused?: boolean;
controlled?: string;
state?: string | null;
name?: string | null;
@@ -923,6 +925,9 @@ export interface VisualInfo {
/** Set by the read model from drawing_lookups when M-Files has a staged copy. */
staged_rev?: { rev: number | string; name: string | null; asset_id?: string };
called?: CalledRev | null;
/** The M-Files copy attached by the drawing job. `controlled` is set when it is the rev VISUAL calls at a status other
* than Effective's newest (Retired, say). */
vault?: { asset_id: string; name?: string | null; rev: number | string; note?: string | null; at?: string; controlled?: string } | null;
partspecs?: string[];
folded?: FoldedOp[];
manual_dwg?: HandUpload;