Flow Model
The Flow model represents automation test flows that can be executed on Android devices. It contains the flow definition, execution logic, and caching information.
Schema Definition
model Flow {
id String @id @default(uuid())
name String
testInstructions String
targetDevice String
setupHooks String[]
tearDownHooks String[]
cachedParsedCommand Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
cachedSetupHooks Json?
cachedTeardownHooks Json?
displayOrder Int @default(0)
isSubflow Boolean @default(false)
labels String[] @default([])
subflowReferences Json?
coordinateCache FlowCoordinateCache[]
recordings Recording[]
}
Field Descriptions
Primary Fields
| Field | Type | Description |
|---|---|---|
id | String | UUID primary key |
name | String | Human-readable flow name |
testInstructions | String | Natural language description of what the flow does |
targetDevice | String | Target device identifier for execution |
Hook System (Legacy)
| Field | Type | Description |
|---|---|---|
setupHooks | String[] | Array of raw command strings to run before flow execution |
tearDownHooks | String[] | Array of raw command strings to run after flow execution |
Cached Data
| Field | Type | Description |
|---|---|---|
cachedParsedCommand | Json? | Parsed and structured command representation |
cachedSetupHooks | Json? | Processed setup hook data |
cachedTeardownHooks | Json? | Processed teardown hook data |
Organization
| Field | Type | Description |
|---|---|---|
displayOrder | Int | Order for displaying flows in UI (default: 0) |
isSubflow | Boolean | Whether this flow can be used as a subflow (default: false) |
labels | String[] | Array of label strings for organization |
subflowReferences | Json? | Structured references to setup/teardown subflows |
Metadata
| Field | Type | Description |
|---|---|---|
createdAt | DateTime | Creation timestamp |
updatedAt | DateTime | Last update timestamp |
Relationships
One-to-Many
- coordinateCache:
FlowCoordinateCache[]- Cached UI element coordinates for this flow - recordings:
Recording[]- Associated automation session recordings
Usage Examples
Creating a Basic Flow
const flow = await prisma.flow.create({
data: {
name: "Login Test",
testInstructions: "Test user login functionality",
targetDevice: "emulator-5554",
labels: ["authentication", "smoke-test"]
}
});
Creating a Flow with Hooks
const flow = await prisma.flow.create({
data: {
name: "Complete User Journey",
testInstructions: "Test full user registration and login",
targetDevice: "device-123",
setupHooks: [
"launch_app com.example.app",
"wait 2000"
],
tearDownHooks: [
"force_stop com.example.app"
],
labels: ["registration", "integration"]
}
});
Creating a Subflow
const subflow = await prisma.flow.create({
data: {
name: "Login Helper",
testInstructions: "Reusable login steps",
targetDevice: "any",
isSubflow: true,
labels: ["helper", "authentication"]
}
});
Flow with Subflow References
const flow = await prisma.flow.create({
data: {
name: "E-commerce Test Suite",
testInstructions: "Complete e-commerce user journey",
targetDevice: "device-456",
subflowReferences: {
setupSubflowReferences: [
{
flowId: "setup-environment",
preSubflowDelay: 1000,
postSubflowDelay: 500
}
],
teardownSubflowReferences: [
{
flowId: "cleanup-data",
preSubflowDelay: 0,
postSubflowDelay: 1000
}
]
},
labels: ["ecommerce", "integration"]
}
});
Query Examples
Find Flows by Labels
const authFlows = await prisma.flow.findMany({
where: {
labels: {
hasSome: ["authentication"]
}
}
});
Get Flow with Relations
const flow = await prisma.flow.findUnique({
where: { id: "flow-123" },
include: {
coordinateCache: true,
recordings: {
orderBy: { createdAt: "desc" },
take: 5
}
}
});
Get Flows for Device
const deviceFlows = await prisma.flow.findMany({
where: {
OR: [
{ targetDevice: "emulator-5554" },
{ targetDevice: "any" }
]
},
orderBy: { displayOrder: "asc" }
});
Update Flow Labels
await prisma.flow.update({
where: { id: "flow-123" },
data: {
labels: {
push: "new-label"
}
}
});
Migration Notes
From Legacy Hooks to Subflows
The schema supports both legacy string-based hooks and modern subflow references:
Legacy (still supported):
{
"setupHooks": ["launch_app com.example.app", "wait 2000"],
"tearDownHooks": ["force_stop com.example.app"]
}
Modern (recommended):
{
"subflowReferences": {
"setupSubflowReferences": [
{
"flowId": "app-launch-flow",
"preSubflowDelay": 1000,
"postSubflowDelay": 500
}
]
}
}
Coordinate Caching
UI element coordinates are cached separately in FlowCoordinateCache for performance. This allows different coordinate sets for the same flow on different devices/screen sizes.
Recording Association
Recordings are linked to flows to provide execution history and debugging capabilities. Multiple recordings can be associated with a single flow.
Performance Considerations
Indexing
- Primary key on
id - Consider index on
targetDevicefor device-specific queries - Consider GIN index on
labelsfor label filtering - Index on
displayOrderfor sorted listings - Index on
isSubflowfor subflow filtering
Query Optimization
- Use
selectto fetch only needed fields - Include relations only when necessary
- Use pagination for large result sets
- Cache frequently accessed flows
Data Volume
- JSON fields can store complex data structures
- Consider archiving old execution data
- Regular cleanup of unused coordinate cache entries