Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .agents/skills/add-django-config-env-var/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
name: add-django-config-env-var
description: Add a new environment variable for a Django setting in Baserow and propagate it to the few repo files that usually need it. Use this when a request says a config env var must be added in several places or references `INTEGRATION_LOCAL_BASEROW_PAGE_SIZE_LIMIT` as the pattern to follow.
---

# Add Django Config Env Var

Use `INTEGRATION_LOCAL_BASEROW_PAGE_SIZE_LIMIT` as the template. The env var name should be prefixed with `BASEROW_` but the internal var isn't.

Keep the change simple and explicit. Do not add abstractions for this.

## Files To Check

When adding a new setting, usually check these files:

- `backend/src/baserow/config/settings/base.py`
- `docker-compose.yml`
- `docker-compose.no-caddy.yml`
- `web-frontend/env-remap.mjs`
- Backend or frontend code that uses the setting
- A focused test if behavior changes

## Workflow

1. Add the Django setting in `backend/src/baserow/config/settings/base.py` near the closest related setting.

Example:

```python
MY_SETTING = int(os.getenv("BASEROW_MY_SETTING", 123))
```

2. If the variable should be configurable in Docker, add it everywhere the similar example appears in:

- `docker-compose.yml`
- `docker-compose.no-caddy.yml`

3. If the frontend needs it at runtime, add it to `web-frontend/env-remap.mjs`.

4. Update consumers to use the setting:

- Backend: `settings.MY_SETTING`
- Tests: `override_settings(MY_SETTING=...)`

5. Add or update a targeted test if the setting changes behavior.

6. Add the related documentation

## Quick Checklist

1. Add it in `base.py`
2. Mirror the matching Docker entries
3. Add the Nuxt remap if frontend code needs it
4. Use `settings.<NAME>` in code
5. Add a focused test if needed
6. Add the documentation

## Guardrails

- Do not add a raw `os.getenv(...)` in application code when the value belongs in Django settings.
- Do not update only one Docker location if the example appears in several places.
- Do not expose a backend-only setting to Nuxt unless the frontend actually needs it.
- Prefer copying the closest existing setting instead of inventing a new pattern.
4 changes: 4 additions & 0 deletions .agents/skills/add-django-config-env-var/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "Add Django Config Env Var"
short_description: "Add and propagate a Django env variable"
default_prompt: "Use $add-django-config-env-var to add a new environment variable that changes Django configuration across Baserow."
145 changes: 145 additions & 0 deletions .agents/skills/create-update-service/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
name: create-update-service
description: Allow to create or update Baserow Integrations and Services
---

# 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.

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 and the Automation tool. Each of them should be compatible with both tools.

## First Step

Before editing, identify which of these applies:

1. New integration type only
2. New service type attached to an existing integration
3. Update to an existing integration or service
4. Full feature spanning backend, frontend, translations, and tests

Then inspect the closest existing example with `rg` before changing files.

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`

## Backend Checklist

For a new or updated service type, check these areas:

1. Model fields exist and support the intended configuration.
2. The `ServiceType` subclass exposes the right `type`, `model_class`, `dispatch_types`, `allowed_fields`, and serializer configuration.
3. Related nested objects are handled in `after_create`, update helpers, or custom methods when needed.
4. Context/schema methods are implemented if the service emits data for downstream nodes.
5. The service is registered in `backend/src/baserow/contrib/integrations/apps.py`.
6. A migration is added if models changed.

For a new or updated integration type, check these areas:

1. The `IntegrationType` subclass defines `type`, `model_class`, serializer field names, allowed fields, and sensitive fields when relevant.
2. Any integration-specific context data or permissions behavior is preserved.
3. The integration is registered in `backend/src/baserow/contrib/integrations/apps.py`.
4. 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/**`

## Frontend Checklist

If the feature is user-configurable, update the frontend in parallel with the backend:

1. Add or update the service or integration type class.
2. Register it in `web-frontend/modules/integrations/plugin.js`.
3. Add or update the form component used to configure it.
4. Add translations in `web-frontend/modules/integrations/locales/en.json`.
5. Add any supporting mixins, helpers, or assets only if the existing pattern requires them.

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

1. Start from the closest existing service type with similar dispatch behavior:
`ACTION`, `DATA`, or trigger behavior.
2. Add or update the backend model if the service needs persisted fields.
3. Implement or extend the backend `ServiceType` subclass.
4. Register the service in `backend/src/baserow/contrib/integrations/apps.py`.
5. Implement the frontend service type class and form component.
6. Register the service in `web-frontend/modules/integrations/plugin.js`.
7. Add translations and tests.

### Creating a new integration type

1. Start from the closest existing integration type with similar auth or configuration needs.
2. Add or update the backend model if required.
3. Implement or extend the backend `IntegrationType` subclass.
4. Register the integration in `backend/src/baserow/contrib/integrations/apps.py`.
5. Implement the frontend integration type class and form component.
6. Register the integration in `web-frontend/modules/integrations/plugin.js`.
7. Add translations and tests.

### Updating an existing type

1. Find all backend and frontend registrations for the type string.
2. Check whether API serializers, nested relations, or schema generation need updates.
3. Keep existing `type` identifiers stable unless the user explicitly wants a breaking change.
4. Check whether old records need a migration or a data backfill.
5. 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/**`

Frontend examples:

- Unit tests near `web-frontend/test/unit/integrations/**`

Minimum validation before finishing:

1. The type is registered on both backend and frontend when applicable.
2. The create and update flows serialize the intended fields.
3. Required translations exist.
4. Migrations are present for model changes.
5. The most relevant targeted tests pass, or the failure is reported explicitly.

## Search Patterns

Use these searches to move quickly:

- `rg -n "class .*ServiceType" backend/src/baserow/contrib/integrations`
- `rg -n "class .*IntegrationType" backend/src/baserow/contrib/integrations`
- `rg -n "register\\(" backend/src/baserow/contrib/integrations/apps.py web-frontend/modules/integrations/plugin.js`
- `rg -n "getType\\(\\)" web-frontend/modules/integrations`
- `rg -n "\"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 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.
4 changes: 4 additions & 0 deletions .agents/skills/create-update-service/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: 'Integrations and Services'
short_description: 'Create or update Baserow Integrations and Services'
default_prompt: 'Use $create-update-service to create or update Baserow Integrations and Services.'
175 changes: 175 additions & 0 deletions .agents/skills/write-frontend-unit-test/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
---
name: write-frontend-unit-test
description: Write or update Baserow frontend unit tests for core, premium, or enterprise code using the repo's existing Vitest, Nuxt, Vue Test Utils, TestApp, and snapshot patterns.
---

# Write Baserow Frontend Unit Tests

Use this skill when a task is to add, fix, or extend a frontend unit test in `web-frontend`, `premium/web-frontend`, or `enterprise/web-frontend`.

Do not invent a generic Vue testing style. This repo already has established patterns. Start by finding the closest existing spec and copy its setup shape.

## First Step

Before editing, identify the test target:

1. Pure utility or parser function
2. Vuex store logic
3. Vue component mounted with the shared app context
4. Nuxt/Vue 3 component mounted directly with `mountSuspended`
5. Premium or enterprise variant of one of the above

Then inspect the nearest existing spec in the same module area.

Useful searches:

- `rg --files web-frontend/test premium/web-frontend/test enterprise/web-frontend/test | rg '\.spec\.'`
- `rg -n "new TestApp\\(|new PremiumTestApp\\(|mountSuspended\\(" web-frontend/test premium/web-frontend/test enterprise/web-frontend/test`
- `rg -n "toMatchSnapshot\\(|vi\\.fn\\(|vi\\.spyOn\\(" web-frontend/test premium/web-frontend/test enterprise/web-frontend/test`

## Tooling Used In This Repo

Current frontend unit tests use:

- `vitest` for `describe`, `test`, `expect`, `vi`
- `@vue/test-utils`
- `@nuxt/test-utils/runtime` with `mountSuspended`
- Repo helpers such as `TestApp`, `PremiumTestApp`, `MockServer`, and fixtures under `web-frontend/test`
- Snapshot assertions for rendered HTML when the component output matters

Important local files:

- `web-frontend/vitest.setup.ts`
- `web-frontend/test/helpers/testApp.js`
- `premium/web-frontend/test/helpers/premiumTestApp.js`

`vitest.setup.ts` already mocks i18n, UUID generation, and `WebSocket`. Reuse that environment instead of re-mocking those globally in each spec.

## Choose The Right Pattern

### Pure utility tests

For functions in `modules/*/utils/**`, keep the test simple:

1. Import the function directly.
2. Use plain inputs and deterministic assertions.
3. Prefer `toStrictEqual`, `toBe`, or explicit formatted objects over snapshots.

Good examples:

- `web-frontend/test/unit/core/utils/date.spec.js`
- `web-frontend/test/unit/core/utils/string.spec.js`

### Store tests

For Vuex store behavior, prefer `TestApp` unless the existing spec clearly uses a temporary local store:

1. Create `testApp = new TestApp()` in `beforeEach`.
2. Read `store = testApp.store`.
3. Seed state through store actions or the mock server.
4. Always `await testApp.afterEach()` in `afterEach`.

Good examples:

- `web-frontend/test/unit/core/store/auth.spec.js`
- `web-frontend/test/unit/builder/store/dataSource.spec.js`

If the code lives in premium and needs premium-only auth/license behavior, use `PremiumTestApp`.

### Shared app component tests

For many components, especially older patterns or components coupled to store, router, registry, or client behavior:

1. Create `testApp = new TestApp()` or `new PremiumTestApp()`.
2. Mount with `testApp.mount(Component, { props, propsData, slots, listeners, global })`.
3. Prefer the existing helper in the file, for example `mountComponent(...)`.
4. Clean up with `await testApp.afterEach()`.

`TestApp.mount` supports both `props` and legacy `propsData`, and converts `listeners` into Vue 3 event props. Match the nearby spec instead of rewriting all setup.

Good examples:

- `web-frontend/test/unit/core/components/dropdown.spec.js`
- `premium/web-frontend/test/unit/premium/view/calendar/calendarView.spec.js`

### Direct `mountSuspended` component tests

For newer Nuxt/Vue 3 component tests that do not need the full helper wrapper:

1. Use `const testApp = useNuxtApp()` in `beforeEach` if the component expects injected app/store context.
2. Mount with `mountSuspended(Component, { props, slots, global: { provide, stubs, mocks } })`.
3. Provide injected dependencies explicitly.

Good examples:

- `web-frontend/test/unit/builder/components/elements/components/HeadingElement.spec.js`

## Assertions

Prefer the narrowest assertion that proves behavior:

- Use `toStrictEqual` or `toEqual` for transformed data and store state.
- Use `toBe` for scalar values.
- Use `vi.fn()` and `vi.spyOn()` for event handlers and method calls.
- Use snapshots for rendered markup where the repo already uses them.

Do not default to snapshots for pure logic.

When asserting reactive store objects, this repo sometimes normalizes them with:

```js
JSON.parse(JSON.stringify(value))
```

Use that only when the nearby test does it for Vue reactivity serialization issues.

Don't assert internals, always assert visible result in the DOM. For instance don't
use

```js
expect(wrapper.vm.values.use_instance_smtp_settings).toBe(false) # BAD
```

Don't directly use vm properties.

## Mocking And Fixtures

Prefer repo helpers over bespoke mocks:

1. Use `testApp.mockServer` when the behavior depends on store-backed API calls.
2. Use fixtures under `web-frontend/test/fixtures` and premium or enterprise fixture folders when suitable.
3. Use `testApp.dontFailOnErrorResponses()` only when the test intentionally exercises failing responses.

Do not build a large custom mock environment if `TestApp` already provides the needed app, client, registry, router, and store wiring.

## File Placement

Follow the existing test tree:

- Core: `web-frontend/test/unit/...`
- Premium: `premium/web-frontend/test/unit/...`
- Enterprise: `enterprise/web-frontend/test/unit/...`

Keep the spec near the feature area rather than creating a new generic test folder.

## Validation

Run the narrowest relevant test command first.

Examples:

- `just f yarn test:core --run test/unit/core/components/dropdown.spec.js`
- `just f yarn test:core --run test/unit/core/store/auth.spec.js`
- `just f yarn test:premium --run ../premium/web-frontend/test/unit/premium/view/calendar/calendarView.spec.js`
- `just f yarn test:enterprise --run ../enterprise/web-frontend/test/unit/enterprise/plugins.spec.js`

If a snapshot changes intentionally, review the diff instead of blindly accepting it.

## Guardrails

- Do not introduce Jest APIs. Use Vitest APIs already present in the repo.
- Do not add a standalone mount helper when `TestApp` or `PremiumTestApp` already fits.
- Do not over-mock store, router, or client dependencies if the real test helpers can provide them.
- Do not mix unrelated styles in one file. Match the nearest local spec.
- Do not leave out `afterEach` cleanup when using `TestApp` or `PremiumTestApp`.
- Do not create broad integration-style tests when a focused unit test is enough.
Loading
Loading