Skip to main content

Advanced Case 1: Tech Teams Encapsulate Complex Logic for Business Operations

Overview

The basic guide shows the simplest scenario: a user says one sentence, and the AI auto-creates a requirement. But in real ToB operations, many tasks go far beyond simple CRUD on a single table — changing a requirement's status, for example, requires updating the main table, writing a history record, and notifying stakeholders, all at once.

This case study uses "requirement status change" as an example to demonstrate: when business logic involves multi-table writes, state transition validation, and transactional consistency, how the tech team can build a function endpoint, and how the AI loads a Skill to complete the entire flow with a single sentence.


Business Scenario: Why Function Endpoints Are Needed

In the basic guide, the AI can directly operate on the database. But in real-world business, many operations have stricter requirements:

Strong validation: Status must flow in order (New → Assigned → In Progress → Testing → Completed → Closed). You can't jump from New directly to Completed.

Data consistency: When changing status, you must simultaneously record who changed it, when, and from what to what — the main table and history table must both update, and one cannot succeed while the other fails.

Transactional guarantees: An operation touches multiple tables. If any write fails, everything must roll back.

In these scenarios, the tech team needs to build a function endpoint that encapsulates validation logic and transaction guarantees, registers it on the platform, and lets the AI call it. Business users don't need to know what SQL is inside the function or how many writes it does — they just call the endpoint, and data consistency is guaranteed by the tech layer.


Technical Implementation: Building the Function

Registration Path

The function is an independent endpoint script (ENDPOINT). After registration, it's accessible via:

POST /api/endpoint/{appCode}/{scriptName}

This example uses:

  • Script name: update_requirement_status
  • App: app-173e8652 (Qizhi Yuntu)
  • Full path: POST /api/endpoint/app-173e8652/update_requirement_status

Prerequisites

Before development, the tech team should confirm:

  • App app-173e8652 exists and has yt_requirements (main requirements table) and yt_requirement_history (status history table) data models
  • The operator has write permissions for both models

Function Code

The tech team implements the status change with simultaneous main table update and history record creation:

/**
* Requirement status change (dual-write: main table + history table)
* Script name: update_requirement_status
* App: app-173e8652
*/
export default async function updateRequirementStatus(params, context) {
const { id, new_status, operator_id, reason } = params;

// -------- Part 1: Query and Validation --------

// 1. Query current requirement info
const requirement = await context.client.models.yt_requirements.findOne({
id: id,
});

if (!requirement) {
throw new Error("Requirement not found");
}

const oldStatus = requirement.status;

// 2. Validate state transition
const validTransitions = {
new: ["assigned", "closed"],
assigned: ["in_progress", "closed"],
in_progress: ["testing", "closed"],
testing: ["completed", "in_progress"],
completed: ["closed"],
closed: [],
};

if (!validTransitions[oldStatus]?.includes(new_status)) {
throw new Error(
`Status cannot transition from ${oldStatus} to ${new_status}`
);
}

// -------- Part 2: Dual Write (Transactional) --------
// The system detects write operations and auto-starts a Best Effort 1PC transaction
// No manual commit/rollback needed — normal return = commit, exception = rollback

// 3. Update main table: requirement status
await context.client.models.yt_requirements.update({
id: id,
status: new_status,
});

// 4. Write history table: change record
await context.client.models.yt_requirement_history.create({
requirement_id: id,
user_id: operator_id,
field_name: "status",
old_value: oldStatus,
new_value: new_status,
created_at: new Date().toISOString(),
});

// -------- Part 3: Return Result --------
return {
success: true,
requirement_id: id,
old_status: oldStatus,
new_status: new_status,
operator_id: operator_id,
message: "Status updated successfully, history record synced",
};
}

Transaction Mechanism

Lovrabet uses a Best Effort 1PC transaction model. The tech team never manages transactions manually:

TimingBehavior
Read operations (findOne / getList)No transaction, no connection held
First write operation (update / create)Transaction auto-starts
Subsequent writesAuto-join the same transaction
Script returns normallyAuto-commit all transactions
Script throws an exceptionAuto-rollback all transactions

The tech team just writes logic in business order. Transactions are managed automatically by the platform.


Skill Encapsulation: One Sentence for Business Users

Once the function endpoint is ready, how do business users interact with it?

Encapsulate the flow into a Skill. The AI loads it and automatically: confirms the requirement exists → calls the function → notifies stakeholders.

Skill Template

---
name: update_requirement_status
version: 0.1.0
description: "Requirement status change. Trigger words: mark as completed, change requirement to, update requirement status."
---

# Requirement Status Change

## Step 1: Confirm the requirement exists

Query whether the requirement ID provided by the user exists and what its current status is. If not found, inform the user and stop.

## Step 2: Change status and record history

Call the update_requirement_status endpoint to simultaneously:
- Update the requirement status to the user-specified value
- Create a history record (original status, new status, operator, timestamp)

If the endpoint returns failure, inform the user of the reason and stop.

## Step 3: Notify the requirement creator

Look up who created the requirement and send them an email or Lark message:
- Which requirement had a status change
- What the new status is

## Notes

- Status values must be valid (new / assigned / in_progress / testing / completed / closed)
- If the user hasn't specified a reason, ask before proceeding
- Step 3 notification is informational only, no further action required
- Do NOT call the raw dataset API directly

Usage Example

User Input

Mark the requirement "App theme auto-adapts to phone case color" as completed

AI Automatically

Loads Skill → Confirms requirement exists → Calls function endpoint (main table update + history write in one transaction) → Notifies the requirement creator

Example Output

✅ Status updated
━━━━━━━━━━━━━━━━━━
Requirement ID: 305
Title: App theme auto-adapts to phone case color
Status: In Progress → Completed
Operator: Zixuan
Change history: Recorded
━━━━━━━━━━━━━━━━━━
Notification: Email sent to requirement creator

FAQ

Q: Do I need to set up my own infrastructure to develop function endpoints?

No. Just develop and register scripts under your existing Lovrabet app. Transactions, connection management, and access control are all provided by the platform. You can use the Rabetbase CLI developer toolkit.

Q: Isn't it hard to maintain state transition rules inside a function?

It's far safer than exposing the database directly to AI. When rules change, the tech team only updates the function code — the Skill and AI prompts don't need any changes.

Q: What if the function endpoint returns an error?

Check the error message. Common causes: requirement ID doesn't exist, invalid status transition, insufficient permissions. Errors are passed through to the AI, which will inform the user.

Q: Do business users need to know the valid status values?

No. The Skill already defines the valid values. Business users just say "mark as completed" and the AI maps it to the correct status code.

Q: What if we need to add more dimensions later, like priority change records?

Just add history table fields in the function. The Skill describes business steps, not specific field names.