Skip to content

feat: draft proposals#1910

Open
brunod-e wants to merge 22 commits into
devfrom
feat/draft-proposals
Open

feat: draft proposals#1910
brunod-e wants to merge 22 commits into
devfrom
feat/draft-proposals

Conversation

@brunod-e
Copy link
Copy Markdown
Collaborator

@railway-app
Copy link
Copy Markdown

railway-app Bot commented May 15, 2026

This PR was not deployed automatically as @brunod-e does not have access to the Railway project.

In order to get automatic PR deploys, please add @brunod-e to your workspace on Railway.

@brunod-e brunod-e self-assigned this May 15, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented May 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
anticapture Ready Ready Preview, Comment May 29, 2026 10:26am
anticapture-storybook Ready Ready Preview, Comment May 29, 2026 10:26am

Request Review

Copy link
Copy Markdown

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

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: 90434edf5b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/api/src/controllers/draft-proposals/index.ts
Comment thread apps/dashboard/features/create-proposal/components/ProposalCreationForm.tsx Outdated
Copy link
Copy Markdown
Collaborator

🔍 UI Review — Feat/draft proposals

Figma: Path C — file mUgy2KpQ3gJ07yZaUaXu8l consulted. Nav bar node 2454:21551 confirmed visually. Draft card node 2503:22598 returned invalid — reviewed against ClickUp spec 86agjwww8 text instead.
Preview: Auth-gated (403) — no bypass secret configured. Visual review limited to Figma + diff.


🟡 Findings

1. Share / Copy link buttons are not in the Figma spec [Figma-confirmed] [ClickUp-spec-confirmed]

Severity: Medium

  • Nav bar — Figma node 2454:21551 shows only Save Draft + Publish on the right side. No "Copy link" button exists in the design.
  • Draft card — ClickUp spec 86agjwww8 lists: "title · 'Draft' badge · relative date · Edit CTA · Delete CTA" — no Share button.

These are useful additions, but they currently have no design coverage. Please either update the Figma spec to include these states (enabled / disabled / mobile) or link the ClickUp task where this was approved, so the design system stays in sync.


2. Clipboard errors are silently swallowed [Code-only]

Severity: Medium — user always sees "Share link copied" even when the write fails.

In apps/dashboard/features/create-proposal/utils/draftShareUrl.ts:

export const copyDraftShareUrl = (basePath: string, draftId: string): void => {
  void navigator.clipboard.writeText(buildDraftShareUrl(basePath, draftId));
};

void discards the promise. If writeText rejects (privacy settings, non-HTTPS, background tab on mobile Safari), the toast fires as "success" regardless. The existing CopyAndPasteButton in shared/components/buttons/CopyAndPasteButton.tsx handles this correctly with try/catch + icon feedback and is worth reusing or using as a reference.

Suggested fix: return the promise and check it before toasting:

export const copyDraftShareUrl = async (basePath: string, draftId: string): Promise<boolean> => {
  try {
    await navigator.clipboard.writeText(buildDraftShareUrl(basePath, draftId));
    return true;
  } catch {
    return false;
  }
};

3. No feedback when a shared draft can't be loaded [UX-heuristic]

Severity: Low

In ProposalCreationForm.tsx, the shared-draft hydration silently swallows API failures:

void getDraftProposal(daoId, draftId)
  .then((shared) => { ... })
  .catch(() => {
    // Draft not found or fetch failed — leave form empty
  });

If the draft was deleted or the link is stale, the user lands on an empty form with no explanation. A single error toast would make this much clearer:

.catch(() => {
  showCustomToast("Could not load the shared draft", "error");
});

4. Delete draft error not surfaced in GovernanceSection [Code-only]

Severity: Low

onConfirm={() => {
  if (draftToDelete !== null) {
    void deleteDraft(draftToDelete); // no error handling
    setDraftToDelete(null);
  }
}}

If the API call fails, the modal closes and the optimistic UI removal may not match server state. saveDraft wraps its call in try/catch with a toast — deleteDraft should do the same here.


5. Drafts tab shows empty state while loading [UX-heuristic]

Severity: Low

useDrafts now returns isLoading but GovernanceSection doesn't use it:

const { drafts, deleteDraft } = useDrafts(daoId, address); // isLoading ignored

On first mount the API call is in flight and drafts.length === 0, so the tab renders <DraftEmptyState /> — indistinguishable from "you have no drafts." A skeleton row (same pattern used in the ProposalListSection above) while isLoading is true would prevent this.


✅ Confirmed correct

  • DraftCard button layout — Share, Edit, and Delete all use className="flex-1 sm:flex-none" consistently. Mobile layout is uniform. ✓
  • Conditional Copy linkonShare={currentDraftId ? handleShare : undefined} correctly hides the button until a draft has been saved at least once. ✓
  • ?draftId param is consumedProposalCreationForm reads the param and does a two-stage lookup (local cache → getDraftProposal API) with a proper loading guard via hasHydratedDraftRef. The share-a-draft feature is end-to-end functional. ✓
  • Toast messagesshowCustomToast used consistently across save, share, and error flows. ✓
  • DS Button component used — no hand-rolled button primitives in new code. ✓
  • localStorage → API migrationmigratedRef guard prevents double-migration on remount. Fallback to local drafts on failure is safe. ✓

Reviewed by @isadorable-png — automated UI review


Generated by Claude Code

Comment thread apps/api/cmd/index.ts Outdated
The migration effect's deps are [daoId, dao, address], so a transient API
failure during the same mount left users stranded on local/empty drafts
until they remounted or switched wallet/DAO. Surface an `error` flag and
`retry()` callback from useDrafts (bumped via a retryToken in the dep
list), and render a Retry button in the drafts tab — both when the list
is empty after failure and as an inline banner when local fallback
drafts are shown.

Addresses Codex review comment #3285061890 on PR #1910.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown

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

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: 53eff25532

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/api/src/controllers/draft-proposals/index.ts
Comment thread apps/dashboard/features/create-proposal/hooks/useDrafts.ts Outdated
brunod-e and others added 2 commits May 22, 2026 08:29
…raft (#3248645685)

When hydrating a draft via the shared-link API path, do not set
currentDraftId unless shared.author matches the connected address.
This prevents Save from calling updateDraftProposal on a draft the
viewer does not own (which returns 404) and instead forks it as a
new draft.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Capture address at effect start and use a cancelled flag in the cleanup
so an in-flight response from a previous wallet cannot overwrite drafts
after the user switches accounts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

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

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: da43ac6e95

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@pikonha pikonha marked this pull request as draft May 22, 2026 12:54
Add a cancelled flag in the shared-draft hydration effect so out-of-order
responses from prior draftId values cannot overwrite the form after
in-app navigation between shared links.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

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

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: 6e889d370a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants