Transform meetings page into context page with tabs

Add structured organization context with 5 markdown sections (Product, Architecture, Team, Processes, Customers) editable inline. Meetings are now a tab within the context page. Moved all GraphQL queries from hooks/graph/MeetingGraph.ts into colocated components following new best practices. Updated database schema, backend services, GraphQL resolvers, and MCP API to support the new context fields and structure.

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2026-03-19 17:42:14 +01:00
parent c2a1843c67
commit a9ebeef0fa
25 changed files with 1156 additions and 380 deletions

View File

@@ -3241,3 +3241,43 @@ func (r *Resolver) UnarchiveDocumentTool(ctx context.Context, req *mcp.CallToolR
Document: types.NewDocument(document, profileIDs(approverPage)),
}, nil
}
func (r *Resolver) GetOrganizationContextTool(ctx context.Context, req *mcp.CallToolRequest, input *types.GetOrganizationContextInput) (*mcp.CallToolResult, types.GetOrganizationContextOutput, error) {
r.MustAuthorize(ctx, input.OrganizationID, probo.ActionOrganizationContextGet)
prb := r.ProboService(ctx, input.OrganizationID)
orgContext, err := prb.Organizations.GetContext(ctx, input.OrganizationID)
if err != nil {
return nil, types.GetOrganizationContextOutput{}, fmt.Errorf("cannot get organization context: %w", err)
}
return nil, types.GetOrganizationContextOutput{
OrganizationContext: types.NewOrganizationContext(orgContext),
}, nil
}
func (r *Resolver) UpdateOrganizationContextTool(ctx context.Context, req *mcp.CallToolRequest, input *types.UpdateOrganizationContextInput) (*mcp.CallToolResult, types.UpdateOrganizationContextOutput, error) {
r.MustAuthorize(ctx, input.OrganizationID, probo.ActionOrganizationContextUpdate)
prb := r.ProboService(ctx, input.OrganizationID)
orgContext, err := prb.Organizations.UpdateContext(
ctx,
probo.UpdateOrganizationContextRequest{
OrganizationID: input.OrganizationID,
Product: &input.Product,
Architecture: &input.Architecture,
Team: &input.Team,
Processes: &input.Processes,
Customers: &input.Customers,
},
)
if err != nil {
return nil, types.UpdateOrganizationContextOutput{}, fmt.Errorf("cannot update organization context: %w", err)
}
return nil, types.UpdateOrganizationContextOutput{
OrganizationContext: types.NewOrganizationContext(orgContext),
}, nil
}

View File

@@ -6323,6 +6323,79 @@ components:
$ref: "#/components/schemas/GID"
description: Deleted applicability statement ID
OrganizationContext:
type: object
required:
- organization_id
properties:
organization_id:
$ref: "#/components/schemas/GID"
description: Organization ID
product:
type: string
description: Product description
architecture:
type: string
description: Architecture description
team:
type: string
description: Team description
processes:
type: string
description: Processes description
customers:
type: string
description: Customers description
GetOrganizationContextInput:
type: object
required:
- organization_id
properties:
organization_id:
$ref: "#/components/schemas/GID"
description: Organization ID
GetOrganizationContextOutput:
type: object
required:
- organization_context
properties:
organization_context:
$ref: "#/components/schemas/OrganizationContext"
UpdateOrganizationContextInput:
type: object
required:
- organization_id
properties:
organization_id:
$ref: "#/components/schemas/GID"
description: Organization ID
product:
type: string
description: Product description
architecture:
type: string
description: Architecture description
team:
type: string
description: Team description
processes:
type: string
description: Processes description
customers:
type: string
description: Customers description
UpdateOrganizationContextOutput:
type: object
required:
- organization_context
properties:
organization_context:
$ref: "#/components/schemas/OrganizationContext"
tools:
- name: listOrganizations
description: List all organizations the user has access to
@@ -7441,3 +7514,20 @@ tools:
$ref: "#/components/schemas/DeleteApplicabilityStatementInput"
outputSchema:
$ref: "#/components/schemas/DeleteApplicabilityStatementOutput"
- name: getOrganizationContext
description: Get the organization context containing structured sections about the company
hints:
readonly: true
idempotent: true
inputSchema:
$ref: "#/components/schemas/GetOrganizationContextInput"
outputSchema:
$ref: "#/components/schemas/GetOrganizationContextOutput"
- name: updateOrganizationContext
description: Update the organization context sections (product, architecture, team, processes, customers)
hints:
readonly: false
inputSchema:
$ref: "#/components/schemas/UpdateOrganizationContextInput"
outputSchema:
$ref: "#/components/schemas/UpdateOrganizationContextOutput"

View File

@@ -0,0 +1,30 @@
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package types
import (
"go.probo.inc/probo/pkg/coredata"
)
func NewOrganizationContext(oc *coredata.OrganizationContext) *OrganizationContext {
return &OrganizationContext{
OrganizationID: oc.OrganizationID,
Product: oc.Product,
Architecture: oc.Architecture,
Team: oc.Team,
Processes: oc.Processes,
Customers: oc.Customers,
}
}