Skip to content

Add admin dashboard project creation flow#295

Open
michaelmwu wants to merge 9 commits into
mainfrom
michaelmwu/admin-project-creation
Open

Add admin dashboard project creation flow#295
michaelmwu wants to merge 9 commits into
mainfrom
michaelmwu/admin-project-creation

Conversation

@michaelmwu
Copy link
Copy Markdown
Member

Summary

  • Add an admin dashboard flow for creating ERPNext-backed Projects with a new or existing Customer.
  • Add optional new-customer setup for Customer details, primary Contact, primary Address, Cost Center, billing currency, and Activity Type.
  • Add ERPNext API helpers and dashboard endpoints for Customer, Contact, Account Manager, and Cost Center lookups.
  • Rebuild the static dashboard bundle served by the API.

Details

  • Activity Type defaults to Engineering for {{project_name}} unless overridden in Advanced.
  • Cost Center is selected from ERPNext and defaults to Projects - 5.
  • Account Manager is selected from enabled @508.dev ERPNext Users; backend rejects non-508 email values.
  • Contact information is prioritized in the form; Address is optional billing/invoice metadata.
  • When both Contact and Address are created, Contact email/phone are mirrored into the Address record behind the scenes.
  • Existing Customer mode only asks for the existing Customer and project-level overrides.

Validation

  • uv run pytest tests/unit/test_erpnext_client.py tests/unit/test_backend_api.py -q
  • ./scripts/lint.sh
  • ./scripts/mypy.sh
  • bun run lint && bun run typecheck && bun run test
  • bun run build

Copilot AI review requested due to automatic review settings May 19, 2026 23:29
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

Warning

Rate limit exceeded

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

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ 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.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 789a4243-8b41-4ff9-9086-c43d5bbec168

📥 Commits

Reviewing files that changed from the base of the PR and between d1055d3 and e73c95e.

📒 Files selected for processing (11)
  • apps/admin_dashboard/src/main.tsx
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-CE-XSKF2.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CIisEPpj.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-Gtwe3h94.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-WxptdPpM.js
  • apps/api/src/five08/backend/static/dashboard/index.html
  • packages/shared/src/five08/clients/erpnext.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_erpnext_client.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/admin-project-creation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an admin-dashboard “New ERP project” flow that can create an ERPNext-backed Project (optionally creating/associating a Customer, Contact, Address, Cost Center, and Activity Type), plus supporting ERPNext lookup endpoints and client helpers.

Changes:

  • Extend the shared ERPNext client with generic CRUD helpers plus Customer/Contact/Address/Project creation utilities and cost center/customer/contact/user lookup helpers.
  • Add new dashboard API endpoints for ERPNext lookups and for creating the full ERPNext project setup (with validation + audit event).
  • Add a dashboard UI modal for creating projects, wiring it into the Projects view; rebuild the static dashboard bundle served by the API.

Reviewed changes

Copilot reviewed 8 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/shared/src/five08/clients/erpnext.py Adds generic record CRUD + new helper methods for dashboard-driven ERPNext record creation and lookups.
apps/api/src/five08/backend/api.py Adds request model, ERPNext lookup helpers, project-setup creation logic, and new dashboard API routes/handlers.
apps/admin_dashboard/src/main.tsx Adds ERPNext lookup client calls and a “New project” modal/flow in the dashboard Projects view.
tests/unit/test_erpnext_client.py Adds unit tests covering the new ERPNext client helper behaviors and payload shaping.
tests/unit/test_backend_api.py Adds unit tests for new dashboard endpoints and ERPNext project setup orchestration.
apps/api/src/five08/backend/static/dashboard/index.html Updates asset references for the rebuilt dashboard bundle.
apps/api/src/five08/backend/static/dashboard/.vite/manifest.json Updates Vite manifest to the new built asset names.
apps/api/src/five08/backend/static/dashboard/assets/index-cL6hQWRe.css New built CSS bundle output.
apps/api/src/five08/backend/static/dashboard/assets/index-Cjc8hvil.css Removes prior built CSS bundle output.
Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-cL6hQWRe.css: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +333 to +334
"address_title": (address_title or normalized_customer).strip(),
"address_type": (address_type or "Billing").strip(),
Comment on lines +2865 to +2871
useEffect(() => {
void onLoadCostCentersRef.current().then((options) => {
setCostCenters(options)
setCostCenter((current) =>
options.some((option) => option.name === current) ? current : "Projects - 5",
)
})
Comment thread apps/admin_dashboard/src/main.tsx Outdated
Comment on lines +2865 to +2895
useEffect(() => {
void onLoadCostCentersRef.current().then((options) => {
setCostCenters(options)
setCostCenter((current) =>
options.some((option) => option.name === current) ? current : "Projects - 5",
)
})
}, [])

useEffect(() => {
if (customerMode !== "existing") return
const handle = window.setTimeout(() => {
void onSearchCustomersRef.current(customerQuery).then(setCustomerResults)
}, 250)
return () => window.clearTimeout(handle)
}, [customerMode, customerQuery])

useEffect(() => {
if (customerMode !== "new") return
const handle = window.setTimeout(() => {
void onSearchAccountManagersRef.current(accountManagerQuery).then(setAccountManagerResults)
}, 250)
return () => window.clearTimeout(handle)
}, [customerMode, accountManagerQuery])

useEffect(() => {
if (customerMode !== "new" || contactMode !== "existing") return
const handle = window.setTimeout(() => {
void onSearchContactsRef.current(contactQuery).then(setContactResults)
}, 250)
return () => window.clearTimeout(handle)
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: 019859158e

ℹ️ 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 on lines +3161 to +3165
customer_doc = client.create_customer(
customer_name=customer_name,
account_manager=account_manager,
default_currency=currency or "USD",
customer_details=customer_details,
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 Validate optional address/contact fields before creating Customer

This branch persists a new ERPNext Customer before checking address_line1_required and contact_first_name_required, so a malformed request (e.g., address city without line 1, or contact email without first name) returns 400 after already creating a Customer record. In production this leaves orphan Customer data even though the API reports validation failure.

Useful? React with 👍 / 👎.

Comment on lines +3254 to +3258
project_detail = client.create_project(
project_name=project_name,
customer=customer_id,
project_type="External",
default_cost_center=default_cost_center or "Projects - 5",
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 Prevent partial success when post-project steps fail

The project is created before ensure_activity_type and local cache refresh run, so if either later step fails (ERP permission/transient error or local cache write issue), the handler returns 502 even though the ERP project was already created. Users retrying after that error can create duplicate projects because the first write already succeeded.

Useful? React with 👍 / 👎.

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: 6236244cb4

ℹ️ 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 apps/api/src/five08/backend/api.py Outdated
Comment on lines +3221 to +3225
activity_type_name = _text_or_none(
payload.activity_type
) or _default_activity_type_for_project(project_name)
if len(activity_type_name) > 140:
raise ValueError("activity_type_too_long")
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 Cap default activity type to ERPNext field limit

project_name is allowed up to 140 characters, but when activity_type is omitted the code derives it as Engineering for {project_name} and then enforces a 140-character cap on that derived value. This makes otherwise valid project names (roughly 125–140 chars) fail with activity_type_too_long unless the caller manually overrides activity type, which is an unexpected validation failure for normal requests.

Useful? React with 👍 / 👎.

…ect-creation

# Conflicts:
#	apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
#	apps/api/src/five08/backend/static/dashboard/index.html
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 11 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-cL6hQWRe.css: Language not supported

Comment on lines +2954 to +2968
async function submit() {
if (!canSubmit) return
const effectiveActivityType = activityTypeEdited
? activityType.trim()
: defaultActivityType.trim()
const success = await props.onCreateProject({
project_name: projectName.trim(),
customer_mode: customerMode,
customer_name: customerMode === "new" ? customerName.trim() : undefined,
customer: customerMode === "existing" ? selectedCustomer.trim() : undefined,
account_manager: customerMode === "new" ? accountManager.trim() || undefined : undefined,
default_billing_currency: customerMode === "new" ? currency.trim() || "USD" : undefined,
default_cost_center: costCenter.trim() || "Projects - 5",
activity_type: effectiveActivityType || undefined,
customer_details: customerMode === "new" ? customerDetails.trim() || undefined : undefined,
Comment thread apps/admin_dashboard/src/main.tsx Outdated
New ERP project
</strong>
<span className="text-sm text-muted-foreground">
Creates a project and associated customer.
Comment thread tests/unit/test_backend_api.py Outdated
Comment on lines +3051 to +3058
def test_dashboard_search_erpnext_customers_requires_project_write(
client: TestClient,
) -> None:
session = api.AuthSession(
subject="steering-1",
email="steering@508.dev",
display_name="Steering User",
groups=["Steering Committee"],
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: e1a20b48ed

ℹ️ 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 on lines +481 to +482
if project_id:
return self.get_project(project_id)
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 Return created project when detail fetch fails

After create_record("Project", payload) succeeds, this method unconditionally performs a second GET and propagates any failure from that read. In transient ERP/API failures where the POST succeeded but the follow-up GET fails, the dashboard request returns 502 even though the project was already created, so operator retries can create duplicate ERPNext projects. The create path should treat the POST response as success (or degrade/fallback) instead of failing the whole operation on a non-critical read-after-write.

Useful? React with 👍 / 👎.

Copilot AI review requested due to automatic review settings May 20, 2026 02:31
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 11 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-PFWgNLiP.css: Language not supported

Comment thread apps/api/src/five08/backend/api.py Outdated
"ERPNext Project was created but local cache refresh failed project=%s",
erpnext_project_id,
)
cache_refresh_error = str(exc)
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: ff1154e814

ℹ️ 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 apps/api/src/five08/backend/api.py Outdated
return []
client = _erpnext_client()
try:
users = client.search_users(normalized_query, limit=20)
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 account managers before applying result limit

The search limits ERPNext users to 20 before restricting to enabled @508.dev accounts, so valid account managers can be dropped whenever the first 20 matches are mostly external or disabled users. In that case the UI shows no eligible managers even though they exist, which blocks or misleads project setup in larger user directories. Push the domain/enabled constraints into the ERPNext query (or increase/paginate before filtering) so limiting is applied to the eligible set.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 11 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-Gtwe3h94.css: Language not supported

Copilot AI review requested due to automatic review settings May 20, 2026 02:57
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