Add Activepieces integration for workflow automation

- Add Activepieces fork with SmoothSchedule custom piece
- Create integrations app with Activepieces service layer
- Add embed token endpoint for iframe integration
- Create Automations page with embedded workflow builder
- Add sidebar visibility fix for embed mode
- Add list inactive customers endpoint to Public API
- Include SmoothSchedule triggers: event created/updated/cancelled
- Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-18 22:59:37 -05:00
parent 9848268d34
commit 3aa7199503
16292 changed files with 1284892 additions and 4708 deletions

View File

@@ -0,0 +1,12 @@
import { Static, Type } from '@sinclair/typebox'
import { BaseModelSchema } from '../common'
export const Cell = Type.Object({
...BaseModelSchema,
recordId: Type.String(),
fieldId: Type.String(),
projectId: Type.String(),
value: Type.Unknown(),
})
export type Cell = Static<typeof Cell>

View File

@@ -0,0 +1,29 @@
import { Static, Type } from '@sinclair/typebox'
import { FieldType } from '../field'
const StaticDropdownData = Type.Object({
options: Type.Array(Type.Object({
value: Type.String(),
})),
})
export const CreateFieldRequest = Type.Union([Type.Object({
name: Type.String(),
type: Type.Literal(FieldType.STATIC_DROPDOWN),
tableId: Type.String(),
data: StaticDropdownData,
externalId: Type.Optional(Type.String()),
}), Type.Object({
name: Type.String(),
type: Type.Union([Type.Literal(FieldType.TEXT), Type.Literal(FieldType.NUMBER), Type.Literal(FieldType.DATE)]),
tableId: Type.String(),
externalId: Type.Optional(Type.String()),
})])
export const UpdateFieldRequest = Type.Object({
name: Type.String(),
})
export type CreateFieldRequest = Static<typeof CreateFieldRequest>
export type UpdateFieldRequest = Static<typeof UpdateFieldRequest>

View File

@@ -0,0 +1,58 @@
import { Static, Type } from '@sinclair/typebox'
import { Cursor } from '../../common/seek-page'
export const CreateRecordsRequest = Type.Object({
records: Type.Array(Type.Array(Type.Object({
fieldId: Type.String(),
value: Type.String(),
}))),
tableId: Type.String(),
})
export type CreateRecordsRequest = Static<typeof CreateRecordsRequest>
export const UpdateRecordRequest = Type.Object({
cells: Type.Optional(Type.Array(Type.Object({
fieldId: Type.String(),
value: Type.String(),
}))),
tableId: Type.String(),
agentUpdate: Type.Optional(Type.Boolean()),
})
export type UpdateRecordRequest = Static<typeof UpdateRecordRequest>
export enum FilterOperator {
EQ = 'eq',
NEQ = 'neq',
GT = 'gt',
GTE = 'gte',
LT = 'lt',
LTE = 'lte',
CO = 'co',
}
export const Filter = Type.Object({
fieldId: Type.String(),
value: Type.String(),
operator: Type.Optional(Type.Enum(FilterOperator)),
})
export type Filter = Static<typeof Filter>
export const ListRecordsRequest = Type.Object({
tableId: Type.String(),
limit: Type.Optional(Type.Number({})),
cursor: Type.Optional(Type.String({})),
filters: Type.Optional(Type.Array(Filter)),
})
export type ListRecordsRequest = Omit<Static<typeof ListRecordsRequest>, 'cursor'> & { cursor: Cursor | undefined }
export const DeleteRecordsRequest = Type.Object({
ids: Type.Array(Type.String()),
})
export type DeleteRecordsRequest = Static<typeof DeleteRecordsRequest>

View File

@@ -0,0 +1,45 @@
import { Static, Type } from '@sinclair/typebox'
import { TableAutomationStatus, TableAutomationTrigger } from '../table'
import { TableWebhookEventType } from '../table-webhook'
export const CreateTableRequest = Type.Object({
name: Type.String(),
externalId: Type.Optional(Type.String()),
})
export type CreateTableRequest = Static<typeof CreateTableRequest>
export const ExportTableResponse = Type.Object({
fields: Type.Array(Type.Object({ id: Type.String(), name: Type.String() })),
rows: Type.Array(Type.Record(Type.String(), Type.String())),
name: Type.String(),
})
export type ExportTableResponse = Static<typeof ExportTableResponse>
export const CreateTableWebhookRequest = Type.Object({
events: Type.Array(Type.Enum(TableWebhookEventType)),
webhookUrl: Type.String(),
flowId: Type.String(),
})
export type CreateTableWebhookRequest = Static<typeof CreateTableWebhookRequest>
export const UpdateTableRequest = Type.Object({
name: Type.Optional(Type.String()),
trigger: Type.Optional(Type.Enum(TableAutomationTrigger)),
status: Type.Optional(Type.Enum(TableAutomationStatus)),
})
export type UpdateTableRequest = Static<typeof UpdateTableRequest>
export const ListTablesRequest = Type.Object({
limit: Type.Optional(Type.Number({})),
cursor: Type.Optional(Type.String({})),
name: Type.Optional(Type.String({})),
externalIds: Type.Optional(Type.Array(Type.String())),
})
export type ListTablesRequest = Static<typeof ListTablesRequest>

View File

@@ -0,0 +1,37 @@
import { Static, Type } from '@sinclair/typebox'
import { BaseModelSchema } from '../common'
export enum FieldType {
TEXT = 'TEXT',
NUMBER = 'NUMBER',
DATE = 'DATE',
STATIC_DROPDOWN = 'STATIC_DROPDOWN',
}
export const Field = Type.Union([Type.Object({
...BaseModelSchema,
name: Type.String(),
externalId: Type.String(),
type: Type.Literal(FieldType.STATIC_DROPDOWN),
tableId: Type.String(),
projectId: Type.String(),
data: Type.Object({
options: Type.Array(Type.Object({
value: Type.String(),
})),
}),
}), Type.Object({
...BaseModelSchema,
name: Type.String(),
externalId: Type.String(),
type: Type.Union([Type.Literal(FieldType.TEXT), Type.Literal(FieldType.NUMBER), Type.Literal(FieldType.DATE)]),
tableId: Type.String(),
projectId: Type.String(),
})])
export type Field = Static<typeof Field>
export const StaticDropdownEmptyOption = {
label: '',
value: '',
}

View File

@@ -0,0 +1,8 @@
export * from './dto/tables.dto'
export * from './dto/fields.dto'
export * from './dto/records.dto'
export * from './table'
export * from './field'
export * from './record'
export * from './cell'
export * from './table-webhook'

View File

@@ -0,0 +1,25 @@
import { Static, Type } from '@sinclair/typebox'
import { BaseModelSchema } from '../common'
import { Cell } from './cell'
export const Record = Type.Object({
...BaseModelSchema,
tableId: Type.String(),
projectId: Type.String(),
})
export type Record = Static<typeof Record>
export const PopulatedRecord = Type.Composite([
Record,
Type.Object({
cells: Type.Record(Type.String(), Type.Composite([
Type.Pick(Cell, ['updated', 'created', 'value']),
Type.Object({
fieldName: Type.String(),
}),
])),
}),
])
export type PopulatedRecord = Static<typeof PopulatedRecord>

View File

@@ -0,0 +1,18 @@
import { Static, Type } from '@sinclair/typebox'
import { BaseModelSchema } from '../common'
export enum TableWebhookEventType {
RECORD_CREATED = 'RECORD_CREATED',
RECORD_UPDATED = 'RECORD_UPDATED',
RECORD_DELETED = 'RECORD_DELETED',
}
export const TableWebhook = Type.Object({
...BaseModelSchema,
projectId: Type.String(),
tableId: Type.String(),
events: Type.Array(Type.Enum(TableWebhookEventType)),
flowId: Type.String(),
})
export type TableWebhook = Static<typeof TableWebhook>

View File

@@ -0,0 +1,34 @@
import { Static, Type } from '@sinclair/typebox'
import { BaseModelSchema, NullableEnum } from '../common'
import { Field } from './field'
export enum TableAutomationTrigger {
ON_NEW_RECORD = 'ON_NEW_RECORD',
ON_UPDATE_RECORD = 'ON_UPDATE_RECORD',
}
export enum TableAutomationStatus {
ENABLED = 'ENABLED',
DISABLED = 'DISABLED',
}
export const Table = Type.Object({
...BaseModelSchema,
name: Type.String(),
projectId: Type.String(),
externalId: Type.String(),
status: NullableEnum(Type.Enum(TableAutomationStatus)),
trigger: NullableEnum(Type.Enum(TableAutomationTrigger)),
})
export type Table = Static<typeof Table>
export const PopulatedTable = Type.Composite([
Table,
Type.Object({
fields: Type.Array(Field),
}),
])
export type PopulatedTable = Static<typeof PopulatedTable>