feat: admin Chart of Accounts editor (L4)#89
Conversation
Adds /coa page for L4 (owner/admin) users to view and manage tenant-specific Chart of Accounts overrides alongside the 80 global defaults. New: client/src/pages/CoaAdmin.tsx - Searchable, filterable table (scope: all/global/tenant, type: 5 enum) - Stats header: total / global / tenant-specific counts - Create form with 8 fields (code, name, type, subtype, parent, schedule E, tax deductible, description) - Toggle activate/deactivate for tenant-specific accounts - Global defaults are displayed read-only (cannot be edited through this UI) - L4 authorization enforced server-side; UI shows friendly "need owner/admin role" error if PATCH/POST returns 403 validateNewAccountCode() enforces the ChittyFinance code-range convention: - 4-digit code required - Code must fall inside one of the ranges defined for its type (e.g. expense codes must be in 5000-5499, 5100-5199, 6000-6099, 7000-7099, or 9000-9999) - Code must not already exist for this tenant or as a global default - Parent code must exist in the COA if provided Hook additions (client/src/hooks/use-classification.ts): - useCreateCoaAccount() — POST /api/coa - useUpdateCoaAccount() — PATCH /api/coa/:id - Both invalidate the tenant-scoped /api/coa cache on success Wiring: - /coa route added to App.tsx - Sidebar link added (cfo, accountant roles; L4 check is server-side) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@coderabbitai review Please evaluate:
|
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThe PR introduces a new Chart of Accounts administration feature to the frontend, including a new routing entry, sidebar navigation link, two React Query mutation hooks for create and update operations, and a full-featured admin page component with form validation, filtering, and account management capabilities. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
chittyfinance | 3566bd0 | Apr 10 2026, 10:51 PM |
Code Review — feat: admin Chart of Accounts editor (L4)Overall the feature is well-structured and the client-side validation logic is clear. A few issues worth addressing before merge: Bugs / Correctness1. Dead const [editing, setEditing] = useState<ChartOfAccount | null>(null);The table has no Edit button wired to it. Either add inline editing or remove this state. As-is it implies an incomplete feature and will produce a TypeScript unused-variable warning. 2. <input maxLength={4} ... />3. Expense range 4. <button
onClick={() => handleToggleActive(a)}
disabled={updateAccount.isPending}
...
>Design / Architecture5. Server-side routes not in this PR 6. mutationFn: ({ id, ...data }: { id: string } & Partial<ChartOfAccount>) =>
apiRequest('PATCH', `/api/coa/${id}`, data)...
7. Not using shadcn/ui components (CLAUDE.md convention) Minor8. onError: (err: unknown) => {
const msg = err instanceof Error ? err.message : 'Create failed';
...
}9. 10. Summary
The validation logic itself ( |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3566bd0050
ℹ️ 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".
| return; | ||
| } | ||
| updateAccount.mutate( | ||
| { id: account.id, isActive: !account.isActive }, |
There was a problem hiding this comment.
Patch only fields accepted by the COA update API
handleToggleActive sends { id, isActive }, but the PATCH /api/coa/:id request body is validated with coaUpdateSchema = coaCreateSchema.partial() in server/routes/classification.ts, which does not include isActive. In Zod, unknown keys are stripped by default, so the server receives no activation change and the toggle silently does nothing for every tenant account even though the UI reports success.
Useful? React with 👍 / 👎.
| const duplicate = existing.find((a) => a.code === code); | ||
| if (duplicate) { | ||
| const scope = duplicate.tenantId ? 'this tenant' : 'global defaults'; | ||
| return { valid: false, reason: `Code ${code} already exists in ${scope} (${duplicate.name})` }; | ||
| } |
There was a problem hiding this comment.
Allow tenant overrides of global account codes
This duplicate check rejects any code already present in existing, including global defaults, so the create form blocks tenant-specific overrides before the request is sent. That conflicts with the backend behavior (POST /api/coa only rejects duplicates when the same tenant already owns the code) and with override resolution logic that prefers tenant accounts over globals, so users cannot create intended tenant overrides for existing global codes from this page.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Adds a new client-side admin experience for managing tenant-specific Chart of Accounts (COA) entries, integrating with the existing /api/coa endpoints and exposing the feature through the main app navigation.
Changes:
- Introduces a new
/coapage with COA listing, filtering/search, and a create + activate/deactivate workflow for tenant-owned accounts. - Adds React Query mutation hooks for creating and updating COA accounts.
- Wires the page into routing and adds a Sidebar navigation entry.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| client/src/pages/CoaAdmin.tsx | New COA admin page UI with validation, create form, and tenant-only activation toggles. |
| client/src/hooks/use-classification.ts | Adds useCreateCoaAccount and useUpdateCoaAccount hooks and query invalidation for COA refresh. |
| client/src/components/layout/Sidebar.tsx | Adds “Chart of Accounts” nav item pointing to /coa. |
| client/src/App.tsx | Registers the /coa route to render the new COA admin page. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const duplicate = existing.find((a) => a.code === code); | ||
| if (duplicate) { | ||
| const scope = duplicate.tenantId ? 'this tenant' : 'global defaults'; | ||
| return { valid: false, reason: `Code ${code} already exists in ${scope} (${duplicate.name})` }; | ||
| } |
| * (the DB permits tenant overrides of globals, but we warn to prevent | ||
| * accidental shadowing; the caller can ignore the warning) |
| expense: [ | ||
| { min: 5000, max: 5499, label: 'Property Operating' }, | ||
| { min: 5100, max: 5199, label: 'Utilities' }, | ||
| { min: 5200, max: 5299, label: 'HOA & Association' }, | ||
| { min: 5300, max: 5399, label: 'Financial' }, | ||
| { min: 5400, max: 5499, label: 'Depreciation' }, | ||
| { min: 6000, max: 6099, label: 'Administrative' }, | ||
| { min: 7000, max: 7099, label: 'Capital Improvements' }, | ||
| { min: 9000, max: 9999, label: 'Suspense / Non-Deductible' }, | ||
| ], |
|
|
||
| function handleToggleActive(account: ChartOfAccount) { | ||
| // Only tenant-owned accounts can be deactivated; global defaults are read-only | ||
| if (!account.tenantId) { |
| const [scopeFilter, setScopeFilter] = useState<ScopeFilter>('all'); | ||
| const [typeFilter, setTypeFilter] = useState<TypeFilter>('all'); | ||
| const [showCreate, setShowCreate] = useState(false); | ||
| const [editing, setEditing] = useState<ChartOfAccount | null>(null); |
Summary
Adds
/coaadmin page for L4 (owner/admin) users to view and manage tenant-specific Chart of Accounts overrides alongside the 80 global defaults seeded in #86.Features
validateNewAccountCoderulesEnforces the ChittyFinance code-range convention client-side before submitting:
Plus: 4-digit code required, no duplicates (tenant or global), parent code must exist if provided.
Authorization
/api/coa*callrequireL4()which checkstenant_users.rolefor owner/admin)Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit