jaz-cli 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/skills/api/SKILL.md +162 -0
- package/assets/skills/api/references/dependencies.md +139 -0
- package/assets/skills/api/references/endpoints.md +1299 -0
- package/assets/skills/api/references/errors.md +751 -0
- package/assets/skills/api/references/feature-glossary.md +216 -0
- package/assets/skills/api/references/field-map.md +428 -0
- package/assets/skills/api/references/full-api-surface.md +699 -0
- package/assets/skills/api/references/search-reference.md +714 -0
- package/assets/skills/conversion/SKILL.md +130 -0
- package/assets/skills/conversion/references/edge-cases.md +174 -0
- package/assets/skills/conversion/references/file-analysis.md +120 -0
- package/assets/skills/conversion/references/file-types.md +501 -0
- package/assets/skills/conversion/references/mapping-rules.md +166 -0
- package/assets/skills/conversion/references/option1-full.md +145 -0
- package/assets/skills/conversion/references/option2-quick.md +197 -0
- package/assets/skills/conversion/references/verification.md +142 -0
- package/dist/commands/init.js +76 -0
- package/dist/commands/update.js +28 -0
- package/dist/commands/versions.js +33 -0
- package/dist/index.js +52 -0
- package/dist/types/index.js +5 -0
- package/dist/utils/github.js +81 -0
- package/dist/utils/logger.js +21 -0
- package/dist/utils/template.js +49 -0
- package/package.json +44 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: api
|
|
3
|
+
version: 2.0.0
|
|
4
|
+
description: Complete reference for the Jaz/Juan REST API — the accounting platform backend. Use this skill whenever building, modifying, debugging, or extending any code that calls the API — including API clients, integrations, data seeding, test data, or new endpoint work. Contains every field name, response shape, error, gotcha, and edge case discovered through live production testing.
|
|
5
|
+
license: MIT
|
|
6
|
+
compatibility: Requires Jaz/Juan API key (x-jk-api-key header). Works with Claude Code, Claude Cowork, Claude.ai, and any agent that reads markdown.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Jaz API Skill
|
|
10
|
+
|
|
11
|
+
You are working with the **Jaz/Juan REST API** — the backend for Jaz (Singapore) and Juan (Philippines) accounting platforms.
|
|
12
|
+
|
|
13
|
+
## When to Use This Skill
|
|
14
|
+
|
|
15
|
+
- Writing or modifying any code that calls the Jaz API
|
|
16
|
+
- Building API clients, integrations, or data pipelines
|
|
17
|
+
- Debugging API errors (422, 400, 404, 500)
|
|
18
|
+
- Adding support for new Jaz API endpoints
|
|
19
|
+
- Reviewing code that constructs Jaz API request payloads
|
|
20
|
+
|
|
21
|
+
## Quick Reference
|
|
22
|
+
|
|
23
|
+
**Base URL**: `https://api.getjaz.com`
|
|
24
|
+
**Auth**: `x-jk-api-key: <key>` header on every request — key has `jk-` prefix (e.g., `jk-a1b2c3...`). NOT `Authorization: Bearer` or `x-api-key`.
|
|
25
|
+
**Content-Type**: `application/json` for all POST/PUT/PATCH
|
|
26
|
+
**All paths are prefixed**: `/api/v1/` (e.g., `https://api.getjaz.com/api/v1/invoices`)
|
|
27
|
+
|
|
28
|
+
## Critical Rules
|
|
29
|
+
|
|
30
|
+
### Identifiers & Dates
|
|
31
|
+
1. **All IDs are `resourceId`** — never `id`. References use `<resource>ResourceId` suffix.
|
|
32
|
+
2. **All transaction dates are `valueDate`** — not `issueDate`, `invoiceDate`, `date`. This is an accounting term meaning "date of economic effect."
|
|
33
|
+
3. **All dates are `YYYY-MM-DD` strings** — ISO datetime and epoch ms are rejected.
|
|
34
|
+
|
|
35
|
+
### Payments (Cross-Currency Aware)
|
|
36
|
+
4. **Payment amounts have two fields**: `paymentAmount` = bank account currency (actual cash moved), `transactionAmount` = transaction document currency (invoice/bill/credit note — amount applied to balance). For same-currency, both are equal. For FX (e.g., USD invoice paid from SGD bank at 1.35): `paymentAmount: 1350` (SGD), `transactionAmount: 1000` (USD).
|
|
37
|
+
5. **Payment date is `valueDate`** — not `paymentDate`, not `date`.
|
|
38
|
+
6. **Payment bank account is `accountResourceId`** — not `bankAccountResourceId`.
|
|
39
|
+
7. **Payments require 6 fields**: `paymentAmount`, `transactionAmount`, `accountResourceId`, `paymentMethod`, `reference`, `valueDate`.
|
|
40
|
+
8. **Payments wrapped in `{ payments: [...] }`** — array recommended. Flat objects are now auto-wrapped by the API, but array format is preferred for clarity.
|
|
41
|
+
|
|
42
|
+
### Names & Fields
|
|
43
|
+
9. **Line item descriptions use `name`** — not `description`.
|
|
44
|
+
10. **Item names**: canonical field is `internalName`, but `name` alias is accepted on POST. GET responses return both `internalName` and `name`.
|
|
45
|
+
11. **Tag names**: canonical field is `tagName`, but `name` alias is accepted on POST. GET responses return both `tagName` and `name`.
|
|
46
|
+
12. **Custom field names**: POST uses `name`, GET returns both `customFieldName` and `name`.
|
|
47
|
+
13. **Invoice/bill number is `reference`** — not `referenceNumber`.
|
|
48
|
+
|
|
49
|
+
### Transaction Creation
|
|
50
|
+
14. **`saveAsDraft`** defaults to `false` — omitting it creates a finalized transaction. Explicitly sending `saveAsDraft: true` creates a draft.
|
|
51
|
+
15. **If `saveAsDraft: false`** (or omitted), every lineItem MUST have `accountResourceId`.
|
|
52
|
+
16. **Phones MUST be E.164** — `+65XXXXXXXX` (SG), `+63XXXXXXXXXX` (PH). No spaces.
|
|
53
|
+
|
|
54
|
+
### Chart of Accounts
|
|
55
|
+
17. **Tax profiles pre-exist** — NEVER create them. Only GET and map.
|
|
56
|
+
18. **Bank accounts are CoA entries** with `accountType: "Bank Accounts"`. No separate endpoint.
|
|
57
|
+
19. **CoA bulk-upsert wrapper is `accounts`** — not `chartOfAccounts`.
|
|
58
|
+
20. **CoA POST uses `currency`** — not `currencyCode`. (Asymmetry — GET returns `currencyCode`.)
|
|
59
|
+
21. **CoA POST uses `classificationType`** — GET returns `accountType`. Same values.
|
|
60
|
+
22. **CoA code mapping: match by NAME, not code** — pre-existing accounts may have different codes. Resource IDs are the universal identifier.
|
|
61
|
+
|
|
62
|
+
### Journals & Cash
|
|
63
|
+
23. **Journals use `journalEntries`** with `amount` + `type: "DEBIT"|"CREDIT"` — NOT `debit`/`credit` number fields.
|
|
64
|
+
24. **Journals have NO `currency` field** at top level — sending it causes "Invalid request body".
|
|
65
|
+
25. **Cash entries use `accountResourceId`** at top level for the BANK account + `journalEntries` array for offsets.
|
|
66
|
+
|
|
67
|
+
### Credit Notes & Refunds
|
|
68
|
+
26. **Credit note application wraps in `credits` array** with `amountApplied` — not flat.
|
|
69
|
+
27. **CN refunds use `refunds` wrapper** with `refundAmount` + `refundMethod` — NOT `payments`/`paymentAmount`/`paymentMethod`.
|
|
70
|
+
|
|
71
|
+
### Inventory Items
|
|
72
|
+
28. **Inventory items require**: `unit` (e.g., `"pcs"`), `costingMethod` (`"FIXED"` or `"WAC"`), `cogsResourceId`, `blockInsufficientDeductions`, `inventoryAccountResourceId`. `purchaseAccountResourceId` MUST be Inventory-type CoA.
|
|
73
|
+
29. **Delete inventory items via `DELETE /items/:id`** — not `/inventory-items/:id`.
|
|
74
|
+
|
|
75
|
+
### Cash Transfers
|
|
76
|
+
30. **Cash transfers use `cashOut`/`cashIn` sub-objects** — NOT flat `fromAccountResourceId`/`toAccountResourceId`. Each: `{ accountResourceId, amount }`.
|
|
77
|
+
|
|
78
|
+
### Schedulers
|
|
79
|
+
31. **Scheduled invoices/bills wrap in `{ invoice: {...} }` or `{ bill: {...} }`** — not flat. Recurrence field is `repeat` (NOT `frequency`/`interval`). `saveAsDraft: false` required.
|
|
80
|
+
32. **Scheduled journals use FLAT structure** with `schedulerEntries` — not nested in `journal` wrapper.
|
|
81
|
+
|
|
82
|
+
### Bookmarks
|
|
83
|
+
33. **Bookmarks use `items` array wrapper** with `name`, `value`, `categoryCode`, `datatypeCode`.
|
|
84
|
+
|
|
85
|
+
### Custom Fields
|
|
86
|
+
34. **Do NOT send `appliesTo` on custom field POST** — causes "Invalid request body". Only send `name`, `type`, `printOnDocuments`.
|
|
87
|
+
|
|
88
|
+
### Reports
|
|
89
|
+
35. **Report field names differ by type** — this is the most error-prone area:
|
|
90
|
+
|
|
91
|
+
| Report | Required Fields |
|
|
92
|
+
|--------|----------------|
|
|
93
|
+
| Trial balance | `startDate`, `endDate` |
|
|
94
|
+
| Balance sheet | `primarySnapshotDate` |
|
|
95
|
+
| P&L | `primarySnapshotDate`, `secondarySnapshotDate` |
|
|
96
|
+
| General ledger | `startDate`, `endDate`, `groupBy: "ACCOUNT"` |
|
|
97
|
+
| Cashflow | `primaryStartDate`, `primaryEndDate` |
|
|
98
|
+
| Cash balance | `reportDate` |
|
|
99
|
+
| AR/AP report | `endDate` |
|
|
100
|
+
| AR/AP summary | `startDate`, `endDate` |
|
|
101
|
+
| Bank balance summary | `primarySnapshotDate` |
|
|
102
|
+
| Equity movement | `primarySnapshotStartDate`, `primarySnapshotEndDate` |
|
|
103
|
+
|
|
104
|
+
36. **Data exports use simpler field names**: P&L export uses `startDate`/`endDate` (NOT `primarySnapshotDate`). AR/AP export uses `endDate`.
|
|
105
|
+
|
|
106
|
+
### Pagination
|
|
107
|
+
37. **All list/search endpoints use `limit`/`offset` pagination** — NOT `page`/`size`. Default limit=100, offset=0. Max limit=1000, max offset=65536. `page`/`size` params are silently ignored. Response shape: `{ totalPages, totalElements, data: [...] }`.
|
|
108
|
+
|
|
109
|
+
### Other
|
|
110
|
+
38. **Currency rates use `/organization-currencies/:code/rates`** — note the HYPHENATED path (NOT `/organization/currencies`). Enable currencies first via `POST /organization/currencies`, then set rates via `POST /organization-currencies/:code/rates` with body `{ "rate": 0.74, "rateApplicableFrom": "YYYY-MM-DD" }` (see Rule 48 for direction). Cannot set rates for org base currency. Full CRUD: POST (create), GET (list), GET/:id, PUT/:id, DELETE/:id.
|
|
111
|
+
39. **FX invoices/bills MUST use `currency` object** — `currencyCode: "USD"` (string) is **silently ignored** (transaction created in base currency!). Use `currency: { sourceCurrency: "USD" }` to auto-fetch platform rate (ECB/FRANKFURTER), or `currency: { sourceCurrency: "USD", exchangeRate: 1.35 }` for a custom rate. Rate hierarchy: org rate → platform/ECB → transaction-level.
|
|
112
|
+
40. **Invoice GET uses `organizationAccountResourceId`** for line item accounts — POST uses `accountResourceId`. Request-side aliases resolve `issueDate` → `valueDate`, `bankAccountResourceId` → `accountResourceId`, etc.
|
|
113
|
+
41. **Scheduler GET returns `interval`** — POST uses `repeat`. (Response-side asymmetry remains.)
|
|
114
|
+
42. **Search sort is an object** — `{ sort: { sortBy: ["valueDate"], order: "DESC" } }`. Required when `offset` is present (even `offset: 0`).
|
|
115
|
+
43. **Bank records: two import methods** — Multipart CSV/OFX via `POST /magic/importBankStatementFromAttachment` (fields: `sourceFile`, `accountResourceId`, `businessTransactionType: "BANK_STATEMENT"`, `sourceType: "FILE"`). JSON via `POST /bank-records/:accountResourceId` with `{ records: [{description, netAmount, valueDate, ...}] }`.
|
|
116
|
+
44. **Withholding tax** on bills/supplier CNs only. Retry pattern: if `WITHHOLDING_CODE_NOT_FOUND`, strip field and retry.
|
|
117
|
+
45. **Known API bugs (500s)**: Contact groups PUT, custom fields PUT, capsules POST, catalogs POST, inventory balances GET — all return 500.
|
|
118
|
+
46. **Non-existent endpoints**: `POST /deposits` and `POST /inventory/adjustments` return 404 — these endpoints are not implemented.
|
|
119
|
+
47. **Attachments require PDF/PNG**: `POST /:type/:id/attachments` uses multipart `file` field but rejects `text/plain`. Use `application/pdf` or `image/png`.
|
|
120
|
+
48. **Currency rate direction: `rate` = functionalToSource (1 base = X foreign)** — POST `rate: 0.74` for a SGD org means 1 SGD = 0.74 USD. **If your data stores rates as "1 USD = 1.35 SGD" (sourceToFunctional), you MUST invert: `rate = 1 / 1.35 = 0.74`.** GET confirms both: `rateFunctionalToSource` (what you POSTed) and `rateSourceToFunctional` (the inverse).
|
|
121
|
+
|
|
122
|
+
### Search & Filter
|
|
123
|
+
49. **Search endpoint universal pattern** — All 28 `POST /*/search` endpoints share identical structure: `{ filter?, sort: { sortBy: ["field"], order: "ASC"|"DESC" }, limit: 1-1000, offset: 0-65536 }`. Sort is REQUIRED when offset is present (even `offset: 0`). Default limit: 100. `sortBy` is always an array on all endpoints (no exceptions). See `references/search-reference.md` for per-endpoint filter/sort fields.
|
|
124
|
+
50. **Filter operator reference** — String: `eq`, `neq`, `contains`, `in` (array, max 100), `likeIn` (array, max 100), `reg` (regex array, max 100), `isNull` (bool). Numeric: `eq`, `gt`, `gte`, `lt`, `lte`, `in`. Date (YYYY-MM-DD): `eq`, `gt`, `gte`, `lt`, `lte`, `between` (exactly 2 values). DateTime (RFC3339): same operators, converted to epoch ms internally. Boolean: `eq`. JSON: `jsonIn`, `jsonNotIn`. Logical: nest with `and`/`or`/`not` objects, or use `andGroup`/`orGroup` arrays (invoices, bills, journals, credit notes).
|
|
125
|
+
51. **Date format asymmetry (CRITICAL)** — Request dates: `YYYY-MM-DD` strings (all create/update and DateExpression filters). Request datetimes: RFC3339 strings (DateTimeExpression filters for `createdAt`, `updatedAt`, `approvedAt`, `submittedAt`). **ALL response dates**: `int64` epoch milliseconds — including `valueDate`, `createdAt`, `updatedAt`, `approvedAt`, `submittedAt`, `matchDate`. Convert: `new Date(epochMs).toISOString().slice(0,10)`.
|
|
126
|
+
52. **Field aliases on create endpoints** — Middleware transparently maps: `issueDate`/`date` → `valueDate` (invoices, bills, credit notes, journals). `name` → `tagName` (tags) or `internalName` (items). `paymentDate` → `valueDate`, `bankAccountResourceId` → `accountResourceId` (payments). `paymentAmount` → `refundAmount`, `paymentMethod` → `refundMethod` (credit note refunds). `accountType` → `classificationType`, `currencyCode` → `currency` (CoA). Canonical names always work; aliases are convenience only.
|
|
127
|
+
53. **All search/list responses are flat** — every search and list endpoint returns `{ totalElements, totalPages, data: [...] }` directly (no outer `data` wrapper). Access the array via `response.data`, pagination via `response.totalElements`.
|
|
128
|
+
54. **Scheduled endpoints support date aliases** — `txnDateAliases` middleware (mapping `issueDate`/`date` → `valueDate`) now applies to all scheduled create/update endpoints: `POST/PUT /scheduled/invoices`, `POST/PUT /scheduled/bills`, `POST/PUT /scheduled/journals`, `POST/PUT /scheduled/subscriptions`.
|
|
129
|
+
55. **Kebab-case URL aliases** — `capsuleTypes` endpoints also accept kebab-case paths: `/capsule-types` (list, search, CRUD). `moveTransactionCapsules` also accepts `/move-transaction-capsules`. Both camelCase and kebab-case work identically.
|
|
130
|
+
|
|
131
|
+
## Supporting Files
|
|
132
|
+
|
|
133
|
+
For detailed reference, read these files in this skill directory:
|
|
134
|
+
|
|
135
|
+
- **[references/search-reference.md](./references/search-reference.md)** — Complete search/filter/sort reference for all 28 search endpoints — per-endpoint filter fields, sort fields, operator types
|
|
136
|
+
- **[references/endpoints.md](./references/endpoints.md)** — Full API endpoint reference with request/response examples
|
|
137
|
+
- **[references/errors.md](./references/errors.md)** — Complete error catalog: every error, cause, and fix
|
|
138
|
+
- **[references/field-map.md](./references/field-map.md)** — Complete field name mapping (what you'd guess vs actual), date format matrix, middleware aliases
|
|
139
|
+
- **[references/dependencies.md](./references/dependencies.md)** — Resource creation dependencies and required order
|
|
140
|
+
- **[references/full-api-surface.md](./references/full-api-surface.md)** — Complete endpoint catalog (80+ endpoints), enums, search filters, limits
|
|
141
|
+
- **[references/feature-glossary.md](./references/feature-glossary.md)** — Business context per feature — what each feature does and why, extracted from [help.jaz.ai](https://help.jaz.ai)
|
|
142
|
+
- **[help-center-mirror/](./help-center-mirror/)** — Full help center content split by section (auto-generated from [help.jaz.ai](https://help.jaz.ai))
|
|
143
|
+
|
|
144
|
+
## DX Overhaul (Implemented)
|
|
145
|
+
|
|
146
|
+
The backend DX overhaul is live. Key improvements now available:
|
|
147
|
+
- **Request-side field aliases**: `name` → `tagName`/`internalName`, `issueDate` → `valueDate`, `bankAccountResourceId` → `accountResourceId`, and more. Both canonical and alias names are accepted.
|
|
148
|
+
- **Response-side aliases**: Tags, items, and custom fields return `name` alongside canonical field names (`tagName`, `internalName`, `customFieldName`).
|
|
149
|
+
- **`saveAsDraft` defaults to `false`**: Omitting it creates a finalized transaction. No longer required on POST.
|
|
150
|
+
- **`POST /items/search` available**: Advanced search with filters now works for items.
|
|
151
|
+
- **NormalizeToArray**: Flat payment/refund/credit objects are auto-wrapped into arrays. Array format is still recommended.
|
|
152
|
+
- **Nil-safe deletes**: Delete endpoints return 404 (not 500) when resource not found.
|
|
153
|
+
|
|
154
|
+
## Recommended Client Patterns
|
|
155
|
+
|
|
156
|
+
- **Serialization (Python)**: `model_dump(mode="json", by_alias=True, exclude_unset=True, exclude_none=True)`
|
|
157
|
+
- **Field names**: All request bodies use camelCase
|
|
158
|
+
- **Date serialization**: Python `date` type → `YYYY-MM-DD` strings
|
|
159
|
+
- **Bill payments**: Embed in bill creation body (safest). Standalone `POST /bills/{id}/payments` also works.
|
|
160
|
+
- **Bank records**: Use multipart `POST /magic/importBankStatementFromAttachment`
|
|
161
|
+
- **Scheduled bills**: Wrap as `{ status, startDate, endDate, repeat, bill: {...} }`
|
|
162
|
+
- **FX currency**: `currency: { sourceCurrency: "USD" }` (auto-fetches platform rate) or `currency: { sourceCurrency: "USD", exchangeRate: 1.35 }` (custom rate). **Never use `currencyCode` string** — silently ignored.
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Jaz API Resource Dependencies
|
|
2
|
+
|
|
3
|
+
> Required creation order and dependency chain for Jaz API resources.
|
|
4
|
+
> Understanding these dependencies prevents cascading failures.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Dependency Graph
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
Organization ──┐
|
|
12
|
+
├── CoA ──────────────────┐
|
|
13
|
+
Tax Profiles ──┤ ├── Items ──┐
|
|
14
|
+
Currencies ────┤ │ │
|
|
15
|
+
Tags ──────────┘ │ │
|
|
16
|
+
│ │
|
|
17
|
+
├── Contacts ──┐
|
|
18
|
+
│ │
|
|
19
|
+
│ ├── Invoices ──┬── Payments
|
|
20
|
+
│ ├── Bills ─────┤── Bill Payments
|
|
21
|
+
│ ├── Journals ├── Credit Notes
|
|
22
|
+
│ ├── Cash-In └── Credit Applications
|
|
23
|
+
│ └── Cash-Out
|
|
24
|
+
│
|
|
25
|
+
└── Bank Records (need bankAccountId from CoA)
|
|
26
|
+
Schedulers (need contactId + accountId)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Required Creation Order
|
|
32
|
+
|
|
33
|
+
Resources MUST be created in this order. Steps at the same level can run in parallel.
|
|
34
|
+
|
|
35
|
+
### Level 0: Discovery (read-only)
|
|
36
|
+
- `GET /organization` → org name, base currency, country, lockDate
|
|
37
|
+
- `GET /chart-of-accounts` → existing accounts (keyed by name AND code)
|
|
38
|
+
- `GET /tax-profiles` → pre-existing tax profiles (map taxTypeCode → resourceId)
|
|
39
|
+
- `GET /organization/currencies` → enabled currencies
|
|
40
|
+
- `GET /contacts` → existing contacts
|
|
41
|
+
- `GET /items` → existing items
|
|
42
|
+
- `GET /tags` → existing tags
|
|
43
|
+
|
|
44
|
+
### Level 1: Foundation (parallel)
|
|
45
|
+
- `POST /chart-of-accounts/bulk-upsert` → create/update accounts
|
|
46
|
+
- `POST /organization/currencies` → enable FX currencies
|
|
47
|
+
- `POST /tags` → create tags
|
|
48
|
+
- `POST /custom-fields` → create custom fields
|
|
49
|
+
|
|
50
|
+
**Tax profiles are READ-ONLY** — discovered in Level 0, never created.
|
|
51
|
+
|
|
52
|
+
### Level 2: Entities (parallel)
|
|
53
|
+
- `POST /contacts` → create customers and suppliers
|
|
54
|
+
- `POST /items` → create items (needs CoA + tax profile IDs from Levels 0-1)
|
|
55
|
+
|
|
56
|
+
### Level 3: Transactions (parallel)
|
|
57
|
+
- `POST /invoices` → create invoices (needs contacts + CoA + tax profiles)
|
|
58
|
+
- `POST /bills` → create bills (same deps, can embed payments)
|
|
59
|
+
- `POST /journals` → create journal entries (needs CoA)
|
|
60
|
+
- `POST /cash-in-journals` → cash receipts (needs bank account from CoA)
|
|
61
|
+
- `POST /cash-out-journals` → cash payments (needs bank account from CoA)
|
|
62
|
+
|
|
63
|
+
### Level 4: Settlements (parallel)
|
|
64
|
+
- `POST /invoices/{id}/payments` → record invoice payments (needs invoice + bank account)
|
|
65
|
+
- `POST /bills/{id}/payments` → record bill payments (needs bill + bank account; fixed in PR #112)
|
|
66
|
+
- `POST /customer-credit-notes` → create customer CNs (needs contacts)
|
|
67
|
+
- `POST /supplier-credit-notes` → create supplier CNs (needs contacts)
|
|
68
|
+
- `POST /invoices/{id}/credits` → apply CNs to invoices (needs invoice + CN IDs)
|
|
69
|
+
|
|
70
|
+
### Level 5: Bank & Recurring (parallel)
|
|
71
|
+
- `POST /magic/importBankStatementFromAttachment` → import bank records (needs bank account from CoA)
|
|
72
|
+
- `POST /scheduled/invoices` → create invoice schedulers (needs contacts + CoA)
|
|
73
|
+
- `POST /scheduled/bills` → create bill schedulers (needs contacts + CoA)
|
|
74
|
+
|
|
75
|
+
### Level 5b: Optional/Experimental (Parallel)
|
|
76
|
+
- POST /api/v1/catalogs (needs Items from Level 2)
|
|
77
|
+
- POST /api/v1/deposits (needs Contacts + CoA-Bank from Level 0-1)
|
|
78
|
+
- POST /api/v1/fixed-assets (needs CoA from Level 0-1)
|
|
79
|
+
- POST /api/v1/inventory/adjustments (needs Items from Level 2)
|
|
80
|
+
|
|
81
|
+
These endpoints may not be available on all organizations. Use try/catch with graceful fallback.
|
|
82
|
+
|
|
83
|
+
### Level 6: Verification
|
|
84
|
+
- `POST /generate-reports/trial-balance` → verify data integrity
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Key Dependencies Explained
|
|
89
|
+
|
|
90
|
+
| Step | Needs from... | Why |
|
|
91
|
+
|------|--------------|-----|
|
|
92
|
+
| Items | CoA (Level 1) | `saleAccountResourceId`, `purchaseAccountResourceId` |
|
|
93
|
+
| Items | Tax Profiles (Level 0) | `saleTaxProfileResourceId`, `purchaseTaxProfileResourceId` |
|
|
94
|
+
| Contacts | Nothing | Standalone — only name, currency, phone |
|
|
95
|
+
| Invoices | Contacts (Level 2) | `contactResourceId` |
|
|
96
|
+
| Invoices | CoA (Level 1) | `lineItems[].accountResourceId` (if saveAsDraft: false) |
|
|
97
|
+
| Invoices | Tax Profiles (Level 0) | `lineItems[].taxProfileResourceId` |
|
|
98
|
+
| Invoice Payments | Invoices (Level 3) | URL: `/invoices/{invoiceResourceId}/payments` |
|
|
99
|
+
| Bill Payments | Bills (Level 3) | URL: `/bills/{billResourceId}/payments` (or embedded) |
|
|
100
|
+
| Payments | CoA-Bank (Level 0) | `accountResourceId` (the bank account) |
|
|
101
|
+
| Credit Notes | Contacts (Level 2) | `contactResourceId` |
|
|
102
|
+
| Credit Applications | Invoices + CNs (Level 3-4) | Both `invoiceResourceId` and `creditNoteResourceId` |
|
|
103
|
+
| Bank Records | CoA-Bank (Level 0) | Multipart: `/magic/importBankStatementFromAttachment` |
|
|
104
|
+
| Schedulers | Contacts + CoA (Level 1-2) | Full invoice/bill payload inside |
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## What Happens If You Break The Order
|
|
109
|
+
|
|
110
|
+
| Mistake | Error You'll See |
|
|
111
|
+
|---------|-----------------|
|
|
112
|
+
| Create invoices before CoA | `"lineItems[0].accountResourceId is required"` |
|
|
113
|
+
| Create invoices before contacts | `"contactResourceId is a required field"` |
|
|
114
|
+
| Create payments before invoices | 404 on `/invoices/{id}/payments` |
|
|
115
|
+
| Create bank records before CoA probe | Bank account ID unknown |
|
|
116
|
+
| Create items before CoA | Items created but with no sale/purchase accounts |
|
|
117
|
+
| Create credit apps before CNs | `"creditNoteResourceId must be a valid UUID"` |
|
|
118
|
+
| Skip tax profile discovery | Invoices with no tax |
|
|
119
|
+
| Map CoA by code not name | Account lookup fails (pre-existing codes differ) |
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## CoA Code Mapping Strategy
|
|
124
|
+
|
|
125
|
+
Pre-existing accounts may have different codes than your templates:
|
|
126
|
+
- "Cost of Goods Sold" = code 310 in the API, code 5000 in template
|
|
127
|
+
- "Accounts Receivable" can have `code: null` in the API
|
|
128
|
+
|
|
129
|
+
**Always map by NAME, not code**. When building lookup maps, key by both:
|
|
130
|
+
```javascript
|
|
131
|
+
coaIds[acct.name] = acct.resourceId;
|
|
132
|
+
if (acct.code) coaIds[acct.code] = acct.resourceId;
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Resource IDs are the universal identifier, not codes.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
*Last updated: 2026-02-08 — Extracted from chronology.md, stripped of project-specific seeder logic for portability*
|