Development Guidelines & Common Pitfalls
This document provides best practice guidelines for development based on the Lovrabet platform.
Prerequisite Reading
If you're not yet familiar with Lovrabet's tool ecosystem, we recommend reading Developer Toolchain Overview first.
Core Philosophy
AI handles standardized repetitive work, humans focus on creative value output
- AI's strengths - Rapid generation of standardized, zero-error basic features
- Human strengths - Creative thinking, industry insights, user empathy
- Perfect collaboration - AI provides infrastructure, humans build unique value
Application Scenarios
1. Mini Program Ecosystem Expansion
Build WeChat Mini Programs and Alipay Mini Programs based on enterprise data:
import { createClient } from "@lovrabet/sdk";
const client = createClient({
appCode: "your-enterprise-app",
token: wx.getStorageSync("userToken"),
});
const customerData = await client.models.customers.filter({
region: "East China",
level: "VIP",
});
2. Workflow Automation
Build complex approval processes and data processing pipelines:
const approvalWorkflow = {
trigger: await client.models.orders.filter({ status: "pending" }),
conditions: [
{ field: "amount", operator: ">", value: 10000 },
{ field: "customer.level", operator: "=", value: "VIP" },
],
actions: ["sendNotification", "createApprovalTask", "updateOrderStatus"],
};
3. Multi-System Integration Hub
Connect Lovrabet with existing enterprise systems (ERP, CRM, OA):
const dataHub = {
lovrabet: await lovrabetClient.models.products.filter(),
erp: await erpConnector.getInventory(),
crm: await crmConnector.getCustomers(),
synchronize: () => {
// Complex data sync and transformation logic
},
};
Client Management
Frontend: Singleton Pattern Reuse
// Recommended: Singleton pattern, global reuse
// src/api/client.ts
import { createClient } from "@lovrabet/sdk";
export const client = createClient({
appCode: "your-app-code",
});
// Use in components
import { client } from "@/api/client";
// Not recommended: Creating new instance each time
function MyComponent() {
const client = createClient({ appCode: "..." }); // Creates new instance on every render
}
Backend: Spring Bean Singleton
// Recommended: Use @Bean singleton
@Configuration
public class LovrabetConfig {
@Bean
public LovrabetSDKClient lovrabetSDKClient() {
return new LovrabetSDKClient(accessKey, baseUrl);
}
}
Security
AccessKey Management
# Use environment variables
export LOVRABET_ACCESS_KEY="ak-your-access-key"
// Never hardcode AccessKey in frontend
const client = createClient({
accessKey: "ak-xxx", // Dangerous! Will be exposed in browser
});
// Use Cookie or Token in browser
const client = createClient({
appCode: "your-app-code",
// Automatically uses Cookie authentication
});
Sensitive Data Masking
// Frontend: Mask phone number
const maskPhone = (phone: string) => {
return phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
};
// 138****8000
// Backend: Log masking
String maskedPhone = phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
log.info("Customer phone: {}", maskedPhone);
Performance Optimization
Pagination and Debouncing
// Use pagination
const { data } = await client.models.customers.filter({
currentPage: 1,
pageSize: 20,
});
// Debounce search
import { debounce } from "lodash-es";
const handleSearch = debounce(async (keyword) => {
await client.models.customers.filter({ searchKeyword: keyword });
}, 300);
Code Splitting
// Route lazy loading
import { lazy } from "react";
const CustomerAnalysis = lazy(() => import("./pages/CustomerAnalysis"));
Backend Caching
// Use Caffeine cache
private final Cache<String, Object> cache = Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(5, TimeUnit.MINUTES)
.build();
Error Handling
Frontend Unified Handling
try {
const result = await client.models.customers.filter(params);
if (result.success) {
setData(result.data);
} else {
message.error(result.message);
}
} catch (error) {
console.error("API call failed:", error);
message.error("Network error, please try again later");
}
Backend Retry Mechanism
public <T> LovrabetResult<T> executeWithRetry(
Supplier<LovrabetResult<T>> operation, int maxRetries) {
for (int attempt = 0; attempt <= maxRetries; attempt++) {
try {
LovrabetResult<T> result = operation.get();
if (result.isSuccess()) return result;
Thread.sleep((long) Math.pow(2, attempt) * 1000);
} catch (Exception e) {
if (attempt == maxRetries) throw new RuntimeException("Retry failed", e);
}
}
return null;
}
Logging Standards
Structured Logging
@Slf4j
public class DataService {
public void createData(Map<String, Object> data) {
long startTime = System.currentTimeMillis();
log.info("Start operation - operation={}, dataSize={}", "create", data.size());
LovrabetResult<String> result = sdkClient.create(request);
long duration = System.currentTimeMillis() - startTime;
if (result.isSuccess()) {
log.info("Operation success - id={}, duration={}ms", result.getData(), duration);
} else {
log.error("Operation failed - code={}, duration={}ms", result.getResultCode(), duration);
}
}
}
Testing Strategy
Frontend Unit Testing
import { render, screen, waitFor } from "@testing-library/react";
test("should load customers", async () => {
render(<CustomerList />);
await waitFor(() => {
expect(screen.getByText("Zhang San")).toBeInTheDocument();
});
});
Backend Integration Testing
@SpringBootTest
public class DataServiceIntegrationTest {
@Autowired
private DataService dataService;
@Test
public void testGetCustomers() {
List<Map<String, Object>> customers = dataService.getCustomers(1, 10);
assertNotNull(customers);
assertTrue(customers.size() > 0);
}
}
Deployment Recommendations
Frontend Deployment
lovrabet build
# Output in dist/ directory, deploy to CDN
Nginx Configuration:
server {
listen 80;
root /var/www/your-app/dist;
location / {
try_files $uri $uri/ /index.html;
}
location ~* \.(js|css|png|jpg|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Backend Docker Deployment
FROM openjdk:11-jre-slim
WORKDIR /app
COPY target/myapp.jar app.jar
ENV LOVRABET_ACCESS_KEY=""
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Health Check
@GetMapping("/health/lovrabet")
public Map<String, Object> checkHealth() {
Map<String, Object> health = new HashMap<>();
try {
long start = System.currentTimeMillis();
LovrabetResult<?> result = sdkClient.getDatasetCodeList(request);
health.put("status", result.isSuccess() ? "UP" : "DOWN");
health.put("responseTime", (System.currentTimeMillis() - start) + "ms");
} catch (Exception e) {
health.put("status", "DOWN");
health.put("error", e.getMessage());
}
return health;
}
Summary
| Practice Area | Key Points |
|---|---|
| Client Management | Use singleton pattern for both frontend and backend |
| Security | Never hardcode AccessKey in frontend |
| Performance | Pagination, caching, code splitting |
| Error Handling | Unified handling + retry mechanism |
| Logging | Structured logging, sensitive data masking |
| Testing | Unit tests + integration tests |
| Deployment | Health checks, containerization |
Related Documentation
- Developer Toolchain Overview - Learn about the five-tool ecosystem
- Integration Development Step-by-Step Guide - Complete process from scratch
- TypeScript SDK Guide - Frontend data operations
- Java SDK Guide - Backend data operations
- OpenAPI Documentation - HTTP API details