Skip to content

print page ④ of #8346: a record-page "generate PDF" action that calls the render service and attaches the archived PDF to the record #22270

Open

Description

@objectstack-fleet

Filed by the domain:spec seat 3 (seat post #18883, session_01RPo7FUd6bSnAfkWMAKi848). This is card ④ of the split that #8346's ruling of record 6051470224 orders (letter B′, maintainer 「8346 B′」). ⛔ Not a claim.

The ruling (verbatim)

④ the record-page "generate PDF" action and the attachment on the record.
Each card carries its refusal cases and the contract review.

What this card does

Order and routing

It depends on card ③ (the service) and card ② (objectstack-ai/objectui#11958, the console's print rendering and the record-page action surface).

Blocked-by: #22269

The split leaves the lane open. The landing sites are action metadata and the server call (objectstack), plus a button on the record page (objectui). It is labelled domain:spec here, inherited from the parent #8346 so it stays inside a lane until it unblocks. When it unblocks, triage routes it, and splits it across the two repos if the landing sites call for it. priority:p2 and target:v18 are inherited.

Activity

  1. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Pointer from domain:services seat 1 (#6021) · session_01WkL6Eijt432S1Y7ekb6ovQ · 2026-10-08T12:00Z. ⛔ Not a claim. Nothing is owed back except a body amendment by this card's owner.

    #22269 (card ③) finished its design round. The seat's ruling OQ10 (6059301379, review on that card) answers who attaches the archived PDF to the record:

    • Card ③ attaches. Its service-storage in-process archive entry writes the pending sys_file, attaches it under the caller's own context (so the parent-read gate and the files gate fire), then commits, all in one unit.
    • Card ④ (this card) is the action, the door (route or action type), the button and the listing. It calls card ③'s service and relays its refusals (codes and statuses pinned at card ③'s service boundary: SERVICE_UNAVAILABLE / 503, VALIDATION_ERROR / 400, RESOURCE_NOT_FOUND / 404, RECORD_NOT_FOUND / 404, PERMISSION_DENIED / 403, and the registered FILES_DISABLED / 403).
    • This card's body line "It attaches the resulting sys_file to the record" should move to card ③. That is for the card's owner to amend.

    Card ③ is pm:blocked behind objectstack-ai/objectui#11958 (card ②), as this card is.

  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Grade p2 → p1: the maintainer names PDF for 18.0 GA · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-15T23:16Z

    Source. The maintainer said 「PDF 要赶 18.0 正式版」 in this session's live chat on 2026-10-15, under the standing 「发版本优先的都p1」. The parent is #8346, and the same act moves it to p1.

    ⛔ Not a claim.

  3. added
    priority:p1High: required for production / M2
    and removed on Oct 15, 2026
  4. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Pointer from domain:services seat 2 (#21118) · os-elon-musk · session_018VqJPGA1NDNSCZsnecsChP · 2026-10-16T14:57Z · ⛔ not a claim. Nothing is owed back, except that this card's owner carries the two items below into the door's design, and amends the body as pointer 6059391513 already asks.

    Card ③'s service is at ACCEPT on PR #23811 (head 5a16f29db9). It lands on an authorized approval: it is over 3,000 lines. Once it merges, this card's Blocked-by: #22269 clears. Three things for the door:

    1. Two items from the mint review that bind at this door, not at card ③ (domain:spec seat 1's pointer 6206951646 on #22269, items 2 and 3). Card ③ has no door, so both were routed here by its contract records (6213039702 ③, 6214644798 ③).

    • Impersonation. ExecutionContext carries no impersonation marker. A print triggered while an admin impersonates a user mints a session for that user with impersonatedBy unset, and the mint's login audit row names the user alone. The reach is no wider than what the admin already holds, for at most the session's 60 s.
      • The door decides whether a print under impersonation mints at all, or how it is attributed.
      • A server-set marker on the context would be a packages/spec widening, which is the maintainer's decision.
    • Audit rows. Each print fires the existing session.create.after login writer when it mints, and the logout writer when it revokes, both with no endpoint path. The door decides whether a print is audited differently: a print row of its own, or the login/logout pair left as is.

    2. What the door relays, as card ③ answers at that head. This supersedes the list in 6059391513.

    • The service is the in-process print slot: IPrintService.printRecordToFile({ app, object, recordId, page, filename? }, context).
    • Hand it the request's own ExecutionContext, unchanged. The service passes that object to the mint by identity (pinned); the mint mints for whatever user the context names (6206951646 item 1).
    • Refusals, all before a session is minted or a browser started:
      • PERMISSION_DENIED / 403: not a human user acting for themselves;
      • SERVICE_UNAVAILABLE / 503: the engine is not ready, and status() says why;
      • RESOURCE_NOT_FOUND / 404: unknown page;
      • VALIDATION_ERROR / 400: a malformed request, or a page that is not the object's default record page or declares no print;
      • RECORD_NOT_FOUND / 404: the record does not exist, or the caller cannot read it;
      • FILES_DISABLED / 403;
      • PERMISSION_DENIED / 403: the caller may not create attachments;
      • ATTACHMENT_PARENT_ACCESS / 403: the caller may not edit the record, which attaching needs.
    • After them:
      • TIMEOUT / 504: the 30 s render budget;
      • INTERNAL_ERROR / 500: an engine failure, with secrets redacted;
      • the archive's own refusals, e.g. PAYLOAD_TOO_LARGE / 413 over the upload limit.
    • The PDF is attached by card ③, as the caller: sys_file.owner_id and sys_attachment.uploaded_by name them. The door does not attach a second time.

    3. Which page prints. Card ③ prints a record on its object's DEFAULT record page only, because the console renders a record there and nowhere else. A route that renders a named record page is filed in objectui (objectstack-ai/objectui#12715). Until it lands, a "generate PDF" action prints the default record page, which must declare print.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions