Create Or Update Baserow Services And Integrations
Use this skill when a task involves creating or updating a Baserow integration type or service type in the contrib/integrations stack, especially when that service must be usable as one or more of:
- Application Builder data source
- Application Builder workflow action
- Automation node action
- Automation node trigger
- Dashboard data source
- Plain integration-backed service
This repo already has the core patterns. Prefer copying an existing implementation close to the target behavior instead of inventing a new structure.
Integrations and services are shared by the Application Builder, Dashboard, and Automation tools. The reusable service lives in contrib/integrations; product-specific objects usually wrap that service.
Service Usage Map
Decide the intended product surface before editing:
| Surface |
Backend wrapper |
Frontend wrapper |
Required dispatch type |
| Builder data source |
DataSource.service in backend/src/baserow/contrib/builder/data_sources/** |
Service type registered in web-frontend/modules/integrations/plugin.js and used by builder data source UI |
DispatchTypes.DATA |
| Dashboard data source |
DashboardDataSource.service in backend/src/baserow/contrib/dashboard/** |
Service type registered in integrations plugin and dashboard form/UI |
DispatchTypes.DATA |
| Builder workflow action |
BuilderWorkflowServiceActionType subclass in backend/src/baserow/contrib/builder/workflow_actions/workflow_action_types.py plus a workflow action model |
WorkflowActionType subclass in web-frontend/modules/builder/workflowActionTypes.js |
DispatchTypes.ACTION |
| Automation action node |
AutomationNodeActionNodeType subclass in backend/src/baserow/contrib/automation/nodes/node_types.py plus an automation node model |
ActionNodeTypeMixin node type in web-frontend/modules/automation/nodeTypes.js |
DispatchTypes.ACTION |
| Automation trigger node |
trigger node type in backend/src/baserow/contrib/automation/nodes/node_types.py, often using TriggerServiceTypeMixin |
TriggerNodeTypeMixin node type in web-frontend/modules/automation/nodeTypes.js |
trigger-capable service type |
For data sources, a service with DispatchTypes.DATA is normally enough because the product object points directly at the service. For workflow actions and automation nodes, also add wrapper types/models so the service appears in the action/node registries.
First Step
Before editing, identify which of these applies:
- New integration type only
- New service type attached to an existing integration
- Existing service exposed on a new surface, such as automation or builder
- Update to an existing integration, service, or wrapper type
- Full feature spanning backend, frontend, translations, and tests
Then inspect the closest existing example with grep before changing files. If
rg is available, it is a faster equivalent for the same patterns and target
paths.
Useful starting points:
- Backend registrations:
backend/src/baserow/contrib/integrations/apps.py
- Frontend registrations:
web-frontend/modules/integrations/plugin.js
- Core backend service examples:
backend/src/baserow/contrib/integrations/core/service_types.py
- Core frontend service examples:
web-frontend/modules/integrations/core/serviceTypes.js
- Backend integration example:
backend/src/baserow/contrib/integrations/core/integration_types.py
- Frontend integration example:
web-frontend/modules/integrations/core/integrationTypes.js
- Builder workflow action wrappers:
backend/src/baserow/contrib/builder/workflow_actions/workflow_action_types.py
- Automation node wrappers:
backend/src/baserow/contrib/automation/nodes/node_types.py
- Frontend builder workflow action wrappers:
web-frontend/modules/builder/workflowActionTypes.js
- Frontend automation node wrappers:
web-frontend/modules/automation/nodeTypes.js
Backend Checklist
For a new or updated service type, check these areas:
- Model fields exist and support the intended configuration.
- The
ServiceType subclass exposes the right type, model_class, dispatch_types, allowed_fields, and serializer configuration.
- Related nested objects are handled in
after_create, update helpers, or custom methods when needed.
- Context/schema methods are implemented if the service emits data for downstream nodes.
- Serialized foreign keys or IDs are migrated during import/export.
- The service is registered in
backend/src/baserow/contrib/integrations/apps.py.
- A migration is added if models changed.
For a new or updated integration type, check these areas:
- The
IntegrationType subclass defines type, model_class, serializer field names, allowed fields, and sensitive fields when relevant.
- Any integration-specific context data or permissions behavior is preserved.
- The integration is registered in
backend/src/baserow/contrib/integrations/apps.py.
- A migration is added if models changed.
Common backend files to inspect:
backend/src/baserow/contrib/integrations/*/models.py
backend/src/baserow/contrib/integrations/*/service_types.py
backend/src/baserow/contrib/integrations/*/integration_types.py
backend/src/baserow/contrib/integrations/api/**
backend/src/baserow/contrib/integrations/migrations/**
backend/src/baserow/core/services/registries.py
backend/src/baserow/contrib/builder/data_sources/**
backend/src/baserow/contrib/builder/workflow_actions/**
backend/src/baserow/contrib/automation/nodes/**
backend/src/baserow/contrib/dashboard/**
Import/Export ID Migration
When a service serializes a foreign key or path containing IDs, migrate it through
id_mapping during import.
- Use
deserialize_property() for simple fields like workflow_id, table_id,
or field_id.
- Use
create_instance_from_serialized() for nested rows or lists that must be
recreated after the service exists.
- Use
import_serialized() when IDs or UUIDs must be reserved before normal
deserialization.
- For data-provider paths, also check
import_path() and
import_context_path(). Formula fields are normally migrated separately via
the import_formula callback.
- Common keys include
automation_workflows, automation_workflow_nodes,
builder_*, database_tables, database_fields, integrations, and
services.
Examples: CoreStartWorkflowServiceType.deserialize_property() for workflow IDs,
CoreRouterServiceType for edge UIDs, local Baserow service types for table/field
IDs, and premium grouped aggregate services for nested field references. Add a
regression test that imports with an old-to-new id_mapping.
Product Surface Checklist
Builder or Dashboard data source
- Ensure the backend service type has
DispatchTypes.DATA.
- Confirm
dispatch() returns the shape expected by get_schema(), get_data_schema(), get_result(), or existing frontend consumers.
- Add frontend service type behavior for data-source UX, including form component, validation, schema helpers, result helpers, and error messages.
- Register the service in backend and frontend integration registries.
- Check data-source create/update/dispatch serializers and tests if new fields or output shape are introduced.
Builder workflow action
- Ensure the backend service type has
DispatchTypes.ACTION.
- Add or reuse a workflow action model in
backend/src/baserow/contrib/builder/workflow_actions/models.py.
- Add a
BuilderWorkflowServiceActionType subclass with type, model_class, service_type, and get_pytest_params.
- Register it in
backend/src/baserow/contrib/builder/apps.py.
- Add a frontend workflow action type in
web-frontend/modules/builder/workflowActionTypes.js that points to the service type.
- Register it in
web-frontend/modules/builder/plugin.js.
- Add translations for the action label, description, validation, and form copy.
Automation action node
- Ensure the backend service type has
DispatchTypes.ACTION.
- Add or reuse an automation node model in
backend/src/baserow/contrib/automation/nodes/models.py.
- Add an
AutomationNodeActionNodeType subclass with type, model_class, service_type, and get_pytest_params.
- Register it in
backend/src/baserow/contrib/automation/apps.py.
- Add a frontend node type using
ActionNodeTypeMixin in web-frontend/modules/automation/nodeTypes.js.
- Register it in
web-frontend/modules/automation/plugin.js.
- Add translations for the node label, default label template, description, validation, and form copy.
Automation trigger node
- Use or implement a trigger-capable service type, usually with
TriggerServiceTypeMixin.
- Add or reuse an automation trigger node model and backend node type with
is_workflow_trigger behavior via the existing trigger mixins/patterns.
- Register the backend node type in
backend/src/baserow/contrib/automation/apps.py.
- Add a frontend node type using
TriggerNodeTypeMixin.
- Register it in
web-frontend/modules/automation/plugin.js.
- Confirm sample data, output schema, edge behavior, and workflow simulation behavior match existing trigger patterns.
Frontend Checklist
If the feature is user-configurable, update the frontend in parallel with the backend:
- Add or update the service or integration type class.
- Register it in
web-frontend/modules/integrations/plugin.js.
- Add or update the form component used to configure it.
- Add translations in
web-frontend/modules/integrations/locales/en.json.
- Add any supporting mixins, helpers, or assets only if the existing pattern requires them.
- If exposed as a builder workflow action or automation node, add and register the frontend wrapper type in the relevant builder or automation module.
Common frontend files to inspect:
web-frontend/modules/integrations/*/serviceTypes.js
web-frontend/modules/integrations/*/integrationTypes.js
web-frontend/modules/integrations/*/components/services/**
web-frontend/modules/integrations/*/components/integrations/**
web-frontend/modules/integrations/locales/en.json
How To Implement
Creating a new service type
- Start from the closest existing service type with similar dispatch behavior:
ACTION, DATA, or trigger behavior.
- Add or update the backend model if the service needs persisted fields.
- Implement or extend the backend
ServiceType subclass.
- Register the service in
backend/src/baserow/contrib/integrations/apps.py.
- Implement the frontend service type class and form component.
- Register the service in
web-frontend/modules/integrations/plugin.js.
- Add product-specific wrappers only for the surfaces requested.
- Add translations and tests.
Exposing an existing service on another surface
- Check the service has the required dispatch capability for the target surface.
- Add only the missing wrapper type/model/registration for that surface.
- Reuse the existing service form and schema helpers unless the target surface genuinely needs different UX.
- Keep service
type identifiers stable and choose wrapper type identifiers consistent with nearby examples.
- Add targeted tests for the wrapper create/update/dispatch path.
Creating a new integration type
- Start from the closest existing integration type with similar auth or configuration needs.
- Add or update the backend model if required.
- Implement or extend the backend
IntegrationType subclass.
- Register the integration in
backend/src/baserow/contrib/integrations/apps.py.
- Implement the frontend integration type class and form component.
- Register the integration in
web-frontend/modules/integrations/plugin.js.
- Add translations and tests.
Updating an existing type
- Find all backend and frontend registrations for the type string.
- Check whether API serializers, nested relations, or schema generation need updates.
- Keep existing
type identifiers stable unless the user explicitly wants a breaking change.
- Check whether old records need a migration or a data backfill.
- Update tests for both create and update flows when behavior changes.
Testing Expectations
Run the narrowest relevant tests first or create one if none exists.
Backend examples:
- Integration and Service tests in
backend/tests/baserow/api/integrations/**
- Builder data source tests in
backend/tests/baserow/contrib/builder/data_sources/** and API data-source tests nearby.
- Builder workflow action tests in
backend/tests/baserow/contrib/builder/workflow_actions/** and API workflow-action tests nearby.
- Automation node tests in
backend/tests/baserow/contrib/automation/nodes/** and API node tests nearby.
- Dashboard data-source tests in
backend/tests/baserow/contrib/dashboard/** when the service is exposed there.
Frontend examples:
- Unit tests near
web-frontend/test/unit/integrations/**
- Builder workflow action and data source tests near
web-frontend/test/unit/builder/**
- Automation node tests near
web-frontend/test/unit/automation/**
Minimum validation before finishing:
- The type is registered on both backend and frontend when applicable.
- The create and update flows serialize the intended fields.
- The target product surface can create, update, serialize, import/export, and dispatch the service or wrapper.
- Output schema/sample data is available when downstream formula/data-provider features depend on it.
- Required translations exist.
- Migrations are present for model changes.
- The most relevant targeted tests pass, or the failure is reported explicitly.
Search Patterns
Use these searches to move quickly:
Use rg -n "<pattern>" <paths> as a faster equivalent when rg is available.
grep -RInE "class .*ServiceType" backend/src/baserow/contrib/integrations
grep -RInE "class .*IntegrationType" backend/src/baserow/contrib/integrations
grep -RInE "DispatchTypes\\.(ACTION|DATA)" backend/src/baserow/contrib/integrations
grep -RInE "TriggerServiceTypeMixin|ListServiceTypeMixin" backend/src/baserow/contrib/integrations
grep -RInE "register\\(" backend/src/baserow/contrib/integrations/apps.py web-frontend/modules/integrations/plugin.js
grep -RInE "BuilderWorkflowServiceActionType|builder_workflow_action_type_registry" backend/src/baserow/contrib/builder
grep -RInE "AutomationNodeActionNodeType|TriggerNodeType|automation_node_type_registry" backend/src/baserow/contrib/automation
grep -RInE "WorkflowActionType|register\\('workflowAction'" web-frontend/modules/builder
grep -RInE "ActionNodeTypeMixin|TriggerNodeTypeMixin|register\\('node'" web-frontend/modules/automation
grep -RInE "getType\\(\\)" web-frontend/modules/integrations
grep -RInE "\"serviceType\\.|integrationType\\.\"" web-frontend/modules/integrations/locales/en.json
Guardrails
- Do not add a backend type without checking the matching frontend registration path.
- Do not rename a persisted
type string casually.
- Do not forget migrations when model fields change.
- Do not expose a service as a data source unless it can be dispatched as
DispatchTypes.DATA.
- Do not expose a service as a workflow action or action node unless it can be dispatched as
DispatchTypes.ACTION.
- Do not add automation or builder wrappers when a plain data source service registration is sufficient.
- Do not add broad abstractions unless at least two existing implementations already need them.
- Prefer matching the nearest existing module layout over introducing a new folder structure.
1---2name: create-update-service3description: Create or update Baserow integration and service types, including services exposed as Application Builder data sources, Builder workflow actions, Automation node actions, Automation node triggers, or dashboard data sources. Use when adding a ServiceType/IntegrationType subclass, registering backend/frontend types, or wiring service wrappers in builder or automation.4---56# Create Or Update Baserow Services And Integrations78Use this skill when a task involves creating or updating a Baserow integration type or service type in the `contrib/integrations` stack, especially when that service must be usable as one or more of:910- Application Builder data source11- Application Builder workflow action12- Automation node action13- Automation node trigger14- Dashboard data source15- Plain integration-backed service1617This repo already has the core patterns. Prefer copying an existing implementation close to the target behavior instead of inventing a new structure.1819Integrations and services are shared by the Application Builder, Dashboard, and Automation tools. The reusable service lives in `contrib/integrations`; product-specific objects usually wrap that service.2021## Service Usage Map2223Decide the intended product surface before editing:2425| Surface | Backend wrapper | Frontend wrapper | Required dispatch type |26|---|---|---|---|27| Builder data source | `DataSource.service` in `backend/src/baserow/contrib/builder/data_sources/**` | Service type registered in `web-frontend/modules/integrations/plugin.js` and used by builder data source UI | `DispatchTypes.DATA` |28| Dashboard data source | `DashboardDataSource.service` in `backend/src/baserow/contrib/dashboard/**` | Service type registered in integrations plugin and dashboard form/UI | `DispatchTypes.DATA` |29| Builder workflow action | `BuilderWorkflowServiceActionType` subclass in `backend/src/baserow/contrib/builder/workflow_actions/workflow_action_types.py` plus a workflow action model | `WorkflowActionType` subclass in `web-frontend/modules/builder/workflowActionTypes.js` | `DispatchTypes.ACTION` |30| Automation action node | `AutomationNodeActionNodeType` subclass in `backend/src/baserow/contrib/automation/nodes/node_types.py` plus an automation node model | `ActionNodeTypeMixin` node type in `web-frontend/modules/automation/nodeTypes.js` | `DispatchTypes.ACTION` |31| Automation trigger node | trigger node type in `backend/src/baserow/contrib/automation/nodes/node_types.py`, often using `TriggerServiceTypeMixin` | `TriggerNodeTypeMixin` node type in `web-frontend/modules/automation/nodeTypes.js` | trigger-capable service type |3233For data sources, a service with `DispatchTypes.DATA` is normally enough because the product object points directly at the service. For workflow actions and automation nodes, also add wrapper types/models so the service appears in the action/node registries.3435## First Step3637Before editing, identify which of these applies:38391. New integration type only402. New service type attached to an existing integration413. Existing service exposed on a new surface, such as automation or builder424. Update to an existing integration, service, or wrapper type435. Full feature spanning backend, frontend, translations, and tests4445Then inspect the closest existing example with `grep` before changing files. If46`rg` is available, it is a faster equivalent for the same patterns and target47paths.4849Useful starting points:5051- Backend registrations: `backend/src/baserow/contrib/integrations/apps.py`52- Frontend registrations: `web-frontend/modules/integrations/plugin.js`53- Core backend service examples: `backend/src/baserow/contrib/integrations/core/service_types.py`54- Core frontend service examples: `web-frontend/modules/integrations/core/serviceTypes.js`55- Backend integration example: `backend/src/baserow/contrib/integrations/core/integration_types.py`56- Frontend integration example: `web-frontend/modules/integrations/core/integrationTypes.js`57- Builder workflow action wrappers: `backend/src/baserow/contrib/builder/workflow_actions/workflow_action_types.py`58- Automation node wrappers: `backend/src/baserow/contrib/automation/nodes/node_types.py`59- Frontend builder workflow action wrappers: `web-frontend/modules/builder/workflowActionTypes.js`60- Frontend automation node wrappers: `web-frontend/modules/automation/nodeTypes.js`6162## Backend Checklist6364For a new or updated service type, check these areas:65661. Model fields exist and support the intended configuration.672. The `ServiceType` subclass exposes the right `type`, `model_class`, `dispatch_types`, `allowed_fields`, and serializer configuration.683. Related nested objects are handled in `after_create`, update helpers, or custom methods when needed.694. Context/schema methods are implemented if the service emits data for downstream nodes.705. Serialized foreign keys or IDs are migrated during import/export.716. The service is registered in `backend/src/baserow/contrib/integrations/apps.py`.727. A migration is added if models changed.7374For a new or updated integration type, check these areas:75761. The `IntegrationType` subclass defines `type`, `model_class`, serializer field names, allowed fields, and sensitive fields when relevant.772. Any integration-specific context data or permissions behavior is preserved.783. The integration is registered in `backend/src/baserow/contrib/integrations/apps.py`.794. A migration is added if models changed.8081Common backend files to inspect:8283- `backend/src/baserow/contrib/integrations/*/models.py`84- `backend/src/baserow/contrib/integrations/*/service_types.py`85- `backend/src/baserow/contrib/integrations/*/integration_types.py`86- `backend/src/baserow/contrib/integrations/api/**`87- `backend/src/baserow/contrib/integrations/migrations/**`88- `backend/src/baserow/core/services/registries.py`89- `backend/src/baserow/contrib/builder/data_sources/**`90- `backend/src/baserow/contrib/builder/workflow_actions/**`91- `backend/src/baserow/contrib/automation/nodes/**`92- `backend/src/baserow/contrib/dashboard/**`9394### Import/Export ID Migration9596When a service serializes a foreign key or path containing IDs, migrate it through97`id_mapping` during import.9899- Use `deserialize_property()` for simple fields like `workflow_id`, `table_id`,100 or `field_id`.101- Use `create_instance_from_serialized()` for nested rows or lists that must be102 recreated after the service exists.103- Use `import_serialized()` when IDs or UUIDs must be reserved before normal104 deserialization.105- For data-provider paths, also check `import_path()` and106 `import_context_path()`. Formula fields are normally migrated separately via107 the `import_formula` callback.108- Common keys include `automation_workflows`, `automation_workflow_nodes`,109 `builder_*`, `database_tables`, `database_fields`, `integrations`, and110 `services`.111112Examples: `CoreStartWorkflowServiceType.deserialize_property()` for workflow IDs,113`CoreRouterServiceType` for edge UIDs, local Baserow service types for table/field114IDs, and premium grouped aggregate services for nested field references. Add a115regression test that imports with an old-to-new `id_mapping`.116117## Product Surface Checklist118119### Builder or Dashboard data source1201211. Ensure the backend service type has `DispatchTypes.DATA`.1222. Confirm `dispatch()` returns the shape expected by `get_schema()`, `get_data_schema()`, `get_result()`, or existing frontend consumers.1233. Add frontend service type behavior for data-source UX, including form component, validation, schema helpers, result helpers, and error messages.1244. Register the service in backend and frontend integration registries.1255. Check data-source create/update/dispatch serializers and tests if new fields or output shape are introduced.126127### Builder workflow action1281291. Ensure the backend service type has `DispatchTypes.ACTION`.1302. Add or reuse a workflow action model in `backend/src/baserow/contrib/builder/workflow_actions/models.py`.1313. Add a `BuilderWorkflowServiceActionType` subclass with `type`, `model_class`, `service_type`, and `get_pytest_params`.1324. Register it in `backend/src/baserow/contrib/builder/apps.py`.1335. Add a frontend workflow action type in `web-frontend/modules/builder/workflowActionTypes.js` that points to the service type.1346. Register it in `web-frontend/modules/builder/plugin.js`.1357. Add translations for the action label, description, validation, and form copy.136137### Automation action node1381391. Ensure the backend service type has `DispatchTypes.ACTION`.1402. Add or reuse an automation node model in `backend/src/baserow/contrib/automation/nodes/models.py`.1413. Add an `AutomationNodeActionNodeType` subclass with `type`, `model_class`, `service_type`, and `get_pytest_params`.1424. Register it in `backend/src/baserow/contrib/automation/apps.py`.1435. Add a frontend node type using `ActionNodeTypeMixin` in `web-frontend/modules/automation/nodeTypes.js`.1446. Register it in `web-frontend/modules/automation/plugin.js`.1457. Add translations for the node label, default label template, description, validation, and form copy.146147### Automation trigger node1481491. Use or implement a trigger-capable service type, usually with `TriggerServiceTypeMixin`.1502. Add or reuse an automation trigger node model and backend node type with `is_workflow_trigger` behavior via the existing trigger mixins/patterns.1513. Register the backend node type in `backend/src/baserow/contrib/automation/apps.py`.1524. Add a frontend node type using `TriggerNodeTypeMixin`.1535. Register it in `web-frontend/modules/automation/plugin.js`.1546. Confirm sample data, output schema, edge behavior, and workflow simulation behavior match existing trigger patterns.155156## Frontend Checklist157158If the feature is user-configurable, update the frontend in parallel with the backend:1591601. Add or update the service or integration type class.1612. Register it in `web-frontend/modules/integrations/plugin.js`.1623. Add or update the form component used to configure it.1634. Add translations in `web-frontend/modules/integrations/locales/en.json`.1645. Add any supporting mixins, helpers, or assets only if the existing pattern requires them.1656. If exposed as a builder workflow action or automation node, add and register the frontend wrapper type in the relevant builder or automation module.166167Common frontend files to inspect:168169- `web-frontend/modules/integrations/*/serviceTypes.js`170- `web-frontend/modules/integrations/*/integrationTypes.js`171- `web-frontend/modules/integrations/*/components/services/**`172- `web-frontend/modules/integrations/*/components/integrations/**`173- `web-frontend/modules/integrations/locales/en.json`174175## How To Implement176177### Creating a new service type1781791. Start from the closest existing service type with similar dispatch behavior:180 `ACTION`, `DATA`, or trigger behavior.1812. Add or update the backend model if the service needs persisted fields.1823. Implement or extend the backend `ServiceType` subclass.1834. Register the service in `backend/src/baserow/contrib/integrations/apps.py`.1845. Implement the frontend service type class and form component.1856. Register the service in `web-frontend/modules/integrations/plugin.js`.1867. Add product-specific wrappers only for the surfaces requested.1878. Add translations and tests.188189### Exposing an existing service on another surface1901911. Check the service has the required dispatch capability for the target surface.1922. Add only the missing wrapper type/model/registration for that surface.1933. Reuse the existing service form and schema helpers unless the target surface genuinely needs different UX.1944. Keep service `type` identifiers stable and choose wrapper `type` identifiers consistent with nearby examples.1955. Add targeted tests for the wrapper create/update/dispatch path.196197### Creating a new integration type1981991. Start from the closest existing integration type with similar auth or configuration needs.2002. Add or update the backend model if required.2013. Implement or extend the backend `IntegrationType` subclass.2024. Register the integration in `backend/src/baserow/contrib/integrations/apps.py`.2035. Implement the frontend integration type class and form component.2046. Register the integration in `web-frontend/modules/integrations/plugin.js`.2057. Add translations and tests.206207### Updating an existing type2082091. Find all backend and frontend registrations for the type string.2102. Check whether API serializers, nested relations, or schema generation need updates.2113. Keep existing `type` identifiers stable unless the user explicitly wants a breaking change.2124. Check whether old records need a migration or a data backfill.2135. Update tests for both create and update flows when behavior changes.214215## Testing Expectations216217Run the narrowest relevant tests first or create one if none exists.218219Backend examples:220221- Integration and Service tests in `backend/tests/baserow/api/integrations/**`222- Builder data source tests in `backend/tests/baserow/contrib/builder/data_sources/**` and API data-source tests nearby.223- Builder workflow action tests in `backend/tests/baserow/contrib/builder/workflow_actions/**` and API workflow-action tests nearby.224- Automation node tests in `backend/tests/baserow/contrib/automation/nodes/**` and API node tests nearby.225- Dashboard data-source tests in `backend/tests/baserow/contrib/dashboard/**` when the service is exposed there.226227Frontend examples:228229- Unit tests near `web-frontend/test/unit/integrations/**`230- Builder workflow action and data source tests near `web-frontend/test/unit/builder/**`231- Automation node tests near `web-frontend/test/unit/automation/**`232233Minimum validation before finishing:2342351. The type is registered on both backend and frontend when applicable.2362. The create and update flows serialize the intended fields.2373. The target product surface can create, update, serialize, import/export, and dispatch the service or wrapper.2384. Output schema/sample data is available when downstream formula/data-provider features depend on it.2395. Required translations exist.2406. Migrations are present for model changes.2417. The most relevant targeted tests pass, or the failure is reported explicitly.242243## Search Patterns244245Use these searches to move quickly:246247Use `rg -n "<pattern>" <paths>` as a faster equivalent when `rg` is available.248249- `grep -RInE "class .*ServiceType" backend/src/baserow/contrib/integrations`250- `grep -RInE "class .*IntegrationType" backend/src/baserow/contrib/integrations`251- `grep -RInE "DispatchTypes\\.(ACTION|DATA)" backend/src/baserow/contrib/integrations`252- `grep -RInE "TriggerServiceTypeMixin|ListServiceTypeMixin" backend/src/baserow/contrib/integrations`253- `grep -RInE "register\\(" backend/src/baserow/contrib/integrations/apps.py web-frontend/modules/integrations/plugin.js`254- `grep -RInE "BuilderWorkflowServiceActionType|builder_workflow_action_type_registry" backend/src/baserow/contrib/builder`255- `grep -RInE "AutomationNodeActionNodeType|TriggerNodeType|automation_node_type_registry" backend/src/baserow/contrib/automation`256- `grep -RInE "WorkflowActionType|register\\('workflowAction'" web-frontend/modules/builder`257- `grep -RInE "ActionNodeTypeMixin|TriggerNodeTypeMixin|register\\('node'" web-frontend/modules/automation`258- `grep -RInE "getType\\(\\)" web-frontend/modules/integrations`259- `grep -RInE "\"serviceType\\.|integrationType\\.\"" web-frontend/modules/integrations/locales/en.json`260261## Guardrails262263- Do not add a backend type without checking the matching frontend registration path.264- Do not rename a persisted `type` string casually.265- Do not forget migrations when model fields change.266- Do not expose a service as a data source unless it can be dispatched as `DispatchTypes.DATA`.267- Do not expose a service as a workflow action or action node unless it can be dispatched as `DispatchTypes.ACTION`.268- Do not add automation or builder wrappers when a plain data source service registration is sufficient.269- Do not add broad abstractions unless at least two existing implementations already need them.270- Prefer matching the nearest existing module layout over introducing a new folder structure.