Commit graph

77 commits

Author SHA1 Message Date
Nick Misasi
0fda377dec docs(13-04): create server gRPC CLAUDE.md
Add AI development guidance for Mattermost contributors working on the
Python plugin gRPC infrastructure. Includes directory structure, key
components, proto organization, common patterns, and instructions for
adding new API methods and hooks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 10:42:03 -05:00
Nick Misasi
f1f1ee8d95 docs(13-01): create comprehensive gRPC architecture documentation
Add ARCHITECTURE.md documenting the Python plugin gRPC system including:
- High-level overview and ASCII system architecture diagram
- Component layer documentation (Protocol, Go Infrastructure, Python SDK)
- Process lifecycle (loading, environment variables, shutdown)
- Communication flow diagrams (hooks, API calls, ServeHTTP streaming)
- Key design decisions (embedded AppError, 64KB chunks, APIServerRegistrar)
- Complete file reference table mapping functionality to source files
- Extension guide for adding new API methods and hooks

This documentation enables internal Mattermost engineers to understand,
debug, and extend the Python plugin infrastructure.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 10:38:52 -05:00
Nick Misasi
3397ba6a4f bench(10-03): add Go gRPC benchmark tests
Create comprehensive benchmark tests measuring gRPC server overhead
for Python plugin API calls. Benchmarks use in-memory bufconn to
isolate gRPC serialization/transport overhead from network latency.

Benchmarks included:
- BenchmarkGetServerVersion: minimal RPC baseline (~36us)
- BenchmarkGetUser: entity retrieval with model conversion (~38us)
- BenchmarkCreatePost: entity creation with request/response (~41us)
- BenchmarkGetChannel: channel retrieval pattern (~37us)
- BenchmarkKVSet/KVGet: key-value operations (~37-38us)
- BenchmarkHasPermissionTo: permission check hot-path (~37us)
- BenchmarkIsEnterpriseReady: simple boolean response (~36us)

Results establish baseline for comparing Python plugin overhead vs
native Go plugins.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 15:40:27 -05:00
Nick Misasi
926b6f3483 chore(10-02): add CI-friendly integration test runner scripts
Create shell scripts for consistent test invocation across CI environments:

Python script (python-sdk/scripts/run_integration_tests.sh):
- Auto-detects virtual environment or uses system Python
- Installs package in editable mode if not present
- Runs test_integration_e2e.py with verbose output
- Supports passing extra pytest arguments

Go script (server/public/pluginapi/grpc/scripts/run_integration_tests.sh):
- Runs from the correct module directory
- Filters to TestPythonPlugin and TestIntegration tests
- Disables test caching for clean CI runs
- Supports passing extra go test arguments

Both scripts:
- Are executable (chmod +x)
- Print diagnostic information (working dir, version)
- Exit with appropriate error codes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 15:36:57 -05:00
Nick Misasi
e05bbb5f81 test(10-02): add Go integration tests for Python plugin lifecycle
Create integration tests that prove Go gRPC server and Python plugin
communicate correctly via simulated in-memory gRPC communication:

- TestPythonPluginLifecycle: Full lifecycle (activate, deactivate)
- TestPythonPluginAPICall: Round-trip plugin -> API server callback
- TestPythonPluginHookChain: MessageWillBePosted modification/rejection
- TestPythonPluginActivationFailure: Error propagation from plugin
- TestPythonPluginAPIErrorPropagation: AppError -> gRPC status mapping
- TestIntegrationConcurrentHookCalls: Concurrent hook invocations

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 15:32:04 -05:00
Nick Misasi
11ddd32a8c test(08-02): add tests for response streaming, flush, and invalid status codes
Go tests:
- TestInvalidStatusCode_TooLow: verify status 42 returns 500 error
- TestInvalidStatusCode_TooHigh: verify status 1000 returns 500 error
- TestInvalidStatusCode_DoesNotPanic: ensure no panic for any invalid code
- TestFlush_WithFlusher: verify flush calls http.Flusher.Flush()
- TestFlush_WithoutFlusher: verify flush doesn't panic without Flusher
- TestFlushGracefulDegradation: mirror plugin/http_test.go behavior
- TestStreamResponseBody_WithFlush: verify flush flags processed in stream
- TestEarlyResponse_CancelsRequestSend: verify early response stops sender

Python tests:
- test_flush_method_exists: verify flush() is callable
- test_flush_applies_to_last_write: verify retroactive flush
- test_flush_applies_to_next_write_when_empty: verify pre-write flush
- test_multiple_writes_with_selective_flush: verify selective flushing
- test_streaming_response_chunks: verify multiple writes = multiple messages
- test_empty_body_response: verify no-body response handling
- test_response_headers_in_first_message: verify header placement

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:40:41 -05:00
Nick Misasi
49941d877a feat(08-02): implement Go streaming response with flush support
Update ServeHTTPCaller to support true streaming responses:
- Full-duplex operation: plugin can respond before request body is consumed
- Flush support: best-effort flushing when underlying writer supports http.Flusher
- Status code validation (100-999 range) to prevent server panics
- Early response handling with proper goroutine cleanup
- Proper error responses for invalid status codes and plugin failures

Key changes:
- Add logger to ServeHTTPCaller for error logging
- Add context cancellation to sendRequest for early response termination
- Add receiveFirstResponse to handle first message with body chunk + flush
- Add writeResponseHeaders with status code validation
- Add flush() method for best-effort HTTP flushing
- Update streamResponseBody to handle flush flag

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:36:28 -05:00
Nick Misasi
5c7aecda49 feat(08-02): extend protobuf contract for response streaming + flush
Add flush field to ServeHTTPResponse for best-effort HTTP flush support.
Update ServeHTTPResponse and ServeHTTPResponseInit with comprehensive
documentation of streaming invariants, message ordering, and status
code validation rules.

Changes:
- Add flush boolean field (field 4) to ServeHTTPResponse
- Document response streaming invariants (init-once, header locking)
- Document status code validation (100-999 range, 0 defaults to 200)
- Regenerate Go and Python protobuf code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:34:36 -05:00
Nick Misasi
503ab08cbc test(08-01): add comprehensive tests for ServeHTTP streaming
Add tests for both Go and Python ServeHTTP implementations covering:
- Body chunking behavior (small, exact, multiple, large bodies)
- Context cancellation during body streaming
- Header conversion utilities
- HTTPRequest/HTTPResponseWriter helper classes
- Request body assembly from multiple chunks
- Error handling (500 for handler errors, 404 for missing handler)

Go tests:
- TestChunking_* for body chunking scenarios
- TestConvertHTTPHeaders for header conversion
- TestBuildRequestInit for request metadata building
- TestWriteResponseHeaders for response header writing
- TestContextCancellation_DuringBodyRead for cancellation

Python tests:
- TestHTTPRequest for request wrapper class
- TestHTTPResponseWriter for response writer class
- TestHeaderConversion for proto<->dict conversion
- TestServeHTTPServicer for gRPC servicer behavior
- TestChunkingBehavior for body assembly
- TestCancellation for request cancellation

Also:
- Fixed sendRequest to properly set body_complete flag on EOF
- Added ServeHTTP to HookName enum

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:31:30 -05:00
Nick Misasi
75bdac1b13 feat(08-01): implement Go gRPC client for ServeHTTP streaming
Add ServeHTTPCaller that streams HTTP requests to Python plugins
and receives streaming responses.

Key features:
- Bidirectional streaming for efficient large body transfer
- 64KB chunked request body streaming (no full buffering)
- Context cancellation propagation from HTTP client disconnect
- HTTPHeader conversion supporting multi-value headers
- PluginContext passed through to Python handler

Implementation details:
- sendRequest: streams body chunks with completion flag
- receiveResponseInit: gets status code and headers
- streamResponseBody: writes response chunks to ResponseWriter
- buildRequestInit: converts http.Request to protobuf init

Note: Response streaming improvements deferred to 08-02.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:25:07 -05:00
Nick Misasi
19c392084b feat(08-01): add protobuf contract for ServeHTTP request streaming
Add bidirectional streaming RPC for ServeHTTP hook to support
efficient HTTP request/response transfer between Go and Python.

Key changes:
- New hooks_http.proto with ServeHTTPRequest/Response messages
- HTTPHeader message for multi-value header support
- ServeHTTPRequestInit with full request metadata
- ServeHTTPResponseInit for status and headers
- Body chunks with completion flag for streaming
- Updated hooks.proto with ServeHTTP streaming RPC
- Regenerated Go and Python code

Design decisions:
- 64KB default chunk size per gRPC best practices
- First message carries metadata, subsequent messages carry body
- body_complete flag signals end of stream
- Headers as repeated HTTPHeader for multi-value support

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 14:23:38 -05:00
Nick Misasi
06407e18c6 feat(04-04): implement remaining gRPC handlers for Plugin API
Add handlers for all remaining Plugin API methods not covered by 04-02 or 04-03:
- Licensing & System: GetLicense, GetSystemInstallDate, GetDiagnosticId, GetTelemetryId
- Configuration: LoadPluginConfiguration, GetConfig, GetUnsanitizedConfig, SaveConfig, GetPluginConfig, SavePluginConfig
- Plugin Management: GetBundlePath, GetPlugins, EnablePlugin, DisablePlugin, RemovePlugin, GetPluginStatus, InstallPlugin
- Logging: LogDebug, LogInfo, LogWarn, LogError
- Commands: RegisterCommand, UnregisterCommand, ExecuteSlashCommand, CreateCommand, ListCommands, GetCommand, UpdateCommand, DeleteCommand
- Bots: CreateBot, PatchBot, GetBot, GetBots, UpdateBotActive, PermanentDeleteBot, EnsureBotUser
- Emojis: GetEmoji, GetEmojiByName, GetEmojiImage, GetEmojiList
- OAuth: CreateOAuthApp, GetOAuthApp, UpdateOAuthApp, DeleteOAuthApp
- Groups: GetGroup, GetGroupByName, GetGroupMemberUsers, GetGroupsBySource, GetGroupsForUser, CreateGroup, DeleteGroup, UpsertGroupMember, DeleteGroupMember, UpsertGroupSyncable, GetGroupSyncable, UpdateGroupSyncable, DeleteGroupSyncable
- Shared Channels: ShareChannel, UpdateSharedChannel, UnshareChannel, UpdateSharedChannelCursor, SyncSharedChannel, RegisterPluginForSharedChannels, UnregisterPluginForSharedChannels
- WebSocket: PublishWebSocketEvent
- Cluster: PublishPluginClusterEvent
- Interactive Dialog: OpenInteractiveDialog
- Upload Session: CreateUploadSession, UploadData, GetUploadSession
- Push Notification: SendPushNotification
- Mail: SendMail
- Plugin HTTP: PluginHTTP
- Trial License: RequestTrialLicense
- Permissions: RolesGrantPermission
- Cloud: GetCloudLimits
- Collection and Topic: RegisterCollectionAndTopic

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:34:09 -05:00
Nick Misasi
8c8093edb4 feat(04-03): implement KV Store API gRPC handlers with tests
Implement all KV Store-related gRPC RPC handlers:
- KVSet, KVGet, KVDelete, KVDeleteAll
- KVSetWithExpiry, KVSetWithOptions
- KVCompareAndSet, KVCompareAndDelete
- KVList

Add comprehensive unit tests for:
- Set/Get roundtrip
- Get non-existent key (nil value)
- Delete and DeleteAll
- CompareAndSet success and mismatch cases
- CompareAndDelete
- SetWithExpiry and SetWithOptions
- Error handling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:13:03 -05:00
Nick Misasi
391f390daa feat(04-03): implement File API gRPC handlers with tests
Implement all File-related gRPC RPC handlers:
- GetFileInfo, GetFileInfos, GetFile
- GetFileLink, ReadFile, UploadFile
- CopyFileInfos, SetFileSearchableContent

Add comprehensive unit tests for:
- GetFileInfo success and not found cases
- GetFile success and error cases
- ReadFile success and not found cases
- UploadFile success and permission error
- CopyFileInfos and SetFileSearchableContent
- GetFileInfos with options

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:11:39 -05:00
Nick Misasi
716ec55099 feat(04-03): implement Post API gRPC handlers with tests
Implement all Post-related gRPC RPC handlers:
- CreatePost, UpdatePost, DeletePost, GetPost
- AddReaction, RemoveReaction, GetReactions
- SendEphemeralPost, UpdateEphemeralPost, DeleteEphemeralPost
- GetPostThread, GetPostsSince, GetPostsAfter, GetPostsBefore
- GetPostsForChannel, SearchPostsInTeam, SearchPostsInTeamForUser

Add comprehensive unit tests for:
- CreatePost success and error paths
- GetPost success and not found cases
- DeletePost with permission error
- UpdatePost, reactions, ephemeral posts
- PostList retrieval methods

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:10:08 -05:00
Nick Misasi
e4fb3f2a07 test(04-02): add unit tests for User/Team/Channel handlers
Add comprehensive unit tests for gRPC handlers using bufconn and
plugintest mocks. Tests cover:
- User handlers: GetUser, GetUserByEmail, GetUserByUsername,
  CreateUser, DeleteUser, HasPermissionTo, HasPermissionToTeam,
  HasPermissionToChannel, error handling (NotFound)
- Team handlers: GetTeam, GetTeamByName, CreateTeam, DeleteTeam,
  GetTeams, CreateTeamMember
- Channel handlers: GetChannel, GetChannelByName, CreateChannel,
  DeleteChannel, GetDirectChannel, GetGroupChannel, AddChannelMember,
  DeleteChannelMember, SearchChannels

All tests verify correct delegation to plugin.API and proper
protobuf conversion.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:09:46 -05:00
Nick Misasi
badb9f394d feat(04-02): implement Channel API gRPC handlers
Implement gRPC handlers for all Channel-related Plugin API methods:
- Channel CRUD: CreateChannel, DeleteChannel, GetChannel, GetChannelByName,
  GetChannelByNameForTeamName, UpdateChannel
- Channel queries: GetPublicChannelsForTeam, GetChannelsForTeamForUser,
  GetChannelStats, SearchChannels
- Direct/Group messages: GetDirectChannel, GetGroupChannel
- Channel membership: AddChannelMember, AddUserToChannel, GetChannelMember,
  GetChannelMembers, GetChannelMembersByIds, GetChannelMembersForUser,
  UpdateChannelMemberRoles, UpdateChannelMemberNotifications,
  PatchChannelMembersNotifications, DeleteChannelMember
- Sidebar categories: CreateChannelSidebarCategory,
  GetChannelSidebarCategories, UpdateChannelSidebarCategories

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:09:39 -05:00
Nick Misasi
d4c3d6fec1 feat(04-02): implement Team API gRPC handlers
Implement gRPC handlers for all Team-related Plugin API methods:
- Team CRUD: CreateTeam, DeleteTeam, GetTeam, GetTeamByName,
  GetTeams, UpdateTeam, SearchTeams
- Team membership: CreateTeamMember, CreateTeamMembers,
  CreateTeamMembersGracefully, DeleteTeamMember, GetTeamMember,
  GetTeamMembers, GetTeamMembersForUser, UpdateTeamMemberRoles
- Team icons: GetTeamIcon, SetTeamIcon, RemoveTeamIcon
- Team data: GetTeamsForUser, GetTeamsUnreadForUser, GetTeamStats

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:09:31 -05:00
Nick Misasi
3179c816df feat(04-02): implement User API gRPC handlers
Implement gRPC handlers for all User-related Plugin API methods:
- User CRUD: CreateUser, DeleteUser, GetUser, GetUserByEmail,
  GetUserByUsername, GetUsersByUsernames, GetUsersByIds, GetUsers,
  GetUsersInTeam, UpdateUser
- Status: GetUserStatus, GetUserStatusesByIds, UpdateUserStatus,
  SetUserStatusTimedDND, UpdateUserActive
- Custom status: UpdateUserCustomStatus, RemoveUserCustomStatus
- Permissions: HasPermissionTo, HasPermissionToTeam, HasPermissionToChannel
- Session: GetSession, CreateSession, ExtendSessionExpiry, RevokeSession,
  CreateUserAccessToken, RevokeUserAccessToken
- Preferences: GetPreferenceForUser, GetPreferencesForUser,
  UpdatePreferencesForUser, DeletePreferencesForUser
- Other: GetUsersInChannel, GetLDAPUserAttributes, SearchUsers,
  GetProfileImage, SetProfileImage, PublishUserTyping,
  UpdateUserAuth, UpdateUserRoles

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:09:25 -05:00
Nick Misasi
1850fb785e feat(04-02): add Team model to proto conversion functions
Add conversion functions between model.Team/TeamMember/TeamUnread/TeamStats
and their protobuf equivalents. Includes:
- teamToProto/teamFromProto for Team conversion
- teamMemberToProto/teamMemberFromProto for TeamMember conversion
- teamUnreadToProto for TeamUnread conversion
- teamStatsToProto for TeamStats conversion
- teamMembersWithErrorToProto for graceful member creation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:09:16 -05:00
Nick Misasi
8f5aa1070d fix(04-03): fix conversion type errors in channel/user/common
Fix compilation errors in existing conversion files:

convert_channel.go:
- Add sidebarCategorySortingToProto/FromProto helper functions
- Convert SidebarCategorySorting properly (string type, not int32)

convert_user.go:
- Add time import
- Fix CustomStatus.ExpiresAt conversion (time.Time, not int64)

convert_common.go:
- Remove unused structpb import

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:05:37 -05:00
Nick Misasi
dc5293d19d feat(04-03): add Post/File/KV type conversion functions
Add pb <-> model conversion functions for Post, File, and KV Store types:

convert_post.go:
- Post, PostMetadata, PostEmbed, Reaction conversions
- PostList and PostSearchResults conversions
- SearchParams and SearchParameter conversions

convert_file.go:
- FileInfo conversions
- GetFileInfosOptions conversion

convert_kv.go:
- PluginKVSetOptions conversion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 14:05:26 -05:00
Nick Misasi
296da1e5f2 docs(04-01): add extension guide for subsequent plans
Enhance package documentation to explain how subsequent plans (04-02
through 04-04) should extend the APIServer with new RPC implementations.
Includes code example and key patterns for error handling and model
conversion.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:57:43 -05:00
Nick Misasi
0c6a537cc0 test(04-01): add bufconn test harness and smoke tests
Add in-memory gRPC testing infrastructure using bufconn. Includes:
- testHarness struct for easy test setup/teardown
- Smoke tests for GetServerVersion and IsEnterpriseReady RPCs
- Comprehensive error conversion tests for all HTTP->gRPC mappings
- Tests use plugintest.API mock from the existing codebase

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:57:06 -05:00
Nick Misasi
809566ca55 feat(04-01): implement shared error conversion helpers
Add AppErrorToStatus and ErrorToStatus functions to centralize the
conversion of Mattermost errors to gRPC status codes. Maps HTTP codes
to gRPC codes following Phase 1 research recommendations:
- 400 -> InvalidArgument
- 401 -> Unauthenticated
- 403 -> PermissionDenied
- 404 -> NotFound
- 409 -> AlreadyExists
- 413/429 -> ResourceExhausted
- 501 -> Unimplemented
- 503 -> Unavailable
- default -> Internal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:56:10 -05:00
Nick Misasi
aad79469cf feat(04-01): add gRPC API server skeleton
Create the APIServer struct that wraps plugin.API and embeds
UnimplementedPluginAPIServer for incremental implementation.
Includes Register helper and smoke RPCs (GetServerVersion,
IsEnterpriseReady) to validate the wiring.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:55:43 -05:00
Nick Misasi
20f7cdebcd feat(03-04): update Makefile and generate Go code
- Add hooks_command.proto to Makefile proto mappings
- Update hooks_command.proto to import api_remaining.proto for shared types
  (CommandArgs, CommandResponse, PluginClusterEvent)
- Define new types: WebSocketRequest, SyncMsgJson, SyncResponse, RemoteCluster
- Generated Go code compiles successfully
- Total hooks in PluginHooks service: 41 (excluding deferred ServeHTTP/ServeMetrics)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:42:31 -05:00
Nick Misasi
0c75338a99 feat(03-04): add remaining hook RPCs to PluginHooks service
Update hooks.proto with 11 new RPCs for command/websocket/cluster/shared channels/support hooks:

COMMAND HOOKS:
- ExecuteCommand

WEBSOCKET HOOKS:
- OnWebSocketConnect
- OnWebSocketDisconnect
- WebSocketMessageHasBeenPosted

CLUSTER HOOKS:
- OnPluginClusterEvent

SHARED CHANNELS HOOKS:
- OnSharedChannelsSyncMsg
- OnSharedChannelsPing
- OnSharedChannelsAttachmentSyncMsg
- OnSharedChannelsProfileImageSyncMsg

SUPPORT HOOKS:
- GenerateSupportData

Also added note about ServeHTTP and ServeMetrics being deferred to Phase 8.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:40:25 -05:00
Nick Misasi
8261d03e05 feat(03-04): create hooks_command.proto with command/cluster/websocket hook definitions
Add protobuf message definitions for command, WebSocket, cluster, shared channels,
and support data generation hooks including:
- CommandArgs, CommandResponse, SlackAttachment model types
- PluginClusterEvent, WebSocketRequest model types
- SyncMsgJson, SyncResponse, RemoteCluster for shared channels
- Request/response messages for 11 hooks:
  - ExecuteCommand
  - OnPluginClusterEvent
  - OnWebSocketConnect/Disconnect
  - WebSocketMessageHasBeenPosted
  - OnSharedChannelsSyncMsg/Ping/AttachmentSyncMsg/ProfileImageSyncMsg
  - GenerateSupportData

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:39:45 -05:00
Nick Misasi
8bbc01cca2 feat(03-03): update Makefile and generate Go code for user/channel hooks
- Add hooks_user_channel.proto mapping to Makefile proto generation
- Regenerate Go protobuf code with new user/channel hook types
- Generated hooks_user_channel.pb.go with all message types
- Updated hooks.pb.go and hooks_grpc.pb.go with new RPCs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:37:13 -05:00
Nick Misasi
6f4a0fe8c9 feat(03-03): add user/channel hook RPCs to PluginHooks service
Add 10 RPC definitions to PluginHooks service:
- USER HOOKS: UserHasBeenCreated, UserWillLogIn, UserHasLoggedIn,
  UserHasBeenDeactivated, OnSAMLLogin
- CHANNEL AND TEAM HOOKS: ChannelHasBeenCreated, UserHasJoinedChannel,
  UserHasLeftChannel, UserHasJoinedTeam, UserHasLeftTeam

Import hooks_user_channel.proto for request/response message types.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:36:16 -05:00
Nick Misasi
e6c343c72b feat(03-03): create hooks_user_channel.proto with user/channel hook definitions
Add protobuf definitions for 10 user and channel lifecycle hooks:
- UserHasBeenCreated, UserWillLogIn, UserHasLoggedIn, UserHasBeenDeactivated
- OnSAMLLogin (with JSON blob for SAML assertion)
- ChannelHasBeenCreated
- UserHasJoinedChannel, UserHasLeftChannel (with optional actor)
- UserHasJoinedTeam, UserHasLeftTeam (with optional actor)

Includes SamlAssertionInfoJson type for handling external SAML library types.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:35:44 -05:00
Nick Misasi
5b3ef59f9a feat(03-02): update Makefile and generate Go code for message hooks
- Add hooks_message.proto mapping to Makefile for proto generation
- Update hooks_message.proto to import api_remaining.proto for
  PushNotification and Preference types (avoiding redefinition)
- Generate Go code for all message hook messages and RPCs

Verified:
- make proto-gen succeeds
- go build ./public/pluginapi/grpc/generated/go/pluginapiv1/... succeeds

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:33:52 -05:00
Nick Misasi
079fd4cd61 feat(03-02): add message hook RPCs to PluginHooks service
Add 12 message-related RPC definitions to the PluginHooks service:
- MessageWillBePosted - intercept/modify posts before save
- MessageWillBeUpdated - intercept/modify post updates before save
- MessageHasBeenPosted - notification after post created
- MessageHasBeenUpdated - notification after post updated
- MessagesWillBeConsumed - filter posts before client delivery
- MessageHasBeenDeleted - notification after post deleted
- FileWillBeUploaded - intercept/modify file uploads
- ReactionHasBeenAdded - notification after reaction added
- ReactionHasBeenRemoved - notification after reaction removed
- NotificationWillBePushed - intercept/modify push notifications
- EmailNotificationWillBeSent - intercept/modify email notifications
- PreferencesHaveChanged - notification after preferences changed

Each RPC includes documentation explaining:
- When the hook is called
- How to use return values (modify, reject, allow)
- The original Go signature

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:32:27 -05:00
Nick Misasi
ab912b3a2d feat(03-02): create hooks_message.proto with message hook definitions
Add protobuf message definitions for 12 message-related hooks:
- MessageWillBePosted, MessageWillBeUpdated
- MessageHasBeenPosted, MessageHasBeenUpdated
- MessagesWillBeConsumed, MessageHasBeenDeleted
- FileWillBeUploaded
- ReactionHasBeenAdded, ReactionHasBeenRemoved
- NotificationWillBePushed, EmailNotificationWillBeSent
- PreferencesHaveChanged

Also defines model types:
- PushNotification (typed proto, moderate size)
- EmailNotificationJson (JSON blob wrapper for complex type)
- EmailNotificationContent (typed return for email hook)
- Preference (simple 4-field struct)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 13:31:51 -05:00
Nick Misasi
54d0d6cc8b feat(02-01): add PluginAPI proto skeleton and parity verifier
- Create api.proto with PluginAPI service definition covering all 236
  methods from server/public/plugin/api.go
- Create api_user_team.proto with User, Session, and Team request/response
  messages with placeholder fields
- Create api_channel_post.proto with Channel, Post, and Emoji messages
- Create api_kv_config.proto with KV store, config, plugin, and logging
  messages
- Create api_file_bot.proto with File, Upload, and Bot messages
- Create api_remaining.proto with Server, Command, Preference, OAuth,
  Group, SharedChannel, Property, and Audit messages
- Add ViewUsersRestrictions to common.proto
- Add apiverify tool that parses Go API interface and proto service
  to ensure parity
- Update Makefile with new proto file mappings

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 11:24:09 -05:00
Nick Misasi
8a38e38f0d feat(03-01): add lifecycle/system hook RPCs in hooks_lifecycle.proto and hooks.proto
Define protobuf messages and PluginHooks gRPC service for lifecycle and
system hooks:
- Implemented: returns list of hooks the plugin implements
- OnActivate/OnDeactivate: plugin lifecycle events
- OnConfigurationChange: configuration change notifications
- OnInstall: plugin installation event
- OnSendDailyTelemetry: daily telemetry hook
- RunDataRetention: data retention batch processing
- OnCloudLimitsUpdated: cloud product limit changes
- ConfigurationWillBeSaved: configuration validation/modification

Also adds model types:
- OnInstallEvent: mirrors model.OnInstallEvent
- ProductLimits/FilesLimits/MessagesLimits/TeamsLimits: typed cloud limits
- ConfigJson: JSON blob wrapper for model.Config (too large for typed proto)

Updates Makefile to include new proto file mappings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 11:18:19 -05:00
Nick Misasi
99f4b588a8 feat(03-01): add shared hook context types (PluginContext) in hooks_common.proto
Add hooks_common.proto with PluginContext message that mirrors the
server/public/plugin/context.go Context struct. This provides session_id,
request_id, ip_address, accept_language, and user_agent fields for passing
hook invocation context from server to plugins.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 11:16:06 -05:00
Nick Misasi
1a8f3c0c4e feat(01-03): add error handling and RPC envelope conventions
- Add RequestContext message for request metadata (plugin_id, request_id,
  session_id, user_id) to enable logging correlation across Go/Python
- Add params field (google.protobuf.Struct) to AppError for error message
  interpolation, matching model.AppError's params field
- Document RPC envelope conventions in proto comments:
  - Request messages: {Method}Request with RequestContext as field 1
  - Response messages: {Method}Response with AppError as field 1
  - Error strategy: Response-embedded AppError (Option B) for full
    semantic preservation, gRPC status reserved for transport errors
- Regenerate Go code with new types

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 11:10:27 -05:00
Nick Misasi
ca57bca5a2 feat(01-02): add core protobuf types (User, Channel, Post, Team, FileInfo)
- Add common.proto with Empty, StringMap, and AppError messages
- Add user.proto with User message (34 fields mirroring model.User)
- Add channel.proto with Channel, ChannelType enum, ChannelBannerInfo
- Add post.proto with Post, PostMetadata, PostEmbed, PostPriority, Reaction
- Add team.proto with Team, TeamMember, TeamUnread, TeamType enum
- Add file.proto with FileInfo, FileUploadResponse, FileData
- Update Makefile to support all proto files with proper import mappings
- Remove bootstrap.proto (replaced by common.proto)
- Use google.protobuf.Struct for dynamic JSON fields (Post.props, Channel.props)
- All timestamps are int64 (milliseconds since epoch)
- All IDs are strings (26-char base32)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 11:06:42 -05:00
Nick Misasi
2e61b0e626 feat(01-01): add protobuf directory structure and bootstrap.proto
- Create server/public/pluginapi/grpc/proto/ for proto sources
- Create server/public/pluginapi/grpc/generated/go/ for generated Go code
- Add bootstrap.proto with Empty message for validating codegen pipeline
- Generate bootstrap.pb.go using protoc v6.33.4 / protoc-gen-go v1.36.6

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 10:59:17 -05:00
Ben Schumacher
97dedb9de5
Migrate from gopkg.in/yaml.v3 to github.com/goccy/go-yaml (#34510)
Some checks are pending
API / build (push) Waiting to run
Server CI / Compute Go Version (push) Waiting to run
Server CI / Check mocks (push) Blocked by required conditions
Server CI / Check go mod tidy (push) Blocked by required conditions
Server CI / check-style (push) Blocked by required conditions
Server CI / Check serialization methods for hot structs (push) Blocked by required conditions
Server CI / Vet API (push) Blocked by required conditions
Server CI / Check migration files (push) Blocked by required conditions
Server CI / Generate email templates (push) Blocked by required conditions
Server CI / Check store layers (push) Blocked by required conditions
Server CI / Check mmctl docs (push) Blocked by required conditions
Server CI / Postgres with binary parameters (push) Blocked by required conditions
Server CI / Postgres (push) Blocked by required conditions
Server CI / Postgres (FIPS) (push) Blocked by required conditions
Server CI / Generate Test Coverage (push) Blocked by required conditions
Server CI / Run mmctl tests (push) Blocked by required conditions
Server CI / Run mmctl tests (FIPS) (push) Blocked by required conditions
Server CI / Build mattermost server app (push) Blocked by required conditions
Web App CI / check-lint (push) Waiting to run
Web App CI / check-i18n (push) Waiting to run
Web App CI / check-types (push) Waiting to run
Web App CI / test (push) Waiting to run
Web App CI / build (push) Waiting to run
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-18 08:52:05 +01:00
Julien Tant
78050bb0d3
Change properties search signature to support multiple TargetIDs (#33873)
* change properties search

* add tests

* Fix calls to to the search methods

* Fix SearchPropertyFields call with wrong signature
2025-09-11 22:56:01 +00:00
Guillermo Vayá
d15b933888
[MM-64683] Implement property field counting functionality in Plugin API (#33438)
* Implement property field limit enforcement and counting functionality in Plugin API

- Added a limit of 20 property fields per group in the CreatePropertyField method.
- Introduced CountPropertyFields method to count active and all property fields, including deleted ones.
- Enhanced tests to validate the new property field limit and counting behavior.
- Updated related API and service methods to support the new functionality.

* Update server/channels/app/properties/property_field.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix vet

* fix lint error

* fix test

* fix tests

* fix test

* count properties + targets

* Update server/channels/app/plugin_api.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* remove test for limit

* fix more tests

* improve testing messages now that the limit is removed

* Apply suggestion from @calebroseland

Co-authored-by: Caleb Roseland <caleb@calebroseland.com>

* Apply suggestion from @calebroseland

Co-authored-by: Caleb Roseland <caleb@calebroseland.com>

* Apply suggestion from @calebroseland

Co-authored-by: Caleb Roseland <caleb@calebroseland.com>

* Apply suggestion from @calebroseland

Co-authored-by: Caleb Roseland <caleb@calebroseland.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Julien Tant <785518+JulienTant@users.noreply.github.com>
Co-authored-by: Caleb Roseland <caleb@calebroseland.com>
2025-09-11 12:49:14 -07:00
Jesse Hallam
8cace74692
MM-64486: Remove telemetry (#33606)
* MM-64486: Remove telemetry

Remove telemetry from Mattermost. We're no longer relying on Rudder upstream, and no longer making use of this information.

* recover mock for SystemStore.Get

* Fix TestClearPushNotificationSync by adding missing SystemStore mock

The test was failing because the SystemStore mock was missing the Get()
method that's required by the ServerId() function. Added the missing mock
to return a StringMap with SystemServerId.

* fix mocking issue

* Remove now-unused telemetry and constants

* Remove "Disable telemetry events" debug setting

* Remove empty functions

* Remove most "Telemetry tracking removed" comments

* Remove remains of DataPrefetch telemetry

* Remove now-unused prop from InviteMembersButton

* Remove trackDotMenuEvent

* Remove some more leftover comments

* Remove lingering logic related to trackingLocation

* Remove now-unused argument from useCopyText

* Remove lingering telemetry references from PreparingWorkspace

* fixup Remove trackDotMenuEvent

* Remove lingering telemetry references from signup page and password check

* Update snapshots and fix test broken by my changes

* Fix unintended behavior change in thread list filtering

Remove handleSetFilter wrapper that was accidentally modified during
telemetry removal. The function was calling clear() when switching to
unread filter, which was not the original behavior. Use setFilter
directly instead, restoring the original functionality.

* Remove unused useOpenDowngradeModal hook

The useOpenDowngradeModal hook was not being used anywhere in the codebase.

* Remove unused expandableLink from useExpandOverageUsersCheck

The expandableLink return value was not being used by any components.

* Re-add missing TeamLinkClicked performance telemetry

The mark(Mark.TeamLinkClicked) call was accidentally removed from the
handleSwitch function. This telemetry is needed for Looker-based
performance tracking.

* drop LogSettings.VerboseDiagnostics

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-09-04 18:46:18 +00:00
Agniva De Sarker
9dd8c056e7
MM-63368: Remove MySQL (#33458)
https://mattermost.atlassian.net/browse/MM-63368

```release-note
Remove MySQL support from the codebase entirely.
```
2025-07-22 20:40:55 +05:30
Ben Schumacher
9add320011
[MM-64654] Migrate to modern Go features (#31820) 2025-07-18 12:54:51 +02:00
Julien Tant
731bd7c414
MM-63285: Add property field methods to plugin API (#31035)
Co-authored-by: Claude <noreply@anthropic.com>
2025-06-10 16:10:28 -07:00
Ben Cooke
bfe90c3704
New pluginapi method for syncables (#30790)
* new pluginapi method for syncables
---------
Co-authored-by: Mattermost Build <build@mattermost.com>
2025-05-21 14:44:34 -04:00
Harshil Sharma
a76c063d85
Renamed premium SKU to Enterprise Advanced (#30882) 2025-05-02 11:34:46 +05:30