mcp-quickbase 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.sdd/tickets/RELS_relationship-management/README.md +98 -0
- package/.sdd/tickets/RELS_relationship-management/planning/analysis.md +190 -0
- package/.sdd/tickets/RELS_relationship-management/planning/architecture.md +413 -0
- package/.sdd/tickets/RELS_relationship-management/planning/plan.md +177 -0
- package/.sdd/tickets/RELS_relationship-management/planning/quality-strategy.md +335 -0
- package/.sdd/tickets/RELS_relationship-management/planning/review-updates.md +95 -0
- package/.sdd/tickets/RELS_relationship-management/planning/security-review.md +213 -0
- package/.sdd/tickets/RELS_relationship-management/planning/ticket-review.md +885 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.1001_domain-setup.md +96 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.1002_get-relationships-tool.md +142 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.1003_register-phase1-tools.md +105 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.2001_create-relationship-tool.md +151 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.2002_update-relationship-tool.md +145 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.3001_delete-relationship-tool.md +154 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.4001_integration-testing.md +159 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS.4002_final-verification.md +182 -0
- package/.sdd/tickets/RELS_relationship-management/tasks/RELS_TASK_INDEX.md +179 -0
- package/dist/tools/apps/list_tables.d.ts +5 -5
- package/dist/tools/apps/list_tables.js +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.js +4 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/relationships/create_relationship.d.ts +150 -0
- package/dist/tools/relationships/create_relationship.js +181 -0
- package/dist/tools/relationships/create_relationship.js.map +1 -0
- package/dist/tools/relationships/delete_relationship.d.ts +66 -0
- package/dist/tools/relationships/delete_relationship.js +85 -0
- package/dist/tools/relationships/delete_relationship.js.map +1 -0
- package/dist/tools/relationships/get_relationships.d.ts +126 -0
- package/dist/tools/relationships/get_relationships.js +126 -0
- package/dist/tools/relationships/get_relationships.js.map +1 -0
- package/dist/tools/relationships/index.d.ts +14 -0
- package/dist/tools/relationships/index.js +37 -0
- package/dist/tools/relationships/index.js.map +1 -0
- package/dist/tools/relationships/update_relationship.d.ts +139 -0
- package/dist/tools/relationships/update_relationship.js +168 -0
- package/dist/tools/relationships/update_relationship.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Ticket: Relationship Management
|
|
2
|
+
|
|
3
|
+
**Ticket ID:** RELS
|
|
4
|
+
**Status:** Planning Complete
|
|
5
|
+
**Created:** 2025-12-28
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
Implement full support for managing table-to-table relationships in the MCP Quickbase server. This includes four tools: `get_relationships`, `create_relationship`, `update_relationship`, and `delete_relationship`. Special attention is given to tool descriptions that clearly communicate destructive behavior to AI agents, ensuring they request user confirmation before performing irreversible operations.
|
|
10
|
+
|
|
11
|
+
## Problem Statement
|
|
12
|
+
|
|
13
|
+
The MCP Quickbase server currently lacks support for managing table-to-table relationships through the Quickbase API. Relationships are fundamental to Quickbase applications, enabling linked records, lookup fields (displaying parent data in child records), and summary fields (aggregating child data in parent records). Without this capability, agents cannot:
|
|
14
|
+
|
|
15
|
+
- Explore existing table structures and data connections
|
|
16
|
+
- Create new relationships when building applications
|
|
17
|
+
- Enhance relationships with additional calculated fields
|
|
18
|
+
- Remove relationships when refactoring applications
|
|
19
|
+
|
|
20
|
+
## Proposed Solution
|
|
21
|
+
|
|
22
|
+
Add a new `relationships` domain to the tools directory following existing patterns. Implement four tools mapping directly to the Quickbase Relationships API:
|
|
23
|
+
|
|
24
|
+
| Tool | Operation | Safety Level |
|
|
25
|
+
|------|-----------|--------------|
|
|
26
|
+
| `get_relationships` | List all relationships for a table | Safe (read-only) |
|
|
27
|
+
| `create_relationship` | Create new relationship with optional lookup/summary fields | Safe (creates new) |
|
|
28
|
+
| `update_relationship` | Add lookup/summary fields to existing relationship | Safe (additive only) |
|
|
29
|
+
| `delete_relationship` | Delete entire relationship including all lookup/summary fields | **DESTRUCTIVE** |
|
|
30
|
+
|
|
31
|
+
### Key Design Decisions
|
|
32
|
+
|
|
33
|
+
1. **Agent-Safety-First Descriptions**: Tool descriptions explicitly warn about destructive operations and recommend user confirmation
|
|
34
|
+
2. **Flat Parameter Structure**: Simple, snake_case parameters following existing conventions
|
|
35
|
+
3. **Separate Domain Directory**: `src/tools/relationships/` with domain index and individual tool files
|
|
36
|
+
|
|
37
|
+
## Relevant Agents
|
|
38
|
+
|
|
39
|
+
- **ticket-planner** (planning phase) - Completed
|
|
40
|
+
- **task-creator** (task generation) - Next step
|
|
41
|
+
- **implement-feature** (implementation) - Phases 1-3
|
|
42
|
+
- **verify-task** (verification) - Phase 4
|
|
43
|
+
- **commit-task** (commit) - Phase 4
|
|
44
|
+
|
|
45
|
+
## Deliverables
|
|
46
|
+
|
|
47
|
+
### Code Deliverables
|
|
48
|
+
|
|
49
|
+
- `src/tools/relationships/index.ts` - Domain registration
|
|
50
|
+
- `src/tools/relationships/get_relationships.ts` - GET tool
|
|
51
|
+
- `src/tools/relationships/create_relationship.ts` - POST tool
|
|
52
|
+
- `src/tools/relationships/update_relationship.ts` - POST tool (update)
|
|
53
|
+
- `src/tools/relationships/delete_relationship.ts` - DELETE tool
|
|
54
|
+
- `src/__tests__/tools/relationships.test.ts` - Unit tests
|
|
55
|
+
- Updated `src/tools/index.ts` - Registration integration
|
|
56
|
+
|
|
57
|
+
### Documentation Deliverables
|
|
58
|
+
|
|
59
|
+
Planning documents in [planning/](planning/):
|
|
60
|
+
- Comprehensive tool descriptions with safety warnings
|
|
61
|
+
- API endpoint mappings
|
|
62
|
+
- Type definitions
|
|
63
|
+
|
|
64
|
+
## Planning Documents
|
|
65
|
+
|
|
66
|
+
- [analysis.md](planning/analysis.md) - Problem analysis, API research, success criteria
|
|
67
|
+
- [architecture.md](planning/architecture.md) - Solution design, component interfaces, data flow
|
|
68
|
+
- [plan.md](planning/plan.md) - 4-phase execution plan with agent assignments
|
|
69
|
+
- [quality-strategy.md](planning/quality-strategy.md) - Testing approach, coverage requirements
|
|
70
|
+
- [security-review.md](planning/security-review.md) - Security assessment, destructive operation safeguards
|
|
71
|
+
|
|
72
|
+
## Phase Overview
|
|
73
|
+
|
|
74
|
+
| Phase | Objective | Tools |
|
|
75
|
+
|-------|-----------|-------|
|
|
76
|
+
| 1 | Foundation & Read Operations | `get_relationships` |
|
|
77
|
+
| 2 | Write Operations (Non-Destructive) | `create_relationship`, `update_relationship` |
|
|
78
|
+
| 3 | Destructive Operations with Safety | `delete_relationship` |
|
|
79
|
+
| 4 | Integration & Verification | All tools tested and registered |
|
|
80
|
+
|
|
81
|
+
## Tasks
|
|
82
|
+
|
|
83
|
+
See [tasks/](tasks/) for all ticket tasks (to be created by task-creator agent).
|
|
84
|
+
|
|
85
|
+
## API Reference
|
|
86
|
+
|
|
87
|
+
**Quickbase Relationships API Endpoints:**
|
|
88
|
+
|
|
89
|
+
| Method | Endpoint | Tool |
|
|
90
|
+
|--------|----------|------|
|
|
91
|
+
| GET | `/v1/tables/{tableId}/relationships` | `get_relationships` |
|
|
92
|
+
| POST | `/v1/tables/{tableId}/relationships` | `create_relationship` |
|
|
93
|
+
| POST | `/v1/tables/{tableId}/relationships/{relationshipId}` | `update_relationship` |
|
|
94
|
+
| DELETE | `/v1/tables/{tableId}/relationships/{relationshipId}` | `delete_relationship` |
|
|
95
|
+
|
|
96
|
+
## Next Step
|
|
97
|
+
|
|
98
|
+
**Recommended:** Run `/sdd:review RELS` to validate planning documents before creating tasks.
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Analysis: Relationship Management
|
|
2
|
+
|
|
3
|
+
## Problem Definition
|
|
4
|
+
|
|
5
|
+
The MCP Quickbase server currently lacks support for managing table-to-table relationships through the Quickbase API. Relationships are a fundamental feature in Quickbase that allow linking records between tables, creating lookup fields (to display parent data in child records), and summary fields (to aggregate child data in parent records). Without relationship management capabilities, agents cannot:
|
|
6
|
+
|
|
7
|
+
1. Query existing relationships between tables
|
|
8
|
+
2. Create new relationships to link tables
|
|
9
|
+
3. Add lookup/summary fields to existing relationships
|
|
10
|
+
4. Delete relationships when no longer needed
|
|
11
|
+
|
|
12
|
+
This gap significantly limits the utility of the MCP server for database schema management and application configuration tasks.
|
|
13
|
+
|
|
14
|
+
## Context
|
|
15
|
+
|
|
16
|
+
### Why This Work Is Needed
|
|
17
|
+
|
|
18
|
+
Quickbase applications commonly have complex table structures with multiple relationships. Common use cases include:
|
|
19
|
+
|
|
20
|
+
- **Project Management**: Projects (parent) -> Tasks (child) with lookup fields for project name, summary fields for task counts
|
|
21
|
+
- **CRM**: Customers (parent) -> Orders (child) with summary fields for total revenue
|
|
22
|
+
- **Inventory**: Warehouses (parent) -> Products (child) with lookup fields for location info
|
|
23
|
+
|
|
24
|
+
Agents need to understand and modify these relationships to:
|
|
25
|
+
- Explore application schemas
|
|
26
|
+
- Create new tables with proper relationships
|
|
27
|
+
- Add calculated fields that span relationships
|
|
28
|
+
- Refactor application structure
|
|
29
|
+
|
|
30
|
+
### Quickbase Relationships API
|
|
31
|
+
|
|
32
|
+
The Quickbase RESTful API provides four endpoints for relationship management:
|
|
33
|
+
|
|
34
|
+
| Operation | Method | Endpoint | Description |
|
|
35
|
+
|-----------|--------|----------|-------------|
|
|
36
|
+
| Get Relationships | GET | `/v1/tables/{tableId}/relationships` | List all relationships for a table |
|
|
37
|
+
| Create Relationship | POST | `/v1/tables/{tableId}/relationships` | Create a new relationship with optional lookup/summary fields |
|
|
38
|
+
| Update Relationship | POST | `/v1/tables/{tableId}/relationships/{relationshipId}` | Add lookup/summary fields to existing relationship |
|
|
39
|
+
| Delete Relationship | DELETE | `/v1/tables/{tableId}/relationships/{relationshipId}` | Delete relationship and all associated lookup/summary fields |
|
|
40
|
+
|
|
41
|
+
## Existing Solutions
|
|
42
|
+
|
|
43
|
+
### Industry Patterns
|
|
44
|
+
|
|
45
|
+
Other database management tools handle relationships similarly:
|
|
46
|
+
- **Airtable API**: Provides link fields and rollup fields with similar semantics
|
|
47
|
+
- **Notion API**: Relations and rollups follow a comparable pattern
|
|
48
|
+
- **Microsoft Power Platform**: Dataverse relationships use similar parent-child paradigms
|
|
49
|
+
|
|
50
|
+
### Codebase Patterns
|
|
51
|
+
|
|
52
|
+
The existing codebase has established patterns for tool implementation:
|
|
53
|
+
|
|
54
|
+
1. **Tool Structure** (`src/tools/base.ts`):
|
|
55
|
+
- Tools extend `BaseTool<TParams, TResult>`
|
|
56
|
+
- Implement `name`, `description`, `paramSchema`, and `run()` method
|
|
57
|
+
- Use `QuickbaseClient` for API calls
|
|
58
|
+
|
|
59
|
+
2. **Domain Organization** (`src/tools/index.ts`):
|
|
60
|
+
- Tools grouped by domain (apps, tables, fields, records, files, reports)
|
|
61
|
+
- Each domain has `index.ts` with `register*Tools()` function
|
|
62
|
+
- Exports tool classes and registration function
|
|
63
|
+
|
|
64
|
+
3. **API Client Pattern** (`src/client/quickbase.ts`):
|
|
65
|
+
- Uses `request()` method with `RequestOptions`
|
|
66
|
+
- Supports GET, POST, PUT, DELETE, PATCH methods
|
|
67
|
+
- Automatic retry, caching (for GET), and rate limiting
|
|
68
|
+
|
|
69
|
+
4. **Type Definitions**:
|
|
70
|
+
- Interfaces for params and results defined in tool files
|
|
71
|
+
- JSON Schema for `paramSchema` used by MCP protocol
|
|
72
|
+
- Zod validation happens in base class
|
|
73
|
+
|
|
74
|
+
## Current State
|
|
75
|
+
|
|
76
|
+
The codebase currently supports:
|
|
77
|
+
- **Apps**: create, update, list tables
|
|
78
|
+
- **Tables**: create, update, get fields
|
|
79
|
+
- **Fields**: create, update
|
|
80
|
+
- **Records**: create, update, query, bulk operations
|
|
81
|
+
- **Files**: upload, download
|
|
82
|
+
- **Reports**: run
|
|
83
|
+
|
|
84
|
+
Relationships are **not** currently supported. The `getTableFields` tool returns field information but does not include relationship metadata.
|
|
85
|
+
|
|
86
|
+
## Research Findings
|
|
87
|
+
|
|
88
|
+
### API Response Structures
|
|
89
|
+
|
|
90
|
+
From the Quickbase API documentation (via Microsoft Learn connector reference):
|
|
91
|
+
|
|
92
|
+
**Relationship Object**:
|
|
93
|
+
```typescript
|
|
94
|
+
interface Relationship {
|
|
95
|
+
id: number; // Relationship ID (foreign key field ID)
|
|
96
|
+
parentTableId: string; // Parent table DBID
|
|
97
|
+
childTableId: string; // Child table DBID
|
|
98
|
+
foreignKeyField: { // Reference field in child table
|
|
99
|
+
id: number;
|
|
100
|
+
label: string;
|
|
101
|
+
type: string;
|
|
102
|
+
};
|
|
103
|
+
isCrossApp: boolean; // Whether cross-app relationship
|
|
104
|
+
lookupFields: Array<{ // Lookup fields from parent
|
|
105
|
+
id: number;
|
|
106
|
+
label: string;
|
|
107
|
+
type: string;
|
|
108
|
+
}>;
|
|
109
|
+
summaryFields: Array<{ // Summary fields in parent
|
|
110
|
+
id: number;
|
|
111
|
+
label: string;
|
|
112
|
+
type: string;
|
|
113
|
+
}>;
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Get Relationships Response**:
|
|
118
|
+
```typescript
|
|
119
|
+
interface GetRelationshipsResponse {
|
|
120
|
+
relationships: Relationship[];
|
|
121
|
+
metadata: {
|
|
122
|
+
skip: number;
|
|
123
|
+
totalRelationships: number;
|
|
124
|
+
numRelationships: number;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Destructive Operation Warning
|
|
130
|
+
|
|
131
|
+
**DELETE Relationship is highly destructive**:
|
|
132
|
+
- Deletes ALL lookup fields associated with the relationship
|
|
133
|
+
- Deletes ALL summary fields associated with the relationship
|
|
134
|
+
- Data in those fields is permanently lost
|
|
135
|
+
- The reference field itself is NOT deleted
|
|
136
|
+
- Cannot be undone
|
|
137
|
+
|
|
138
|
+
This is the most destructive operation in this feature set and requires special handling for agent safety.
|
|
139
|
+
|
|
140
|
+
### Key Constraints
|
|
141
|
+
|
|
142
|
+
1. **Same-App Only**: Relationships can only be created between tables in the same app (cross-app relationships are read-only)
|
|
143
|
+
2. **Reference Field Persistence**: The reference (foreign key) field remains after relationship deletion
|
|
144
|
+
3. **Additive Updates**: Updating relationships only adds fields; existing fields are not deleted
|
|
145
|
+
4. **Summary Field Complexity**: Summary fields require accumulation type (SUM, COUNT, AVG, MAX, MIN) and optional WHERE filter
|
|
146
|
+
|
|
147
|
+
## Constraints
|
|
148
|
+
|
|
149
|
+
### Technical Constraints
|
|
150
|
+
|
|
151
|
+
1. **Quickbase API Limits**: Standard rate limiting applies (handled by existing client)
|
|
152
|
+
2. **Table ID Required**: All operations require the child table ID
|
|
153
|
+
3. **Relationship ID**: Required for update/delete; equals the foreign key field ID
|
|
154
|
+
4. **Field Types**: Lookup/summary field types are determined by source fields
|
|
155
|
+
|
|
156
|
+
### Business Constraints
|
|
157
|
+
|
|
158
|
+
1. **Destructive Operations**: Must warn agents clearly about data loss
|
|
159
|
+
2. **User Confirmation**: Destructive operations should request user confirmation
|
|
160
|
+
3. **Consistency**: Must follow existing tool patterns and naming conventions
|
|
161
|
+
|
|
162
|
+
### Time Constraints
|
|
163
|
+
|
|
164
|
+
1. Focus on core CRUD operations first
|
|
165
|
+
2. Advanced features (cross-app relationship viewing) can be deferred
|
|
166
|
+
|
|
167
|
+
## Success Criteria
|
|
168
|
+
|
|
169
|
+
### Functional Requirements
|
|
170
|
+
|
|
171
|
+
- [ ] `get_relationships` tool lists all relationships for a table with complete metadata
|
|
172
|
+
- [ ] `create_relationship` tool creates relationships with optional lookup/summary fields
|
|
173
|
+
- [ ] `update_relationship` tool adds lookup/summary fields to existing relationships
|
|
174
|
+
- [ ] `delete_relationship` tool removes relationships with appropriate warnings
|
|
175
|
+
|
|
176
|
+
### Non-Functional Requirements
|
|
177
|
+
|
|
178
|
+
- [ ] Tool descriptions clearly indicate destructive operations
|
|
179
|
+
- [ ] Delete operation description strongly warns about data loss
|
|
180
|
+
- [ ] All tools follow existing codebase patterns (BaseTool, naming, types)
|
|
181
|
+
- [ ] Unit test coverage >= 35% (existing threshold)
|
|
182
|
+
- [ ] All tools include parameter validation via JSON Schema
|
|
183
|
+
- [ ] Error messages are actionable and specific
|
|
184
|
+
|
|
185
|
+
### Agent Safety Requirements
|
|
186
|
+
|
|
187
|
+
- [ ] Destructive tool descriptions include "DESTRUCTIVE" or "WARNING" labels
|
|
188
|
+
- [ ] Delete tool description explains exactly what will be lost
|
|
189
|
+
- [ ] Descriptions help agents understand when each tool is appropriate
|
|
190
|
+
- [ ] Create/Update operations clearly explain their non-destructive nature
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
# Architecture: Relationship Management
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This feature adds a new `relationships` domain to the MCP Quickbase server, following the established patterns used by other domains (apps, tables, fields, etc.). The implementation consists of four tools mapping directly to the Quickbase Relationships API endpoints, with special attention to tool descriptions that clearly communicate destructive behavior to AI agents.
|
|
6
|
+
|
|
7
|
+
## Design Decisions
|
|
8
|
+
|
|
9
|
+
### Decision 1: Separate Relationships Domain
|
|
10
|
+
|
|
11
|
+
**Context:** Relationships could be implemented as part of the `tables` domain or as a new domain.
|
|
12
|
+
|
|
13
|
+
**Decision:** Create a new `src/tools/relationships/` domain directory.
|
|
14
|
+
|
|
15
|
+
**Rationale:**
|
|
16
|
+
- Follows existing pattern where each API resource area has its own domain
|
|
17
|
+
- Provides clear separation of concerns
|
|
18
|
+
- Allows for future expansion (e.g., cross-app relationship tools)
|
|
19
|
+
- Consistent with how `fields`, `records`, `files`, `reports` are organized
|
|
20
|
+
|
|
21
|
+
### Decision 2: Agent-Safety-First Tool Descriptions
|
|
22
|
+
|
|
23
|
+
**Context:** The delete operation is highly destructive, and agents may use tools without fully understanding consequences.
|
|
24
|
+
|
|
25
|
+
**Decision:** Implement a description format that:
|
|
26
|
+
1. Starts with clear action statement
|
|
27
|
+
2. Includes WARNING label for destructive operations
|
|
28
|
+
3. Lists exactly what will be deleted/lost
|
|
29
|
+
4. Suggests safer alternatives where applicable
|
|
30
|
+
5. Recommends user confirmation for destructive operations
|
|
31
|
+
|
|
32
|
+
**Rationale:**
|
|
33
|
+
- MCP tool descriptions are the primary way agents understand tool behavior
|
|
34
|
+
- Explicit warnings reduce risk of unintended data loss
|
|
35
|
+
- Following patterns from other enterprise API tools
|
|
36
|
+
- Aligns with user requirement for "clearly indicate potentially destructive changes"
|
|
37
|
+
|
|
38
|
+
### Decision 3: Flat Parameter Structure
|
|
39
|
+
|
|
40
|
+
**Context:** The API has nested structures for summary fields (accumulationType, where, label).
|
|
41
|
+
|
|
42
|
+
**Decision:** Use flat parameter structures with clear naming:
|
|
43
|
+
```typescript
|
|
44
|
+
{
|
|
45
|
+
summary_field_id: number;
|
|
46
|
+
summary_label: string;
|
|
47
|
+
summary_accumulation_type: string;
|
|
48
|
+
summary_where?: string;
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Rationale:**
|
|
53
|
+
- Matches existing tool patterns (e.g., `create_field`)
|
|
54
|
+
- Simpler for agents to construct
|
|
55
|
+
- Reduces nesting complexity in JSON Schema
|
|
56
|
+
- Clear parameter names are self-documenting
|
|
57
|
+
|
|
58
|
+
### Decision 4: TypeScript Interfaces for API Types
|
|
59
|
+
|
|
60
|
+
**Context:** Need to represent Quickbase API response types.
|
|
61
|
+
|
|
62
|
+
**Decision:** Define interfaces in each tool file for params and results, following existing patterns.
|
|
63
|
+
|
|
64
|
+
**Rationale:**
|
|
65
|
+
- Consistent with existing codebase (see `create_table.ts`, `create_field.ts`)
|
|
66
|
+
- Keeps related types close to their usage
|
|
67
|
+
- Enables strong typing throughout
|
|
68
|
+
|
|
69
|
+
## Technology Choices
|
|
70
|
+
|
|
71
|
+
| Component | Choice | Rationale |
|
|
72
|
+
|-----------|--------|-----------|
|
|
73
|
+
| Language | TypeScript | Existing codebase uses TypeScript with strict mode |
|
|
74
|
+
| Validation | Zod (via base class) | Already integrated in BaseTool |
|
|
75
|
+
| HTTP Client | QuickbaseClient | Existing client with retry, caching, rate limiting |
|
|
76
|
+
| Testing | Jest | Existing test framework |
|
|
77
|
+
| Linting | ESLint + Prettier | Existing configuration |
|
|
78
|
+
|
|
79
|
+
## Component Design
|
|
80
|
+
|
|
81
|
+
### Directory Structure
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
src/tools/relationships/
|
|
85
|
+
index.ts # Domain registration and exports
|
|
86
|
+
get_relationships.ts # GET /relationships tool
|
|
87
|
+
create_relationship.ts # POST /relationships tool
|
|
88
|
+
update_relationship.ts # POST /relationships/{id} tool
|
|
89
|
+
delete_relationship.ts # DELETE /relationships/{id} tool
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Component 1: GetRelationshipsTool
|
|
93
|
+
|
|
94
|
+
**Responsibilities:**
|
|
95
|
+
- Query all relationships for a given table
|
|
96
|
+
- Support pagination (skip parameter)
|
|
97
|
+
- Return relationship metadata including lookup and summary fields
|
|
98
|
+
|
|
99
|
+
**Interface:**
|
|
100
|
+
```typescript
|
|
101
|
+
interface GetRelationshipsParams {
|
|
102
|
+
table_id: string; // Required: Child table ID (DBID)
|
|
103
|
+
skip?: number; // Optional: Pagination offset
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
interface GetRelationshipsResult {
|
|
107
|
+
relationships: Relationship[];
|
|
108
|
+
metadata: {
|
|
109
|
+
totalRelationships: number;
|
|
110
|
+
numRelationships: number;
|
|
111
|
+
skip: number;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Description Format:**
|
|
117
|
+
```
|
|
118
|
+
Gets all table-to-table relationships for a specified table. Returns both relationships
|
|
119
|
+
where this table is the child (has reference fields pointing to parents) and where this
|
|
120
|
+
table is the parent (has child tables referencing it). Use this tool to explore table
|
|
121
|
+
structure and understand data connections before modifying relationships.
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Component 2: CreateRelationshipTool
|
|
125
|
+
|
|
126
|
+
**Responsibilities:**
|
|
127
|
+
- Create new relationship between tables
|
|
128
|
+
- Optionally create lookup fields during creation
|
|
129
|
+
- Optionally create summary field during creation
|
|
130
|
+
|
|
131
|
+
**Interface:**
|
|
132
|
+
```typescript
|
|
133
|
+
interface CreateRelationshipParams {
|
|
134
|
+
table_id: string; // Required: Child table ID
|
|
135
|
+
parent_table_id: string; // Required: Parent table ID
|
|
136
|
+
foreign_key_label?: string; // Optional: Label for reference field
|
|
137
|
+
lookup_field_ids?: number[]; // Optional: Parent field IDs to create as lookups
|
|
138
|
+
summary_field_id?: number; // Optional: Child field ID to summarize
|
|
139
|
+
summary_label?: string; // Optional: Label for summary field
|
|
140
|
+
summary_accumulation_type?: string; // Required if summary_field_id: SUM/COUNT/AVG/MAX/MIN
|
|
141
|
+
summary_where?: string; // Optional: Quickbase query filter for summary
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Note: JSON Schema validation must enforce that summary_accumulation_type is required
|
|
145
|
+
// when summary_field_id is provided. Use conditional validation in paramSchema.
|
|
146
|
+
|
|
147
|
+
interface CreateRelationshipResult {
|
|
148
|
+
id: number;
|
|
149
|
+
parentTableId: string;
|
|
150
|
+
childTableId: string;
|
|
151
|
+
foreignKeyField: FieldInfo;
|
|
152
|
+
lookupFields: FieldInfo[];
|
|
153
|
+
summaryFields: FieldInfo[];
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Description Format:**
|
|
158
|
+
```
|
|
159
|
+
Creates a new table-to-table relationship linking a child table to a parent table.
|
|
160
|
+
This creates a reference field in the child table. Optionally creates lookup fields
|
|
161
|
+
(to display parent data in child records) and/or a summary field (to aggregate child
|
|
162
|
+
data in parent records). Relationships can only be created between tables in the same
|
|
163
|
+
application. This operation is SAFE and does not modify existing data.
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Component 3: UpdateRelationshipTool
|
|
167
|
+
|
|
168
|
+
**Responsibilities:**
|
|
169
|
+
- Add lookup fields to existing relationship
|
|
170
|
+
- Add summary field to existing relationship
|
|
171
|
+
- Does NOT delete existing fields (additive only)
|
|
172
|
+
|
|
173
|
+
**Interface:**
|
|
174
|
+
```typescript
|
|
175
|
+
interface UpdateRelationshipParams {
|
|
176
|
+
table_id: string; // Required: Child table ID
|
|
177
|
+
relationship_id: number; // Required: Relationship ID (foreign key field ID)
|
|
178
|
+
lookup_field_ids?: number[]; // Optional: Additional parent field IDs for lookups
|
|
179
|
+
summary_field_id?: number; // Optional: Child field ID to summarize
|
|
180
|
+
summary_label?: string; // Optional: Label for summary field
|
|
181
|
+
summary_accumulation_type?: string; // Required if summary_field_id
|
|
182
|
+
summary_where?: string; // Optional: Quickbase query filter
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Note: JSON Schema validation must enforce that summary_accumulation_type is required
|
|
186
|
+
// when summary_field_id is provided. Use conditional validation in paramSchema.
|
|
187
|
+
|
|
188
|
+
interface UpdateRelationshipResult {
|
|
189
|
+
id: number;
|
|
190
|
+
parentTableId: string;
|
|
191
|
+
childTableId: string;
|
|
192
|
+
foreignKeyField: FieldInfo;
|
|
193
|
+
lookupFields: FieldInfo[];
|
|
194
|
+
summaryFields: FieldInfo[];
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Description Format:**
|
|
199
|
+
```
|
|
200
|
+
Adds lookup fields and/or summary fields to an existing relationship. This operation
|
|
201
|
+
is ADDITIVE ONLY - it will not delete existing lookup or summary fields. Use this to
|
|
202
|
+
enhance relationships with additional calculated fields. To remove fields from a
|
|
203
|
+
relationship, you must delete them individually using the field deletion tools.
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Component 4: DeleteRelationshipTool
|
|
207
|
+
|
|
208
|
+
**Responsibilities:**
|
|
209
|
+
- Delete entire relationship
|
|
210
|
+
- Clearly warn about data loss in description
|
|
211
|
+
- Return confirmation of what was deleted
|
|
212
|
+
|
|
213
|
+
**Interface:**
|
|
214
|
+
```typescript
|
|
215
|
+
interface DeleteRelationshipParams {
|
|
216
|
+
table_id: string; // Required: Child table ID
|
|
217
|
+
relationship_id: number; // Required: Relationship ID to delete
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
interface DeleteRelationshipResult {
|
|
221
|
+
relationshipId: number;
|
|
222
|
+
deleted: boolean;
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Description Format (Critical for Agent Safety):**
|
|
227
|
+
```
|
|
228
|
+
WARNING: DESTRUCTIVE OPERATION - Permanently deletes an entire table-to-table
|
|
229
|
+
relationship INCLUDING ALL LOOKUP AND SUMMARY FIELDS associated with it. All data
|
|
230
|
+
in those fields will be permanently lost and CANNOT be recovered. The reference
|
|
231
|
+
field in the child table will NOT be deleted (it will remain and may need to be
|
|
232
|
+
manually deleted using field deletion tools if no longer needed). Before using
|
|
233
|
+
this tool:
|
|
234
|
+
1. Use get_relationships to see what fields will be deleted
|
|
235
|
+
2. Confirm with the user that they want to proceed
|
|
236
|
+
3. Consider if you only need to delete specific fields instead
|
|
237
|
+
|
|
238
|
+
Only use this tool when you are certain the entire relationship should be removed.
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Shared Types
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
interface FieldInfo {
|
|
245
|
+
id: number;
|
|
246
|
+
label: string;
|
|
247
|
+
type: string;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
interface Relationship {
|
|
251
|
+
id: number;
|
|
252
|
+
parentTableId: string;
|
|
253
|
+
childTableId: string;
|
|
254
|
+
foreignKeyField: FieldInfo;
|
|
255
|
+
isCrossApp: boolean;
|
|
256
|
+
lookupFields: FieldInfo[];
|
|
257
|
+
summaryFields: FieldInfo[];
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Data Flow
|
|
262
|
+
|
|
263
|
+
### Get Relationships Flow
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
Agent Request
|
|
267
|
+
|
|
|
268
|
+
v
|
|
269
|
+
GetRelationshipsTool.execute(params)
|
|
270
|
+
|
|
|
271
|
+
v
|
|
272
|
+
BaseTool.validateParams(params)
|
|
273
|
+
|
|
|
274
|
+
v
|
|
275
|
+
QuickbaseClient.request({
|
|
276
|
+
method: 'GET',
|
|
277
|
+
path: `/tables/${tableId}/relationships`,
|
|
278
|
+
params: { skip }
|
|
279
|
+
})
|
|
280
|
+
|
|
|
281
|
+
v
|
|
282
|
+
Transform API Response
|
|
283
|
+
|
|
|
284
|
+
v
|
|
285
|
+
Return GetRelationshipsResult
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Create Relationship Flow
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
Agent Request
|
|
292
|
+
|
|
|
293
|
+
v
|
|
294
|
+
CreateRelationshipTool.execute(params)
|
|
295
|
+
|
|
|
296
|
+
v
|
|
297
|
+
BaseTool.validateParams(params)
|
|
298
|
+
|
|
|
299
|
+
v
|
|
300
|
+
Build Request Body (parentTableId, lookupFieldIds, summaryFields)
|
|
301
|
+
|
|
|
302
|
+
v
|
|
303
|
+
QuickbaseClient.request({
|
|
304
|
+
method: 'POST',
|
|
305
|
+
path: `/tables/${tableId}/relationships`,
|
|
306
|
+
body: requestBody
|
|
307
|
+
})
|
|
308
|
+
|
|
|
309
|
+
v
|
|
310
|
+
Transform API Response
|
|
311
|
+
|
|
|
312
|
+
v
|
|
313
|
+
Return CreateRelationshipResult
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Delete Relationship Flow
|
|
317
|
+
|
|
318
|
+
```
|
|
319
|
+
Agent Request
|
|
320
|
+
|
|
|
321
|
+
v
|
|
322
|
+
DeleteRelationshipTool.execute(params)
|
|
323
|
+
|
|
|
324
|
+
v
|
|
325
|
+
BaseTool.validateParams(params)
|
|
326
|
+
|
|
|
327
|
+
v
|
|
328
|
+
QuickbaseClient.request({
|
|
329
|
+
method: 'DELETE',
|
|
330
|
+
path: `/tables/${tableId}/relationships/${relationshipId}`
|
|
331
|
+
})
|
|
332
|
+
|
|
|
333
|
+
v
|
|
334
|
+
Return DeleteRelationshipResult (confirmation)
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## Integration Points
|
|
338
|
+
|
|
339
|
+
### Tool Registration
|
|
340
|
+
|
|
341
|
+
Update `src/tools/index.ts`:
|
|
342
|
+
```typescript
|
|
343
|
+
import { registerRelationshipTools } from './relationships';
|
|
344
|
+
|
|
345
|
+
export function initializeTools(client: QuickbaseClient, cacheService: CacheService): void {
|
|
346
|
+
// ... existing registrations ...
|
|
347
|
+
|
|
348
|
+
// Register relationship management tools
|
|
349
|
+
registerRelationshipTools(client);
|
|
350
|
+
|
|
351
|
+
// ...
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export * from './relationships';
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
### API Endpoints
|
|
358
|
+
|
|
359
|
+
All tools use the existing `QuickbaseClient.request()` method with these endpoints:
|
|
360
|
+
|
|
361
|
+
| Tool | Method | Path |
|
|
362
|
+
|------|--------|------|
|
|
363
|
+
| get_relationships | GET | `/tables/{tableId}/relationships` |
|
|
364
|
+
| create_relationship | POST | `/tables/{tableId}/relationships` |
|
|
365
|
+
| update_relationship | POST | `/tables/{tableId}/relationships/{relationshipId}` |
|
|
366
|
+
| delete_relationship | DELETE | `/tables/{tableId}/relationships/{relationshipId}` |
|
|
367
|
+
|
|
368
|
+
### Caching Behavior
|
|
369
|
+
|
|
370
|
+
- GET requests are cached by `QuickbaseClient` by default
|
|
371
|
+
- Create/Update/Delete requests skip cache and may invalidate related cached data
|
|
372
|
+
- Consider adding `skipCache: true` for relationship queries if stale data is problematic
|
|
373
|
+
|
|
374
|
+
## Performance Considerations
|
|
375
|
+
|
|
376
|
+
### Rate Limiting
|
|
377
|
+
|
|
378
|
+
- Existing rate limiter (10 req/sec default) handles all requests
|
|
379
|
+
- Relationship operations are typically low-volume
|
|
380
|
+
- No special performance optimizations needed
|
|
381
|
+
|
|
382
|
+
### Response Size
|
|
383
|
+
|
|
384
|
+
- `get_relationships` may return large responses for tables with many relationships
|
|
385
|
+
- Pagination (skip parameter) is available for large result sets
|
|
386
|
+
- No need for custom pagination handling beyond exposing skip parameter
|
|
387
|
+
|
|
388
|
+
## Maintainability
|
|
389
|
+
|
|
390
|
+
### Code Organization
|
|
391
|
+
|
|
392
|
+
- Each tool in its own file with params/result interfaces
|
|
393
|
+
- Shared types can be extracted to a types file if needed later
|
|
394
|
+
- Registration pattern keeps index.ts clean
|
|
395
|
+
|
|
396
|
+
### Error Handling
|
|
397
|
+
|
|
398
|
+
- Use existing `ApiResponse` pattern with success/error states
|
|
399
|
+
- Throw descriptive errors that bubble up through BaseTool
|
|
400
|
+
- Include table ID and relationship ID in error context
|
|
401
|
+
|
|
402
|
+
### Documentation
|
|
403
|
+
|
|
404
|
+
- Tool descriptions serve as primary documentation for agents
|
|
405
|
+
- JSDoc comments on interfaces for developer documentation
|
|
406
|
+
- README update for human users
|
|
407
|
+
|
|
408
|
+
### Testing Strategy
|
|
409
|
+
|
|
410
|
+
- Unit tests for each tool following existing patterns
|
|
411
|
+
- Mock QuickbaseClient for isolation
|
|
412
|
+
- Test success, validation errors, API errors, and edge cases
|
|
413
|
+
- Specific tests for destructive operation handling
|