Skip to main content

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​

FieldTypeDescription
idStringUUID primary key
nameStringHuman-readable flow name
testInstructionsStringNatural language description of what the flow does
targetDeviceStringTarget device identifier for execution

Hook System (Legacy)​

FieldTypeDescription
setupHooksString[]Array of raw command strings to run before flow execution
tearDownHooksString[]Array of raw command strings to run after flow execution

Cached Data​

FieldTypeDescription
cachedParsedCommandJson?Parsed and structured command representation
cachedSetupHooksJson?Processed setup hook data
cachedTeardownHooksJson?Processed teardown hook data

Organization​

FieldTypeDescription
displayOrderIntOrder for displaying flows in UI (default: 0)
isSubflowBooleanWhether this flow can be used as a subflow (default: false)
labelsString[]Array of label strings for organization
subflowReferencesJson?Structured references to setup/teardown subflows

Metadata​

FieldTypeDescription
createdAtDateTimeCreation timestamp
updatedAtDateTimeLast 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 targetDevice for device-specific queries
  • Consider GIN index on labels for label filtering
  • Index on displayOrder for sorted listings
  • Index on isSubflow for subflow filtering

Query Optimization​

  • Use select to 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