Skip to content

add dashboard for manager and stakeholder - #13

Open
tswast wants to merge 6 commits into
mainfrom
users
Open

add dashboard for manager and stakeholder#13
tswast wants to merge 6 commits into
mainfrom
users

Conversation

@tswast

@tswast tswast commented Jul 19, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

Comment thread project_funding_ledger/routes/organization.py Outdated
return user, None
return user, profile_res.data
except Exception:
return None, None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I recommend raising a unique exception, like AuthRequiredError or something, rather than ever returning (None, None).

There are several advantages to doing this.

First, you can register an error handler function with the Flask instance. The uncaught AuthRequiredError can then be handled via exactly one code path, rather than handling (None, None) in every individual route. See the Flask .register_error_handler() docs for more info.

Second, eliminating (None, None) as a return value makes the types returned by this function very consistent. Callers can know with certainty what they're getting back, and this can be enforced with type checkers.

Comment on lines +51 to +56
orgs = []
for perm in (perms_res.data or []):
org = perm.get('organization')
if org and org.get('deleted_at') is None:
org['permission_level'] = perm.get('permission_level')
orgs.append(org)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This loop is filtering out orgs that haven't been deleted, but that should happen in the database query, not in a Python loop.

I recommend updating the query to only include orgs whose deleted_at value IS NULL.

if perms_res.data and len(perms_res.data) > 0:
return True, perms_res.data[0].get('permission_level')

return False, None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As noted in a previous comment, this function should raise an exception.

This standardizes handling and types.

return jsonify({"error": "Creating an organization requires Program Manager or Admin privileges"}), 403

data = request.json or {}
organization_name = (data.get('organization_name') or '').strip()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This can crash if the organization_name is provided by the user but isn't a string. For example:

data = {"organization_name": 1}

(data.get("organization_name") or '').strip()  # AttributeError

All of the code needs to check not only the existence, but also the type of the value.

This can be accomplished using e.g. a helper function, or -- and I strongly recommend doing this -- a tool like pydantic or marshmallow to validate the incoming data.

Comment on lines +212 to +219
key_res = client.table('organization_key').insert({
'import_key': import_key,
'created_by_user_id': profile['id'],
'updated_by_user_id': profile['id']
}).execute()

if not key_res.data:
raise ValueError("Failed to create organization_key record")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does .execute() happen in a transaction? It looks like this code path is running without a transaction, which suggests that if this first INSERT succeeds but something else fails later, there could potentially be dead records in the database.

Please double-check me on that, but that's what it looks like to me.


data = request.json or {}
organization_name = (data.get('organization_name') or '').strip()
organization_slug = (data.get('organization_slug') or '').strip().lower()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It doesn't look like the organization_slug is getting validated. This must be done server-side.

I see that it's getting updated by Javascript in the template, but it's possible for a request to come through that contains unacceptable characters, and that needs to be guarded here.

@tswast

tswast commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks @kurtmckee ! I'll aim to take some time to address this tomorrow.

tswast and others added 5 commits July 31, 2026 16:16
Co-authored-by: Kurt McKee <contactme@kurtmckee.org>
Merge remote-tracking branch 'origin/main' into users
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.

2 participants