Skip to content

P2 Zapier: public app attachment uploads#702

Open
jaeyunha wants to merge 4 commits into
stagingfrom
issue-589-p2-zapier-public-zapier-app-with-t
Open

P2 Zapier: public app attachment uploads#702
jaeyunha wants to merge 4 commits into
stagingfrom
issue-589-p2-zapier-public-zapier-app-with-t

Conversation

@jaeyunha

Copy link
Copy Markdown
Member

Summary

  • complete Zapier create_attachment with comment attachment metadata plus presigned S3 upload contract
  • update Zapier app fields and docs for fileName/contentType/size upload flow
  • add focused coverage for the attachment upload contract

Verification

  • make check
  • npm test -- tests/zapier.test.ts tests/zapier-app.test.ts tests/zapier-routes.test.ts tests/zapier-attachment-action.test.ts
  • env -u NEXT_PUBLIC_APP_URL -u DATABASE_URL -u DB_USER -u DB_PASSWORD -u DB_HOST -u DB_PORT -u DB_NAME -u DB_SSL -u SENDER_EMAIL -u EMAIL_FROM -u SES_FROM_EMAIL make test

jaeyunha and others added 4 commits June 9, 2026 10:08
Add the Zapier manifest, auth test, trigger polling, action wrappers, webhook subscription registration, OAuth bearer validation, and setup docs for #589.

Constraint: Full reliable webhook delivery worker is not present in this branch, so this slice stores signed Zapier webhook subscriptions and documents the delivery handoff.

Tested: make check; npx vitest run tests/zapier.test.ts tests/zapier-routes.test.ts; npx vitest run tests/account-security-route.test.ts tests/workspace-invite-route.test.ts tests/team-cycles-cycleId-route.test.ts tests/project-templates-route.test.ts; npx vitest run tests/auth.test.ts; npx vitest run tests/security-settings-view.test.tsx; npx vitest run tests/agent-logic.test.tsx

Not-tested: make test times out under full-suite concurrency in unrelated suites that pass individually; make test-e2e is blocked by local Postgres password authentication failure for user postgres.

Confidence: medium

Co-authored-by: OmX <omx@oh-my-codex.dev>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99a49bda5c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/proxy.ts
"/api/workspaces",
"/api/test",
"/api/account",
"/api/zapier",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Expose the OAuth token endpoint to Zapier

The Zapier app exchanges the authorization code by POSTing to /api/oauth/token from Zapier's servers, which do not have a Better Auth session cookie. This change only makes /api/zapier public, so proxy() still redirects unauthenticated /api/oauth/token requests to /login before the token route runs; the OAuth connection flow will fail immediately after the user authorizes the app.

Useful? React with 👍 / 👎.

Comment thread src/lib/zapier.ts
Comment on lines +1052 to +1055
const teamRecord =
readString(body.teamId) || readString(body.teamKey)
? await findTeamForZapier(context.workspaceId, body)
: null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate the project team before creating the project

When create_project includes an invalid teamId or teamKey, the project row is inserted first and only then findTeamForZapier throws. Zapier receives an error, but the workspace is left with a newly created unlinked project, so a typo in the optional team field corrupts data instead of making the action atomic.

Useful? React with 👍 / 👎.

Comment thread src/lib/zapier.ts
Comment on lines +1194 to +1195
.orderBy(desc(issueHistory.createdAt))
.limit(limit * 3);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Filter status changes in the query

For the status_change trigger, the query fetches only the latest limit * 3 generic update history rows and filters for changedFields.includes("stateId") afterward. In workspaces with more than three times the requested limit of non-status updates after a status change, Zapier will never see those status changes even though they are newer than the cursor; the state-change predicate needs to be applied before limiting.

Useful? React with 👍 / 👎.

Comment thread apps/zapier/index.ts
Comment on lines +480 to +484
...commonIssueFields.filter((field) =>
typeof field === "string"
? field !== "teamKey" && field !== "teamId"
: field.key !== "teamKey" && field.key !== "teamId",
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep title optional for issue updates

The Update Issue action reuses commonIssueFields, whose title field is marked required, so Zapier will force users to supply a title even when they only want to change status, priority, assignee, or another field. The backend supports partial updates with any one editable field, but this public app definition makes those valid update scenarios unusable from Zapier.

Useful? React with 👍 / 👎.

@jaeyunha

Copy link
Copy Markdown
Member Author

Controller intake: blocked before QA/merge.

Current blocker:

  • PR is CONFLICTING against staging and has no GitHub checks reported.
  • The diff writes legacy top-level src/... and tests/... paths plus Next src/app/api/... business routes. Current staging is the split monorepo: web under apps/web/..., Go API under apps/api/..., OpenAPI/migrations under packages/proto/..., SDK under packages/sdk/....
  • Zapier public app triggers/actions and attachment upload contracts need to be rebuilt on the current Go API/OpenAPI/SDK boundary; business endpoints should not be added as Next API routes.

Required fix:

  1. Rebuild/rebase from current origin/staging.
  2. Port valid web/admin changes into apps/web/... and API/storage/Zapier contract changes into apps/api + packages/proto/SDK as needed.
  3. Preserve the P2 Zapier: public Zapier app with triggers and actions #589 spec-prep contract.
  4. Rerun focused Zapier/API/SDK/web gates plus make check/make test, or report the exact unrelated baseline blocker.

@jaeyunha

Copy link
Copy Markdown
Member Author

⚠️ Not mergeable as-is — wrong architecture (needs regeneration, not conflict resolution).

This PR's changed files are on the pre-monorepo-split src/ layout, which no longer exists — business logic sits in old Next.js src/app/api/* routes instead of the Go API (apps/api) + packages/proto/openapi.yaml + generated SDK. So the CONFLICTING state isn't a normal merge conflict; every file targets a path that's gone. This is the same problem that sank the earlier batch of integration PRs.

Conflict resolution can't fix this — it needs to be rebuilt on the current architecture from the spec in #589 against current staging. Leaving this open for now (not closing), but it should not be merged in its current form. Issue #589 stays open as the source of truth.

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