Skip to content

Add org-code multi-management scoping and fix notification fan-out#40

Merged
fuzziecoder merged 1 commit intomainfrom
codex/fix-notification-issue-and-update-admin-management
Feb 22, 2026
Merged

Add org-code multi-management scoping and fix notification fan-out#40
fuzziecoder merged 1 commit intomainfrom
codex/fix-notification-issue-and-update-admin-management

Conversation

@fuzziecoder
Copy link
Copy Markdown
Owner

@fuzziecoder fuzziecoder commented Feb 22, 2026

Motivation

  • Add per-management/org scoping so each admin/management (identified by a 4-digit Org Code) only sees and receives notifications for their org, and ensure notification fan-out reliably reaches all users in the org.
  • Capture management metadata during signup so new accounts can be associated with the correct org and admins can manage multiple organizations.

Description

  • Extend types and DB surface: added org_code and management_name to UserProfile and Spot in types.ts and added a migration supabase_migration_orgs.sql to add/index/backfill these columns and enforce a 4-digit org-code format.
  • Auth/UI changes: AuthContext.login now accepts an optional orgCode and Supabase/mock auth are filtered by profiles.org_code, and LoginPage collects Org Code (4 digits) for login and managementName + orgCode during mobile setup.
  • Org-scoped data access: spotService.getUpcomingSpot/getUpcomingSpots/getPastSpots accept an optional orgCode filter and createSpot persists org_code, and pages that fetch spots (HomePage, DrinksPage, DrinksPageNew, PaymentPage) now pass profile?.org_code when calling getUpcomingSpot.
  • Notification fan-out fix: notificationService.createNotificationForAllUsers now accepts an optional orgCode and only inserts notifications for users in that org; Home page and real-time handlers pass the current user's org code when broadcasting spot/create/update/delete/RSVP messages.
  • Development mock updates: services/mockApi.ts updated to include org_code/management_name on mock users and to respect orgCode during mock login; profileService.createProfile persists org metadata.

Testing

  • Ran npm run build successfully (production build completed without errors).
  • Started the dev server (vite) and verified the updated login UI (Org Code field) by capturing a screenshot of the running app (screenshot produced).
  • Verified the app compiles after iterative edits (second npm run build also succeeded).

Codex Task


Open with Devin

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 22, 2026

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

Project Deployment Actions Updated (UTC)
brocode-spot-update-app Ready Ready Preview, Comment Feb 22, 2026 1:56pm

@gitguardian
Copy link
Copy Markdown

gitguardian Bot commented Feb 22, 2026

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
27476629 Triggered Generic Password 4c0eb46 pages/LoginPage.tsx View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@fuzziecoder fuzziecoder self-assigned this Feb 22, 2026
@fuzziecoder fuzziecoder merged commit 0a38144 into main Feb 22, 2026
3 of 4 checks passed
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 22, 2026

Warning

Rate limit exceeded

@fuzziecoder has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 46 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/fix-notification-issue-and-update-admin-management

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

View 6 additional findings in Devin Review.

Open in Devin Review

Comment thread pages/PaymentPage.tsx
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 PaymentPage fetchData uses stale profile?.org_code due to missing dependency in useCallback

The fetchData callback in PaymentPage references profile?.org_code at line 40 but the useCallback dependency array at line 88 only includes [profile?.id]. This means the callback captures a stale closure over org_code.

Root Cause and Impact

At pages/PaymentPage.tsx:40, the function calls spotService.getUpcomingSpot(profile?.org_code), but the useCallback at pages/PaymentPage.tsx:88 has [profile?.id] as its only dependency. If profile.org_code changes (or is populated after initial render while profile.id stays the same), the memoized callback will use the old org_code value.

In practice, this means the PaymentPage could fetch spots from the wrong org or fail to filter by org at all, showing payments for spots from other organizations.

The other pages that were updated (HomePage, DrinksPage) correctly include profile?.org_code or profile in their dependency arrays, but PaymentPage was missed.

(Refers to line 88)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread contexts/AuthContext.tsx
Comment on lines 100 to 105
// Fallback to mockApi for development
const { user: loggedInUser, profile: userProfile } =
await mockApi.login(identifier, password);
await mockApi.login(identifier, password, orgCode);

// If using mockApi, try to find the UUID in Supabase
try {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Login setLoading(false) never called when mockApi.login throws, leaving AuthContext permanently in loading state

In AuthContext.login, if the Supabase login fails (caught at line 96-98) and then mockApi.login at line 102 also throws (e.g., invalid credentials with wrong org code), the error propagates uncaught within the login function. The setLoading(false) at line 126 is never reached, leaving AuthContext.loading stuck as true.

Root Cause and Impact

The login function at contexts/AuthContext.tsx:57 calls setLoading(true) at line 58. The Supabase attempt is wrapped in try-catch (lines 60-98), but the mockApi.login call at line 102 and subsequent code (lines 100-126) are NOT in a try-catch. If mockApi.login throws "Invalid credentials", the error propagates to the caller.

While the caller (LoginPage.handleLogin) catches the error in its own try-catch and resets its local loading state, the AuthContext.loading remains true forever. This was a pre-existing issue, but this PR makes it significantly more likely to trigger: the new orgCode filter means mockApi.login will throw more often (e.g., when a user enters the wrong org code), since the mock login now checks (!orgCode?.trim() || u.org_code === orgCode.trim()) at services/mockApi.ts:332.

Impact: After a failed login attempt, AuthContext.loading stays true, which could disable UI elements or cause other components that depend on this state to behave incorrectly.

(Refers to lines 100-127)

Prompt for agents
In contexts/AuthContext.tsx, the login function (lines 57-127) needs to ensure setLoading(false) is always called, even when mockApi.login throws. Wrap lines 100-126 (the mockApi fallback and subsequent code) in a try-catch-finally, or better yet, wrap the entire login function body in a try-finally block. For example, change the structure so that setLoading(false) is in a finally block at the outermost level of the login function:

const login = async (identifier: string, password: string, orgCode?: string) => {
  setLoading(true);
  try {
    // ... existing Supabase login attempt ...
    // ... existing mockApi fallback ...
  } catch (err) {
    // re-throw so callers can handle
    throw err;
  } finally {
    setLoading(false);
  }
};

Note: you need to remove the existing setLoading(false) calls at lines 93 and 126 and consolidate them into the single finally block.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant