Skip to content

fix: resolve clearance graph importer from the declaration, not the caller - #39

Open
devin-ai-integration[bot] wants to merge 1 commit into
devin/nsw-parity-registrationsfrom
devin/regulatory-graph-importer-identity
Open

fix: resolve clearance graph importer from the declaration, not the caller#39
devin-ai-integration[bot] wants to merge 1 commit into
devin/nsw-parity-registrationsfrom
devin/regulatory-graph-importer-identity

Conversation

@devin-ai-integration

Copy link
Copy Markdown

Summary

regulatory.clearanceGraph previewed obligations for the caller, while the release gate evaluates them for the declaration's principal, so the two disagreed for anyone filing on behalf of someone else:

clearanceGraph            → importerId = ctx.user.id
permit matching           → where ogaPermits.consigneeId = importerId
assertDeclarationFormalitiesSatisfied → importerId = declaration.principalId ?? declaration.traderId

An agent filing for a principal, or an officer previewing a declaration, never matched the principal's permit, so the graph reported blocking obligations on a consignment that release would (correctly) let through.

The graph now resolves the identity the same way the gate does when a declarationId is supplied, and authorises the caller with the pattern allocateQuota already uses in the same file:

if (input.declarationId) {
  const [declaration] = await db.select()...;            // NOT_FOUND if absent
  if (role !== "admin" && role !== "customs_officer")
    await requireDeclarationActor(declaration, ctx.user);
  importerId = declaration.principalId ?? declaration.traderId;
}

Without a declarationId it stays a hypothetical preview keyed on the caller. No client-supplied importer identity was added — that would let any caller enumerate another party's permit position.

server/regulatory.graph-importer.test.ts pins the invariant against Postgres: principal, authorised agent and customs-officer previews all report the principal's permit as satisfying and agree with assertDeclarationFormalitiesSatisfied, and an unrelated third party gets FORBIDDEN.

Typecheck is at the repo's standing 72-diagnostic baseline with none in the changed files; the regulatory vitest files pass (10 tests). Based on devin/nsw-parity-registrations because #33#35 are still open and carry the regulatory layer.

Link to Devin session: https://app.devin.ai/sessions/e68f0a7bf0e04fb8a3ba32ddb8e1fa23
Requested by: @munisp

Co-Authored-By: Patrick Munis <pmunis@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Author
Original prompt from Patrick

Clone, review and analyze this https://github.com/munisp/singlewindow
Afterwhich, using Attach file analyze the codebase and implement the findings
ATTACHMENT:"https://app.devin.ai/attachments/80878dc3-af42-4287-9b79-2ab7bdfe3f03/codebase-defect-discovery-prompt.pdf"

@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant