Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b1e6d5a9d |
+1
-1
@@ -4,6 +4,6 @@ set -e
|
||||
echo "==> START Registering cron jobs"
|
||||
|
||||
cd /app/packages/twenty-server
|
||||
yarn command:prod cron:register:all
|
||||
yarn command:prod cron:register:all --dev-mode
|
||||
|
||||
echo "==> DONE"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
||||
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
|
||||
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
@@ -18,10 +16,10 @@ export const QueryParamsFiltersEffect = () => {
|
||||
useFiltersFromQueryParams();
|
||||
const { hasFiltersQueryParams } = useHasFiltersInQueryParams();
|
||||
|
||||
const { objectNamePlural = '' } = useParams();
|
||||
const { objectNameSingular } = useObjectNameSingularFromPlural({
|
||||
objectNamePlural,
|
||||
});
|
||||
// Use objectNameSingular from validated RecordIndex context instead of raw
|
||||
// URL params to avoid crashes when navigating to non-existent objects
|
||||
const { objectNameSingular, recordIndexId } =
|
||||
useRecordIndexContextOrThrow();
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular,
|
||||
});
|
||||
@@ -30,7 +28,6 @@ export const QueryParamsFiltersEffect = () => {
|
||||
|
||||
const { mapViewFiltersToRecordFilters } = useMapViewFiltersToFilters();
|
||||
|
||||
const { recordIndexId } = useRecordIndexContextOrThrow();
|
||||
const setCurrentRecordFilters = useSetAtomComponentState(
|
||||
currentRecordFiltersComponentState,
|
||||
recordIndexId,
|
||||
|
||||
@@ -2,7 +2,6 @@ import { isNonEmptyString, isObject } from '@sniptt/guards';
|
||||
import qs from 'qs';
|
||||
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useObjectNameSingularFromPlural } from '@/object-metadata/hooks/useObjectNameSingularFromPlural';
|
||||
import { isCompositeFieldType } from '@/object-record/object-filter-dropdown/utils/isCompositeFieldType';
|
||||
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
|
||||
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
@@ -10,17 +9,18 @@ import { filterUrlQueryParamsSchema } from '@/views/schemas/filterUrlQueryParams
|
||||
import { type ViewFilter } from '@/views/types/ViewFilter';
|
||||
import { deserializeUrlRecursiveFilterGroup } from '@/views/utils/deserializeUrlRecursiveFilterGroup';
|
||||
import { splitFieldNameIntoBaseAndSubField } from '@/views/utils/splitFieldNameIntoBaseAndSubField';
|
||||
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
|
||||
import { useCallback } from 'react';
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { type ViewFilterOperand } from 'twenty-shared/types';
|
||||
import { isDefined, isExpectedSubFieldName } from 'twenty-shared/utils';
|
||||
|
||||
export const useFiltersFromQueryParams = () => {
|
||||
const [searchParams] = useSearchParams();
|
||||
const { objectNamePlural = '' } = useParams();
|
||||
const { objectNameSingular } = useObjectNameSingularFromPlural({
|
||||
objectNamePlural,
|
||||
});
|
||||
|
||||
// Use objectNameSingular from validated RecordIndex context instead of raw
|
||||
// URL params to avoid crashes when navigating to non-existent objects
|
||||
const { objectNameSingular } = useRecordIndexContextOrThrow();
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
|
||||
import { Command, CommandRunner } from 'nest-commander';
|
||||
import { Command, CommandRunner, Option } from 'nest-commander';
|
||||
|
||||
import { MarketplaceCatalogSyncCronCommand } from 'src/engine/core-modules/application/application-marketplace/crons/commands/marketplace-catalog-sync.cron.command';
|
||||
import { StaleRegistrationCleanupCronCommand } from 'src/engine/core-modules/application/application-oauth/stale-registration-cleanup/commands/stale-registration-cleanup.cron.command';
|
||||
@@ -68,8 +68,33 @@ export class CronRegisterAllCommand extends CommandRunner {
|
||||
super();
|
||||
}
|
||||
|
||||
private devMode = false;
|
||||
|
||||
@Option({
|
||||
flags: '--dev-mode',
|
||||
description:
|
||||
'Only register cron jobs relevant to app development (cron triggers, marketplace sync, version check, stale cleanup)',
|
||||
required: false,
|
||||
})
|
||||
parseDevMode(): boolean {
|
||||
this.devMode = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static readonly DEV_MODE_COMMANDS = new Set([
|
||||
'CronTrigger',
|
||||
'MarketplaceCatalogSync',
|
||||
'ApplicationVersionCheck',
|
||||
'StaleRegistrationCleanup',
|
||||
]);
|
||||
|
||||
async run(): Promise<void> {
|
||||
this.logger.log('Registering all background sync cron jobs...');
|
||||
this.logger.log(
|
||||
this.devMode
|
||||
? 'Registering app-dev cron jobs...'
|
||||
: 'Registering all background sync cron jobs...',
|
||||
);
|
||||
|
||||
const allCommands = [
|
||||
{
|
||||
@@ -170,12 +195,18 @@ export class CronRegisterAllCommand extends CommandRunner {
|
||||
},
|
||||
];
|
||||
|
||||
const commands = this.devMode
|
||||
? allCommands.filter(({ name }) =>
|
||||
CronRegisterAllCommand.DEV_MODE_COMMANDS.has(name),
|
||||
)
|
||||
: allCommands;
|
||||
|
||||
let successCount = 0;
|
||||
let failureCount = 0;
|
||||
const failures: string[] = [];
|
||||
const successes: string[] = [];
|
||||
|
||||
for (const { name, command } of allCommands) {
|
||||
for (const { name, command } of commands) {
|
||||
try {
|
||||
this.logger.log(`Registering ${name} cron job...`);
|
||||
await command.run();
|
||||
|
||||
-1
@@ -7,7 +7,6 @@ export const WORKFLOW_SYSTEM_PROMPTS = {
|
||||
|
||||
Tool usage strategy:
|
||||
- Chain multiple tools to solve complex tasks
|
||||
- Prefer batch tools (\`create_many_*\`, \`update_many_*\`, etc.) over looping single-item calls
|
||||
- If a tool fails, try alternative approaches
|
||||
- Use results from one tool to inform the next
|
||||
- Don't give up after first failure - be persistent
|
||||
|
||||
-1
@@ -41,7 +41,6 @@ For simple CRUD operations (find/create/update/delete a record), you do NOT need
|
||||
- Always apply filters to narrow results — don't fetch all records of a type.
|
||||
- Fetch one type of data at a time and check if you have what you need before fetching more.
|
||||
- Every record returned consumes context. Fetching too many records at once will cause failures.
|
||||
- For multiple items of the same type, use batch tools (\`create_many_*\`, \`update_many_*\`, etc.) instead of looping single-item calls.
|
||||
|
||||
## Tool Strategy
|
||||
|
||||
|
||||
@@ -1304,17 +1304,6 @@
|
||||
"contextWindowTokens": 64000,
|
||||
"maxOutputTokens": 64000
|
||||
},
|
||||
{
|
||||
"name": "mistral-medium-2604",
|
||||
"label": "Mistral Medium 3.5",
|
||||
"modelFamily": "MISTRAL",
|
||||
"inputCostPerMillionTokens": 1.5,
|
||||
"outputCostPerMillionTokens": 7.5,
|
||||
"contextWindowTokens": 262144,
|
||||
"maxOutputTokens": 262144,
|
||||
"modalities": ["image"],
|
||||
"supportsReasoning": true
|
||||
},
|
||||
{
|
||||
"name": "devstral-small-2505",
|
||||
"label": "Devstral Small 2505",
|
||||
@@ -1333,6 +1322,16 @@
|
||||
"contextWindowTokens": 128000,
|
||||
"maxOutputTokens": 128000
|
||||
},
|
||||
{
|
||||
"name": "mistral-medium-latest",
|
||||
"label": "Mistral Medium (latest)",
|
||||
"modelFamily": "MISTRAL",
|
||||
"inputCostPerMillionTokens": 0.4,
|
||||
"outputCostPerMillionTokens": 2,
|
||||
"contextWindowTokens": 128000,
|
||||
"maxOutputTokens": 16384,
|
||||
"modalities": ["image"]
|
||||
},
|
||||
{
|
||||
"name": "open-mistral-7b",
|
||||
"label": "Mistral 7B",
|
||||
@@ -1379,17 +1378,6 @@
|
||||
"contextWindowTokens": 262144,
|
||||
"maxOutputTokens": 262144,
|
||||
"modalities": ["image"]
|
||||
},
|
||||
{
|
||||
"name": "mistral-medium-latest",
|
||||
"label": "Mistral Medium (latest)",
|
||||
"modelFamily": "MISTRAL",
|
||||
"inputCostPerMillionTokens": 1.5,
|
||||
"outputCostPerMillionTokens": 7.5,
|
||||
"contextWindowTokens": 262144,
|
||||
"maxOutputTokens": 262144,
|
||||
"modalities": ["image"],
|
||||
"supportsReasoning": true
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1419,24 +1407,6 @@
|
||||
"maxOutputTokens": 4096,
|
||||
"modalities": ["image"]
|
||||
},
|
||||
{
|
||||
"name": "grok-4.3",
|
||||
"label": "Grok 4.3",
|
||||
"modelFamily": "GROK",
|
||||
"inputCostPerMillionTokens": 1.25,
|
||||
"outputCostPerMillionTokens": 2.5,
|
||||
"cachedInputCostPerMillionTokens": 0.2,
|
||||
"longContextCost": {
|
||||
"inputCostPerMillionTokens": 2.5,
|
||||
"outputCostPerMillionTokens": 5,
|
||||
"thresholdTokens": 200000,
|
||||
"cachedInputCostPerMillionTokens": 0.4
|
||||
},
|
||||
"contextWindowTokens": 1000000,
|
||||
"maxOutputTokens": 30000,
|
||||
"modalities": ["image"],
|
||||
"supportsReasoning": true
|
||||
},
|
||||
{
|
||||
"name": "grok-3-mini-fast",
|
||||
"label": "Grok 3 Mini Fast",
|
||||
|
||||
+6
-6
@@ -42,7 +42,7 @@ export const CALENDAR_CHANNEL_DATA_SEEDS: CalendarChannelDataSeed[] = [
|
||||
handle: 'tim@apple.dev',
|
||||
visibility: CalendarChannelVisibility.METADATA,
|
||||
isContactAutoCreationEnabled: true,
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
},
|
||||
{
|
||||
id: CALENDAR_CHANNEL_DATA_SEED_IDS.JONY,
|
||||
@@ -50,7 +50,7 @@ export const CALENDAR_CHANNEL_DATA_SEEDS: CalendarChannelDataSeed[] = [
|
||||
handle: 'jony@apple.dev',
|
||||
visibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||
isContactAutoCreationEnabled: true,
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
},
|
||||
{
|
||||
id: CALENDAR_CHANNEL_DATA_SEED_IDS.PHIL,
|
||||
@@ -58,7 +58,7 @@ export const CALENDAR_CHANNEL_DATA_SEEDS: CalendarChannelDataSeed[] = [
|
||||
handle: 'phil@apple.dev',
|
||||
visibility: CalendarChannelVisibility.METADATA,
|
||||
isContactAutoCreationEnabled: true,
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
},
|
||||
{
|
||||
id: CALENDAR_CHANNEL_DATA_SEED_IDS.JANE,
|
||||
@@ -66,7 +66,7 @@ export const CALENDAR_CHANNEL_DATA_SEEDS: CalendarChannelDataSeed[] = [
|
||||
handle: 'jane.austen@apple.dev',
|
||||
visibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||
isContactAutoCreationEnabled: true,
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
},
|
||||
{
|
||||
id: CALENDAR_CHANNEL_DATA_SEED_IDS.COMPANY_MAIN,
|
||||
@@ -74,7 +74,7 @@ export const CALENDAR_CHANNEL_DATA_SEEDS: CalendarChannelDataSeed[] = [
|
||||
handle: 'company-main@apple.dev',
|
||||
visibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||
isContactAutoCreationEnabled: true,
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
},
|
||||
{
|
||||
id: CALENDAR_CHANNEL_DATA_SEED_IDS.TEAM_CALENDAR,
|
||||
@@ -82,6 +82,6 @@ export const CALENDAR_CHANNEL_DATA_SEEDS: CalendarChannelDataSeed[] = [
|
||||
handle: 'team-calendar@apple.dev',
|
||||
visibility: CalendarChannelVisibility.SHARE_EVERYTHING,
|
||||
isContactAutoCreationEnabled: true,
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
+6
-6
@@ -59,7 +59,7 @@ export const MESSAGE_CHANNEL_DATA_SEEDS: MessageChannelDataSeed[] = [
|
||||
type: MessageChannelType.EMAIL,
|
||||
connectedAccountId: CONNECTED_ACCOUNT_DATA_SEED_IDS.TIM,
|
||||
handle: 'tim@apple.dev',
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_PENDING,
|
||||
},
|
||||
@@ -72,7 +72,7 @@ export const MESSAGE_CHANNEL_DATA_SEEDS: MessageChannelDataSeed[] = [
|
||||
type: MessageChannelType.EMAIL,
|
||||
connectedAccountId: CONNECTED_ACCOUNT_DATA_SEED_IDS.JONY,
|
||||
handle: 'jony.ive@apple.dev',
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_PENDING,
|
||||
},
|
||||
@@ -85,7 +85,7 @@ export const MESSAGE_CHANNEL_DATA_SEEDS: MessageChannelDataSeed[] = [
|
||||
type: MessageChannelType.EMAIL,
|
||||
connectedAccountId: CONNECTED_ACCOUNT_DATA_SEED_IDS.PHIL,
|
||||
handle: 'phil.schiler@apple.dev',
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_PENDING,
|
||||
},
|
||||
@@ -98,7 +98,7 @@ export const MESSAGE_CHANNEL_DATA_SEEDS: MessageChannelDataSeed[] = [
|
||||
type: MessageChannelType.EMAIL,
|
||||
connectedAccountId: CONNECTED_ACCOUNT_DATA_SEED_IDS.JANE,
|
||||
handle: 'jane.austen@apple.dev',
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_PENDING,
|
||||
},
|
||||
@@ -111,7 +111,7 @@ export const MESSAGE_CHANNEL_DATA_SEEDS: MessageChannelDataSeed[] = [
|
||||
type: MessageChannelType.EMAIL,
|
||||
connectedAccountId: CONNECTED_ACCOUNT_DATA_SEED_IDS.TIM, // Use TIM's connected account for shared inbox
|
||||
handle: 'support@apple.dev',
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_PENDING,
|
||||
},
|
||||
@@ -124,7 +124,7 @@ export const MESSAGE_CHANNEL_DATA_SEEDS: MessageChannelDataSeed[] = [
|
||||
type: MessageChannelType.EMAIL,
|
||||
connectedAccountId: CONNECTED_ACCOUNT_DATA_SEED_IDS.TIM, // Use TIM's connected account for shared inbox
|
||||
handle: 'sales@apple.dev',
|
||||
isSyncEnabled: false,
|
||||
isSyncEnabled: true,
|
||||
visibility: MessageChannelVisibility.SHARE_EVERYTHING,
|
||||
syncStage: MessageChannelSyncStage.MESSAGE_LIST_FETCH_PENDING,
|
||||
},
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ export class MessagingBlocklistListener {
|
||||
);
|
||||
}
|
||||
|
||||
@OnDatabaseBatchEvent('blocklist', DatabaseEventAction.DELETED)
|
||||
@OnDatabaseBatchEvent('blocklist', DatabaseEventAction.CREATED)
|
||||
async handleDeletedEvent(
|
||||
payload: WorkspaceEventBatch<
|
||||
ObjectRecordDeleteEvent<BlocklistWorkspaceEntity>
|
||||
|
||||
Reference in New Issue
Block a user