Qontak | Chatbot & AI | Mekari Action — Jurnal: Create Sales Order & Sales Invoice
Jurnal product-action PRD under the Mekari Action ANCHOR. This is the first per-product action catalog built on top of the shipped HMAC foundation (BOT-4210). It consumes the Phase 1 picker + one-time SSO approval + credential plumbing (Phase 1 PRD) — it does not rebuild any of it. It fills the gap Phase 1 deliberately leaves open: the actual Jurnal action tools, their HMAC scopes, and the executor/runtime acceptance criteria (excluded from Phase 1 by its S3 #9 + NEG-7).
Grounding: Jurnal API contract pulled from the live OpenAPI spec (
api-doc.jurnal.id/swagger.json, Swagger 2.0, hostapi.mekari.com, HMAC auth). BE/FE feasibility grounded inchatbot(lib/jurnal/commerce_hmac.rb,lib/mekari_hmac/signer.rb, theNodeExecutorInterfaceaction framework) andchatbot-fe(the schema-drivenDrawerActionaction-config flow).
HEADER BLOCK
| Field | Value |
|---|---|
| PM | Dimas Fauzi Hidayat |
| PRD Version | 1.1 |
| Status | DRAFT |
| PRD Type | NEW |
| Epic | TBD — Epic to be created and linked |
| Squad | BOT |
| RFC Link | Planned — RFC to be created once aligned with engineering. Parent: RFC — Mekari Internal MCP · HMAC tech doc (DONE) |
| Figma Master | N/A — no new screen. Reuses the existing Action drawer (Mekari Jurnal group); per-action details form is schema-generated. |
| Anchor | Mekari Action — ANCHOR (Confluence QON 51159335062) |
| Labels | epic:qontak-chatbot | module:ai-agent | feature:mekari-action |
| Last Updated | 2026-06-20 |
2. One-liner + Problem
One-liner: Enable the Qontak AI Agent to create a Jurnal sales order or sales invoice during a conversation — configured by a non-technical admin, authenticated via HMAC, with no API hand-wiring.
Problem: The Mekari Action HMAC foundation is shipped and the Phase 1 picker + one-time approval flow is in build, but no actual Mekari-product action exists yet — the Mekari Jurnal drawer group is scaffolded and commented out, with no backend executor behind it. So a Qontak admin who has bought Qontak + Jurnal still cannot make their AI Agent create a sales order or invoice without falling back to the generic API Integration action (manual URL, headers, body, and credential wiring — too technical for the non-developer Admin and Implementation Consultant personas). Jurnal is named as a target PUMA beta pairing (Qontak + Jurnal), so the absence of a working Jurnal action directly blocks the first cross-sell proof point this initiative exists to deliver.
3. Target Users + Persona Context
(Inherits the initiative personas from the ANCHOR S2 — CS Ops Lead / Bot Manager, Mekari Implementation Consultant, non-technical Qontak Admin. The Jurnal-specific framing:)
| Persona | Role | Goal | Pain | Workaround |
|---|---|---|---|---|
| Primary — Admin/SPV | Qontak admin/supervisor at a company running both Qontak and Jurnal | Let the AI Agent create a sales order / invoice in Jurnal from a confirmed customer order, without developer help | The Mekari Jurnal actions don't exist yet; the only path is the generic API Integration action, which needs manual HMAC signing, endpoint, and body config | Escalate order entry to a human who keys the order into Jurnal manually, or pay for a custom integration |
| Secondary — Implementation Consultant | Internal Mekari consultant onboarding a Qontak + Jurnal customer | Stand up a working order-taking agent in onboarding hours, not weeks | Every Qontak + Jurnal onboarding rebuilds the same API Integration from scratch | Hand-build the API Integration action per customer |
Design constraint (inherited): end-to-end operable by a non-technical user — no knowledge of HMAC, scopes, or the Jurnal API required.
4. Non-Goals
- No new drawer group or screen. Reuses the existing
Mekari Jurnalgroup and the schema-driven action-config drawer. No bespoke Jurnal UI. - Picker / approval / credential plumbing is out of scope — owned by the Phase 1 PRD. This PRD consumes it.
- Create only. No update, delete, list, convert-to-invoice, payments, or quote actions for Jurnal in this phase (the API supports them; deferred).
- Core fields only. Customer, transaction date, and line items. Shipping, withholding tax, discounts, custom fields, deposit, terms, and tags rely on Jurnal defaults this phase (see S7 contract).
- No master-data management. Customers and products must already exist in Jurnal; this action references them by name and does not create them.
- No AI Agent runtime/LLM behavior changes (prompt/tool selection, fallback) — owned by the parent AI Agent runtime layer (matches Phase 1 S3 #9 / NEG-7). This PRD owns the executor contract and its ACs, not model behavior.
- No multi-credential per company — one Jurnal HMAC credential per AI Agent config (Phase 3 of the ANCHOR resolves multi-CID).
5. Constraints
| Field | Value |
|---|---|
| Platform | Web only — AI Agent config UI is web-only (matches ANCHOR S8a). Action execution is server-side. |
| Performance | Jurnal create call p95 ≤ 3s end-to-end (HMAC sign + api.mekari.com round-trip). Hard timeout 10s → surfaced as a runtime failure signal. |
| Data limits | No app-imposed cap on line items per create this phase — Jurnal's own API limit applies (exact value tracked in Open Questions #4). Action-config payload: no app-imposed size cap. No new data retention — config persists with the AI Agent record; no intermediate artifacts are stored. |
| Auth | HMAC-SHA256 (date + request-line, cavage-style) via the shared mekari_hmac credential — lib/mekari_hmac/signer.rb. Client id/secret provisioned by the AL approval webhook (Phase 1). |
| Plan scope | AI Agent feature flag ON and Mekari Action add-on SKU active (compound entitlement, per ANCHOR S8a 2026-04-27). |
| Feature flag | mekari_action_enabled — default OFF, enabled per-company via the Phase 1 provisioning flow. Jurnal actions appear in the Mekari Jurnal group only when ON. |
| Read/write | Configure: Admin, Supervisor (per Phase 1). Execute: the AI Agent runtime on behalf of the configured agent. |
6. New Features
No new screen. The action-config UI is schema-driven: the existing right-side DrawerAction flow in chatbot-fe renders the form from each action's properties definition, with the per-field "Let AI decide / Set manually" toggle. Building the Jurnal actions = registering two ActionListItems under the Mekari Jurnal group + their field schema + two backend executors. No new Vue component is required.
URL / Access: /chatbot/ai-agent/{agent_id}/config → Add action → Mekari Jurnal group. Access: Admin, Supervisor (flag ON + SKU active).
Component tree (reuse — annotated):
| Component | Parent | Purpose |
|---|---|---|
NewActionDrawer.vue → Mekari Jurnal group | Action picker | Un-comment the scaffolded group; lists the two Jurnal actions |
ActionListItem "Create sales order" | Mekari Jurnal group | Opens the config drawer for jurnal_sales_order_create |
ActionListItem "Create sales invoice" | Mekari Jurnal group | Opens the config drawer for jurnal_sales_invoice_create |
DrawerAction (reused as-is) | — | Renders the config form from the action properties schema |
| Connection selector | DrawerAction | Read-only mekari_hmac Jurnal credential (provisioned via Phase 1) |
| Core field rows (customer / transaction date / line items) | DrawerAction | One row per field, each with the Let AI decide / Set manually toggle |
Two action entries (per ANCHOR S1 IA Surface — Mekari Jurnal group):
| Action | node_type | Endpoint (host api.mekari.com) |
|---|---|---|
| Create sales order | jurnal_sales_order_create | POST /public/jurnal/api/v1/sales_orders |
| Create sales invoice | jurnal_sales_invoice_create | POST /public/jurnal/api/v1/sales_invoices |
Config drawer content (both actions, identical shape):
| Section | Field | Notes |
|---|---|---|
| Identity | Action name | Required. Default e.g. "Create sales order in Jurnal". |
| Identity | When and how to trigger this action? | Required. Pre-filled trigger description. |
| Connection | Jurnal connection | The mekari_hmac credential (read-only here; created via Phase 1 approval). |
| Fields (core) | Customer (person_name) | Must be an existing customer in Jurnal (not vendor). Name, resolved by Jurnal. |
| Fields (core) | Transaction date (transaction_date) | Defaults to today if AI-filled. |
| Fields (core) | Line items (transaction_lines_attributes[]) | Repeatable: product name (product_name), quantity (quantity), rate (rate). |
Each field defaults to Let AI decide (the AI Agent fills it from the conversation); the admin can switch any field to Set manually for a fixed value.
UI States:
| State | Description |
|---|---|
| Empty | Drawer opens with default action name + trigger text, "Not connected" if no Jurnal credential, one empty line-item row. |
| Loading | Connection list and (if Set manually) product/customer lookups show inline loaders. |
| Error | Invalid/missing connection → inline error on the connection field; Save disabled until a valid Jurnal credential is selected. |
| Success | Valid config → Save enabled; action persists to the AI Agent's action set and appears in the agent's tool list. |
Figma (reference, not new design): the existing Action drawer frame in the canonical ✨ Bot - AI file (LJ6ePL0PjxKbHYZZdNK4LX) — the DrawerAction being reused. Exact node id pending V1 verification (shared open item with the ANCHOR S9 / Phase 1). No new frame to design.
7. API & Webhook Behavior
Plain-language behavior. The two creates share one request shape (wrapped in
sales_order/sales_invoice). No formalrequiredfields in the Jurnal spec, but a create functionally needs a customer, a date, and ≥1 line item.
Behavior 1: Create a Jurnal sales order
| Field | Detail |
|---|---|
| Entity affected | A new Sales Order in the company's Jurnal account. |
| Triggered by | AI Agent identifies a confirmed order intent and has resolved customer + line items. |
| Information passed | Jurnal connection (HMAC client id/secret), person_name (customer), transaction_date, and transaction_lines_attributes[] (product_name, quantity, rate). |
| Expected behavior | • Signer builds HMAC headers (Date, Authorization) over date + request-line.• POST /public/jurnal/api/v1/sales_orders with the sales_order-wrapped body.• On 2xx: returns the created order id/number to the runtime for the agent to confirm to the customer. |
| Failure behavior | • Customer or product name not found in Jurnal → 4xx; surface a runtime failure signal with the unresolved name; agent asks the customer to clarify / hands off. • Invalid/expired HMAC scope or credential → auth error; log mekari_action_credential_failed; no order created.• Timeout (>10s) → failure signal, no silent retry this phase. |
Behavior 2: Create a Jurnal sales invoice
| Field | Detail |
|---|---|
| Entity affected | A new Sales Invoice in the company's Jurnal account. |
| Triggered by | AI Agent identifies an invoice intent with resolved customer + line items. |
| Information passed | Same as Behavior 1, wrapped in sales_invoice → POST /public/jurnal/api/v1/sales_invoices. |
| Expected behavior | • Same HMAC signing path. • On 2xx: returns invoice id/number to the runtime. |
| Failure behavior | • Same name-resolution, auth, and timeout failure modes as Behavior 1. |
Claude resolves during RFC: exact HMAC scope strings (e.g. jurnal:sales_orders:create), request/response JSON, and error-code mapping — see Open Questions #1.
8. System Flow + User Stories + ACs
8.1 System Flow
Flow: Admin configures, AI Agent creates a Jurnal sales order Type: User Journey + API Sequence
- Admin opens AI Agent config → Add action → expands the
Mekari Jurnalgroup (flag ON, SKU active). - Admin selects Create sales order; the schema-driven drawer opens.
- Admin selects the Jurnal connection (provisioned via the Phase 1 approval flow), names the action, leaves core fields on Let AI decide, and saves.
- At runtime, a customer confirms an order; the AI Agent resolves
person_name+ line items from the conversation. - The
jurnal_sales_order_createexecutor signs the request with themekari_hmaccredential. - Executor calls
POST /public/jurnal/api/v1/sales_orders. - On 2xx → order id/number returned; agent confirms to the customer.
- If the customer/product name doesn't resolve in Jurnal (4xx) → failure signal logged; agent asks for clarification or hands off.
- If the credential/scope is invalid →
mekari_action_credential_failedlogged; no order created.
8.2 User Stories
[JURNAL-S01] — Configure a Jurnal create action
| User Story | As an Admin/SPV, I want to add a "Create sales order" or "Create sales invoice" Jurnal action to my AI Agent and map its core fields, so that the agent can record orders/invoices in Jurnal without me wiring an API by hand. |
| Before State | The Mekari Jurnal group is scaffolded but commented out in NewActionDrawer.vue; no Jurnal action is selectable, and no executor exists. |
| After Delta | Two actions (jurnal_sales_order_create, jurnal_sales_invoice_create) appear under Mekari Jurnal; selecting one opens the schema-driven config with a Jurnal connection selector and the core field set (customer, transaction date, line items), each with the AI/manual toggle. |
| Importance | Must Have |
| Mockup / Technical Notes | No Figma — schema-driven drawer (reuses DrawerAction). Data Fields: person_name (string) — user input/AI; transaction_date (date) — user input/AI; transaction_lines_attributes[] (product_name string, quantity int, rate int) — user input/AI; connection_id (int) — Jurnal mekari_hmac credential. |
| Acceptance Criteria | — Happy Path — • AC-1: Given flag mekari_action_enabled ON and the Mekari Action SKU active, when the Admin expands the Mekari Jurnal group, then "Create sales order" and "Create sales invoice" are listed.• AC-2: Given the Admin selects "Create sales order", when the drawer opens, then it shows action name, trigger description, a Jurnal connection selector, and the core fields (customer, transaction date, line items) each defaulting to "Let AI decide". • AC-3: Given a valid Jurnal connection is selected and required fields are configured, when the Admin clicks Save, then the action is added to the agent's action set and Save is disabled until a valid connection is selected. • AC-4: Given a saved Jurnal action, when the Admin reopens it, then they can edit its fields or remove it from the agent's action set via the drawer (Edit / Delete), the same as any other action — the configuration is fully reversible. — Error / Unhappy Path — • ERR-1: Given no Jurnal credential exists for the company, when the drawer opens, then the connection shows "Not connected" and Save stays disabled with an inline prompt to complete approval (Phase 1 flow). — Permission Model — • CAN: Admin, Supervisor with flag ON + SKU active. • CANNOT: agents/users without the flag or SKU; non-Admin/SPV roles. • Unauthorized: the Mekari Jurnal actions are not rendered (no 403).— Negative Scenarios — • NEG-1: Given core-fields-only scope, when the Admin looks for shipping/tax/discount fields, then they are not present this phase. |
Dependencies: Phase 1 picker + approval + credential plumbing.
[JURNAL-S02] — AI Agent creates a sales order
| User Story | As a configured AI Agent, I want to create a sales order in Jurnal when a customer confirms an order, so that the order is recorded without a human re-keying it. |
| Before State | None — no Jurnal executor exists; orders are entered manually by a human. |
| After Delta | A jurnal_sales_order_create executor signs via mekari_hmac and calls POST /public/jurnal/api/v1/sales_orders, returning the created order to the runtime. |
| Importance | Must Have |
| Mockup / Technical Notes | Executor follows NodeExecutorInterface; signing via lib/mekari_hmac/signer.rb; client patterned on lib/jurnal/commerce_hmac.rb#post_order. |
| Acceptance Criteria | — Happy Path — • AC-1: Given the Create sales order action is configured (flag ON) and the agent has resolved person_name + ≥1 line item, when the action fires, then the executor calls POST /public/jurnal/api/v1/sales_orders with HMAC headers and the sales_order-wrapped body.• AC-2: Given Jurnal returns 2xx, when the response is received, then the order id/number is returned to the runtime for the agent to confirm to the customer. • AC-3: Given transaction_date is left to AI and unspecified by the customer, when the action fires, then it defaults to the current date.• AC-4: Given the agent resolves N line items (N ≥ 1), when the action fires, then all N are sent in transaction_lines_attributes[]; no per-action line-item cap is imposed beyond Jurnal's own API limit (tracked in Open Questions #4).— Error / Unhappy Path — • ERR-1: Given the resolved customer or product name does not exist in Jurnal, when Jurnal returns 4xx, then no order is created, a runtime failure signal is logged with the unresolved name, and the agent asks the customer to clarify or hands off. • ERR-2: Given the HMAC credential/scope is invalid or expired, when the call is rejected, then mekari_action_credential_failed is logged and no order is created.• ERR-3: Given Jurnal does not respond within 10s, when the timeout elapses, then the call fails with a failure signal and is not silently retried this phase. • ERR-4: Given the agent resolves zero line items, when the action would fire, then it does NOT call Jurnal — it returns a "no items to record" failure signal and asks the customer to confirm at least one product. — Runtime States — (server-side executor; no drawer UI of its own) • Empty: zero resolved line items → no call; clarify with customer (ERR-4). • Loading: synchronous within the action invocation; no separate UI state. • Error: surfaced as the runtime failure signals in ERR-1/2/3. • Success: order id/number returned to the runtime for the agent to confirm. — Negative Scenarios — (from Non-Goals) • NEG-1: Given core-fields-only scope, when the agent attempts to set shipping, withholding tax, or discount, then those fields are not sent and Jurnal defaults apply this phase. • NEG-2: Given a customer/product that does not already exist in Jurnal, when the action fires, then it does NOT create master data — it fails per ERR-1 (no auto-create this phase). — Permission Model — • CAN: the AI Agent runtime for an agent with this action configured + valid credential. • CANNOT: any agent without the action or with an invalid credential. The agent CANNOT void, edit, or delete a Jurnal sales order after creation — corrections are made directly in Jurnal by an accounting user (no agent-side reversal this phase). • Unauthorized: action is not invocable; failure signal logged. |
Dependencies: JURNAL-S01.
[JURNAL-S03] — AI Agent creates a sales invoice
| User Story | As a configured AI Agent, I want to create a sales invoice in Jurnal when a customer is to be billed, so that billing is recorded directly from the conversation. |
| Before State | None — no Jurnal invoice executor exists. |
| After Delta | A jurnal_sales_invoice_create executor signs via mekari_hmac and calls POST /public/jurnal/api/v1/sales_invoices. |
| Importance | Must Have |
| Mockup / Technical Notes | Same executor pattern and signing as S02; body wrapped in sales_invoice. SI omits SO-only fields (deposit, shipping_date); not in core scope anyway. |
| Acceptance Criteria | — Happy Path — • AC-1: Given the Create sales invoice action is configured (flag ON) and the agent has resolved person_name + ≥1 line item, when the action fires, then the executor calls POST /public/jurnal/api/v1/sales_invoices with HMAC headers and the sales_invoice-wrapped body.• AC-2: Given Jurnal returns 2xx, when the response is received, then the invoice id/number is returned to the runtime. • AC-3: Given the agent resolves N line items (N ≥ 1), when the action fires, then all N are sent in transaction_lines_attributes[]; no per-action line-item cap is imposed beyond Jurnal's own API limit (tracked in Open Questions #4).— Error / Unhappy Path — • ERR-1: Given an unresolved customer/product name, when Jurnal returns 4xx, then no invoice is created and a failure signal is logged with the unresolved name. • ERR-2: Given an invalid credential/scope, when rejected, then mekari_action_credential_failed is logged and no invoice is created.• ERR-3: Given the agent resolves zero line items, when the action would fire, then it does NOT call Jurnal — it returns a "no items to record" failure signal and asks the customer to confirm at least one product. — Runtime States — (server-side executor; no drawer UI of its own) • Empty: zero resolved line items → no call; clarify with customer (ERR-3). • Loading: synchronous within the action invocation; no separate UI state. • Error: surfaced as the runtime failure signals in ERR-1/2. • Success: invoice id/number returned to the runtime. — Negative Scenarios — (from Non-Goals) • NEG-1: Given core-fields-only scope, when the agent attempts to set shipping, withholding tax, or discount, then those fields are not sent and Jurnal defaults apply this phase. • NEG-2: Given a customer/product that does not already exist in Jurnal, when the action fires, then it does NOT create master data — it fails per ERR-1 (no auto-create this phase). — Permission Model — • CAN: the AI Agent runtime for an agent with this action configured + valid credential. • CANNOT: any agent without the action or with an invalid credential. The agent CANNOT void, edit, or delete a Jurnal sales invoice after creation — corrections are made directly in Jurnal by an accounting user (no agent-side reversal this phase). • Unauthorized: action is not invocable; failure signal logged. |
Dependencies: JURNAL-S01.
9. Rollout
| Field | Value |
|---|---|
| Feature flag | mekari_action_enabled (per-company, from Phase 1) gates the Mekari Jurnal group. |
| Stage 1 | Internal QA accounts with a sandbox Jurnal company (3–5 accounts). |
| Stage 2 | Closed beta: ≥1 Qontak + Jurnal PUMA customer (manually enabled). |
| Stage 3 | All companies with the Mekari Action SKU + a Jurnal connection, on request. |
| GA | All eligible (flag ON + SKU + Jurnal connection). |
| Backward compat | Yes — purely additive; existing actions unaffected. |
| Migration | None. |
10. Observability
| Event Name | Trigger | Properties |
|---|---|---|
jurnal_action_configured | Admin saves a Jurnal create action | action_type, agent_id, company_id, timestamp |
jurnal_action_executed | Executor calls Jurnal create | action_type, agent_id, http_status, latency_ms, timestamp |
jurnal_action_failed | Jurnal create returns non-2xx or times out | action_type, failure_reason (name_not_found / auth / timeout / other), http_status, timestamp |
mekari_action_credential_failed | HMAC credential/scope rejected (shared w/ Phase 1) | company_id, action_type, timestamp |
| Field | Detail |
|---|---|
| Dashboard owner | Chatbot squad (BOT) |
| Alert 1 | jurnal_action_failed rate > 10% over 1h → Slack #chatbot-alerts |
| Alert 2 | mekari_action_credential_failed > 5 in 15m for one company → Slack #chatbot-alerts + on-call |
10.1 Post-Launch Monitoring Cadence
| Field | Detail |
|---|---|
| Review cadence | Weekly for first 4 weeks post-GA, then monthly. |
| Owner | BOT squad PM. |
| Review scope | jurnal_action_executed, jurnal_action_failed, mekari_action_credential_failed. |
| Trigger threshold 1 | jurnal_action_failed (name_not_found) > 20% for 2 consecutive weeks → revisit field-resolution UX (manual customer/product lookup). |
| Trigger threshold 2 | Credential failure rate > 2% sustained → coordinate with AL on scope/credential issues. |
| Rollback consideration | If failure rate is unrecoverable within 48h, PM disables the Jurnal actions via flag pending root cause. |
11. Success Metrics
Adoption & Usage:
| Metric | Definition | Baseline | Target |
|---|---|---|---|
| ⭐ Jurnal action adoption | # companies with ≥1 configured Jurnal action / # companies with Mekari Action SKU + Jurnal connection | N/A — new | ≥40% within 60 days of GA |
| Jurnal actions executed / week | Count of jurnal_action_executed | N/A — new | Growing WoW through beta |
Quality & Accuracy:
| Metric | Definition | Baseline | Target |
|---|---|---|---|
| Jurnal create success rate | 2xx / total executions | N/A — new | ≥95% within 60 days of GA |
| Name-resolution failure rate | name_not_found / total executions | N/A — new | ≤10% within 60 days |
Efficiency & Impact:
| Metric | Definition | Baseline | Target |
|---|---|---|---|
| PUMA proof points | Qontak + Jurnal beta customers with a live Jurnal action | 0 | ≥1 in closed beta (contributes to ANCHOR PUMA KR) |
12. Launch Plan & Stage Gates
| Stage | Audience | Duration | Success Gate to Advance | Owner |
|---|---|---|---|---|
| Internal Alpha | Internal QA + sandbox Jurnal | 2 weeks | 0 P0/P1 bugs; success rate ≥90% in sandbox | PM + QA |
| Closed Beta | ≥1 Qontak + Jurnal customer | 3 weeks | Success rate ≥95%; credential failure ≤2% | PM + CSM |
| GA | All eligible | Ongoing | Beta gates sustained 2 weeks; PMM approved | PM + PMM |
13. Dependencies
| Dependency | Owning Team | Deliverable Needed | Blocking? |
|---|---|---|---|
| Phase 1 picker + one-time approval + credential webhook | Chatbot (BOT) | Provisioned mekari_hmac Jurnal credential bound to the AI Agent config | YES |
| HMAC credential provisioning + approval | Account Launchpad (AL) | POST /v1/hmac_credential_requests → approve → signed webhook (per HMAC tech doc) | NO — DONE |
| Jurnal HMAC scopes for SO/SI create | Platform / Jurnal | Scope strings + entitlement so the issued credential can call the two create endpoints | YES |
| MCP Tool/Scope Catalog entries | Platform | jurnal_sales_order_create / jurnal_sales_invoice_create registered as MCP-backed action items | YES |
14. Key Decisions + Alternatives Rejected
14a — Decisions Made
| Date | Decision | Rationale |
|---|---|---|
| 2026-06-20 | Two separate actions (jurnal_sales_order_create, jurnal_sales_invoice_create) | Matches the one-node-per-action pattern (like Create deal vs Create ticket); clearest for the AI to disambiguate; mirrors ANCHOR S1 (Create sales order, Create invoice). |
| 2026-06-20 | Core fields only (customer, transaction date, line items) | The Jurnal create API has ~25 fields; surfacing all would bury the agent and raise AI-fill error rates. Rely on Jurnal defaults for the rest this phase. |
| 2026-06-20 | Reuse the schema-driven DrawerAction flow; no new UI | The config form is generated from the action properties; building Jurnal = a schema + executors, not a new screen. |
| 2026-06-20 | Reference customer/product by name (person_name, product_name), not ID | The Jurnal API resolves names; agents work in human terms. Mismatch handled as a runtime failure signal. |
14b — Alternatives Rejected
| Alternative | Why Rejected | Date |
|---|---|---|
| One combined "Create Jurnal transaction" action with an SO/SI toggle | Mixes two endpoints behind one tool; harder for the AI to pick correctly; less discoverable. | 2026-06-20 |
| Expose the full ~25-field schema in v1 | Heaviest config and most error-prone for AI-filled values; not needed for the core order-taking use case. | 2026-06-20 |
| Build a bespoke Jurnal config screen | Duplicates the existing schema-driven drawer; more code, more maintenance, no user benefit. | 2026-06-20 |
Reuse commerce_hmac.rb's inline signing as-is | Duplicates the canonical MekariHmac::Signer; the executor should sign via the shared signer for consistency. | 2026-06-20 |
15. Open Questions
| # | Type | Question | Owner | Deadline |
|---|---|---|---|---|
| 1 | Open Question | Exact HMAC scope strings for the two creates (e.g. jurnal:sales_orders:create) and how they map into the issued credential's scope set. | PM + Platform/AL | Before Internal Alpha |
| 2 | Open Question | How are customer/product names resolved — exact match only, or fuzzy/lookup? Determines name-not-found UX and whether a "Set manually" lookup is needed in v1. | PM + Eng | Before Closed Beta |
| 3 | Assumption | The issued mekari_hmac credential is scoped to Jurnal and can call /public/jurnal/api/v1/sales_orders and /sales_invoices (per the parent RFC's per-product scope model). | PM | Before Internal Alpha |
| 4 | Open Question | Should line-item discount and line_tax be promoted into core scope if early beta orders commonly need them? | PM | Closed Beta review |
| 5 | Risk | Jurnal company-level prerequisites (existing customers/products, account setup) may not be met in beta accounts, inflating name-not-found failures. Mitigation: beta onboarding checklist + sandbox seed data. | PM + CSM | Before Closed Beta |
PRD CHANGELOG
| Version | Date | By | Section | Type | Summary |
|---|---|---|---|---|---|
| 1.0 | 2026-06-20 | Claude | All | CREATED | Initial NEW PRD for the Jurnal Create Sales Order & Sales Invoice actions — the first per-product action catalog under the Mekari Action ANCHOR, grounded in the live Jurnal OpenAPI spec and the chatbot/chatbot-fe action framework. |
| 1.1 | 2026-06-20 | Claude | S4, S6, S8 | MODIFIED | Closed score-prd v3.3 blockers: added explicit reversibility to all 3 stories (S01 editable/removable AC-4; S02/S03 CANNOT void/edit/delete created records); added Runtime States, Negative Scenarios, zero-line-item ERR, and a volume AC to S02/S03; added annotated component tree + config URL + reused-drawer Figma reference to S6; added Data limits row + feature-flag default state to S4. |