dd0039ca1cf8400c7c34d4a6e0090e841d8f7812
14 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
dd0039ca1c |
feat(mcp) - optimize instruction prompt and hide get_tool_catalog (#21183)
Workspace-aware initialize.instructions - Deleted the static mcp-server-instructions.const.ts - Created build-mcp-server-instructions.util.ts — a comprehensive system prompt with identity, object list, tool grammar, routing decision tree, intent mapping, skills vs tools, safety constraints, and data efficiency guidelines - Created McpInstructionBuilderService — fetches workspace-specific object names + skill names and injects them into the instructions Hide/deprecate get_tool_catalog Benefit : skip first MCP call (tools are included in instruction) |
||
|
|
cbefd42c4c |
Add SSE streaming support on POST /mcp (Phase 2) (#19528)
## Summary - Add SSE (`text/event-stream`) as an alternative response format on `POST /mcp` per the MCP streamable-http spec - When clients send `Accept: text/event-stream`, the server responds with SSE wire format; otherwise returns JSON as before (fully backwards compatible) - Emit a `notifications/progress` SSE event before tool execution to signal long-running operations - No sessions, no GET SSE, no protocol version bump — this is transport-level only (Phase 2) ## Changes - **New**: `write-sse-event.util.ts` — writes correctly formatted SSE events to Express Response - **New**: `mcp-progress-notification.const.ts` — constants for progress notification method and token prefix - **Modified**: `mcp-core.controller.ts` — checks `Accept` header, branches into SSE vs JSON response path - **Modified**: `mcp-protocol.service.ts` — passes optional `sseWriter` callback to tool executor - **Modified**: `mcp-tool-executor.service.ts` — emits progress notification via `sseWriter` before tool execution - **Tests**: Unit tests for SSE utility, controller SSE/JSON paths, tool executor progress notifications, and integration tests for SSE streaming ## Test plan - [x] Unit tests: `writeSseEvent` utility produces correct SSE wire format - [x] Unit tests: Controller returns SSE headers and writes events when `Accept: text/event-stream` - [x] Unit tests: Controller returns JSON when `Accept: application/json` only - [x] Unit tests: Notifications (no `id`) return 202 regardless of Accept header - [x] Unit tests: Tool executor emits progress notification via sseWriter - [x] Unit tests: Tool executor works without sseWriter (backwards compatible) - [x] Integration tests: SSE response for ping, JSON fallback, progress notification before tool call - [x] All 503 test suites pass, typecheck clean https://claude.ai/code/session_01QrqjBUXePJkPMd6gBAoWaR --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
c407341912 |
feat: optimize hot database queries with multi-layer caching (#19068)
## Summary Introduces multi-layer caching for the 5 most frequent database queries identified in production (Sentry data), targeting the JWT authentication hot path and cron job logic. ### Problem Our database is under heavy load from uncached queries on the auth hot path: - `WorkspaceEntity` lookups: **638 queries/min** - `ApiKeyEntity` lookups: **491 queries/min** - `UserEntity` lookups: **147 queries/min** - `UserWorkspaceEntity` lookups: **143 queries/min** - `LogicFunctionEntity` lookups: **1800 queries/min** (cron job) ### Solution **1. New `CoreEntityCacheService`** for non-workspace-scoped entities (Workspace, User, UserWorkspace): - Mirrors `WorkspaceCacheService` architecture (in-process Map + Redis with hash validation) - Provider pattern with `@CoreEntityCache` decorator - Keyed by entity primary key (not workspaceId) - 100ms local TTL, Redis-backed hash validation for cross-instance consistency - Three providers: `WorkspaceEntityCacheProviderService`, `UserEntityCacheProviderService`, `UserWorkspaceEntityCacheProviderService` **2. New `apiKeyMap` WorkspaceCache** for workspace-scoped API key lookups: - `WorkspaceApiKeyMapCacheService` loads all API keys for a workspace into a map by ID - Leverages existing `WorkspaceCacheService` infrastructure - Cache invalidation on API key create/update/revoke **3. `CronTriggerCronJob` refactored** to use existing `flatLogicFunctionMaps` workspace cache: - Eliminates per-workspace `LogicFunctionEntity` repository queries (~1800/min) - Filters cached data in-memory instead **4. `JwtAuthStrategy` refactored** to use caches for all entity lookups: - Workspace, User, UserWorkspace → `CoreEntityCacheService` - ApiKey → `WorkspaceCacheService` (`apiKeyMap`) - Impersonation queries kept as direct DB queries (rare path, requires relations) **5. Cache invalidation** wired into mutation paths: - `WorkspaceService` → invalidates `workspaceEntity` on save/update/delete - `ApiKeyService` → invalidates `apiKeyMap` on create/update/revoke ### Architecture ``` Request → JwtAuthStrategy ├── Workspace lookup → CoreEntityCacheService (in-process → Redis → DB) ├── User lookup → CoreEntityCacheService (in-process → Redis → DB) ├── UserWorkspace lookup → CoreEntityCacheService (in-process → Redis → DB) └── ApiKey lookup → WorkspaceCacheService (in-process → Redis → DB) CronTriggerCronJob └── LogicFunction lookup → WorkspaceCacheService (flatLogicFunctionMaps) ``` ### Expected Impact | Query | Before | After | |-------|--------|-------| | WorkspaceEntity | 638/min | ~0 (cached) | | ApiKeyEntity | 491/min | ~0 (cached) | | UserEntity | 147/min | ~0 (cached) | | UserWorkspaceEntity | 143/min | ~0 (cached) | | LogicFunctionEntity | 1800/min | ~0 (cached) | ### Not included (ongoing separately) - DataSourceEntity query optimization (IS_DATASOURCE_MIGRATED migration) - ObjectMetadataEntity query optimization (already partially cached) |
||
|
|
9cb21e71fa |
feat: secure and user-scope metadata resolvers for messaging infrastructure (#18787)
## Summary Builds on the messaging infrastructure migration (#18784) by securing and user-scoping all 4 metadata resolvers: ### DTOs secured - **ConnectedAccountDTO**: `@HideField()` on `accessToken`, `refreshToken`, `connectionParameters`, `oidcTokenClaims` - **MessageChannelDTO / CalendarChannelDTO**: `@HideField()` on `syncCursor` - **MessageFolderDTO**: `@HideField()` on `syncCursor`, `externalId` - **UpdateMessageFolderInputUpdates**: stripped to only `isSynced` (removed `name`, `syncCursor`, `pendingSyncAction`) ### Resolvers user-scoped via `@AuthUserWorkspaceId()` - `myConnectedAccounts` — returns only the calling user's accounts (no permission guard) - `myMessageChannels(connectedAccountId?)` — returns channels for the user's connected accounts - `myCalendarChannels(connectedAccountId?)` — same pattern - `myMessageFolders(messageChannelId?)` — returns folders through the ownership chain ### Admin-only listing with permission guard - `connectedAccounts` query retained with `SettingsPermissionGuard(CONNECTED_ACCOUNTS)` for admin listing of all workspace accounts ### Unsafe mutations removed - Removed `createConnectedAccount`, `updateConnectedAccount` (OAuth/IMAP flows create/refresh tokens server-side) - Removed `create*`/`delete*` mutations from MessageChannel, CalendarChannel, MessageFolder (managed by sync engine) ### Update mutations restricted with ownership verification - `deleteConnectedAccount(id)` — verifies `entity.userWorkspaceId === currentUserWorkspaceId` - `updateMessageChannel` / `updateCalendarChannel` / `updateMessageFolder` — verify ownership through connected account chain - New `OWNERSHIP_VIOLATION` exception codes map to `ForbiddenError` in GraphQL ### `@AuthUserWorkspaceId` decorator hardened - Added `allowUndefined` option (default: `false`) — throws `ForbiddenException` if `userWorkspaceId` is undefined (e.g. API key auth) - Existing callers updated to `@AuthUserWorkspaceId({ allowUndefined: true })` where needed - New user-scoped resolvers enforce non-undefined `userWorkspaceId` at decorator level ### Exception handler chaining - `MessageFolderGraphqlApiExceptionInterceptor`, `MessageChannelGraphqlApiExceptionInterceptor`, `CalendarChannelGraphqlApiExceptionInterceptor` chain upstream exception handling (ConnectedAccountException, MessageChannelException) for correct `ForbiddenError` propagation ### Metadata services enhanced - `findByUserWorkspaceId()`, `getUserConnectedAccountIds()`, `findByConnectedAccountIds()`, `findByMessageChannelIds()` - `findBy*ForUser()` methods encapsulate ownership checks before querying - `verifyOwnership()` on all 4 services with proper chain validation - Named parameters throughout for clarity ### Dev seeds for both schemas - Added JANE to connected account, message channel, calendar channel workspace seeds - Created message folder workspace seeds (TIM, JONY, JANE) - New `seed-metadata-entities.util.ts` seeds core schema tables (connectedAccount, messageChannel, calendarChannel, messageFolder) with same IDs as workspace seeds, mapping `accountOwnerId` → `userWorkspaceId` ### Integration tests (using seeds, not raw SQL) - 4 test suites (`connected-account`, `message-channel`, `calendar-channel`, `message-folder`) - Tests use seeded data IDs from seed constants — no raw SQL inserts/deletes - Tests read via GraphQL resolvers - Tests cover: user scoping, admin permission checks, sensitive field exclusion, ownership enforcement on mutations ### Frontend migration - Feature-flag-gated hooks (`useMyConnectedAccounts`, `useMyMessageChannels`, `useMyCalendarChannels`, `useMyMessageFolders`) - When `IS_CONNECTED_ACCOUNT_MIGRATED` is on: hooks use metadata API (`POST /metadata`) - When flag is off: hooks use existing workspace API (`POST /graphql`, current behavior) - Settings account pages updated to use new hooks - `useEffect` extracted to `SettingsAccountsSelectedMessageChannelEffect` component per project conventions - Error messages translated with Lingui ## Test plan - [x] Server typecheck passes - [x] Server lint passes - [x] Server unit tests pass (477 suites, 4269 tests) - [x] Frontend typecheck passes - [x] Frontend lint passes - [x] Integration tests verify user-scoping, ownership enforcement, hidden fields - [ ] CI green --------- Co-authored-by: neo773 <neo773@protonmail.com> |
||
|
|
a07337fea0 |
fix: return method-specific MCP responses (#18671)
## Summary Fixes #18524 Fixes the MCP response contract for non-`initialize` methods. Previously, `/mcp` returned initialize-style metadata for methods like `tools/list`, which caused strict MCP clients to reject the response shape. The endpoint also returned `201 Created` for RPC calls even though no resource was being created. ## Changes - return only method-specific payloads for MCP list methods - `tools/list` -> `{ tools: [...] }` - `prompts/list` -> `{ prompts: [] }` - `resources/list` -> `{ resources: [] }` - keep MCP server metadata only on `initialize` - make `/mcp` return `200 OK` instead of `201 Created` - add regression tests for: - `tools/list` response shape - `prompts/list` response shape - `resources/list` response shape ## Why Strict MCP clients expect: - standard RPC transport semantics over HTTP - method-specific JSON-RPC result payloads Returning initialize metadata for non-`initialize` methods breaks that expectation and can cause client deserialization or protocol validation failures. ## Verification - reproduced the issue locally against `/mcp` - verified `tools/list` was previously returning initialize-style fields - verified `tools/list` now returns only `result.tools` - verified `/mcp` now returns `200 OK` - ran targeted Jest tests: ```bash cd /Users/apple/MyProjects/OpenSource/twenty/packages/twenty-server npx jest --runInBand src/engine/api/mcp/services/__tests__/mcp-protocol.service.spec.ts src/engine/api/mcp/services/__tests__/mcp-tool-executor.service.spec.ts --------- Co-authored-by: Félix Malfait <felix@twenty.com> |
||
|
|
95a35f8a1d |
Implement OAuth 2.0 Dynamic Client Registration (RFC 7591) (#18608)
## Summary This PR implements OAuth 2.0 Dynamic Client Registration (RFC 7591) and OAuth 2.0 Protected Resource Metadata (RFC 9728) support, enabling third-party applications to dynamically register as OAuth clients without manual configuration. ## Key Changes ### OAuth Dynamic Client Registration - **New Controller**: `OAuthRegistrationController` at `POST /oauth/register` endpoint - Validates client metadata according to RFC 7591 specifications - Enforces PKCE-only public client model (no client secrets) - Supports only `authorization_code` grant type and `code` response type - Rate limits registrations to 10 per hour per IP address - Returns `client_id` and registration metadata in response - **Input Validation**: `OAuthRegisterInput` DTO with constraints on: - Client name (max 256 chars) - Redirect URIs (max 20, validated for security) - Grant types, response types, scopes, and auth methods - Logo and client URIs (max 2048 chars) - **Discovery Endpoint Update**: Added `registration_endpoint` to OAuth discovery metadata ### Stale Registration Cleanup - **Cleanup Service**: Automatically removes OAuth-only registrations older than 30 days that have no active installations - **Cron Job**: Runs daily at 02:30 AM UTC with batch processing (100 records per batch) - **CLI Command**: `cron:stale-registration-cleanup` to manually trigger cleanup ### MCP (Model Context Protocol) Authentication - **New Guard**: `McpAuthGuard` implements RFC 9728 compliance - Wraps JWT authentication with proper error responses - Returns `WWW-Authenticate` header with protected resource metadata URL on 401 - Enables OAuth-protected MCP endpoints ### Protected Resource Metadata - **New Endpoint**: `GET /.well-known/oauth-protected-resource` (RFC 9728) - Advertises MCP resource as OAuth-protected - Lists supported scopes and bearer token methods - Enables OAuth clients to discover authorization requirements ### Application Registration Updates - **New Source Type**: `OAUTH_ONLY` enum value for OAuth-only registrations - **Install Service**: Skips artifact installation for OAuth-only apps (no code artifacts) ### Frontend Updates - **Authorization Page**: Support both snake_case (standard OAuth) and camelCase (legacy) query parameters - `client_id` / `clientId` - `code_challenge` / `codeChallenge` - `redirect_uri` / `redirectUrl` ## Implementation Details - **Rate Limiting**: Uses token bucket algorithm with 10 registrations per 3,600,000ms window per IP - **Scope Validation**: Requested scopes are capped to allowed OAuth scopes; defaults to all scopes if not specified - **Redirect URI Validation**: Uses existing `validateRedirectUri` utility for security - **Cache Headers**: Registration responses include `Cache-Control: no-store` and `Pragma: no-cache` - **Batch Processing**: Cleanup operations process 100 records at a time to avoid memory issues - **Grace Period**: 30-day grace period before cleanup to allow time for client activation https://claude.ai/code/session_01PxcuWFFRuXMASMaMGTLYk2 --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: github-actions <github-actions@twenty.com> Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> |
||
|
|
66da296799 |
Unify MCP into single endpoint with lazy tool discovery (#18113)
## Summary - Consolidates the MCP server from two endpoints (`/mcp` + `/mcp/metadata`) into a **single `POST /mcp`** endpoint exposing five high-level tools: `get_tool_catalog`, `learn_tools`, `execute_tool`, `load_skills`, and `search_help_center` - Fixes **DATABASE_CRUD tools not accessible via API key auth** by removing an unnecessary `userId`/`userWorkspaceId` guard in `DatabaseToolProvider` and threading `ApiKeyWorkspaceAuthContext` through the tool context chain - Improves tool descriptions with **STEP 1/2/3 workflow guidance** so AI clients follow the correct discovery flow (catalog → learn → execute) instead of guessing tool names - Simplifies the **frontend AI settings** by removing the schema picker dropdown (no more "Core Schema" vs "Metadata Schema" choice) ## Changes ### Backend - **Deleted**: `mcp-metadata.controller.ts`, `mcp-metadata.service.ts` (merged into core) - **New**: `get-tool-catalog.tool.ts` — browsable, categorized tool discovery - **Fixed**: `DatabaseToolProvider.generateDescriptors` — removed guard that blocked API key access to CRUD tools - **Fixed**: `ToolContext` type + `ToolRegistryService` — `authContext` now flows through so API key CRUD execution works end-to-end - **Updated**: `McpProtocolService` — builds `ApiKeyWorkspaceAuthContext` for API key requests - **Updated**: All MCP tool descriptions with explicit step numbering ### Frontend - **Simplified**: `SettingsAIMCP.tsx` — removed schema selector dropdown, shows single MCP config ## Test plan - [x] All 19 MCP unit tests pass (controller + protocol service) - [x] Server and frontend lint clean - [x] Server and frontend typecheck pass - [x] Live-tested on localhost:3000 with API key: `get_tool_catalog` returns 236 tools including 196 DATABASE_CRUD tools - [x] Live-tested `execute_tool` with `find_companies` via API key — returns real data - [x] Tested MCP connection from Cursor IDE via project-level `.cursor/mcp.json` Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
da064d5e88 |
Support define is tool logic function (#17926)
- supports isTool and timeout settings in defineLogicFunction in apps and in setting tabs definition - compute for all toolInputSchema for logic funciton, in settings and in code steps <img width="991" height="802" alt="image" src="https://github.com/user-attachments/assets/05dc1221-cac9-45a3-87b0-3b13161446fd" /> |
||
|
|
039a3d99a8 |
Fix APIKey typing (#16541)
Following this https://github.com/twentyhq/twenty/pull/16540 Those were not failing (yet) but were wrongly typed and error prone --------- Co-authored-by: Guillim <guillim@users.noreply.github.com> |
||
|
|
e7ebf51e50 |
Replace agent handoff system with planning-based router (#16003)
## Overview This PR replaces the dynamic agent handoff system with a more predictable planning-based router that decides upfront how to handle multi-agent coordination. ## Major Changes ### 🔄 Architecture Shift: Handoffs → Planning **Removed:** - `AgentHandoffEntity` and handoff tracking system - `AgentHandoffService` and `AgentHandoffExecutorService` - Dynamic agent-to-agent transfers during execution - Handoff tool generation and description templates **Added:** - `AiRouterService` with two strategies: `simple` (single agent) and `planned` (multi-agent) - `AgentPlanExecutorService` for executing multi-step plans - Plan validation (cycle detection, dependency resolution) - `UnifiedRouterResult` type with discriminated union ### 🤖 New Standard Agents Added two new specialized agents: - **Researcher Agent**: Web search, fact-finding, competitive intelligence - **Code Agent**: TypeScript function generation for serverless workflows ### 🏗️ Router Refactoring (Latest) Split router responsibilities into focused services: - `AiRouterStrategyDeciderService`: Decides simple vs planned strategy - `AiRouterPlanGeneratorService`: Generates and validates execution plans - `AiRouterService`: Coordinates between services (reduced from 426→275 lines) ### ⚙️ Configuration Improvements - Added `outputStrategy` to agent definitions (`direct` vs `synthesize`) - Removed hardcoded special cases for workflow-builder - Added `plannerModel` field to workspace entity - Increased `MAX_STEPS` from 10 to 25 for complex workflows ### 📝 Agent Prompt Refinements Significantly simplified prompts for better clarity: - Workflow Builder: 51→36 lines - Helper: 49→28 lines - Data Manipulator: Enhanced with sorting guidance ### 🔍 Enhanced Debugging - Plan reasoning and step count in data message parts - Router debug info with token usage tracking - Better logging throughout execution pipeline ## Benefits 1. **Simpler Mental Model**: Router decides upfront vs dynamic transfers 2. **Better Predictability**: Users see the plan before execution 3. **Cleaner Architecture**: SRP with focused services 4. **Configuration Over Code**: Agent behavior via config, not hardcoded logic 5. **Plan Validation**: Catches invalid dependencies and cycles ## Migration Notes - Database migration removes `agentHandoff` table - Adds `plannerModel` column to workspace table - No API breaking changes (agent endpoints unchanged) ## Testing - Integration tests updated to remove handoff dependencies - Agent tool test utilities simplified - Plan validation covered by new logic ## Next Steps (Future PRs) - Parallel execution of independent plan steps - Dynamic re-planning based on results - Plan caching for common routing patterns - Error recovery strategies in plan executor |
||
|
|
9a80164cf3 |
Add comprehensive permission guard coverage across GraphQL and REST endpoints (#15739)
This PR enhances our security model by ensuring all GraphQL resolvers and REST API endpoints have appropriate permission guards. ## Changes ### ESLint Rules - Enhanced `graphql-resolvers-should-be-guarded` to require permission guards on all resolvers (Query, Mutation, Subscription), not just mutations - Enhanced `rest-api-methods-should-be-guarded` to require permission guards on all REST endpoints (GET, POST, PUT, PATCH, DELETE), not just mutating methods - Both rules now enforce consistent security: authentication guards + permission guards for all endpoints ### Permission Guards Added **Public Endpoints** - Added `NoPermissionGuard`: - Auth-related queries (checkUserExists, findWorkspaceFromInviteHash, validatePasswordResetToken) - Billing webhooks (Stripe callbacks) - SSO callbacks (SAML authentication) - Workflow webhooks - Cloudflare webhooks - Route trigger endpoints - GraphQL subscriptions - Current workspace queries - Geo-map address autocomplete - View-related read operations (view-field, view-filter, view-group, view-sort, view-filter-group) **Settings Permission Guards** - Added `SettingsPermissionGuard`: - API Keys management: `PermissionFlagType.API_KEYS_AND_WEBHOOKS` - Webhooks management: `PermissionFlagType.API_KEYS_AND_WEBHOOKS` - Page Layouts (write operations): `PermissionFlagType.LAYOUTS` - REST Metadata API: `PermissionFlagType.DATA_MODEL` - Agent operations: `PermissionFlagType.AI` - Remote servers: `PermissionFlagType.DATA_MODEL` - Remote tables: `PermissionFlagType.DATA_MODEL` - Serverless functions: `PermissionFlagType.WORKFLOWS` **Custom Permission Guards** - Added `CustomPermissionGuard`: - REST Core API (permissions checked at query execution layer) - Timeline calendar events (permission checks in service layer) - Timeline messaging (permission checks in service layer) - Search operations (permission checks in service layer) - View operations (permission checks via dedicated view permission guards) ### View Permission Guards - Created dedicated `FindManyViewsPermissionGuard` and `FindOneViewPermissionGuard` for reading views - Created `CreateViewPermissionGuard` for view creation with visibility-based permission checks - All view child entities (view-field, view-filter, view-sort, view-group, view-filter-group) use `NoPermissionGuard` for reads - Write operations on view child entities use dedicated permission guards that check parent view access ### Page Layout Permissions - Read operations (GET/Query) now use `NoPermissionGuard` - users can view layouts without LAYOUTS permission - Write operations (POST/PATCH/DELETE/Mutation) require `SettingsPermissionGuard(PermissionFlagType.LAYOUTS)` - Applied consistently across page-layout, page-layout-tab, and page-layout-widget endpoints ## Security Model All endpoints now follow a consistent pattern: 1. **Authentication**: `UserAuthGuard`, `WorkspaceAuthGuard`, or `PublicEndpointGuard` 2. **Authorization**: One of: - `SettingsPermissionGuard(PermissionFlagType.XXX)` - for settings/admin operations - `CustomPermissionGuard` - when permissions are checked in service/data layer - `NoPermissionGuard` - for public or non-sensitive read operations The ESLint rules automatically enforce this pattern going forward. ## Stats - 47 files changed - 603 insertions, 163 deletions - 3 new guard files created |
||
|
|
c5564d9bd0 |
[BREAKING CHANGE] refactor: Add Entity suffix to TypeORM entity classes (#15239)
## Summary This PR refactors all TypeORM entity classes in the Twenty codebase to include an 'Entity' suffix (e.g., User → UserEntity, Workspace → WorkspaceEntity) to improve code clarity and follow TypeORM naming conventions. ## Changes ### Entity Renaming - ✅ Renamed **57 core TypeORM entities** with 'Entity' suffix - ✅ Updated all related imports, decorators, and type references - ✅ Fixed Repository<T>, @InjectRepository(), and TypeOrmModule.forFeature() patterns - ✅ Fixed @ManyToOne/@OneToMany/@OneToOne decorator references ### Backward Compatibility - ✅ Preserved GraphQL schema names using @ObjectType('OriginalName') decorators - ✅ **No breaking changes** to GraphQL API - ✅ **No database migrations** required - ✅ File names unchanged (user.entity.ts remains as-is) ### Code Quality - ✅ Fixed **497 TypeScript errors** (82% reduction from 606 to 109) - ✅ **All linter checks passing** - ✅ Improved type safety across the codebase ## Entities Renamed ``` User → UserEntity Workspace → WorkspaceEntity ApiKey → ApiKeyEntity AppToken → AppTokenEntity UserWorkspace → UserWorkspaceEntity Webhook → WebhookEntity FeatureFlag → FeatureFlagEntity ApprovedAccessDomain → ApprovedAccessDomainEntity TwoFactorAuthenticationMethod → TwoFactorAuthenticationMethodEntity WorkspaceSSOIdentityProvider → WorkspaceSSOIdentityProviderEntity EmailingDomain → EmailingDomainEntity KeyValuePair → KeyValuePairEntity PublicDomain → PublicDomainEntity PostgresCredentials → PostgresCredentialsEntity ...and 43 more entities ``` ## Impact ### Files Changed - **400 files** modified - **2,575 insertions**, **2,191 deletions** ### Progress - ✅ **82% complete** (497/606 errors fixed) - ⚠️ **109 TypeScript errors** remain (18% of original) ## Remaining Work The 109 remaining TypeScript errors are primarily: 1. **Function signature mismatches** (~15 errors) - Test mocks with incorrect parameter counts 2. **Entity type mismatches** (~25 errors) - UserEntity vs UserWorkspaceEntity confusion 3. **Pre-existing issues** (~50 errors) - Null safety and DTO compatibility (unrelated to refactoring) 4. **Import type issues** (~10 errors) - Entities imported with 'import type' but used as values 5. **Minor decorator issues** (~9 errors) - onDelete property configurations These can be addressed in follow-up PRs without blocking this refactoring. ## Testing Checklist - [x] Linter passing - [ ] Unit tests should be run (CI will verify) - [ ] Integration tests should be run (CI will verify) - [ ] Manual testing recommended for critical user flows ## Breaking Changes **None** - This is a pure refactoring with full backward compatibility: - GraphQL API unchanged (uses original entity names) - Database schema unchanged - External APIs unchanged ## Notes - Created comprehensive `REFACTORING_STATUS.md` documenting the entire process - All temporary scripts have been cleaned up - Branch: `refactor/add-entity-suffix-to-typeorm-entities` ## Reviewers Please review especially: - Entity renaming patterns - GraphQL backward compatibility - Any areas where entity types are confused (UserEntity vs UserWorkspaceEntity) --------- Co-authored-by: Charles Bochet <charles@twenty.com> |
||
|
|
809fe5699f |
feat(ai): enhance metadata handling and add support for tools, prompt… (#14002)
…s, and resources - Removed unused `ObjectMetadataStandardIdToIdMap`. - Updated Vite config with additional allowed hosts. - Improved MCP service to handle `ping` method and lists for tools, prompts, and resources. - Refactored utility function `isFieldMetadataEntityOfType` for improved type handling. - Expanded MCP metadata service to include tools, prompts, and resources support. |
||
|
|
11abe5440b |
feat(ai): add mcp-metadata (#13150)
Co-authored-by: Félix Malfait <felix@twenty.com> |