feat(count): add Count accounting integration with 43 actions#329
feat(count): add Count accounting integration with 43 actions#329Shubhank-Jonnada wants to merge 5 commits into
Conversation
…egration instance
…l integration tests
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 381c58270e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| async def execute(self, inputs: Dict[str, Any], context: Any): | ||
| try: | ||
| params = {k: v for k, v in inputs.items() if v is not None} | ||
| resp = await _fetch(context, f"{BASE_URL}/reports/trial-balance", params=params) |
There was a problem hiding this comment.
Use POST for report-generation endpoints
The report actions call context.fetch without a method, so they default to GET, but Count’s report-generation APIs (Add Trial Balance, Create Balance Sheet Report, Create PnL) are create/generate endpoints that require POST. In production this causes these actions to fail with method/path errors (or return list endpoints instead of generated reports), so users cannot generate fresh financial statements from get_trial_balance, get_balance_sheet, or get_profit_and_loss.
Useful? React with 👍 / 👎.
|
|
||
| count = Integration.load() | ||
|
|
||
| BASE_URL = "https://api.getcount.com" |
There was a problem hiding this comment.
Use the documented partner API base path
All actions build URLs from https://api.getcount.com with resource paths like /customers, but Count’s partner API documentation defines partner endpoints under /partners/... (for example, the customer endpoint is documented as .../partners/customers). With the current base URL, every action risks calling non-existent or wrong routes, which would break the integration for normal authenticated requests.
Useful? React with 👍 / 👎.
|
Autohive Code Review |
Autohive Code ReviewP1: 0 | P2: 2 | P3: 0 Full review of all changes. Intent verification: Implementation matches stated PR intent (43 actions, all domains covered, OAuth2 auth, all files present). 7 files read beyond the diff to verify findings: 2 finding(s) — count/count.py[P2] Quality — Every update handler ( This pattern mutates the Additionally, this mutates a dict that the action handler did not allocate, which is unexpected for any caller that holds a reference to the original
# Current — mutates the input dict
uuid = inputs.pop("account_uuid")
resp = await _fetch(context, f"{BASE_URL}/accounts/{uuid}", method="PATCH", json=inputs)
# Fix — extract without mutation, build the body explicitly
uuid = inputs["account_uuid"]
body = {k: v for k, v in inputs.items() if k != "account_uuid" and v is not None}
resp = await _fetch(context, f"{BASE_URL}/accounts/{uuid}", method="PATCH", json=body)Apply the same pattern to all 9 update handlers. [P2] Quality — Update handlers send The list/query handlers correctly filter out For a PATCH endpoint this is a correctness issue: the API may interpret an explicit
# Current — sends None fields to a PATCH endpoint
resp = await _fetch(context, f"{BASE_URL}/accounts/{uuid}", method="PATCH", json=inputs)
# Fix — strip None values before sending
body = {k: v for k, v in inputs.items() if k != "account_uuid" and v is not None}
resp = await _fetch(context, f"{BASE_URL}/accounts/{uuid}", method="PATCH", json=body) |
Summary
Count is a modern accounting platform built for startups and SMBs. This integration provides 43 actions covering the full accounting lifecycle — chart of accounts, customers, vendors, products, transactions, invoices, bills, journal entries, tags, and financial reports. Useful for automating bookkeeping, syncing financial data, and generating reports programmatically.
Actions
list_accountscreate_accountupdate_accountdelete_accountlist_customersget_customerfind_customer_by_emailcreate_customerupdate_customerdelete_customerlist_vendorscreate_vendorupdate_vendordelete_vendorlist_productsget_productfind_product_by_namecreate_productupdate_productdelete_productlist_transactionscreate_transactionupdate_transactiondelete_transactionget_invoicecreate_invoiceupdate_invoicedelete_invoicecreate_billupdate_billdelete_billapprove_billlist_journal_entriescreate_journal_entryupdate_journal_entrydelete_journal_entrylist_tagscreate_tagupdate_tagdelete_tagget_trial_balanceget_balance_sheetget_profit_and_lossAuthentication
Files Added
count/config.json— Integration schema and action definitionscount/count.py— Action handlerscount/requirements.txt— Dependenciescount/README.md— Setup and usage documentationcount/icon.png— 512×512 integration iconcount/tests/conftest.py— Shared test fixturescount/tests/test_count_unit.py— Unit tests (mocked)count/tests/test_count_integration.py— Integration tests (live API)Validation
validate_integration.py— passedcheck_code.py— passedruff) — clean