Skip to content

Permissions Demo#17

Open
yoen-velt wants to merge 3 commits into
mainfrom
permissions-demo
Open

Permissions Demo#17
yoen-velt wants to merge 3 commits into
mainfrom
permissions-demo

Conversation

@yoen-velt

@yoen-velt yoen-velt commented Dec 1, 2025

Copy link
Copy Markdown
Collaborator

Pull Request

Description

Type of Change

  • New demo application
  • Bug fix
  • Feature enhancement
  • Documentation update
  • Infrastructure/tooling change
  • Other (please describe):

Monorepo Structure Checklist

If adding a new demo, ensure you've followed the 5-level structure:

  • Placed in correct path: apps/<framework>/<document>/<type>/<implementation>/<library-or-solution>/<demo>/
  • Updated package.json with scoped name: @apps/<framework>-<document>-<library-or-solution>-<demo>
  • Created comprehensive README.md in the demo directory
  • Verified build passes: pnpm --filter <package-name> build
  • Verified dev server runs: pnpm --filter <package-name> dev

Deployment Checklist

If this demo should be deployed:

  • Added/updated Vercel project configuration
  • Updated GitHub Actions workflows (if applicable)
  • Verified deployment paths in CI/CD configs

Testing

  • Tested locally with pnpm -w install && pnpm -w build
  • Verified all affected apps still build
  • Tested dev servers for affected apps

Documentation

  • Updated relevant documentation (if needed)
  • Added demo to master-sample-app (if applicable)
  • Updated deployment docs (if applicable)

Related Issues

Screenshots/Videos

Additional Context


For Reviewers

Demo Location

Path: apps/<framework>/<document>/<type>/<implementation>/<library-or-solution>/<demo>/

Package name: @apps/<...>

How to Test

# Install dependencies
pnpm -w install

# Run the specific demo
pnpm --filter @apps/<package-name> dev

# Build the specific demo
pnpm --filter @apps/<package-name> build

Structure Verification

The demo follows the 5-level hierarchy:

  1. Framework:
  2. Document:
  3. Type:
  4. Implementation:
  5. Library/Solution:
  6. Demo:

Documentation: See README_MONOREPO.md and docs/structure.md for more details on the monorepo structure.


Note

Adds a new Next.js demo app showcasing on-demand permissions with a custom permissions API, Velt auth token endpoint, and integrated Velt collaboration UI.

  • New Demo App: apps/react/permissions/on-demand/custom/permissions-demo (@apps/react-permissions-on-demand-custom-permissions-demo).
    • Next.js + Tailwind setup (app/, styles/, tailwind.config.js, postcss.config.js, tsconfig.json, next.config.js).
    • Documentation and config: README.md, .gitignore, components.json, package.json.
  • Backend (API Routes):
    • app/api/check-permissions/route.ts: Processes batched permission requests, maps resource IDs, computes access via lib/permissions-data, returns Velt-formatted results; CORS OPTIONS handler.
    • app/api/velt/token/route.ts: Proxies to Velt to generate JWT tokens using API/auth keys.
  • Permissions Logic:
    • lib/permissions-data.ts: Defines hierarchy (organization, folder, document), permission states, role configs, inheritance resolution, effective access computation, and localStorage helpers.
  • Frontend UI:
    • components/document/document-canvas.tsx + icons/: Interactive hierarchy visualization with per-node permission dropdowns and access role toggles.
    • Document context: app/document/DocumentContext.tsx and useCurrentDocument.ts (URL/localStorage ID handling).
    • User simulation: app/userAuth/* (random user generation, login/logout context).
    • App providers: app/providers.tsx integrating VeltProvider with permission provider config.
    • Velt integration: components/velt/* (initialize document, comments, sidebar, presence, notifications) with custom wireframes and theming (ui-customization/styles.css).

Written by Cursor Bugbot for commit 2179bbb. This will update automatically on new commits. Configure here.

@yoen-velt yoen-velt self-assigned this Dec 1, 2025
@vercel

vercel Bot commented Dec 1, 2025

Copy link
Copy Markdown

--velt-font-size-md: 0.972rem; /* 15.556px - icon size */
--velt-font-size-lg: 1.167rem; /* 18.667px - icon container */
--velt-font-size-xl: 1.75rem; /* 28px - component height */
--velt-font-size-2xl: 2rem; /* 32px */

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: CSS custom properties declared without selector block

All CSS custom properties in this file (like --velt-default-font-family, --velt-border-radius-*, theme colors, spacing, and font sizes) are declared at the file's top level without being wrapped in a selector such as :root. CSS custom properties must be declared inside a selector block to be valid. The browser will ignore these declarations entirely, causing the Velt UI theme customization to have no effect.

Fix in Cursor Fix in Web


setUser(selectedUser);
setIsUserLoggedIn(true);
} catch {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Empty catch block silently fails user initialization

The useEffect in AppUserProvider wraps initialization logic in a try-catch with an empty catch block (catch {}). If JSON.parse(stored) fails on corrupted localStorage data, or if storage access throws (e.g., storage is disabled), the error is silently swallowed. The user state remains undefined and isUserLoggedIn remains undefined, leaving the demo in a broken state with no indication of what went wrong. The same pattern appears in the login callback.

Additional Locations (1)

Fix in Cursor Fix in Web

selectedUser = userHeader as UserRole;
} else {
selectedUser = loadSelectedUser();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Permission API ignores client-side settings changes

The permission API route calls loadPermissionSettings() and loadSelectedUser() as fallbacks, but these functions require localStorage which doesn't exist on the server. They will always return default values. The API expects settings via custom headers (x-demo-permission-settings, x-demo-selected-user), but no code in the codebase sends these headers. This means permission changes made in the UI are never reflected in actual permission checks - the demo UI appears to work but the underlying permission system always uses defaults.

Fix in Cursor Fix in Web

strokeOpacity={accessMap['doc-c'].hasAccess ? 1 : 0.32}
strokeWidth="2"
strokeDasharray={accessMap['doc-c'].hasAccess ? 'none' : '12 12'}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hierarchy diagram shows wrong parent for Document C

The visual hierarchy diagram draws a connecting line "From Folder B to Document C", implying Document C is a child of Folder B. However, the data hierarchy in permissions-data.ts defines doc-c with parentId: 'org-a', making it a direct child of Organization A. This mismatch will confuse users about permission inheritance - if they set Document C to Inherit, it will inherit from Organization A's permissions, not Folder B's as the visual suggests.

Additional Locations (1)

Fix in Cursor Fix in Web

Regenerate lockfile to resolve missing entries for @veltdev/react@4.6.5
and other packages that were causing build failures on Vercel.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
{ id: 'folder-b', name: 'Folder B', type: 'folder', parentId: 'org-a' },
{ id: 'doc-a', name: 'Document A', type: 'document', parentId: 'folder-b' },
{ id: 'doc-b', name: 'Document B', type: 'document', parentId: 'folder-a' },
{ id: 'doc-c', name: 'Document C', type: 'document', parentId: 'org-a' },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Visual hierarchy mismatches permission inheritance data model

The HIERARCHY_NODES data defines doc-c with parentId: 'org-a', but the visual diagram in document-canvas.tsx draws a connection line from Folder B to Document C (labeled "From Folder B to Document C"). When doc-c is set to 'Inherit', the resolveEffectivePermission function traces doc-c → org-a, completely bypassing folder-b. Users will see folder-b as the visual parent but get inheritance behavior from org-a, causing confusing and incorrect permission calculations.

Additional Locations (1)

Fix in Cursor Fix in Web

case 'OrganizationPrivate':
// Only org members have access
hasAccess = userConfig.orgMember;
accessRole = userConfig.isOwner ? 'editor' : 'editor'; // Org members get editor

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Redundant ternary always returns same value

The ternary expression userConfig.isOwner ? 'editor' : 'editor' always returns 'editor' regardless of the condition, making it pointless dead code. Comparing to the 'Public' case on line 144 which uses isOwner ? 'editor' : 'viewer', this appears to be a copy-paste error where the second 'editor' was likely intended to be 'viewer' to differentiate access roles between owners and regular organization members.

Fix in Cursor Fix in Web

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